ente/server/pkg/controller/user/user_delete.go
2024-03-01 13:37:01 +05:30

92 lines
3 KiB
Go

package user
import (
"encoding/base64"
"github.com/ente-io/museum/ente"
enteJWT "github.com/ente-io/museum/ente/jwt"
"github.com/ente-io/museum/pkg/utils/auth"
"github.com/ente-io/museum/pkg/utils/crypto"
"github.com/ente-io/stacktrace"
"github.com/gin-contrib/requestid"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
func (c *UserController) GetDeleteChallengeToken(ctx *gin.Context) (*ente.DeleteChallengeResponse, error) {
userID := auth.GetUserID(ctx.Request.Header)
user, err := c.UserRepo.Get(userID)
if err != nil {
return nil, stacktrace.Propagate(err, "")
}
keyAttributes, err := c.UserRepo.GetKeyAttributes(userID)
if err != nil {
return nil, stacktrace.Propagate(err, "")
}
logger := logrus.WithFields(logrus.Fields{
"user_id": userID,
"user_email": user.Email,
"req_id": requestid.Get(ctx),
"req_ctx": "request_self_delete",
})
logger.Info("User initiated self-delete")
subscription, err := c.BillingController.GetSubscription(ctx, userID)
if err != nil {
return nil, stacktrace.Propagate(err, "")
}
/* todo: add check to see if there's pending abuse report or if user's master password
was changed in last X days.
*/
shouldNotifyDiscord := subscription.ProductID != ente.FreePlanProductID
if shouldNotifyDiscord {
go c.DiscordController.NotifyAccountDelete(user.ID, string(subscription.PaymentProvider), subscription.ProductID)
}
token, err := c.GetJWTToken(userID, enteJWT.DELETE_ACCOUNT)
if err != nil {
return nil, stacktrace.Propagate(err, "")
}
encryptedToken, err := crypto.GetEncryptedToken(base64.StdEncoding.EncodeToString([]byte(token)), keyAttributes.PublicKey)
if err != nil {
return nil, stacktrace.Propagate(err, "")
}
return &ente.DeleteChallengeResponse{
EncryptedChallenge: &encryptedToken,
AllowDelete: true,
}, nil
}
func (c *UserController) SelfDeleteAccount(ctx *gin.Context, req ente.DeleteAccountRequest) (*ente.DeleteAccountResponse, error) {
userID := auth.GetUserID(ctx.Request.Header)
tokenUserID, err := c.ValidateJWTToken(req.Challenge, enteJWT.DELETE_ACCOUNT)
if err != nil {
return nil, stacktrace.Propagate(err, "failed to validate jwt token")
}
if tokenUserID != userID {
return nil, stacktrace.Propagate(ente.ErrPermissionDenied, "jwtToken belongs to different user")
}
user, err := c.UserRepo.Get(userID)
if err != nil {
return nil, stacktrace.Propagate(err, "")
}
_, err = c.BillingController.GetSubscription(ctx, userID)
if err != nil {
return nil, stacktrace.Propagate(err, "")
}
logger := logrus.WithFields(logrus.Fields{
"user_id": userID,
"user_email": user.Email,
"req_id": requestid.Get(ctx),
"req_ctx": "self_account_deletion",
})
resp, err := c.HandleAccountDeletion(ctx, userID, logger)
if err != nil {
return nil, stacktrace.Propagate(err, "")
}
// Update reason, ignore failure in updating reason
updateErr := c.UserRepo.UpdateDeleteFeedback(userID, req.GetReasonAttr())
if updateErr != nil {
logger.WithError(updateErr).Error("failed to update delete feedback")
}
return resp, nil
}