Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django REST framework: Check user is in group

I was wondering the best way to create a custom permission that checks if a user is in a particular group. Previously, I had a decorator I could use on a view to pass in a tuple of group names along with the user object and then check if that user was in the groups specified.

Ie:

def in_group_views(*group_names):     """Requires user membership in at least one of the groups passed in."""      def in_groups(u):         if u.is_authenticated():             if bool(u.groups.filter(name__in=group_names)) | u.is_superuser:                 return True         return False      return user_passes_test(in_groups) 

How would I do this for DRF for a viewset, taking into account I need to check for different group memberships for different actions (POST,PUT,GET) etc.

Many thanks, Ben

like image 421
Ben Kilah Avatar asked Oct 15 '13 02:10

Ben Kilah


People also ask

What are groups in Django?

Groups. django.contrib.auth.models.Group models are a generic way of categorizing users so you can apply permissions, or some other label, to those users. A user can belong to any number of groups. A user in a group automatically has the permissions granted to that group.

How does Django REST framework authentication work?

Authentication is the mechanism of associating an incoming request with a set of identifying credentials, such as the user the request came from, or the token that it was signed with. The permission and throttling policies can then use those credentials to determine if the request should be permitted.


1 Answers

The sensible way to parameterize permission classes is to put the parameters on the view class. That'll let you change the behaviour from view to view.

Here's an example:

# permissions.py from django.contrib.auth.models import Group from rest_framework import permissions  def is_in_group(user, group_name):     """     Takes a user and a group name, and returns `True` if the user is in that group.     """     try:         return Group.objects.get(name=group_name).user_set.filter(id=user.id).exists()     except Group.DoesNotExist:         return None  class HasGroupPermission(permissions.BasePermission):     """     Ensure user is in required groups.     """      def has_permission(self, request, view):         # Get a mapping of methods -> required group.         required_groups_mapping = getattr(view, "required_groups", {})          # Determine the required groups for this particular request method.         required_groups = required_groups_mapping.get(request.method, [])          # Return True if the user has all the required groups or is staff.         return all([is_in_group(request.user, group_name) if group_name != "__all__" else True for group_name in required_groups]) or (request.user and request.user.is_staff) 

You could then use the HasGroupPermission class like so:

# views.py class MyView(APIView):      permission_classes = [HasGroupPermission]      required_groups = {          'GET': ['moderators', 'members'],          'POST': ['moderators', 'someMadeUpGroup'],          'PUT': ['__all__'],      }       ... 

Hope that helps!

like image 103
Tom Christie Avatar answered Oct 06 '22 04:10

Tom Christie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!