tailly_back_v2/internal/service/user_service.go

115 lines
2.8 KiB
Go

package service
import (
"context"
"errors"
"tailly_back_v2/internal/domain"
"tailly_back_v2/internal/repository"
"tailly_back_v2/pkg/auth"
"time"
)
type UserService interface {
GetByID(ctx context.Context, id int) (*domain.User, error)
GetAll(ctx context.Context, id int) ([]*domain.User, error)
GetByEmail(ctx context.Context, email string) (*domain.User, error)
UpdateProfile(ctx context.Context, id int, username, email, avatar string) (*domain.User, error)
ChangePassword(ctx context.Context, id int, oldPassword, newPassword string) error
}
type userService struct {
userRepo repository.UserRepository
tokenAuth *auth.TokenAuth
}
func (s *userService) GetByEmail(ctx context.Context, email string) (*domain.User, error) {
user, err := s.userRepo.GetByEmail(ctx, email)
if err != nil {
if errors.Is(err, repository.ErrUserNotFound) {
return nil, errors.New("user not found")
}
return nil, err
}
return user, nil
}
func NewUserService(userRepo repository.UserRepository) *userService {
return &userService{
userRepo: userRepo,
}
}
func (s *userService) GetByID(ctx context.Context, id int) (*domain.User, error) {
user, err := s.userRepo.GetByID(ctx, id)
if err != nil {
if errors.Is(err, repository.ErrUserNotFound) {
return nil, errors.New("user not found")
}
return nil, err
}
// Очищаем пароль перед возвратом
user.Password = ""
return user, nil
}
func (s *userService) UpdateProfile(ctx context.Context, id int, username, email, avatar string) (*domain.User, error) {
user, err := s.userRepo.GetByID(ctx, id)
if err != nil {
return nil, err
}
// Проверяем email на уникальность
if email != user.Email {
if _, err := s.userRepo.GetByEmail(ctx, email); err == nil {
return nil, errors.New("email already in use")
}
}
user.Username = username
user.Email = email
user.Avatar = avatar
user.UpdatedAt = time.Now()
if err := s.userRepo.Update(ctx, user); err != nil {
return nil, err
}
// Очищаем пароль перед возвратом
user.Password = ""
return user, nil
}
func (s *userService) ChangePassword(ctx context.Context, id int, oldPassword, newPassword string) error {
user, err := s.userRepo.GetByID(ctx, id)
if err != nil {
return err
}
if !auth.CheckPasswordHash(oldPassword, user.Password) {
return errors.New("invalid current password")
}
hashedPassword, err := auth.HashPassword(newPassword)
if err != nil {
return err
}
user.Password = hashedPassword
return s.userRepo.Update(ctx, user)
}
func (s *userService) GetAll(ctx context.Context, id int) ([]*domain.User, error) {
users, err := s.userRepo.GetAll(ctx, id)
if err != nil {
return nil, err
}
// Возвращаем пустой слайс вместо nil
if users == nil {
return []*domain.User{}, nil
}
return users, nil
}