mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-18 00:55:50 +00:00
feat(epg): restrict program access based on user permissions and enhance channel filtering
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
parent
830b61ae43
commit
292a443a09
2 changed files with 25 additions and 5 deletions
|
|
@ -320,6 +320,15 @@ class ProgramViewSet(viewsets.ModelViewSet):
|
|||
|
||||
queryset = queryset.filter(filters).distinct().order_by('start_time')
|
||||
|
||||
# Restrict results to programs on channels the user can access
|
||||
user = request.user
|
||||
if user.user_level < 10:
|
||||
access_filter = Q(epg__channels__user_level__lte=user.user_level)
|
||||
custom_props = user.custom_properties or {}
|
||||
if custom_props.get('hide_adult_content', False):
|
||||
access_filter &= Q(epg__channels__is_adult=False)
|
||||
queryset = queryset.filter(access_filter).distinct()
|
||||
|
||||
# Resolve field selection before serialization so expensive methods can short-circuit
|
||||
requested_fields = params.get('fields')
|
||||
allowed = set(f.strip() for f in requested_fields.split(',')) if requested_fields else None
|
||||
|
|
@ -327,7 +336,7 @@ class ProgramViewSet(viewsets.ModelViewSet):
|
|||
# Paginate
|
||||
paginator = ProgramSearchPagination()
|
||||
page = paginator.paginate_queryset(queryset, request)
|
||||
serializer = ProgramSearchResultSerializer(page, many=True, context={'fields': allowed})
|
||||
serializer = ProgramSearchResultSerializer(page, many=True, context={'fields': allowed, 'user': request.user})
|
||||
data = serializer.data
|
||||
|
||||
if allowed:
|
||||
|
|
|
|||
|
|
@ -208,21 +208,32 @@ class ProgramSearchResultSerializer(serializers.ModelSerializer):
|
|||
'channels', 'streams',
|
||||
]
|
||||
|
||||
def _accessible_channels(self, obj):
|
||||
"""Return prefetched channels filtered to those the requesting user can access."""
|
||||
channels = list(obj.epg.channels.all()) if obj.epg else []
|
||||
user = self.context.get('user')
|
||||
if user is None or user.user_level >= 10:
|
||||
return channels
|
||||
custom_props = user.custom_properties or {}
|
||||
hide_adult = custom_props.get('hide_adult_content', False)
|
||||
return [
|
||||
ch for ch in channels
|
||||
if ch.user_level <= user.user_level and (not hide_adult or not ch.is_adult)
|
||||
]
|
||||
|
||||
def get_channels(self, obj):
|
||||
fields = self.context.get('fields')
|
||||
if fields is not None and 'channels' not in fields:
|
||||
return []
|
||||
channels = obj.epg.channels.all() if obj.epg else []
|
||||
return ProgramSearchChannelSerializer(channels, many=True).data
|
||||
return ProgramSearchChannelSerializer(self._accessible_channels(obj), many=True).data
|
||||
|
||||
def get_streams(self, obj):
|
||||
fields = self.context.get('fields')
|
||||
if fields is not None and 'streams' not in fields:
|
||||
return []
|
||||
channels = obj.epg.channels.all() if obj.epg else []
|
||||
stream_ids = set()
|
||||
streams = []
|
||||
for ch in channels:
|
||||
for ch in self._accessible_channels(obj):
|
||||
for s in ch.streams.all():
|
||||
if s.id not in stream_ids:
|
||||
stream_ids.add(s.id)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue