185 lines
4.4 KiB
Go
185 lines
4.4 KiB
Go
package services
|
|
|
|
import (
|
|
"errors"
|
|
"gobeyhan/database"
|
|
"gobeyhan/database/models"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type UserService struct{}
|
|
|
|
func NewUserService() *UserService {
|
|
return &UserService{}
|
|
}
|
|
|
|
// GetAllUsers retrieves all users, optionally including soft-deleted ones
|
|
func (s *UserService) GetAllUsers(includeDeleted bool, page, limit int) ([]models.User, int64, error) {
|
|
var users []models.User
|
|
var total int64
|
|
|
|
query := database.DB.Preload("Roles").Preload("SocialAccounts")
|
|
|
|
if includeDeleted {
|
|
query = query.Unscoped()
|
|
}
|
|
|
|
query.Model(&models.User{}).Count(&total)
|
|
|
|
err := query.
|
|
Offset((page - 1) * limit).
|
|
Limit(limit).
|
|
Order("created_at DESC").
|
|
Find(&users).Error
|
|
|
|
return users, total, err
|
|
}
|
|
|
|
// GetUserByID retrieves a user by ID
|
|
func (s *UserService) GetUserByID(id uint64) (*models.User, error) {
|
|
var user models.User
|
|
err := database.DB.
|
|
Preload("Roles").
|
|
Preload("SocialAccounts").
|
|
First(&user, id).Error
|
|
|
|
if err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
return &user, nil
|
|
}
|
|
|
|
// GetUserByEmail retrieves a user by email
|
|
func (s *UserService) GetUserByEmail(email string) (*models.User, error) {
|
|
var user models.User
|
|
err := database.DB.
|
|
Preload("Roles").
|
|
Preload("SocialAccounts").
|
|
Where("email = ?", email).
|
|
First(&user).Error
|
|
|
|
if err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
return &user, nil
|
|
}
|
|
|
|
// CreateUser creates a new user with hashed password
|
|
func (s *UserService) CreateUser(user *models.User, password string) error {
|
|
// Hash password if provided
|
|
if password != "" {
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
user.Password = string(hashedPassword)
|
|
}
|
|
|
|
return database.DB.Create(user).Error
|
|
}
|
|
|
|
// VerifyPassword checks if the provided password matches the hashed password
|
|
func (s *UserService) VerifyPassword(hashedPassword, password string) bool {
|
|
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
|
|
return err == nil
|
|
}
|
|
|
|
// UpdateUser updates an existing user
|
|
func (s *UserService) UpdateUser(id uint64, updates map[string]interface{}) error {
|
|
// If password is being updated, hash it first
|
|
if password, ok := updates["password"].(string); ok && password != "" {
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
updates["password"] = string(hashedPassword)
|
|
}
|
|
|
|
result := database.DB.Model(&models.User{}).Where("id = ?", id).Updates(updates)
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
if result.RowsAffected == 0 {
|
|
return gorm.ErrRecordNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// DeleteUser soft deletes a user
|
|
func (s *UserService) DeleteUser(id uint64) error {
|
|
result := database.DB.Delete(&models.User{}, id)
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
if result.RowsAffected == 0 {
|
|
return gorm.ErrRecordNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// RestoreUser restores a soft-deleted user
|
|
func (s *UserService) RestoreUser(id uint64) error {
|
|
result := database.DB.Model(&models.User{}).Unscoped().
|
|
Where("id = ?", id).
|
|
Update("deleted_at", nil)
|
|
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
if result.RowsAffected == 0 {
|
|
return gorm.ErrRecordNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// AssignRole assigns a role to a user
|
|
func (s *UserService) AssignRole(userID, roleID uint64) error {
|
|
var user models.User
|
|
if err := database.DB.First(&user, userID).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
var role models.Role
|
|
if err := database.DB.First(&role, roleID).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
return database.DB.Model(&user).Association("Roles").Append(&role)
|
|
}
|
|
|
|
// RemoveRole removes a role from a user
|
|
func (s *UserService) RemoveRole(userID, roleID uint64) error {
|
|
var user models.User
|
|
if err := database.DB.Preload("Roles").First(&user, userID).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
var role models.Role
|
|
if err := database.DB.First(&role, roleID).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
return database.DB.Model(&user).Association("Roles").Delete(&role)
|
|
}
|
|
|
|
// AssignDefaultRole assigns the default 'user' role to a user
|
|
func (s *UserService) AssignDefaultRole(userID uint64) error {
|
|
var role models.Role
|
|
// Find role by name 'user'
|
|
if err := database.DB.Where("name = ?", "user").First(&role).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
return s.AssignRole(userID, role.ID)
|
|
}
|