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

106 lines
3.4 KiB
Go

package middleware
import (
"context"
"strconv"
"veza-backend-api/internal/models"
"veza-backend-api/internal/response"
"github.com/gin-gonic/gin"
)
// PlaylistPermissionChecker définit l'interface pour vérifier les permissions de playlist
// T0484: Interface pour permettre le mocking dans les tests
type PlaylistPermissionChecker interface {
CheckPermission(ctx context.Context, playlistID, userID int64, 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
}
// Convertir user_id en int64
var userID int64
switch v := userIDInterface.(type) {
case int64:
userID = v
case int:
userID = int64(v)
case float64:
userID = int64(v)
default:
response.Unauthorized(c, "invalid user id type")
c.Abort()
return
}
// Extraire playlistID depuis les paramètres de la route
playlistIDStr := c.Param("id")
if playlistIDStr == "" {
response.BadRequest(c, "playlist id is required")
c.Abort()
return
}
playlistID, err := strconv.ParseInt(playlistIDStr, 10, 64)
if err != nil {
response.BadRequest(c, "invalid playlist id")
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)
}