Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)
like image 844
Anuj TBE Avatar asked May 14 '18 14:05

Anuj TBE


3 Answers

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...
like image 130
Igor Tischenko Avatar answered Sep 23 '22 05:09

Igor Tischenko


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

like image 45
rtindru Avatar answered Sep 20 '22 05:09

rtindru


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.isStaff == True
like image 38
niran Avatar answered Sep 24 '22 05:09

niran