122 lines
4.3 KiB
Go
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
|
|
}
|