Skip to content

There is an open discussion on GitHub – https://github.com/encode/django-rest-framework/discussions/9746.

Why the need for “IsSuperUser”

We had a very specific edge case, where we only want “Super Users” to access a certain API node in NearBeach. We required any users with lower priverledges to be restricted from this node, this does include staff members. Currently – as documented – the permission “IsAdminUser” will check to see if the user has the “is_staff” flagged as true which sadly does not meet our specific requirements.

Author’s Note: The IsAdminUser permission check will cover the vast majority of everyone’s needs. We just had an edge case 🙂

Our current fix

After looking at Django-Rest-Framework’s code, we noticed that we could easily create a work around. The code for the IsAdminUser is located – https://github.com/encode/django-rest-framework/blob/853969c69c815be69513c2f63a41285858a45352/rest_framework/permissions.py#L154.

class IsAdminUser(BasePermission):
    """
    Allows access only to admin users.
    """

    def has_permission(self, request, view):
        return bool(request.user and request.user.is_staff)

To create our own permission check, we copied the IsAdminUser code into our own code base. A new file was created at the location utils/api/permissions.py, with the following modifications applied to it;

  • Changing the class name to IsSuperUser
  • Changed the return bool code to look at the is_superuser field

And we ended up with the following results;

from rest_framework.permissions import BasePermission


class IsSuperUser(BasePermission):
    """
    Allows access only to super users.
    """

    def has_permission(self, request, view):
        return bool(request.user and request.user.is_superuser)

Now to utilse this function, we just need to;

  • Import this permission into our python file
  • Call it at the appropriate place
...
from NearBeach.utils.api.permissions import IsSuperUser
...

@extend_schema(
    tags=['User|User API'],
    methods=["GET", "POST", "DELETE"],
)
class UserApiViewSet(viewsets.ModelViewSet):
    # Setup the queryset and serialiser class
    queryset = ExtendsAuthToken.objects.all()
    serializer_class = UserApiSerializer
    permission_classes = [IsSuperUser]

...

In reality this is a very simple fix to extend the DRF permissions. I hope you find this article useful.