How To Get a List Of All User Permissions Available in Django Based Project

07 Jun · by Tim Kamanin · 3 min read

Django comes with a simple permissions system. It provides a way to assign permissions to specific users and groups of users. The system adds "change, remove and add" permissions automatically to every model class. And it's pretty easy to add custom permissions to a model class, like this:

class Product(models.Model):
  # Model fields go here
  ...
  class Meta:
    permissions = (
      ("can_see_dealer_price", "Can see dealer price"),
    )

And then you can check if the current user has permission:
1) be it inside Django template:

{% if perm.shop.can_see_dealer_price %} 
  {{ dealer_price }}
{% endif %}

2) or inside python code, the most naive way is:

if request.user.has_permission('shop.can_see_dealer_price'):
   # do something with it

3) For more ways to check if user has a permission, please refer to Django docs: https://docs.djangoproject.com/en/1.11/topics/auth/default/#topic-authorization.

You may have already noticed the pattern of how a permission gets registered: app_name.permission_slug.

And now the best part: while developing, you may get lucky and guess this pattern all the time, or you can scratch your head (like me) everytime you need to figure out what 's the correct name of so much needed permission is.

I couldn't find a sane way of figuring out permission names easily, so I came up with a little management command that allows me to list all permissions available in the system, here's the code, please read my comments in the code if you want to understand what's happening:

from django.contrib import auth
from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand


class Command(BaseCommand):
  help = 'Get a list of all permissions available in the system.'

  def handle(self, *args, **options):
    permissions = set()

    # We create (but not persist) a temporary superuser and use it to game the
    # system and pull all permissions easily.
    tmp_superuser = get_user_model()(
      is_active=True,
      is_superuser=True
    )

    # We go over each AUTHENTICATION_BACKEND and try to fetch
    # a list of permissions
    for backend in auth.get_backends():
      if hasattr(backend, "get_all_permissions"):
        permissions.update(backend.get_all_permissions(tmp_superuser))

    # Make an unique list of permissions sorted by permission name.
    sorted_list_of_permissions = sorted(list(permissions))

    # Send a joined list of permissions to a command-line output.
    self.stdout.write('\n'.join(sorted_list_of_permissions))

Put this code inside /management/commands/get_all_permissions.py and then run python manage.py get_all_permissions

You should get a list of permissions that looks more or less like this:

account.add_emailaddress
account.add_emailconfirmation
account.change_emailaddress
account.change_emailconfirmation
account.delete_emailaddress
account.delete_emailconfirmation
auth.add_group
auth.add_permission
auth.change_group
auth.change_permission
auth.delete_group
auth.delete_permission
...
sessions.add_session
sessions.change_session
sessions.delete_session
sites.add_site
sites.change_site
sites.delete_site
users.add_user
users.change_user
users.delete_user

Voila, now you have an easy lookup in user permissions.

I packaged this code into a little module called Django Debug Permissions and published it on PYPI.

Feel free to install it via PIP:

pip install django-debug-permissions

Github repo can be found here: https://github.com/timonweb/django-debug-permissions.

Comments

Required for comment verification