WilliamW
WilliamW

Reputation: 468

"You don't have permission to view or edit anything." even if user has access to model

SOLVED


I know this "error" message is common and there are already posts around this. But did not find a way to fix my issue.

I am using the already existing "User", "Group", "UserManager" provided by Django. However, I have a custom authentication backend:

    class MyAuthentication:
       # ...
       # ...
       def has_perm(self, user_obj, perm, obj=None):
       permissions = Permission.objects.filter(user=user_obj)
       if perm in permissions:
           return True
       return False

My user is an admin NOT a super user. He is part of a group which has all the permissions to view, edit, delete, add my models.

He is able to access them by using the URL directly.

However, when he tries to connect to the admin page /admin/, he is getting this error message. You don't have permission to view or edit anything

I searched for a permission which will give him access to view the lists of models in django documentation, but found nothing.

Do I need to add anything to my backend authentication? Add a new perm ? Even advice on where to look at in order to investigate would be very appreciated!

EDIT1

After debugging the django code itself, I need to add this method:

def has_module_perms(self, user_obj, perm, obj=None):

So stupid error ...

Upvotes: 1

Views: 2357

Answers (2)

Amir Abedi
Amir Abedi

Reputation: 63

I'm using django v3.2.15 and this is my answer based on WilliamW's answer, in my case it works properly. thanks for answer from WilliamW.

from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType

def has_perm(self, perm, obj=None):
    if self.is_superuser:
        return True
    elif self.is_staff:
        has_specific_perm = False

        # Check groups permissions the user is member of a group
        for group in self.groups.all():
            current_permissions: set = {
                f'{itm["content_type__app_label"]}.{itm["codename"]}'
                for itm in (
                    group.permissions.select_related('content_type')
                    .values('codename', 'content_type__app_label')
                )
            }
            has_specific_perm = perm in current_permissions

        # Check user's permissions if group was not enough
        if not has_specific_perm:
            current_permissions: set = {
                f'{itm["content_type__app_label"]}.{itm["codename"]}'
                for itm in (
                    self.user_permissions.select_related('content_type')
                    .values('codename', 'content_type__app_label')
                )
            }
            has_specific_perm = perm in current_permissions

        if self.is_active and self.is_staff and has_specific_perm:
            return True

    return False

Upvotes: 1

WilliamW
WilliamW

Reputation: 468

I needed to change my has_perm, because permissions is a QuerySet of Permission...

In case anyone needs it, here is my working has_perm method and fixed code to check both groups perms and user's perms.

def has_perm(self, user_obj, perm, obj=None):
    permissions = Permission.objects.filter(user=user_obj).values()
    has_specific_perm = False

    # Check groups permissions the user is member of
    for group in user_obj.groups.all():
        has_specific_perm = self.check_has_permission(perm, group.permissions.all().values())

    # Check user's permissions if group was not enough
    if not has_specific_perm:
        has_specific_perm = self.check_has_permission(perm, permissions.values())

    if user_obj.is_active and user_obj.is_staff and has_specific_perm:
        return True
    return False

def has_module_perms(self, user_obj, perm, obj=None):
    return True

def check_has_permission(self, perm, permissions_to_check):
    for index in range(len(permissions_to_check)):
        if perm == permissions_to_check[index]['codename']:
            return True

Upvotes: 2

Related Questions