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
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.
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.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With