manu langat
manu langat

Reputation: 1

Pass argument to custom permision class in django

I have a custom permission class that extends the rest framework base permission. I am trying to pass an argument allowed_groups that will be a list of all the groups that have access to the particular view.

This is my current custom permission implementation.

class CustomUserPermisions(BasePermission): 
    
    message = "Ooops! You do not have permissions to access this particular site"
    def has_permission(self, request, view):
        allowed_groups = [ 'group_hr', 'super_admin', 'employee']
        user1 = Employee.objects.filter(user__email=request.user).first()
        user_groups = user1.user_group.all()
        for group in user_groups:
            if group.title in allowed_groups:
                return True 
        return False

I have tried adding an argument as follows.

class CustomUserPermisions(BasePermission, allowed_groups): 
    
    message = "Ooops! You do not have permissions to access this particular site"
    def has_permission(self, request, view):
        allowed_groups = [ 'group_hr', 'super_admin', 'employee']
        user1 = Employee.objects.filter(user__email=request.user).first()
        user_groups = user1.user_group.all()
        for group in user_groups:
            if group.title in allowed_groups:
                return True 
        return False

but this is the error I am currently receiving.

class CustomUserPermisions(BasePermission, allowed_groups): 

NameError: name 'allowed_groups' is not defined

Is there a better way that I can do this?

Upvotes: 0

Views: 625

Answers (2)

Abduaziz
Abduaziz

Reputation: 1

You can implement __init__ yourself. But if you create an instance of this class (passing an argument to the initializer, which returns the instance), the Django Rest framework again calls this permission class, which gives the TypeError: '...' object is not callable. That's why the previous answer won't work.

To avoid this, you should also implement __call__ which will work when DRF itself calls this permission class, where you need to return the current instance of that class.

Permission class:

class SomePermission(BasePermission):
    def __init__(self, argument): # you can pass here
        self.argument = argument

    def __call__(self, *args, **kwargs):
        return self

    def has_permission(self, request, view) -> bool:
        # You can access using self.argument
        # do some logic
        return True

Usage:

class SomeListView(ListAPIView):
    permission_classes = (SomePermission(my_argument),) # here
    queryset = ...
    serializer_class = ...

Upvotes: -1

DeaX StormZ
DeaX StormZ

Reputation: 86

I guess you are a newcomer to python. You should read https://docs.python.org/3/tutorial/classes.html to get better understanding about python classes.

class CustomUserPermisions(BasePermission, allowed_groups): means that the class CustomUserPermisions inherits from the classes BasePermission and allowed_groups. allowed_groups is not a class, so you get an error.

You should create a class attribute for allowed group :

class CustomUserPermisions(BasePermission):
    def __init__(self, allowed_groups):
        self.allowed_groups = allowed_groups
        self.message = "Ooops! You do not have permissions to access this particular site"

    def has_permission(self, request, view):
        user1 = Employee.objects.filter(user__email=request.user).first()
        user_groups = user1.user_group.all()
        for group in user_groups:
            if group.title in self.allowed_groups:
                return True
        return False

and then call the class constructor :

permissions = CustomUserPermisions(['group_hr', 'super_admin', 'employee'])

Upvotes: 1

Related Questions