package middleware import ( "context" "veza-backend-api/internal/response" "github.com/gin-gonic/gin" "github.com/google/uuid" ) // RoleChecker définit l'interface minimale pour vérifier les rôles et permissions // Permet d'utiliser des mocks dans les tests sans modifier la signature publique // MIGRATION UUID: Utilise maintenant uuid.UUID au lieu de int64 type RoleChecker interface { HasRole(ctx context.Context, userID uuid.UUID, roleName string) (bool, error) HasPermission(ctx context.Context, userID uuid.UUID, resource, action string) (bool, error) } // RequireRole crée un middleware qui exige qu'un utilisateur ait un rôle spécifique func RequireRole(roleService RoleChecker, roleName string) gin.HandlerFunc { return func(c *gin.Context) { // Récupérer user_id du contexte (doit être défini par AuthMiddleware) userIDInterface, exists := c.Get("user_id") if !exists { response.Unauthorized(c, "unauthorized") c.Abort() return } // Extraire user_id comme uuid.UUID (défini par AuthMiddleware) // MIGRATION UUID: Support uuid.UUID directement, plus de conversion en int64 var userID uuid.UUID switch v := userIDInterface.(type) { case uuid.UUID: userID = v case string: // Support legacy: si c'est une string, essayer de la parser en UUID parsed, err := uuid.Parse(v) if err != nil { response.Unauthorized(c, "invalid user id format") c.Abort() return } userID = parsed default: response.Unauthorized(c, "invalid user id type") c.Abort() return } // Vérifier si l'utilisateur a le rôle requis hasRole, err := roleService.HasRole(c.Request.Context(), userID, roleName) if err != nil { response.InternalServerError(c, "failed to check role") c.Abort() return } if !hasRole { response.Forbidden(c, "insufficient permissions") c.Abort() return } c.Next() } } // RequirePermission crée un middleware qui exige qu'un utilisateur ait une permission spécifique func RequirePermission(roleService RoleChecker, resource, action string) gin.HandlerFunc { return func(c *gin.Context) { // Récupérer user_id du contexte (doit être défini par AuthMiddleware) userIDInterface, exists := c.Get("user_id") if !exists { response.Unauthorized(c, "unauthorized") c.Abort() return } // Extraire user_id comme uuid.UUID (défini par AuthMiddleware) // MIGRATION UUID: Support uuid.UUID directement, plus de conversion en int64 var userID uuid.UUID switch v := userIDInterface.(type) { case uuid.UUID: userID = v case string: // Support legacy: si c'est une string, essayer de la parser en UUID parsed, err := uuid.Parse(v) if err != nil { response.Unauthorized(c, "invalid user id format") c.Abort() return } userID = parsed default: response.Unauthorized(c, "invalid user id type") c.Abort() return } // Vérifier si l'utilisateur a la permission requise hasPermission, err := roleService.HasPermission(c.Request.Context(), userID, resource, action) if err != nil { response.InternalServerError(c, "failed to check permission") c.Abort() return } if !hasPermission { response.Forbidden(c, "insufficient permissions") c.Abort() return } c.Next() } }