Santhosh
Santhosh

Reputation: 11834

Django checking user permission before the view

I have a user model as:

class User(AbstractUser):
    USER_TYPE_CHOICES = (
        (1, 'pro_user'),
        (2, 'consumer'),
        (3, 'other'),
    )

    user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES,default=3)

Now I want certain views to be only accessed by pro_user and consumer and certain by pro_user only and certain by consumer and other and such combinations

I have seen @user_passes_test can be used for this. But for multiple condition how to use it

@login_required
@user_passes_test(lambda:u: u.user_type == 1,login_url='/page1/')
@user_passes_test(lambda:u: u.user_type == 2,login_url='/page3/')
def test(request):
    .....

I want to use this like

@login_required
@some_decorator(is_user_type1,is_user_type2)  #<-- pass list of user types allowed and for rest redirect to a url which shows "you are not authorized" 
def test(request):
...

Upvotes: 0

Views: 378

Answers (2)

Peter Krause
Peter Krause

Reputation: 49

You can use the @permission_classes decorator for this. It takes a list of permission classes as argument. You'll need to then create one permission class for each permission you want your view to have, like so:

from rest_framework.permissions import BasePermission


class IsCustomer(BasePermission):
   def has_permission(self, request, view):
      return request.user.user_type == 2

And then, in your view function:

from rest_framework.decorators import permission_classes

@permission_classes([IsCustomer])
def test(request):
   ...

Now, what this will do, is to respond unauthenticated users with a 401. If you want to redirect them somewhere else, a middleware might do the job for you.

class NonCustomerRedirectMiddleware:
   def process_request(self, request):
        if request.user.user_type != 2:
            return HttpResponseRedirect(reverse('login'))
        return None

And then in your settings.py file:

MIDDLEWARE_CLASSES = [
   "your.middleware.folder.NonCustomerRedirectMiddleware"
]

Upvotes: 1

SvenTUM
SvenTUM

Reputation: 809

I just took this from the documentation and adjusted it slightly:

from django.contrib.auth.decorators import login_required, user_passes_test

def user_is_customer_or_pro_user(user):
    return user.user_type in (1, 2)

def user_is_customer(user):
    return user.user_type == 2

def user_is_pro_user(user):
    return user.user_type == 1

@login_required
@user_passes_test(user_is_customer_or_pro_user)
def test(request):
    // ...
    pass

Upvotes: 0

Related Questions