Hi All.
I figure this must be a usage thing rather than a bug, though it does seem
related to https://github.com/encode/django-rest-framework/pull/2933. For
the record I'm using DRF 3.6.2.
I have a view set for a model that has object level permissions. I want
authenticated users to be able to read details for a specified model, but
otherwise want object level permissions enforced.
I've tried a three ways of doing this:
1) overriding get_permissions,
2) implementing a custom permission object, and,
3) overriding check_permissions and check_object_permissions.
The result in each case is the same. With the appropriate code in place the
authenticated user sees a 404 error rather than a serialization of the
object.
The problem seems to be changes that are made to the view and request in
the method override_method called after rendering of the response is called
(Up till this point the response is determined correctly). These changes
make the code below return the wrong responses for object permissions when
they are checked during render in show_form_for_method.
In all three cases I've been relying on view.action to determine if a
retrieve has been requested. This action is changed in override_method. I
could probably use request.method, but override_method seems to change this
from GET to POST.
What is the correct way to provide different permissions for a get as
opposed to a post in a view set? So that the effects of override_method are
ignored? Is there someway to check for the cached request or view?
Examples:
Case 2:
The view set uses the following custom permissions
class CustomObjectPermissions(permissions.DjangoObjectPermissions):
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'],
}
class CustomTransactionObjectPermissions(CustomObjectPermissions):
def has_permission(self, request, view):
if view.action == "retrieve":
return permissions.DjangoModelPermissions().has_permission(
request, view)
return super().has_permission(request, view)
def has_object_permission(self, request, view, obj):
if view.action == "retrieve":
return permissions.DjangoModelPermissions().
has_object_permission(request, view, obj)
return super().has_object_permission(request, view, obj)
For case 3:
The view set implements the following methods
def check_permissions(self, request):
if self.action != "retrieve":
if not permissions.CustomObjectPermissions().has_permission(
request,
self
):
return self.permission_denied(request)
if not rest_framework.permissions.DjangoModelPermissions().
has_permission(
request,
self
):
return self.permission_denied(request)
def check_object_permissions(self, request, obj):
if self.action == "retrieve":
if not permissions.CustomObjectPermissions().
has_object_permission(
request,
self,
obj
):
return self.permission_denied(request)
--
You received this message because you are subscribed to the Google Groups
"Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.