Anuj TBE
Anuj TBE

Reputation: 9790

Django REST Framework allow only superusers to access api web view

I'm using Django 2.0 and Django RESET Framework to write REST API for my application.

I have configured following authentication methods

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
}

As of now, It allows all authenticated users to access web api view.

What I want is to allow few users (probably superadmin users) to be able to access API from Session Authentication or from web browser by logging in.

Edit 2: contacts/views.py

class ContactViewSet(viewsets.ModelViewSet):
    queryset = Contact.objects.all()
    serializer_class = ContactSerializer
    permission_classes = (IsAuthenticated,)

    def perform_create(self, serializer):
        serializer.save(user_id=self.request.user)

Upvotes: 9

Views: 10248

Answers (3)

niran
niran

Reputation: 1980

There is already inbuilt class called IsAdminUser, specify it as values to permission_classes property

from rest_framework.permissions import IsAdminUser

class A:
    permission_classes = (IsAdminUser,)

this checks for the value

reques.user.is_staff == True

Upvotes: 5

Igor  Tischenko
Igor Tischenko

Reputation: 640

For Django 2 (Added in views.py)

from rest_framework.permissions import IsAdminUser

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

class ListSmth(ListCreateAPIView):
    permission_classes = (IsSuperUser,)
    ... Your code...

Upvotes: 14

rtindru
rtindru

Reputation: 5337

So you can leverage permission_classes to do this. DRF's Request object remembers the authentication method that was used in an attribute called _authenticator. You can use this; and use the permission_classes to determine if the pair of (user, authenticator) has permission

class AdminAuthenticationPermission(permissions.BasePermission):
    ADMIN_ONLY_AUTH_CLASSES = [rest_framework.authentication.BasicAuthentication, rest_framework.authentication.SessionAuthentication]

    def has_permission(self, request, view):
        user = request.user
        if user and user.is_authenticated():
            return user.is_superuser or \
                not any(isinstance(request._authenticator, x) for x in self.ADMIN_ONLY_AUTH_CLASSES) 
        return False

class ContactViewSet(viewsets.ModelViewSet):
    queryset = Contact.objects.all()
    serializer_class = ContactSerializer
    permission_classes = (IsAuthenticated, AdminAuthenticationPermission,)

Untested: but should work

Upvotes: 3

Related Questions