diff --git a/gracedb/superevents/api/filters.py b/gracedb/superevents/api/filters.py index 797955cf3523ffd5504dcff0fdc10aec8dfef3d0..f07078d76a2c969afc2a32f2233057d3bb487fd0 100644 --- a/gracedb/superevents/api/filters.py +++ b/gracedb/superevents/api/filters.py @@ -82,3 +82,31 @@ class SupereventOrderingFilter(filters.OrderingFilter): # No ordering was included, or all the ordering fields were invalid return self.get_default_ordering(view) + + +class DjangoObjectAndGlobalPermissionsFilter( + filters.DjangoObjectPermissionsFilter): + """ + Same as DjangoObjectPermissionsFilter, except it allows global permissions. + """ + accept_global_perms = True + + def filter_queryset(self, request, queryset, view): + # Mostly from rest_framework.filters.DjangoObjectPermissionsFilter + # + # We want to defer this import until run-time, rather than import-time. + # See https://github.com/encode/django-rest-framework/issues/4608 + # (Also see #1624 for why we need to make this import explicitly) + from guardian.shortcuts import get_objects_for_user + + extra = {} + user = request.user + model_cls = queryset.model + kwargs = { + 'app_label': model_cls._meta.app_label, + 'model_name': model_cls._meta.model_name + } + permission = self.perm_format % kwargs + extra['accept_global_perms'] = self.accept_global_perms + + return get_objects_for_user(user, permission, queryset, **extra) diff --git a/gracedb/superevents/api/views.py b/gracedb/superevents/api/views.py index 5743be0e798aef01eac5c0580291b169e306fa59..830d34d795d766ba5de46d03318435158c3d115e 100644 --- a/gracedb/superevents/api/views.py +++ b/gracedb/superevents/api/views.py @@ -26,7 +26,8 @@ from events.view_utils import reverse as gracedb_reverse from events.api.backends import LigoAuthentication from ..buildVOEvent import VOEventBuilderException -from .filters import SupereventSearchFilter, SupereventOrderingFilter +from .filters import SupereventSearchFilter, SupereventOrderingFilter, \ + DjangoObjectAndGlobalPermissionsFilter from .mixins import GetParentSupereventMixin, BaseGetObjectMixin, \ SafeDestroyMixin, SafeCreateMixin from .paginators import BasePaginationFactory, CustomLabelPagination, \ @@ -52,7 +53,8 @@ class SupereventViewSet(SafeCreateMixin, viewsets.ModelViewSet): pagination_class = CustomSupereventPagination lookup_field = SUPEREVENT_LOOKUP_FIELD lookup_value_regex = SUPEREVENT_LOOKUP_REGEX - filter_backends = (SupereventSearchFilter, SupereventOrderingFilter,) + filter_backends = (DjangoObjectAndGlobalPermissionsFilter, + SupereventSearchFilter, SupereventOrderingFilter,) ordering_fields = ('created', 't_0', 't_start', 't_end', 'preferred_event__id', 't_0_date', 'is_gw', 'base_date_number', 'gw_date_number', 'category') @@ -64,15 +66,6 @@ class SupereventViewSet(SafeCreateMixin, viewsets.ModelViewSet): serializer_class = SupereventUpdateSerializer return serializer_class - def get_queryset(self): - """Filter queryset for user""" - # TODO: do we need to filter this any further? - # TODO: Check that this might be causing slowness - #queryset = get_objects_for_user(self.request.user, - # 'superevents.view_superevent') - queryset = self.queryset - return queryset - def get_object(self): queryset = self.filter_queryset(self.get_queryset()) superevent_id = self.kwargs.get(self.lookup_field) @@ -172,9 +165,9 @@ class SupereventLogViewSet(mixins.ListModelMixin, parser_class = parsers.FileUploadParser serializer_class = SupereventLogSerializer pagination_class = BasePaginationFactory(results_name='log') + filter_backends = (DjangoObjectAndGlobalPermissionsFilter,) lookup_field = 'N' - # TODO: filter logs for viewers def get_queryset(self): superevent = self.get_parent() queryset = superevent.log_set.all().order_by('N')