2015-07-30 17 views
5

Byłem w stanie skonfigurować django-guardian i mój django-rest-framework jako example in drf docs, ale nie udało mi się osiągnąć pożądanego zachowania. Czy ktoś mógłby wskazać, że robię coś złego, lub jeśli tego, czego chcę, nie można zrobić z guardian?Używanie DjangoObjectPermissionsFilter do filtrowania obiektów użytkownika za pomocą django-guardian

konfiguracji

settings.py

INSTALLED_APPS = (
    ... 
    'guardian', 
    'simple', 
) 

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend', 
    'guardian.backends.ObjectPermissionBackend', 
) 

'DEFAULT_PERMISSION_CLASSES': (
    'infrastructure.permissions.DjangoObjectPermissions', 
) 

infrastructure.permissions.py

from rest_framework import permissions 


class DjangoObjectPermissions(permissions.DjangoObjectPermissions): 
    """ 
    Similar to `DjangoObjectPermissions`, but adding 'view' permissions. 
    """ 
    perms_map = { 
     'GET': ['%(app_label)s.view_%(model_name)s'], 
     'OPTIONS': ['%(app_label)s.view_%(model_name)s'], 
     'HEAD': ['%(app_label)s.view_%(model_name)s'], 
     'POST': ['%(app_label)s.add_%(model_name)s'], 
     'PUT': ['%(app_label)s.change_%(model_name)s'], 
     'PATCH': ['%(app_label)s.change_%(model_name)s'], 
     'DELETE': ['%(app_label)s.delete_%(model_name)s'], 
    } 

models.py

class Event(models.Model): 
    name = models.CharField(max_length=255) 
    min_age = models.IntegerField() 

    def __str__(self): 
     return self.name 

    class Meta: 
     permissions = (('view_event', 'Can view event'),) 

views.py

class EventViewSet(viewsets.ModelViewSet): 
    queryset = models.Event.objects.all() 
    serializer_class = serializers.EventSerializer 
    filter_backends = (filters.DjangoObjectPermissionsFilter,) 

Oczekiwane zachowanie

  • Lista Events zwrócony przez EventViewSet.list zawiera tylko obiekty, które użytkownik może przeglądać wniosek (żądanie użytkownik ma django.auth pozwolenie view_event LUB ('view_event', event_object).
  • EventViewSet.details zwraca instancję Event tylko wtedy, gdy użytkownik żądania ma uprawnienie view_event LUB uprawnienie ('view_event', event_object).

Rzeczywiste zachowanie

  • Jeśli użytkownik ma uprawnienia Django auth view_event i zgody opiekuna ('view_event', event_obj), może uzyskać dostęp do tras list (Getting wszystkie wpisy) i details związane z event_obj.
  • Jeśli użytkownik NIE posiada pozwolenia autoryzacji view_event, ale ma uprawnienia opiekuna ('view_event', event_obj), otrzymuje 403 na wszystkich trasach (w tym details trasę związaną z event_obj, na które mają pozwolenie).
  • Jeśli użytkownik ma view_event, ale nie ma ('view_event', event_obj), może uzyskać dostęp do trasy list (widząc wszystkie wpisy), ale otrzymuje trasę 404 na details, niezależnie od dostępu do wpisu.

Dziękujemy!

+0

Zacząłem grać z opiekunem i widzę to samo zachowanie. Ale nie próbowałem używać 'filter_backends', więc zrobię to. –

Odpowiedz

3

OK, okazuje się, że wszystkie widoki z klasą uprawnień DjangoObjectPermissions zezwalają użytkownikom tylko na wyświetlanie danego zasobu, o ile mają uprawnienia na poziomie modelu i obiektu na poziomie na poziomie modelu i obiektu na poziomie. Fakt, że moi użytkownicy mogą wyświetlać wszystkie obiekty, ale nie można ich odzyskać, jest wynikiem poprawki known bug, która została już naprawiona, ale nie jest jeszcze dostępna w bieżącym wydaniu.