Reputation: 281
I'm sorry if I may have wrong code but I havent really been doing django rest much. I want to detect permissions from django's built in User model. I added a permission to a user model but for some reason has_perm doesn't work. I instead use user_objects.all() and detect if the permission object is there. I want to return an error 400: Unauthorized if the user does not have permission.
Heres my current solution(not working):
class ProgramListCreateView(PermissionRequiredMixin,ListCreateAPIView):
permission_required = Permission.objects.get(name="Can CRUD")
permission_classes = (IsAuthenticated,)
queryset = Program.objects.all()
serializer_class = ProgramSerializer
def check_user(self,request):
if self.permission_required in request.user.user_permissions.all():
return True
return Response(status=400)
when I send a json with the user token without the permission, it still creates the object
Heres my mixin:
class PermissionRequiredMixin(object):
user_check_failure_path = 'auth_login'
permission_required = None
def check_user(self, user):
return user.has_perm(self.permission_required)
note: has_perm always returns false for some reason even if I add it using user.user_permissions.add(permission_object)
Upvotes: 1
Views: 4821
Reputation: 281
Heres what I did: I created a Mixin that extends the default generic API Views and I just override the put post and get functions
class MasterGenericAPIViewMixin(ListCreateAPIView, RetrieveUpdateDestroyAPIView):
codename = None
def post(self, request, *args, **kwargs):
permission = Permission.objects.get(codename=self.codename)
if permission not in request.user.user_permissions.all():
return Response(status=403, data={
"error": "not authorized to add"
})
return self.create(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
permission = Permission.objects.get(codename=self.codename)
if permission not in request.user.user_permissions.all():
return Response(status=403, data={
"error": "not authorized to edit"
})
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
permission = Permission.objects.get(codename=self.codename)
print(permission)
print(request.user)
if permission not in request.user.user_permissions.all():
return Response(status=403, data={
"error": "not authorized to delete"
})
return self.destroy(request, *args, **kwargs)
all my views extended this class
Upvotes: 1
Reputation: 9443
Sounds like you are trying to verify if a particular user has permission to your APIView
.
You can simply use DjangoModelPermissions
read more
class ProgramListCreateView(ListCreateAPIView):
permission_classes = (IsAuthenticated, DjangoModelPermissions)
...
You can also use the custom permission read more
from rest_framework import permissions
class UserPermission(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
'''
Object-level permission to only allow user model manipulation
'''
# IF you would like to allow GET, HEAD or OPTIONS requests,
if request.method in permissions.SAFE_METHODS:
return True
# check if user is owner
return request.user == obj
USAGE
from custom_permission import UserPermission
class ProgramListCreateView(ListCreateAPIView):
permission_classes = (UserPermission, )
...
OR
If you want to make your permission globally you can include it on your settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
'rest_framework.permissions.DjangoModelPermissions',
)
}
Upvotes: 1