且构网

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

授予“用户更改"时如何防止 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)