0

I am trying to set up object-level permissions using Django guardian and groups; where I give permissions to the groups - not the users - and add/remove users from the groups as required.

When a user has permission to interact with an object instance - because they are in a group that has the necessary permissions - how can I determine which of the user's groups gave them the permission?

As an example, building off the example in the django-guardian-docs , ideally there would be something like:

>>> joe.has_perm_from_groups('sites.change_site', site)
[site_owners_group]
Ben
  • 2,143
  • 2
  • 19
  • 27

1 Answers1

0

Django guardian has a shortcut called get_groups_with_perms(obj) that Returns queryset of all Group objects with any object permissions for the given obj. https://django-guardian.readthedocs.io/en/stable/api/guardian.shortcuts.html#get-groups-with-perms

Django has a queryset method called intersection that returns the shared elements of two or more QuerySets https://docs.djangoproject.com/en/3.2/ref/models/querysets/#intersection

Using these two functions, I can find the groups that the user is in that also have permissions for the object. I then use a for loop to identify the group with the permission. If two groups have the permission, I don't know how I would work out which one gave the user the permission, so the first group found is returned.

# Find the union of groups
groups = user.groups.all().intersection(get_groups_with_perms(obj))

# Check if any group has the permission, and return if True
for group in groups:
    if 'change_site' in get_perms(group, obj):
        return group
return None
Ben
  • 2,143
  • 2
  • 19
  • 27