small user service refactoring

This commit is contained in:
Sergey Chubaryan 2025-02-21 17:54:09 +03:00
parent 3d1fe25dcb
commit a27c8669fc
4 changed files with 78 additions and 64 deletions

View File

@ -16,7 +16,7 @@ type inputSendRestorePassword struct {
func NewUserSendRestorePasswordHandler(log logger.Logger, userService services.UserService) gin.HandlerFunc {
return httpserver.WrapGin(log,
func(ctx context.Context, input inputSendRestorePassword) (interface{}, error) {
err := userService.SendEmailForgotPassword(ctx, input.Email)
err := userService.RequestRestorePassword(ctx, input.Email)
return nil, err
},
)

View File

@ -16,7 +16,7 @@ type inputSendVerify struct {
func NewUserSendVerifyEmailHandler(log logger.Logger, userService services.UserService) gin.HandlerFunc {
return httpserver.WrapGin(log,
func(ctx context.Context, input inputSendVerify) (interface{}, error) {
err := userService.SendEmailVerifyUser(ctx, input.Email)
err := userService.RequestVerifyUser(ctx, input.Email)
return nil, err
},
)

View File

@ -91,7 +91,9 @@ func (u *userRepo) GetUserById(ctx context.Context, id string) (*models.UserDTO,
_, span := u.tracer.Start(ctx, "postgres::GetUserById")
defer span.End()
query := `select id, email, secret, full_name, email_verified from users where id = $1;`
query := `
select id, email, secret, full_name, email_verified
from users where id = $1 and activated;`
row := u.db.QueryRowContext(ctx, query, id)
dto := &models.UserDTO{}
@ -110,7 +112,8 @@ func (u *userRepo) GetUserByEmail(ctx context.Context, login string) (*models.Us
_, span := u.tracer.Start(ctx, "postgres::GetUserByEmail")
defer span.End()
query := `select id, email, secret, full_name, email_verified from users where email = $1;`
query := `select id, email, secret, full_name, email_verified
from users where email = $1 and activated;`
row := u.db.QueryRowContext(ctx, query, login)
dto := &models.UserDTO{}

View File

@ -32,13 +32,16 @@ type UserService interface {
CreateUser(ctx context.Context, params UserCreateParams) (*models.UserDTO, error)
AuthenticateUser(ctx context.Context, login, password string) (string, error)
ValidateAuthToken(ctx context.Context, tokenStr string) (*models.UserDTO, error)
// TODO: implement user deactivation flow
// DeactivateUser(ctx context.Context, userId string) error
VerifyEmail(ctx context.Context, actionToken string) error
SendEmailForgotPassword(ctx context.Context, userId string) error
SendEmailVerifyUser(ctx context.Context, email string) error
ChangePassword(ctx context.Context, userId, oldPassword, newPassword string) error
ChangePasswordWithToken(ctx context.Context, actionToken, newPassword string) error
RequestRestorePassword(ctx context.Context, email string) error
RequestVerifyUser(ctx context.Context, email string) error
}
func NewUserService(deps UserServiceDeps) UserService {
@ -132,6 +135,16 @@ func (u *userService) AuthenticateUser(ctx context.Context, email, password stri
return jwt, nil
}
func (u *userService) DeactivateUser(ctx context.Context, userId string) error {
err := u.deps.UserRepo.DeactivateUser(ctx, userId)
if err != nil {
return err
}
u.deps.UserCache.Del(userId)
return nil
}
func (u *userService) VerifyEmail(ctx context.Context, actionToken string) error {
token, err := u.deps.ActionTokenRepo.GetActionToken(ctx, actionToken, models.ActionTokenTargetVerifyEmail)
if err != nil {
@ -150,62 +163,6 @@ func (u *userService) VerifyEmail(ctx context.Context, actionToken string) error
return nil
}
func (u *userService) SendEmailForgotPassword(ctx context.Context, email string) error {
// user, err := u.getUserById(ctx, userId)
user, err := u.deps.UserRepo.GetUserByEmail(ctx, email)
if err != nil {
return err
}
actionToken, err := u.deps.ActionTokenRepo.CreateActionToken(
ctx,
models.ActionTokenDTO{
UserId: user.Id,
Value: uuid.New().String(),
Target: models.ActionTokenTargetRestorePassword,
Expiration: time.Now().Add(15 * time.Minute),
},
)
if err != nil {
return err
}
return u.deps.EventRepo.SendEmailForgotPassword(ctx, user.Email, actionToken.Value)
}
func (u *userService) sendEmailVerifyUser(ctx context.Context, userId, email string) error {
actionToken, err := u.deps.ActionTokenRepo.CreateActionToken(
ctx,
models.ActionTokenDTO{
UserId: userId,
Value: uuid.New().String(),
Target: models.ActionTokenTargetVerifyEmail,
Expiration: time.Now().Add(1 * time.Hour),
},
)
if err != nil {
return err
}
return u.deps.EventRepo.SendEmailVerifyUser(ctx, email, actionToken.Value)
}
func (u *userService) SendEmailVerifyUser(ctx context.Context, email string) error {
//user, err := u.getUserById(ctx, userId)
user, err := u.deps.UserRepo.GetUserByEmail(ctx, email)
if err != nil {
return err
}
if user == nil {
return fmt.Errorf("no such user")
}
if user.EmailVerified {
return fmt.Errorf("user already verified")
}
return u.sendEmailVerifyUser(ctx, user.Id, user.Email)
}
func (u *userService) ChangePasswordWithToken(ctx context.Context, actionToken, newPassword string) error {
token, err := u.deps.ActionTokenRepo.GetActionToken(ctx, actionToken, models.ActionTokenTargetRestorePassword)
if err != nil {
@ -308,3 +265,57 @@ func (u *userService) ValidateAuthToken(ctx context.Context, tokenStr string) (*
return user, nil
}
func (u *userService) RequestRestorePassword(ctx context.Context, email string) error {
user, err := u.deps.UserRepo.GetUserByEmail(ctx, email)
if err != nil {
return err
}
actionToken, err := u.deps.ActionTokenRepo.CreateActionToken(
ctx,
models.ActionTokenDTO{
UserId: user.Id,
Value: uuid.New().String(),
Target: models.ActionTokenTargetRestorePassword,
Expiration: time.Now().Add(15 * time.Minute),
},
)
if err != nil {
return err
}
return u.deps.EventRepo.SendEmailForgotPassword(ctx, user.Email, actionToken.Value)
}
func (u *userService) RequestVerifyUser(ctx context.Context, email string) error {
user, err := u.deps.UserRepo.GetUserByEmail(ctx, email)
if err != nil {
return err
}
if user == nil {
return fmt.Errorf("no such user")
}
if user.EmailVerified {
return fmt.Errorf("user already verified")
}
return u.sendEmailVerifyUser(ctx, user.Id, user.Email)
}
func (u *userService) sendEmailVerifyUser(ctx context.Context, userId, email string) error {
actionToken, err := u.deps.ActionTokenRepo.CreateActionToken(
ctx,
models.ActionTokenDTO{
UserId: userId,
Value: uuid.New().String(),
Target: models.ActionTokenTargetVerifyEmail,
Expiration: time.Now().Add(1 * time.Hour),
},
)
if err != nil {
return err
}
return u.deps.EventRepo.SendEmailVerifyUser(ctx, email, actionToken.Value)
}