Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions files/views/playlists.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

from cms.permissions import IsAuthorizedToAdd, IsUserOrEditor

from ..models import Media, Playlist, PlaylistMedia
from ..models import Media, MediaPermission, Playlist, PlaylistMedia
from ..serializers import MediaSerializer, PlaylistDetailSerializer, PlaylistSerializer


Expand Down Expand Up @@ -82,6 +82,31 @@ def get_playlist(self, friendly_token):
status=status.HTTP_400_BAD_REQUEST,
)

def _get_accessible_media_filter(self, request):
"""
Build a Q object that filters media based on user permissions.
Returns media that is:
- listable (public)
- has direct MediaPermission for the user
- accessible via RBAC category membership (if USE_RBAC is enabled)
"""
conditions = Q(media__listable=True)

if not request.user.is_authenticated:
return conditions

# Check for direct MediaPermission
if MediaPermission.objects.filter(user=request.user).exists():
conditions |= Q(media__permissions__user=request.user)

# Check for RBAC access
if getattr(settings, 'USE_RBAC', False):
rbac_categories = request.user.get_rbac_categories_as_member()
if rbac_categories.exists():
conditions |= Q(media__category__in=rbac_categories)

return conditions

@swagger_auto_schema(
manual_parameters=[],
tags=['Playlists'],
Expand All @@ -95,11 +120,13 @@ def get(self, request, friendly_token, format=None):

serializer = PlaylistDetailSerializer(playlist, context={"request": request})

# If user is the author, show all media; otherwise, show only public and unlisted media
# If user is the author, show all media; otherwise, filter based on permissions (RBAC, direct permissions, or listable)
if request.user.is_authenticated and request.user == playlist.user:
playlist_media = PlaylistMedia.objects.filter(playlist=playlist).prefetch_related("media__user").select_related("media")
else:
playlist_media = PlaylistMedia.objects.filter(playlist=playlist).filter(Q(media__state="public") | Q(media__state="unlisted")).prefetch_related("media__user").select_related("media")
# Apply permission filter to show media accessible via RBAC, direct permissions, or public visibility
accessible_filter = self._get_accessible_media_filter(request)
playlist_media = PlaylistMedia.objects.filter(playlist=playlist).filter(accessible_filter).prefetch_related("media__user").select_related("media").distinct()

playlist_media = [c.media for c in playlist_media]

Expand Down
Loading