How to add permissions based on group membership on Django Rest Framework Class-Based Views?

37 Views Asked by At

Thank you for your time.

The following code is a class-based with the method named get_permissions() which purpose is to allow only the authenticated users to make POST,PUT,DELETE and PATCH requests:

# this works
class MenuItemView(generics.ListCreateAPIView):
    queryset = MenuItem.objects.all()
    serializer_class = MenuItemSerializer

    def get_permissions(self):
        permission_classes = []
        if self.request.method != 'GET':
            permission_classes = [IsAuthenticated]
            
        return [permission() for permission in permission_classes]

The problem is when I try to add to the condition to require also being a member of the 'Manager' group to get authorization, the method gives auth to any users with or without token:

# this doesn't work:
class MenuItemView(generics.ListCreateAPIView):
    queryset = MenuItem.objects.all()
    serializer_class = MenuItemSerializer

    def get_permissions(self):
        permission_classes = []
        is_manager = self.request.user.groups.filter(name='Manager').exists()

        if self.request.method != 'GET' and is_manager:
            permission_classes = [IsAuthenticated]

        return [permission() for permission in permission_classes]

I tried printingis_manager before the if statement, to check in the console it's value and everytime I tested with different tokens of a manager, user, non-user, superuser, and a member of another group and the value was as expected. enter image description here enter image description here

Please help and thank you in advance.

1

There are 1 best solutions below

0
Enrique Dominguez On

I found an article that explained how to create custom permissions: 3rd part of Django REST Framework Permissions Series

With this article I learned how to do the following:

  1. Create a permissions.py file at the API level and to create the custom permission IsManagerOrSuperuser:
# permissions.py
from rest_framework import permissions

class IsManagerOrSuperuser(permissions.BasePermission):
    
    def has_permission(self, request, view):
        manager = request.user.groups.filter(name='manager').exists()
        superuser = request.user.is_superuser

        if manager or superuser:
            return True
  1. Imported the custom permission to the views.py and changed IsAuthenticated for IsManagerOrSuperuser:
# views.py
from .models import MenuItem
from .serializers import MenuItemSerializer
from rest_framework import generics
from .permissions import IsManagerOrSuperuser

class MenuItemView(generics.ListCreateAPIView):
    queryset = MenuItem.objects.all()
    serializer_class = MenuItemSerializer

    def get_permissions(self):
        permission_classes = []
        if self.request.method != 'GET':
            permission_classes = [IsManagerOrSuperuser]
        return [permission() for permission in permission_classes]