I am using Django REST Framework to access a resource 'user'.
As user information is personal, I do not want a GET request to list every user on the system, UNLESS they are an admin.
If the user specifies their id, and they are logged in, I would like them to be able to view their details and amend them (PUT POST DELETE) if required.
So in summary, dis-allow GET method for anyone who isn't an admin and allow GET POST DELETE PUT on logged-in users when viewing their information.
I created the custom permission class:
class UserPermissions(permissions.BasePermission):
"""
Owners of the object or admins can do anything.
Everyone else can do nothing.
"""
def has_permission(self, request, view):
# if admin: True otherwise False
def has_object_permission(self, request, view, obj):
# if request.user is the same user that is contained within the obj then allow
This didn't work. After some debugging I found that it checks has_permission
first, THEN checks has_object_permission
. So if we don't get past that first hurdle GET /user/
, then it won't even consider the next GET /user/id
.
How I would go about getting this to work?
I was using ModelViewSets.
But if you split the List functionality with the Detail then you can give them separate permission classes:
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes=(UserPermissionsAll,)
class UserDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes=(UserPermissionsObj,)
class UserPermissionsAll(permissions.BasePermission):
"""
Owners of the object or admins can do anything.
Everyone else can do nothing.
"""
def has_permission(self, request, view):
if request.user.is_staff:
return True
else:
return False
class UserPermissionsObj(permissions.BasePermission):
"""
Owners of the object or admins can do anything.
Everyone else can do nothing.
"""
def has_object_permission(self, request, view, obj):
if request.user.is_staff:
return True
return obj == request.user