I was able to setup django-guardian
and my django-rest-framework
project as the example in drf docs, but I'm failing to achieve the behavior that I want. Could someone please point out if I'm doing something wrong or if what I want can't be done with guardian
?
Setup
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,)
Expected behavior
Events
returned by EventViewSet.list
contains only objects that the request user can view (request user has django.auth view_event
permission OR ('view_event', event_object)
.EventViewSet.details
returns the Event
instance only if the request user has the view_event
permission OR the ('view_event', event_object)
permission.Actual behavior
view_event
and the guardian permission ('view_event', event_obj)
, it can access the routes list
(getting all entries) and details
associated with the event_obj
.view_event
, but has the guardian permission ('view_event', event_obj)
, they receive a 403 in all routes (including the details
route associated with the event_obj that they have permission over).view_event
but doesn't have ('view_event', event_obj)
, they can access the route list
(seeing all entries), but they receive a 404 in details
route, regardless the entry being accessed.Thank you!
Ok, turns out that all views with permission class DjangoObjectPermissions
will only allow users to see a given resource if they have model-level and object-level permissions. The fact that my users are being able to list all objects, but not retrieving any of them, is because of a known bug that was already corrected but isn't on the current release just yet.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With