139 lines
3.2 KiB
Go
139 lines
3.2 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"go-server/internal/models"
|
|
"go-server/internal/repository"
|
|
|
|
"github.com/google/uuid"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
type UserService struct {
|
|
repo *repository.UserRepository
|
|
}
|
|
|
|
type CreateUserInput struct {
|
|
Email string
|
|
Password string
|
|
FirstName string
|
|
LastName string
|
|
}
|
|
|
|
type UpdateUserInput struct {
|
|
FirstName *string
|
|
LastName *string
|
|
}
|
|
|
|
type ChangePasswordInput struct {
|
|
Password string
|
|
}
|
|
|
|
func NewUserService(repo *repository.UserRepository) *UserService {
|
|
return &UserService{repo: repo}
|
|
}
|
|
|
|
func (s *UserService) GetByID(ctx context.Context, id uuid.UUID) (*models.User, error) {
|
|
return s.repo.GetByID(ctx, id)
|
|
}
|
|
|
|
func (s *UserService) GetAll(ctx context.Context) ([]*models.User, error) {
|
|
return s.repo.GetAll(ctx)
|
|
}
|
|
|
|
func (s *UserService) Create(ctx context.Context, input CreateUserInput) (*models.User, error) {
|
|
hashedPassword, err := hashPassword(input.Password)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("password hashing failed: %w", err)
|
|
}
|
|
|
|
user := &models.User{
|
|
Email: input.Email,
|
|
Password: hashedPassword,
|
|
FirstName: input.FirstName,
|
|
LastName: input.LastName,
|
|
PlatformRole: models.PlatformRoleUser,
|
|
}
|
|
|
|
if err := s.repo.Create(ctx, user); err != nil {
|
|
return nil, fmt.Errorf("failed to create user: %w", err)
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
func (s *UserService) Update(ctx context.Context, id uuid.UUID, input UpdateUserInput) (*models.User, error) {
|
|
user, err := s.repo.GetByID(ctx, id)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to fetch user: %w", err)
|
|
}
|
|
if user == nil {
|
|
return nil, errors.New("user not found")
|
|
}
|
|
|
|
if input.FirstName != nil {
|
|
user.FirstName = *input.FirstName
|
|
}
|
|
if input.LastName != nil {
|
|
user.LastName = *input.LastName
|
|
}
|
|
|
|
if err := s.repo.Update(ctx, user); err != nil {
|
|
return nil, fmt.Errorf("failed to update user: %w", err)
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
func (s *UserService) UpdateLastLogin(ctx context.Context, id uuid.UUID) error {
|
|
user, err := s.repo.GetByID(ctx, id)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to fetch user: %w", err)
|
|
}
|
|
if user == nil {
|
|
return errors.New("user not found")
|
|
}
|
|
|
|
if err := s.repo.Update(ctx, user); err != nil {
|
|
return fmt.Errorf("failed to update last login: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *UserService) Delete(ctx context.Context, id uuid.UUID) error {
|
|
return s.repo.Delete(ctx, id)
|
|
}
|
|
|
|
func (s *UserService) ChangePassword(ctx context.Context, id uuid.UUID, input ChangePasswordInput) error {
|
|
hashedPassword, err := hashPassword(input.Password)
|
|
if err != nil {
|
|
return fmt.Errorf("password hashing failed: %w", err)
|
|
}
|
|
|
|
user, err := s.repo.GetByID(ctx, id)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to fetch user: %w", err)
|
|
}
|
|
if user == nil {
|
|
return errors.New("user not found")
|
|
}
|
|
user.Password = hashedPassword
|
|
if err := s.repo.Update(ctx, user); err != nil {
|
|
return fmt.Errorf("failed to update user: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// hashPassword generates a bcrypt hash for a given password.
|
|
func hashPassword(password string) (string, error) {
|
|
hashed, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return string(hashed), nil
|
|
}
|