Unfortunately it is not possible to achieve what you want out of the box with OpenWISP 2 because of how the default django user & permission system works.
Once a user has the permission to add and change details of users, he will also be able to add / remove the superuser flag on other user.
Therefore that permission should be only granted to trusted users.
In order to achieve what you want, you need to change the UserAdmin class of the openwisp-users module.
I have tried these changes which seem to work pretty well:
class UserAdmin(BaseUserAdmin, BaseAdmin):
# ... omitting existing code for brevity ...
def get_readonly_fields(self, request, obj=None):
# retrieve readonly fields
fields = super(UserAdmin, self).get_readonly_fields(request, obj)
# do not allow operators to set the is_superuser flag
if not request.user.is_superuser:
fields += fields[:] + ['is_superuser'] # copy to avoid modifying reference
return fields
def has_change_permission(self, request, obj=None):
# do not allow operators to edit details of superusers
# returns 403 if trying to access the change form of a superuser
if obj and obj.is_superuser and not request.user.is_superuser:
return False
return super(UserAdmin, self).has_change_permission(request, obj)
def get_queryset(self, request):
qs = super(UserAdmin, self).get_queryset(request)
# hide superusers from operators (they can't edit their details)
if not request.user.is_superuser:
qs = qs.filter(is_superuser=False)
return qs
These changes implement the following 3 things:
- make the is_superuser field readonly for non superusers (aka operators)
- hide superusers to non superusers in the user list
- explicitly forbid changing details of superusers to non superusers (aka operators)
These changes could be integrated in openwisp2 as well. Enjoy and try to contribute if you can (eg: open an issue or pull request in openwisp-users)!
PS: I've included this feature (plus tests and improvements) in the openwisp-users module.