NAM-APJATEL-BACKEND/usecase/auth_usecase.go

95 lines
2.7 KiB
Go

package usecase
import (
"errors"
"users_management/m/config"
"users_management/m/model/dto"
"users_management/m/model/entity"
"users_management/m/repository"
"users_management/m/utils"
"github.com/go-playground/validator/v10"
)
type AuthUsecase interface {
Login(login dto.UserLoginDTO) (string, string, string, error)
Logout(token string) error
ValidateToken(token string) (string, error)
}
type authUsecase struct {
userRepo repository.UsersRepo
cfg *config.Config
validate *validator.Validate
}
func NewAuthUsecase(userRepo repository.UsersRepo, cfg *config.Config) AuthUsecase {
return &authUsecase{
userRepo: userRepo,
cfg: cfg,
validate: validator.New(),
}
}
func (u *authUsecase) Login(login dto.UserLoginDTO) (string, string, string, error) {
// Validate input
if err := u.validate.Struct(login); err != nil {
return "", "", "", err
}
// Get user from database (only approved users can login)
user, err := u.userRepo.GetUserByUsername(login.Username)
if err != nil {
return "", "", "", errors.New("invalid username or password")
}
// Check user status
if user.Status != entity.UserStatusApproved {
switch user.Status {
case entity.UserStatusPending:
return "", "", "", errors.New("your account is pending approval from an administrator")
case entity.UserStatusRejected:
return "", "", "", errors.New("your account has been rejected. Please contact an administrator")
default:
return "", "", "", errors.New("your account is not active")
}
}
// Verify password
if !utils.CheckPasswordHash(login.Password, user.Password) {
return "", "", "", errors.New("invalid username or password")
}
// Generate JWT token
token, err := utils.GenerateJWT(user.ID.String(), user.Username, user.Role.Name)
if err != nil {
return "", "", "", err
}
return token, user.Role.Name, user.Name, nil
}
func (u *authUsecase) Logout(token string) error {
// For JWT, we could implement a blacklist mechanism here
// For now, we'll just return success since JWT tokens expire naturally
return nil
}
func (u *authUsecase) ValidateToken(token string) (string, error) {
_, username, err := utils.ValidateJWT(token)
if err != nil {
return "", err
}
// Verify user still exists and is approved
user, err := u.userRepo.GetUserByUsername(username)
if err != nil {
return "", errors.New("user not found")
}
if user.Status != entity.UserStatusApproved {
return "", errors.New("user account is not active")
}
return username, nil
}