veza/veza-backend-api/internal/services/permission_service.go
2025-12-16 11:23:49 -05:00

122 lines
4.3 KiB
Go

package services
import (
"context"
"errors"
"fmt"
"time"
"veza-backend-api/internal/models"
"github.com/google/uuid"
"gorm.io/gorm"
)
// PermissionService gère les permissions
type PermissionService struct {
db *gorm.DB
}
// NewPermissionService crée un nouveau service de permissions
func NewPermissionService(db *gorm.DB) *PermissionService {
return &PermissionService{db: db}
}
// GetPermissions récupère toutes les permissions
func (s *PermissionService) GetPermissions(ctx context.Context) ([]models.Permission, error) {
var permissions []models.Permission
if err := s.db.WithContext(ctx).Find(&permissions).Error; err != nil {
return nil, fmt.Errorf("failed to get permissions: %w", err)
}
return permissions, nil
}
// GetPermission récupère une permission par son ID
func (s *PermissionService) GetPermission(ctx context.Context, permissionID uuid.UUID) (*models.Permission, error) {
var permission models.Permission
if err := s.db.WithContext(ctx).First(&permission, permissionID).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fmt.Errorf("permission not found")
}
return nil, fmt.Errorf("failed to get permission: %w", err)
}
return &permission, nil
}
// CreatePermission crée une nouvelle permission
func (s *PermissionService) CreatePermission(ctx context.Context, permission *models.Permission) error {
if err := s.db.WithContext(ctx).Create(permission).Error; err != nil {
return fmt.Errorf("failed to create permission: %w", err)
}
return nil
}
// AssignPermissionToRole assigne une permission à un rôle
func (s *PermissionService) AssignPermissionToRole(ctx context.Context, roleID, permissionID uuid.UUID) error {
rolePermission := &models.RolePermission{
RoleID: roleID,
PermissionID: permissionID,
}
if err := s.db.WithContext(ctx).Create(rolePermission).Error; err != nil {
return fmt.Errorf("failed to assign permission: %w", err)
}
return nil
}
// RevokePermissionFromRole révoque une permission d'un rôle
func (s *PermissionService) RevokePermissionFromRole(ctx context.Context, roleID, permissionID uuid.UUID) error {
result := s.db.WithContext(ctx).
Where("role_id = ? AND permission_id = ?", roleID, permissionID).
Delete(&models.RolePermission{})
if result.Error != nil {
return fmt.Errorf("failed to revoke permission: %w", result.Error)
}
if result.RowsAffected == 0 {
return fmt.Errorf("permission assignment not found")
}
return nil
}
// GetRolePermissions récupère toutes les permissions d'un rôle
func (s *PermissionService) GetRolePermissions(ctx context.Context, roleID uuid.UUID) ([]models.Permission, error) {
var permissions []models.Permission
if err := s.db.WithContext(ctx).
Table("permissions").
Joins("JOIN role_permissions ON permissions.id = role_permissions.permission_id").
Where("role_permissions.role_id = ?", roleID).
Find(&permissions).Error; err != nil {
return nil, fmt.Errorf("failed to get role permissions: %w", err)
}
return permissions, nil
}
// HasRole vérifie si un utilisateur a un rôle spécifique
func (s *PermissionService) HasRole(ctx context.Context, userID uuid.UUID, roleName string) (bool, error) {
var count int64
err := s.db.WithContext(ctx).Table("user_roles").
Joins("JOIN roles ON user_roles.role_id = roles.id").
Where("user_roles.user_id = ? AND roles.name = ?", userID, roleName).
Where("user_roles.is_active = ?", true).
Where("user_roles.expires_at IS NULL OR user_roles.expires_at > ?", time.Now()).
Count(&count).Error
if err != nil {
return false, fmt.Errorf("failed to check role: %w", err)
}
return count > 0, nil
}
// HasPermission vérifie si un utilisateur a une permission spécifique
func (s *PermissionService) HasPermission(ctx context.Context, userID uuid.UUID, permissionName string) (bool, error) {
var count int64
err := s.db.WithContext(ctx).Table("user_roles").
Joins("JOIN role_permissions ON user_roles.role_id = role_permissions.role_id").
Joins("JOIN permissions ON role_permissions.permission_id = permissions.id").
Where("user_roles.user_id = ? AND permissions.name = ?", userID, permissionName).
Where("user_roles.is_active = ?", true).
Where("user_roles.expires_at IS NULL OR user_roles.expires_at > ?", time.Now()).
Count(&count).Error
if err != nil {
return false, fmt.Errorf("failed to check permission: %w", err)
}
return count > 0, nil
}