114 lines
3.8 KiB
Go
114 lines
3.8 KiB
Go
package middleware
|
|
|
|
import (
|
|
"context"
|
|
|
|
"veza-backend-api/internal/models"
|
|
"veza-backend-api/internal/response"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// PlaylistPermissionChecker définit l'interface pour vérifier les permissions de playlist
|
|
// T0484: Interface pour permettre le mocking dans les tests
|
|
// MIGRATION UUID: Utilise maintenant uuid.UUID au lieu de int64
|
|
type PlaylistPermissionChecker interface {
|
|
CheckPermission(ctx context.Context, playlistID, userID uuid.UUID, requiredPermission models.PlaylistPermission) (bool, error)
|
|
}
|
|
|
|
// CheckPlaylistPermission crée un middleware qui vérifie si un utilisateur a une permission spécifique sur une playlist
|
|
// T0484: Create Playlist Permission Middleware
|
|
// Le middleware vérifie:
|
|
// - Si l'utilisateur est le propriétaire (a toutes les permissions)
|
|
// - Si l'utilisateur est collaborateur avec la permission requise
|
|
// - Si la playlist est publique et la permission est "read"
|
|
func CheckPlaylistPermission(playlistService PlaylistPermissionChecker, requiredPermission models.PlaylistPermission) 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
|
|
}
|
|
|
|
// Extraire playlistID depuis les paramètres de la route
|
|
// MIGRATION UUID: Parse playlistID comme UUID au lieu de int64
|
|
playlistIDStr := c.Param("id")
|
|
if playlistIDStr == "" {
|
|
response.BadRequest(c, "playlist id is required")
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
playlistID, err := uuid.Parse(playlistIDStr)
|
|
if err != nil {
|
|
response.BadRequest(c, "invalid playlist id format (expected UUID)")
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
// Vérifier la permission via le service
|
|
hasPermission, err := playlistService.CheckPermission(c.Request.Context(), playlistID, userID, requiredPermission)
|
|
if err != nil {
|
|
// Si la playlist n'existe pas, retourner 404
|
|
if err.Error() == "playlist not found" {
|
|
response.NotFound(c, "playlist not found")
|
|
c.Abort()
|
|
return
|
|
}
|
|
response.InternalServerError(c, "failed to check permission")
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
if !hasPermission {
|
|
response.Forbidden(c, "forbidden")
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
// Permission accordée, continuer
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
// RequirePlaylistOwner crée un middleware qui exige que l'utilisateur soit le propriétaire de la playlist
|
|
// T0484: Helper pour vérifier l'ownership
|
|
func RequirePlaylistOwner(playlistService PlaylistPermissionChecker) gin.HandlerFunc {
|
|
return CheckPlaylistPermission(playlistService, models.PlaylistPermissionAdmin)
|
|
}
|
|
|
|
// RequirePlaylistWrite crée un middleware qui exige que l'utilisateur ait la permission write ou admin
|
|
// T0484: Helper pour vérifier la permission d'écriture
|
|
func RequirePlaylistWrite(playlistService PlaylistPermissionChecker) gin.HandlerFunc {
|
|
return CheckPlaylistPermission(playlistService, models.PlaylistPermissionWrite)
|
|
}
|
|
|
|
// RequirePlaylistRead crée un middleware qui exige que l'utilisateur ait la permission read, write ou admin
|
|
// T0484: Helper pour vérifier la permission de lecture
|
|
func RequirePlaylistRead(playlistService PlaylistPermissionChecker) gin.HandlerFunc {
|
|
return CheckPlaylistPermission(playlistService, models.PlaylistPermissionRead)
|
|
}
|