95 lines
2.7 KiB
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
|
|
} |