python - Django Rest Framework: Permissions based on Object Attributes/Ownership -
i'd allow users create , view resources, if:
- they staff or
- they 'owner' of object they're trying create/view
i've got read-only permissions worked out fine, since users have permission lists of objects when primary key used generate viewset. example: /api/users/1/notes returns notes user pk=1.
however, in testing, discovered users can create object 'owned' user posting own list endpoint. example user 1 can send post /api/users/1/notes, specify note data {user: "http://host.tld/users/2/", text: "look! created note in person's account!"}
i've got fix below seems work fine, though feeling i'm swimming against current. right now, within custom permission, create instance of object created , check owner user making request.
is there cleaner way of doing this?
current fix:
def has_permission(self, request, view): if request.user.is_staff: return true elif request.method in permissions.safe_methods: # check user looking own list return request.user == user.objects.get(pk=view.kwargs['user_pk']) elif request.method not in permissions.safe_methods: # user can create/modify object if new object's user == request user # roundabout way of figuring out... better way user_path = request.post['user'].split(request.get_host())[1] func = resolve(user_path).func kwargs = resolve(user_path).kwargs user_for_object = func.cls.model.objects.get(pk=kwargs['pk']) return user_for_object == request.user else: return false
it depends on rest of code.
normally drf object-level checks in method called check_object_permissions
in viewset
or permission backend.
this method gets called (the default implementation) of get_object
check permissions when of generics tries object work on.
if use generic viewsets , /notes
@action
easiest way.
if object in these viewsets note
, suggest build looking similar (for example in mixin add every viewset sitting under /user/
). there many different approaches build nested resources , routing them.
Comments
Post a Comment