Reputation: 1949
I have an Update method in DRF to allow users to update their own profile. The api endpoint is PUT /api/users/{id}/
where id is his own user id. If he attempts to update any other users profile he will receive a HTTP403.
The way I am doing it right now is
def update(self, request, *args, **kwargs):
"""
Update user profile
"""
if int(kwargs['id']) is not request.user.id:
return Response({}, status=status.HTTP_403_FORBIDDEN)
return super(UserViewSet, self).update(request, *args, **kwargs)
I am hoping to do this in a more elegant way, perhaps with a decorator or something?
Upvotes: 1
Views: 2323
Reputation: 47846
You can create a CustomUpdatePermission
class which will grant access to update requests depending on whether the id
in the url and request.user.id
matched or not.
We will check first check that its an update
request. If it was, we will check the value of id
in the url with the id
of request.user
. If they did not match, request will not be granted access and a 403 Forbidden
response will be returned.
from rest_framework import permissions
class CustomUpdatePermission(permissions.BasePermission):
"""
Permission class to check that a user can update his own resource only
"""
def has_permission(self, request, view):
# check that its an update request and user is modifying his resource only
if view.action == 'update' and view.kwargs['id']!=request.user.id:
return False # not grant access
return True # grant access otherwise
You can include this permission class in your UserViewset
by defining permission_classes
setting.
class UserViewSet(viewsets.ModelViewSet):
permission_classes = (CustomUpdatePermission,) # specify custom permission class here
...
Upvotes: 4
Reputation: 10256
If you are using Tokens to authenticate your users, with DRF you can access the current user in request.user
as you can see in Docs.
So, you can match the request.user
's with the incoming id
in url, or use only the request.user
to update info and stop passing id
via URL.
Upvotes: 1