django admin permissions – can edit user but can't edit his permissions – how to do it?

Question:

I gave the editors such permissions:

  • auth | user | can add/change user – ON

  • auth | permissions | can add/change permissions – OFF

Still, when editing, they can change their permissions (and allow themselves actions they shouldn’t do). I’ve found a ticket from 2yrs ago: http://code.djangoproject.com/ticket/6519 and it still works this way.

How to allow user edition (email, passwords, etc..) but block permissions change?

Asked By: zalew

||

Answers:

Your current approach isn’t going to work I’m afraid.

From the Django docs:

If you have permission to add users, you have the power to create superusers, which can then, in turn, change other users.

So if you manage to block the editors from changing permissions, it will not help, because they could still create superusers that can.

Answered By: Alasdair

The code below gives you ability to override the formset, this essentially limits the ability for non-superusers to edit permissions. They can still create users, but they just can’t modify permissions. They can even edit users just fine.

#admin.py

from django.utils.translation import gettext_lazy as _
from django.contrib.auth.admin import UserAdmin

class UserAdmin(UserAdmin):

    # this is for only editing/change/update only please keep in mind that 
    # the user can create superuser that can do everything
    # so we will do the same for the add_view too
    def change_view(self, request, object_id):

        # we want to limit the ability of the normal user to edit permissions.
        if request.user.is_superuser:
            self.fieldsets = (
                (None, {'fields': ('username', 'password')}),
                (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
                (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', 'user_permissions')}),
                (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
                (_('Groups'), {'fields': ('groups',)}),
            )
        else:
            self.fieldsets = (
                (None, {'fields': ('username', 'password')}),
                (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
                #(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', 'user_permissions')}),
                (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
                #(_('Groups'), {'fields': ('groups',)}),
            )
   
    # this is for creating
    def add_view(self, request):

        # we want to limit the ability of the normal user to create permissions.
        if request.user.is_superuser:
            self.add_fieldsets = (
                (None, {'fields': ('username', 'password')}),
                (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
                (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', 'user_permissions')}),
                (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
                (_('Groups'), {'fields': ('groups',)}),
            )
        else:
            self.add_fieldsets = (
                (None, {'fields': ('username', 'password')}),
                (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
                #(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', 'user_permissions')}),
                (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
                #(_('Groups'), {'fields': ('groups',)}),
            )        

        return super(UserAdmin, self).change_view(request)

by saying "normal user" I’m assuming that you know it means user that has is_istaff permission who can access admin site.

Answered By: stormlifter