This commit is contained in:
2026-10-03 01:16:40 +07:00
parent 3f7731411b
commit c69dfb8503
10 changed files with 234 additions and 59 deletions
+45 -14
View File
@@ -82,8 +82,15 @@ func NewUsersService(
}
}
// ErrTermsNotAccepted — регистрация невозможна без акцепта соглашений.
var ErrTermsNotAccepted = errors.New("Необходимо принять Пользовательское соглашение и Политику конфиденциальности")
var (
// ErrTermsNotAccepted — регистрация невозможна без акцепта соглашений.
ErrTermsNotAccepted = errors.New("Необходимо принять Пользовательское соглашение и Политику конфиденциальности")
ErrInvalidEmail = errors.New("Некорректный email")
ErrInvalidCredentials = errors.New("Не верен email или пароль")
ErrInvalidAccountPassword = errors.New("Неверный пароль")
ErrInvalidRefreshToken = errors.New("Пользователь не найден")
ErrInvalidRole = errors.New("Недопустимая роль")
)
func (s *UsersService) AddUser(
ctx context.Context,
@@ -170,12 +177,19 @@ func (s *UsersService) DeleteAccount(
) error {
user, err := s.usersRepo.GetUserByID(ctx, userID)
if err != nil {
if errors.Is(err, users_repo.ErrUserNotFound) {
return ErrUserNotFound
}
return err
}
if err = bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password)); err != nil {
return errors.New("Неверный пароль")
return ErrInvalidAccountPassword
}
return s.usersRepo.DeleteUser(ctx, userID)
err = s.usersRepo.DeleteUser(ctx, userID)
if errors.Is(err, users_repo.ErrUserNotFound) {
return ErrUserNotFound
}
return err
}
func (s *UsersService) RefreshPassword(
@@ -225,15 +239,15 @@ func (s *UsersService) RefreshPassword(
// validateEmail проверяет, что строка является одиночным email-адресом.
func validateEmail(email string) error {
if email == "" {
return errors.New("Email не указан")
return ErrInvalidEmail
}
addr, err := mail.ParseAddress(email)
if err != nil {
return errors.New("Некорректный email")
return ErrInvalidEmail
}
// Отклоняем форму "Имя <a@b.c>" и всё, что не является чистым адресом.
if !strings.EqualFold(addr.Address, email) {
return errors.New("Некорректный email")
return ErrInvalidEmail
}
return nil
}
@@ -249,11 +263,14 @@ func (s *UsersService) Login(
strings.TrimSpace(email),
)
if err != nil {
if errors.Is(err, users_repo.ErrUserNotFound) {
return "", "", err
}
return "", "", err
}
if err = bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password)); err != nil {
return "", "", errors.New("Не верен email или пароль")
return "", "", ErrInvalidCredentials
}
accessToken, err := s.processorJWT.GenerateAccessToken(user.ID, user.Email, user.Roles)
@@ -283,7 +300,7 @@ func (s *UsersService) Refresh(
) (string, string, error) {
claims, err := s.processorJWT.GetClaims(token)
if err != nil {
return "", "", errors.New("Пользователь не найден")
return "", "", ErrInvalidRefreshToken
}
now := time.Now()
@@ -292,7 +309,7 @@ func (s *UsersService) Refresh(
return "", "", err
}
if !ok {
return "", "", errors.New("Пользователь не найден")
return "", "", ErrInvalidRefreshToken
}
if err := s.refreshTokensRepo.DeleteRefreshTokenByJti(ctx, claims.ID); err != nil {
return "", "", err
@@ -300,6 +317,9 @@ func (s *UsersService) Refresh(
user, err := s.usersRepo.GetUserByID(ctx, claims.UserID)
if err != nil {
if errors.Is(err, users_repo.ErrUserNotFound) {
return "", "", ErrInvalidRefreshToken
}
return "", "", err
}
@@ -340,6 +360,9 @@ func (s *UsersService) GetUserByID(
) (*User, error) {
user, err := s.usersRepo.GetUserByID(ctx, userID)
if err != nil {
if errors.Is(err, users_repo.ErrUserNotFound) {
return nil, ErrUserNotFound
}
return nil, err
}
return mapUser(user), nil
@@ -351,9 +374,13 @@ func (s *UsersService) AddUserRole(
role string,
) error {
if !slices.Contains(roles.AllRoles, role) {
return fmt.Errorf("role %s not support", role)
return ErrInvalidRole
}
return s.usersRepo.AddUserRole(ctx, userID, role)
err := s.usersRepo.AddUserRole(ctx, userID, role)
if errors.Is(err, users_repo.ErrUserNotFound) {
return ErrUserNotFound
}
return err
}
func (s *UsersService) DeleteUserRole(
@@ -362,9 +389,13 @@ func (s *UsersService) DeleteUserRole(
role string,
) error {
if !slices.Contains(roles.AllRoles, role) {
return fmt.Errorf("role %s not support", role)
return ErrInvalidRole
}
return s.usersRepo.DeleteUserRole(ctx, userID, role)
err := s.usersRepo.DeleteUserRole(ctx, userID, role)
if errors.Is(err, users_repo.ErrUserNotFound) {
return ErrUserNotFound
}
return err
}
var (