定义现有用户查看或修改其他用户的权限

Define permissions to existing users for viewing or modifying other users

我目前正在学习 Django 中的权限框架,我希望为用户定义一组权限,定义他们是否可以查看或修改系统中的其他用户。

我在多模式数据库上使用 django.auth 框架,其中每个模式都有自己的一组用户。

我想从本质上应用它,但要应用到内置用户 model

class Meta:
        permissions = (
            ("can_view_users", "Can view all users"),
            ("can_modify_users", "Can modify all users"),
            ("can_password_reset_users", "Can reset passwords for all users"),
            ("can_delete_users", "Can delete all users"),
        )

但是我似乎找不到任何关于将此逻辑应用于内置身份验证框架的文档。

我已经通过部署我自己的许可 app 解决了这个问题。我仍然通过内置框架创建和管理用户和会话,但是使用我自己的 model 来管理用户权限。

它按我的预期工作,让我可以从每个用户的角度自定义尽可能多的内容。


步骤

  1. 创建名为 users
  2. 的用于管理权限的新应用
  3. 创建一个名为 Permissions 的模型,其中 ForeignKeyAUTH_USER_MODEL
  4. 创建自定义装饰器以检查用户调用视图的权限
  5. 将装饰器应用于视图,指定视图需要哪些权限

此时,如果用户没有指定的权限,则无法使用页面。这很好,就好像用户尝试 postusers/new 他们的服务器将响应 HTTP 503.


下一个问题是修改基本模板,以便用户只能看到允许他们看到的菜单选项。我通过使用自定义 context_processor.

实现了这一点
  1. 创建自定义 context_processor,它利用 Permissions user_has_perms 检索已验证用户的所有权限。
  2. 将处理器添加到 settings.py
  3. 利用djangos 模板处理呈现用户有权访问的字段

代码

model 权限

class Permissions(models.Model):
    permission_id = models.AutoField(primary_key=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    
    ## User Management ##
    
    can_user_view_staff = models.BooleanField(default = False)

def user_has_perms(user, perm):
    user_exists = Permissions.objects.filter(user_id=user).count()
   
    if user_exists:
        if perm == None:
            ## if no permission specified, return all permissions for user ##
            return Permissions.objects.filter(user_id=user)
        else:            
            return Permissions.objects.filter(user_id=user).values(perm).last()[perm]
    else:
        return False

decorator授权

from django.http import HttpResponseForbidden
from apps.users.models import user_has_perms


## Check if user has permission to load page ##

def authorization_required(permissions=''):
    def decorator(view):
        def wrapper(request, *args, **kwargs):
            can_user = user_has_perms(request.user, permissions)

            if can_user or request.user.is_superuser:
                return view(request, *args, **kwargs)
            else:
                return HttpResponseForbidden()
        return wrapper
    return decorator

views 使用装饰器查看

from decorators.authorization import authorization_required

@login_required
@authorization_required('can_user_view_staff')
def users(request):
    user_model = get_user_model()
    user_list = user_model.objects.all()

    context = {
                'users': user_list
            }
            
    return render(request, 'users/users.html', context)

context_processor

from apps.users.models import user_has_perms

def permissions(request):
    if request.user.is_authenticated:
        user_perms = user_has_perms(request.user, None)
    else:
        user_perms = None

    return {
        'user_perms': user_perms
        }

修改settings.py添加新处理器

TEMPLATES = [
    {
        'OPTIONS': {
            'context_processors': [

                'context_processors.perm_context.permissions',
                ],
        },
    },
]

更新 base.html 以在呈现字段之前检查用户权限

{% if user_perms.can_user_view_staff or request.user.is_superuser %}
    <a class="dropdown-item" href="/users">User Management</a>
{% endif %}