learnsteam-quiz-api/internal/services/auth.go
2023-10-19 22:47:12 +09:00

91 lines
2.3 KiB
Go

package services
import (
"errors"
"studioj/boilerplate_go/internal/models"
"studioj/boilerplate_go/internal/repositories"
"time"
"github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
)
type authService struct {
userRepository repositories.UserRepository
tokenRepository repositories.TokenRepository
}
type AuthService interface {
Register(*models.RegisterRequest) (*models.User, error)
Login(*models.LoginRequest) (*models.User, error)
CreateToken(string) (*models.Token, error)
}
func NewAuthService(userRepository repositories.UserRepository, tokenRepository repositories.TokenRepository) AuthService {
return &authService{
userRepository: userRepository,
tokenRepository: tokenRepository,
}
}
func (s *authService) Register(request *models.RegisterRequest) (*models.User, error) {
hash, err := bcrypt.GenerateFromPassword([]byte(request.Password), 10)
if err != nil {
return nil, errors.New("fail to hash password")
}
// Create the user
newUser := models.User{
ID: uuid.NewString(),
Username: request.Username,
Password: string(hash),
}
user, err := s.userRepository.Create(&newUser)
if err != nil {
return nil, errors.New("fail to create user")
}
return user, err
}
func (s *authService) Login(request *models.LoginRequest) (*models.User, error) {
user, err := s.userRepository.FindByUsername(request.Username)
if err != nil || user == nil {
return nil, errors.New("invalid user or password")
}
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(request.Password))
if err != nil {
return nil, errors.New("invalid user or password")
}
return user, nil
}
func (s *authService) CreateToken(user_id string) (*models.Token, error) {
tokenExpiredAt := time.Now().Add(time.Hour * 24 * 30)
accessToken, err := s.tokenRepository.Generate(user_id, tokenExpiredAt.Unix())
if err != nil {
return nil, err
}
refreshExpiredAt := time.Now().Add(time.Hour * 24 * 90)
refreshToken, err := s.tokenRepository.Generate(user_id, refreshExpiredAt.Unix())
if err != nil {
return nil, err
}
newToken := &models.Token{
ID: uuid.NewString(),
UserID: user_id,
Token: accessToken,
RefreshToken: refreshToken,
Status: "valid",
ExpireAt: tokenExpiredAt,
}
token, err := s.tokenRepository.Create(newToken)
return token, err
}