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 }