Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
fix: inheritance issues
Browse files Browse the repository at this point in the history
  • Loading branch information
irtazaakram committed Aug 29, 2023
1 parent 58fe1de commit e845934
Showing 1 changed file with 101 additions and 2 deletions.
103 changes: 101 additions & 2 deletions registrar/apps/api/v3/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
The public-facing REST API.
"""
import logging
from collections import defaultdict
from functools import cached_property
from django.http import Http404

from edx_api_doc_tools import query_parameter, schema_for
from edx_rest_framework_extensions.auth.jwt.authentication import (
Expand All @@ -12,9 +15,12 @@
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from registrar.apps.core import permissions as perms
from registrar.apps.core.auth_checks import get_programs_by_api_permission
from registrar.apps.core.models import Organization

from ..mixins import TrackViewMixin
from ..serializers import DetailedProgramSerializer
from ..v1.views import ProgramListView
from .pagination import CustomPagination


Expand All @@ -38,7 +44,7 @@
**SCHEMA_COMMON_RESPONSES,
},
)
class ProgramListPaginationView(ProgramListView, TrackViewMixin, ListAPIView):
class ProgramListPaginationView(TrackViewMixin, ListAPIView):
"""
A view for listing program objects.
Expand All @@ -60,3 +66,96 @@ def list(self, request): # pylint: disable=arguments-differ
data = result.data

return Response(data)

def get_queryset(self):
"""
Get the Programs to be serialized and returned.
Overrides ListAPIView.get_queryset.
"""
queryset = self.user_programs_by_api_permission[self.permission_filter]
if title_filter := self.request.GET.get('program_title'):
queryset = [program for program in queryset if title_filter.lower() in program.details.title.lower()]
return queryset

def get_serializer_context(self):
"""
Get the extra data needed to serialize each Program.
Overrides ListAPIView.get_serializer_context.
"""
return {
**super().get_serializer_context(),
"user_api_permissions_by_program": (
self.user_api_permissions_by_program
),
}

@cached_property
def user_api_permissions_by_program(self):
"""
For each Program, the APIPermission that the user possesses on that program.
Calculated and cached once per request.
Returns: dict[Program: list[APIPermission]]
"""
result = defaultdict(list)
for api_permission, programs in self.user_programs_by_api_permission.items():
for program in programs:
result[program].append(api_permission)
return dict(result)

@cached_property
def user_programs_by_api_permission(self):
"""
For each APIPermission, the Programs on which the user possesses that APIPermission.
Calculated and cached once per request.
Returns: dict[APIPermission: list[Program]]
"""
return {
api_permission: list(
get_programs_by_api_permission(
user=self.request.user,
required_api_permission=api_permission,
organization_filter=self.organization_filter,
)
)
for api_permission in perms.API_PERMISSIONS
}

@cached_property
def organization_filter(self):
"""
Return the organization by which results will be filtered,
no None if on filter specified.
Raises 404 for non-existant organiation.
"""
if org_key := self.request.GET.get('org'):
try:
return Organization.objects.get(key=org_key)
except Organization.DoesNotExist as ex:
self.add_tracking_data(failure='org_not_found')
raise Http404() from ex
else:
return None

@cached_property
def permission_filter(self):
"""
Return a list of APIPermission by which results will be filtered,
defaulting to API_READ_METADATA.
Raises 404 for bad permission query param.
"""
perm_query_param = self.request.GET.get('user_has_perm', None)
if not perm_query_param:
return perms.API_READ_METADATA
try:
return perms.API_PERMISSIONS_BY_NAME[perm_query_param]
except KeyError as ex:
self.add_tracking_data(failure='no_such_perm')
raise Http404() from ex

0 comments on commit e845934

Please sign in to comment.