且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

授予“用户更改"权限时,如何防止 Django 管理员中的权限升级?允许?

更新时间:2022-11-25 07:56:57

他们能够在任何账户上设置 is_superuser 标志,包括他们自己的账户.(!!!)

they gain the ability to set the is_superuser flag on any account, including their own. (!!!)

不仅如此,他们还可以一一赋予自己任何权限,效果相同...

Not only this, they also gain the ability to give themselves any permissions one-by-one, same effect...

我确定它涉及子类化 django.contrib.auth.forms.UserChangeForm

I'm sure it involves subclassing django.contrib.auth.forms.UserChangeForm

嗯,不一定.你在django的admin更改页面看到的表单是由admin应用动态创建的,基于UserChangeForm,但是这个类几乎没有在username字段中添加正则表达式验证.

Well, not necessarily. The form you see in the change page of django's admin is dynamically created by the admin application, and based on UserChangeForm, but this class barely adds regex validation to the username field.

并将其连接到我已经自定义的 UserAdmin 对象中...

and hooking it into my already-custom UserAdmin object...

自定义UserAdmin 是这里的方法.基本上,您想将 fieldsets 属性更改为类似的内容:

A custom UserAdmin is the way to go here. Basically, you want to change the fieldsets property to something like that :

class MyUserAdmin(UserAdmin):
    fieldsets = (
        (None, {'fields': ('username', 'password')}),
        (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
        # Removing the permission part
        # (_('Permissions'), {'fields': ('is_staff', 'is_active', 'is_superuser', 'user_permissions')}),
        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
        # Keeping the group parts? Ok, but they shouldn't be able to define
        # their own groups, up to you...
        (_('Groups'), {'fields': ('groups',)}),
    )

但这里的问题是此限制将适用于所有用户.如果这不是您想要的,您可以例如覆盖 change_view 以根据用户的权限进行不同的行为.代码片段:

But the problem here is that this restriction will apply to all users. If this is not what you want, you could for example override change_view to behave differently depending on the permission of the users. Code snippet :

class MyUserAdmin(UserAdmin):
    staff_fieldsets = (
        (None, {'fields': ('username', 'password')}),
        (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
        # No permissions
        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
        (_('Groups'), {'fields': ('groups',)}),
    )

    def change_view(self, request, *args, **kwargs):
        # for non-superuser
        if not request.user.is_superuser:
            try:
                self.fieldsets = self.staff_fieldsets
                response = super(MyUserAdmin, self).change_view(request, *args, **kwargs)
            finally:
                # Reset fieldsets to its original value
                self.fieldsets = UserAdmin.fieldsets
            return response
        else:
            return super(MyUserAdmin, self).change_view(request, *args, **kwargs)