mirror of
https://github.com/ente-io/ente.git
synced 2025-05-05 04:47:41 +00:00
131 lines
4.2 KiB
Go
131 lines
4.2 KiB
Go
package emergency
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/ente-io/museum/pkg/controller"
|
|
"github.com/ente-io/museum/pkg/controller/lock"
|
|
|
|
"github.com/ente-io/museum/ente"
|
|
"github.com/ente-io/museum/pkg/controller/user"
|
|
"github.com/ente-io/museum/pkg/repo"
|
|
"github.com/ente-io/museum/pkg/repo/emergency"
|
|
"github.com/ente-io/stacktrace"
|
|
"github.com/gin-gonic/gin"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type Controller struct {
|
|
Repo *emergency.Repository
|
|
UserRepo *repo.UserRepository
|
|
UserCtrl *user.UserController
|
|
PasskeyController *controller.PasskeyController
|
|
LockCtrl *lock.LockController
|
|
isReminderCronRunning bool
|
|
}
|
|
|
|
func (c *Controller) UpdateContact(ctx *gin.Context,
|
|
userID int64,
|
|
req ente.UpdateContact) error {
|
|
if err := validateUpdateReq(userID, req); err != nil {
|
|
return stacktrace.Propagate(err, "")
|
|
}
|
|
if req.State == ente.ContactDenied || req.State == ente.ContactLeft || req.State == ente.UserRevokedContact {
|
|
activeSessions, sessionErr := c.Repo.GetActiveSessions(ctx, req.UserID, req.EmergencyContactID)
|
|
if sessionErr != nil {
|
|
return stacktrace.Propagate(sessionErr, "")
|
|
}
|
|
for _, session := range activeSessions {
|
|
if req.State == ente.UserRevokedContact {
|
|
rejErr := c.RejectRecovery(ctx, userID, ente.RecoveryIdentifier{
|
|
ID: session.ID,
|
|
UserID: session.UserID,
|
|
EmergencyContactID: session.EmergencyContactID,
|
|
})
|
|
if rejErr != nil {
|
|
return stacktrace.Propagate(rejErr, "failed to reject recovery")
|
|
}
|
|
} else {
|
|
stopErr := c.StopRecovery(ctx, userID, ente.RecoveryIdentifier{
|
|
ID: session.ID,
|
|
UserID: session.UserID,
|
|
EmergencyContactID: session.EmergencyContactID,
|
|
})
|
|
if stopErr != nil {
|
|
return stacktrace.Propagate(stopErr, "failed to stop recovery")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
hasUpdate, err := c.Repo.UpdateState(ctx, req.UserID, req.EmergencyContactID, req.State)
|
|
if !hasUpdate {
|
|
log.WithField("userID", userID).WithField("req", req).
|
|
Warn("No update applied for emergency contact")
|
|
} else {
|
|
go c.sendContactNotification(ctx, req.UserID, req.EmergencyContactID, req.State)
|
|
}
|
|
if err != nil {
|
|
return stacktrace.Propagate(err, "")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *Controller) HandleAccountDeletion(ctx *gin.Context, userID int64, logger *log.Entry) error {
|
|
logger.Info("Clean up emergency contacts on account deletion")
|
|
contacts, err := c.Repo.GetActiveContactForUser(ctx, userID)
|
|
if err != nil {
|
|
return stacktrace.Propagate(err, "")
|
|
}
|
|
if len(contacts) == 0 {
|
|
return nil
|
|
}
|
|
for _, contact := range contacts {
|
|
if contact.UserID == userID {
|
|
logger.Info("Removing emergency contact from user side")
|
|
removeErr := c.UpdateContact(ctx, userID, ente.UpdateContact{
|
|
UserID: userID,
|
|
EmergencyContactID: contact.EmergencyContactID,
|
|
State: ente.UserRevokedContact,
|
|
})
|
|
if removeErr != nil {
|
|
return stacktrace.Propagate(removeErr, "")
|
|
}
|
|
} else {
|
|
logger.Info("Removing user from emergency contact side")
|
|
leaveErr := c.UpdateContact(ctx, userID, ente.UpdateContact{
|
|
UserID: contact.UserID,
|
|
EmergencyContactID: userID,
|
|
State: ente.ContactLeft,
|
|
})
|
|
if leaveErr != nil {
|
|
return stacktrace.Propagate(leaveErr, "")
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validateUpdateReq(userID int64, req ente.UpdateContact) error {
|
|
if req.EmergencyContactID == req.UserID {
|
|
return stacktrace.Propagate(ente.NewBadRequestWithMessage("contact and user can not be same"), "")
|
|
}
|
|
if req.EmergencyContactID != userID && req.UserID != userID {
|
|
return stacktrace.Propagate(ente.ErrPermissionDenied, "user can only update his own state")
|
|
}
|
|
|
|
isActorContact := userID == req.EmergencyContactID
|
|
if isActorContact {
|
|
if req.State == ente.ContactAccepted ||
|
|
req.State == ente.ContactLeft ||
|
|
req.State == ente.ContactDenied {
|
|
return nil
|
|
}
|
|
return stacktrace.Propagate(ente.NewBadRequestWithMessage(fmt.Sprintf("Can not update state to %s", req.State)), "")
|
|
} else {
|
|
if req.State == ente.UserInvitedContact ||
|
|
req.State == ente.UserRevokedContact {
|
|
return nil
|
|
}
|
|
return stacktrace.Propagate(ente.NewBadRequestWithMessage(fmt.Sprintf("Can not update state to %s", req.State)), "")
|
|
}
|
|
}
|