Ramsey
Ramsey

Reputation: 181

How to restrict access to certain groups in django class based view

My views.py have a mix of def and ClassViews:

@login_required(login_url='login')
@allowed_users(allowed_roles=['Admin', 'Staff', 'Lite Scan'])
def litescan(request):
    filteredOutput = Stock.objects.all()
    val = {}...

@method_decorator(login_required(login_url='login'), name='dispatch')
class HomeView(ListView):
    model = Post
    template_name = 'community.html'
    ordering = ['-id']

And here's my decorators.py if that is helpful:

from django.shortcuts import redirect
from django.http import HttpResponseRedirect


def unauthenticated_user(view_func):
    def wrapper_func(request, *args, **kwargs):
        if request.user.is_authenticated:
            return redirect('home')
        else:
            return view_func(request, *args, **kwargs)

    return wrapper_func

def allowed_users(allowed_roles=[]):
    def decorator(view_func):
        def wrapper_func(request, *args, **kwargs):

            group = None
            if request.user.groups.exists():
                group = request.user.groups.all()[0].name

            if group in allowed_roles:
                return view_func(request, *args, **kwargs)
            else:
                url = ('/forbidden')
                return HttpResponseRedirect(url)
        return wrapper_func
    return decorator

I found out that @login_required and @allowed_users give out an error when used with ClassView. So i used @method_decorator which brings me to the login page before redirecting to the page. However, I can not find a way to restrict access to only certain groups like Admin, Staff, Lite Scan with my ClassView.

Little help will be appreciated. Thanks!

Upvotes: 1

Views: 3683

Answers (2)

thirdjal
thirdjal

Reputation: 21

Relying on Django Permissions may be a far simpler approach to giving access to such a view. Rather than checking for a specific list of groups, you can assign permissions to those groups and give access to the view based on whether the user's groups have the appropriate permissions.

views.py

from django.contrib.auth.decorators import permission_required
from django.contrib.auth.mixins import PermissionsRequiredMixin


@permission_required('foo.view_bar')
def my_view(request):
    ...


class MyView(PermissionRequiredMixin, DetailView):
    permission_required = ('foo.view_bar', )
    ...

Upvotes: 2

Shyrtle
Shyrtle

Reputation: 647

You can use AccessMixin for your class views.

Example I found:

from django.contrib.auth.mixins import AccessMixin
from django.http import HttpResponseRedirect 

class FinanceOverview(AccessMixin, TemplateMixin):

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            # This will redirect to the login view
            return self.handle_no_permission()
        if not self.request.user.groups.filter(name="FinanceGrp").exists():
            # Redirect the user to somewhere else - add your URL here
            return HttpResponseRedirect(...)

        # Checks pass, let http method handlers process the request
        return super().dispatch(request, *args, **kwargs)

More info found here: Use LoginRequiredMixin and UserPassesTestMixin at the same time

Upvotes: 4

Related Questions