Reputation: 267
I'm quite new to Django rest framework and are struggling to use the custom model permissions to check if a user is allowed to access a certain endpoint.
Whenever trying to access the endpoint i get the "You are not authorized to perform this action" message even though the user is a superuser and/or has been given all app permissions both to the group and/or user.
Models.py
class User(AbstractBaseUser, PermissionsMixin):
"""
User model which inherits AbstractBaseuser. AbstractBaseUser provides the
core implementation of a user model.
"""
email = models.EmailField(
_('email address'),
unique=True,
)
...
class Meta:
...
permissions = (
('has_users_list', 'Can list users'),
)
Permissions.py
class UserOrGroupPermission(BasePermission):
def has_permission(self, request, view):
user_permissions = Permission.objects.filter(user=request.user)
group_permissions = Permission.objects.filter(group__user=request.user)
# get required permissions variable from view
required_permissions_mapping = getattr(view, 'required_permissions', {})
# determine if the required permissions for the particular request method
required_permissions = required_permissions_mapping.get(request.method, [])
if user_permissions or group_permissions in required_permissions:
return True
Viewsets.py
class UsersListAPIView(generics.ListCreateAPIView):
queryset = User.objects.all().order_by('id')
serializer_class = UsersSerializer
permission_classes = [UserOrGroupPermission]
required_permissions = {
'GET': ['has_users_list']
}
Upvotes: 0
Views: 169
Reputation: 6296
Superusers have all permissions implicitly, which means they necessarily do not have these permissions explicitly assigned to them in the Permission
table. And so you should use if user.is_superuser
to check that he is a superuser.
You also some issues on this line
if user_permissions or group_permissions in required_permissions:
The in
operator takes precedence over the or
operator, so basically what you're checking is if the user has any permissions at all or the user's group permissions are in the set of required permissions. And also, you're comparing permission objects with a list of permission names.
The following should help:
def has_permission(self, request, view):
if request.user.is_superuser:
return True
user_permissions = set(Permission.objects.filter(user=request.user).values_list('codename', flat=True))
group_permissions = set(Permission.objects.filter(group__user=request.user).values_list('codename', flat=True))
# get required permissions variable from view
required_permissions_mapping = getattr(view, 'required_permissions', {})
# determine if the required permissions for the particular request method
required_permissions = set(required_permissions_mapping.get(request.method, []))
if required_permissions.issubset(user_permissions | group_permissions):
return True
return False
It essentially checks if the required permissions are contained in a union of the two sets of permissions
Upvotes: 2