Reputation: 468
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!
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
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
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