Files
Super-HomeworkManager/internal/service/auth_service.go
2025-12-30 21:47:39 +09:00

107 lines
2.3 KiB
Go

package service
import (
"errors"
"homework-manager/internal/models"
"homework-manager/internal/repository"
"golang.org/x/crypto/bcrypt"
)
var (
ErrUserNotFound = errors.New("user not found")
ErrEmailAlreadyExists = errors.New("email already exists")
ErrInvalidCredentials = errors.New("invalid credentials")
)
type AuthService struct {
userRepo *repository.UserRepository
}
func NewAuthService() *AuthService {
return &AuthService{
userRepo: repository.NewUserRepository(),
}
}
func (s *AuthService) Register(email, password, name string) (*models.User, error) {
// Check if email already exists
_, err := s.userRepo.FindByEmail(email)
if err == nil {
return nil, ErrEmailAlreadyExists
}
// Hash password
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return nil, err
}
// Determine role (first user is admin)
role := "user"
count, _ := s.userRepo.Count()
if count == 0 {
role = "admin"
}
user := &models.User{
Email: email,
PasswordHash: string(hashedPassword),
Name: name,
Role: role,
}
if err := s.userRepo.Create(user); err != nil {
return nil, err
}
return user, nil
}
func (s *AuthService) Login(email, password string) (*models.User, error) {
user, err := s.userRepo.FindByEmail(email)
if err != nil {
return nil, ErrInvalidCredentials
}
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password)); err != nil {
return nil, ErrInvalidCredentials
}
return user, nil
}
func (s *AuthService) GetUserByID(id uint) (*models.User, error) {
return s.userRepo.FindByID(id)
}
func (s *AuthService) ChangePassword(userID uint, oldPassword, newPassword string) error {
user, err := s.userRepo.FindByID(userID)
if err != nil {
return ErrUserNotFound
}
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(oldPassword)); err != nil {
return ErrInvalidCredentials
}
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
if err != nil {
return err
}
user.PasswordHash = string(hashedPassword)
return s.userRepo.Update(user)
}
func (s *AuthService) UpdateProfile(userID uint, name string) error {
user, err := s.userRepo.FindByID(userID)
if err != nil {
return ErrUserNotFound
}
user.Name = name
return s.userRepo.Update(user)
}