MIF_E31222379_BE/internal/services/auth/auth_admin_service.go

192 lines
5.2 KiB
Go

package service
/*
import (
"errors"
"fmt"
"log"
"rijig/config"
dto "rijig/dto/auth"
"rijig/internal/repositories"
repository "rijig/internal/repositories/auth"
"rijig/model"
"rijig/utils"
"time"
"github.com/golang-jwt/jwt/v5"
"golang.org/x/crypto/bcrypt"
)
const (
ErrEmailTaken = "email is already used"
ErrPhoneTaken = "phone number is already used"
ErrInvalidPassword = "password does not match"
ErrRoleNotFound = "role not found"
ErrFailedToGenerateToken = "failed to generate token"
ErrFailedToHashPassword = "failed to hash password"
ErrFailedToCreateUser = "failed to create user"
ErrIncorrectPassword = "incorrect password"
ErrAccountNotFound = "account not found"
)
type AuthAdminService interface {
RegisterAdmin(request *dto.RegisterAdminRequest) (*model.User, error)
LoginAdmin(req *dto.LoginAdminRequest) (*dto.LoginResponse, error)
LogoutAdmin(userID, deviceID string) error
}
type authAdminService struct {
UserRepo repository.AuthAdminRepository
RoleRepo repositories.RoleRepository
SecretKey string
}
func NewAuthAdminService(userRepo repository.AuthAdminRepository, roleRepo repositories.RoleRepository, secretKey string) AuthAdminService {
return &authAdminService{UserRepo: userRepo, RoleRepo: roleRepo, SecretKey: secretKey}
}
func (s *authAdminService) RegisterAdmin(request *dto.RegisterAdminRequest) (*model.User, error) {
if existingUser, _ := s.UserRepo.FindByEmail(request.Email); existingUser != nil {
return nil, errors.New(ErrEmailTaken)
}
if existingUser, _ := s.UserRepo.FindByPhone(request.Phone); existingUser != nil {
return nil, errors.New(ErrPhoneTaken)
}
role, err := s.UserRepo.FindRoleByName("administrator")
if err != nil {
return nil, errors.New(ErrRoleNotFound)
}
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(request.Password), bcrypt.DefaultCost)
if err != nil {
log.Println("Error hashing password:", err)
return nil, errors.New(ErrFailedToHashPassword)
}
user := &model.User{
Name: request.Name,
Email: request.Email,
Phone: request.Phone,
Password: string(hashedPassword),
RoleID: role.ID,
Role: role,
Dateofbirth: request.Dateofbirth,
Placeofbirth: request.Placeofbirth,
Gender: request.Gender,
RegistrationStatus: "completed",
}
createdUser, err := s.UserRepo.CreateUser(user)
if err != nil {
log.Println("Error creating user:", err)
return nil, fmt.Errorf("%s: %v", ErrFailedToCreateUser, err)
}
return createdUser, nil
}
func (s *authAdminService) LoginAdmin(req *dto.LoginAdminRequest) (*dto.LoginResponse, error) {
user, err := s.UserRepo.FindByEmail(req.Email)
if err != nil {
log.Println("User not found:", err)
return nil, errors.New(ErrAccountNotFound)
}
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)); err != nil {
log.Println("Incorrect password:", err)
return nil, errors.New(ErrIncorrectPassword)
}
existingUser, err := s.UserRepo.FindAdminByEmailandRoleid(req.Email, "42bdecce-f2ad-44ae-b3d6-883c1fbddaf7")
if err != nil {
return nil, fmt.Errorf("failed to check existing user: %w", err)
}
var adminUser *model.User
if existingUser != nil {
adminUser = existingUser
} else {
adminUser = &model.User{
Email: req.Email,
RoleID: "42bdecce-f2ad-44ae-b3d6-883c1fbddaf7",
}
createdUser, err := s.UserRepo.CreateUser(adminUser)
if err != nil {
return nil, err
}
adminUser = createdUser
}
token, err := s.generateJWTToken(adminUser.ID, req.Deviceid)
if err != nil {
return nil, err
}
role, err := s.RoleRepo.FindByID(user.RoleID)
if err != nil {
return nil, fmt.Errorf("failed to get role: %w", err)
}
deviceID := req.Deviceid
if err := s.saveSessionAdminData(user.ID, deviceID, user.RoleID, role.RoleName, token); err != nil {
return nil, err
}
return &dto.LoginResponse{
UserID: user.ID,
Role: user.Role.RoleName,
Token: token,
}, nil
}
func (s *authAdminService) saveSessionAdminData(userID string, deviceID string, roleID string, roleName string, token string) error {
sessionKey := fmt.Sprintf("session:%s:%s", userID, deviceID)
sessionData := map[string]interface{}{
"userID": userID,
"roleID": roleID,
"roleName": roleName,
}
if err := utils.SetJSONData(sessionKey, sessionData, 24*time.Hour); err != nil {
return fmt.Errorf("failed to set session data: %w", err)
}
if err := utils.SetStringData("session_token:"+userID+":"+deviceID, token, 24*time.Hour); err != nil {
return fmt.Errorf("failed to set session token: %w", err)
}
return nil
}
func (s *authAdminService) generateJWTToken(userID string, deviceID string) (string, error) {
expirationTime := time.Now().Add(24 * time.Hour)
claims := jwt.MapClaims{
"sub": userID,
"exp": expirationTime.Unix(),
"device_id": deviceID,
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
secretKey := config.GetSecretKey()
return token.SignedString([]byte(secretKey))
}
func (s *authAdminService) LogoutAdmin(userID, deviceID string) error {
err := utils.DeleteSessionData(userID, deviceID)
if err != nil {
return fmt.Errorf("failed to delete session from Redis: %w", err)
}
return nil
}
*/