192 lines
5.2 KiB
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
|
|
}
|
|
*/ |