3

I have a custom permission with name = 'can show distribute page', codename='can_show_distribute_page', contenttype='User'.

I add two Groups, named 'manager' and 'normal', one has the cited permission and one not.

How can I judge if a user has that permission?

I tried to use the user.has_perm() method, but it always returns False.

Nicolò Gasparini
  • 2,228
  • 2
  • 24
  • 53
Roger Liu
  • 1,768
  • 3
  • 16
  • 25

2 Answers2

4

The correct way to do this is to use has_perm on the User class. If this is not working, check to make sure that both users are set as active. If that does not seem to be the problem, bring up each user in the shell and call get_group_permissions to see what permissions they actually have through their group memberships.

Thomas
  • 11,757
  • 4
  • 41
  • 57
  • 1
    I do use the has_perm method, which works fine when the user has the permission, but I want to let the user in the group and judge whether he has the permission through the group he is in, how to do this? – Roger Liu May 10 '13 at 07:00
  • has_perm also checks the user's groups to see if they have that permission provided through a group. This should work as intended provided you have it setup right. try using get_group_permissions to verify they are indeed in the correct groups with the correct permissions. – Thomas May 10 '13 at 07:17
  • did it actually fix your problem – Thomas May 10 '13 at 11:25
1

The has_perm method of the AbstractUser (if your User model inherits from it) actually checks, for every auth backend you set up, the inner has_perm function, the code is below:

def _user_has_perm(user, perm, obj):
    """
    A backend can raise `PermissionDenied` to short-circuit permission checking.
    """
    for backend in auth.get_backends():
        if not hasattr(backend, 'has_perm'):
            continue
        try:
            if backend.has_perm(user, perm, obj):
                return True
        except PermissionDenied:
            return False
    return False

So the first thing to check if wheter you have an authorization backend that actually checks the group permissions, you can either create a custom one or use the default ModelBackend,you can specify this in your settings through the following key:

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
]

After that, be sure to pass the permission as a string formatted in the same format used by the backend, in this case the ModelBackend formats it like this f"{perm..content_type.app_label}.{perm.codename}

A working example for your case would be:

user.has_perm("app_name.can_show_distribute_page")
Nicolò Gasparini
  • 2,228
  • 2
  • 24
  • 53