0

I'm just trying start work with Permissions to learn how thats work.

In shell i have empty set() result from user_test.get_all_permissions(). I see this question, is the same of that, but i can't find what is missing im my code:

Edit

Now seeing in class ModelBackend, a particular part confuses my mind: ...get_all_permissions(),...allow an object to be passed as a parameter for object-specific permissions, but this backend does not implement them other than returning an empty set of permissions if obj is not None

And bellow in docs:

get_all_permissions(user_obj, obj=None)

Returns the set of permission strings the user_obj has, including both user permissions and group permissions. Returns an empty set if is_anonymous or is_active is False.

My user have is_active flag=true, even though user_test.get_all_permissions() return empty set().

In this question a comment call my atention: "You need to implement a get_all_permissions in your User model..."

I'm lost in this general understanding that part of Permissions concept.

I created Custom User from AbstractBaseUser, with follow code:

settings.py

...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'users',
]

AUTH_USER_MODEL = 'users.User'

AUTHENTICATION_BACKENDS = [
    'users.backends.CustomModelBackend',
]
...

models.py

class UserManager(BaseUserManager):
    def create_user(self, email, username, phone, password = None):
    ...
    def create_superuser(self, email, username, phone, password = None):
    ...

class User(AbstractBaseUser, PermissionsMixin):
    ...
    objects = UserManager()
    ...
    
    def __str__(self):
        return self.email
    def has_perm(self, perm, obj=None):
        return True
    def has_module_perms(self, app_label):
        return True  

backends.py

class CustomModelBackend(backends.ModelBackend):
    def user_can_authenticate(self, user):
        return True

In shell i try something like:

>>> from users.models import User
>>> user_test = User.objects.get(email="user@example.com")
>>> user_test.get_all_permissions()
set()

That user is superuser. And i test it to regular user to

EDIT

I realized that I might need to implement this in the backend, I don't know if it's the correct path, but making the following change I get the following error:

backends.py edit

from django.contrib.auth import backends

def _user_get_permissions(user, obj, from_name):
    permissions = set()
    name = 'get_%s_permissions' % from_name
    for backend in backends.get_backends():
        if hasattr(backend, name):
            permissions.update(getattr(backend, name)(user, obj))
    return permissions

class CustomModelBackend(backends.ModelBackend):
    
    def user_can_authenticate(self, user):
        return True
    
    def _get_user_permissions(self, user_obj):
        return user_obj.user_permissions.all()
    
    def get_all_permissions(self, obj=None):
        return _user_get_permissions(self, obj, 'all')

The error:

...
line 198, in _user_get_permissions
    permissions.update(getattr(backend, name)(user, obj))
TypeError: get_all_permissions() takes from 1 to 2 positional arguments but 3 were given

What is needed to check that permissions?

Pouya Esmaeili
  • 1,265
  • 4
  • 11
  • 25
MagicHat
  • 379
  • 1
  • 6
  • 28
  • You don't need `user` argument remove it like this: `getattr(backend, name)(obj)` – Ahtisham Jan 16 '22 at 18:25
  • tks for atention, Idk, it seems like ignore my backend or whatever... >>> from users.models import User >>> user_test = User.objects.get(email="user@example.com") >>> user_test.get_all_permissions()` – MagicHat Jan 16 '22 at 18:46
  • Have you tried what i suggested ? – Ahtisham Jan 16 '22 at 18:47
  • @Ahtisham ` File "/home/noot/.virtualenvs/masterEnv/lib/python3.9/site-packages/django/contrib/auth/models.py", line 285, in get_all_permissions return _user_get_permissions(self, obj, 'all') File "/home/noot/.virtualenvs/masterEnv/lib/python3.9/site-packages/django/contrib/auth/models.py", line 198, in _user_get_permissions permissions.update(getattr(backend, name)(user, obj)) TypeError: get_all_permissions() takes from 1 to 2 positional arguments but 3 were given` – MagicHat Jan 16 '22 at 18:47
  • @Ahtisham yeah, above the error – MagicHat Jan 16 '22 at 18:48
  • You have not removed the user argument yet remove it from getattr. – Ahtisham Jan 16 '22 at 18:48
  • @Ahtisham this is what i say... seems like django ignore my backend... and use contrib... i do what u say `permissions.update(getattr(backend, name)(obj))` – MagicHat Jan 16 '22 at 18:50
  • @Ahtisham idk if is relevant, but i use `class UsersAdminSite(admin.AdminSite): ... kadmin = UsersAdminSite(name='kadmin')` – MagicHat Jan 16 '22 at 18:54

2 Answers2

0

For superuser this list would be empty. On has_perm method there is IF for superuser and its always return True for superuser

Sharpek
  • 658
  • 4
  • 5
0

In my case, I had my custom User class, and I was trying to use djago-jazzmin for admin panel. I was getting error because I didn't have get_all_permissions method on my custom User model. Implementing stated method as below solved my problem and I was able to successfully load jazzmin admin:

def get_all_permissions(user=None):
    if user.is_superadmin:
        
        return set()
Yalchin Mammadli
  • 444
  • 4
  • 11