欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

django通用权限控制框架

程序员文章站 2022-05-14 11:09:50
在web项目中根据不同的用户肯定会限制其不同的权限,利用以下模块可以满足日常几乎所有的权限控制 permission_hook.py # 自定义权限控制,必须返回True/false ,True表示允许,false 拒绝 permission_list.py #根据url,访问方法及参数控制用户权限 ......

在web项目中根据不同的用户肯定会限制其不同的权限,利用以下模块可以满足日常几乎所有的权限控制

permission_hook.py  # 自定义权限控制,必须返回true/false  ,true表示允许,false 拒绝

permission_list.py     #根据url,访问方法及参数控制用户权限

permissions.py          #先判断用户是否拥有permission_list.py中的权限,如果验证通过最后验证用户自定义权限。

实例:

permission_hook.p:

django通用权限控制框架
def check_self_user(request):
    '''
    用户只能筛选自己的客户

    '''
    if request.get.get('consultant') == str(request.user.id):
        return true
    if request.get.get('consultant'):
        print('禁止查看非自己的客户')
        return false

    return true
view code

permission_list.py     #根据url,访问方法及参数控制用户权限

django通用权限控制框架
from kingadmin import permission_hook
permission_dict={

    'crm_table_obj_list':['table_obj_list','get',[],{},permission_hook.check_self_user],
    'crm_table_obj_view':['table_obj_change','get',[],{}],
    'crm_table_obj_change':['table_obj_change','post',[],{}]
}
view code

permissions.py

django通用权限控制框架
from django.core.urlresolvers import resolve
from kingadmin.permission_list import permission_dict
from django.shortcuts import redirect,render,httpresponse
from django.utils.safestring import mark_safe

def check_permission(*args,**kwargs):
    request=args[0]
    request_url=resolve(request.path).url_name
    match_key=none
    args_check=none
    kwarg_check=none
    if request.user.is_authenticated() is false:
        return redirect('/login/')

    for permission_key,val in permission_dict.items():
        print('执行args 权限检查-------------')
        per_url=val[0]
        per_method=val[1]
        per_args=val[2]
        per_kwargs=val[3]
        per_hook_func=val[4] if len(permission_dict[permission_key]) > 4 else none

        if request_url == per_url:
            if request.method == per_method:
                args_check=false
                for arg in per_args:
                    request_func=getattr(request,per_method)
                    if request_func.get(arg,none):
                        args_check=true
                        print('存在arg参数')
                    else:
                        print('不存在指定arg参数')
                        args_check=false
                        break
                else:
                    print('未作权限限制,,默认通过')
                    args_check=true
                kwarg_check=false

                for arg_name,arg_val in per_kwargs.items():
                    print('执行 kwargs 权限检查-------------')
                    request_func=getattr(request,per_method)
                    if request_func.get(arg_name) == str(arg_val):
                        kwarg_check=true
                    else:
                        kwarg_check=false
                        break
                else:
                    kwarg_check=true
                    print('未作 kwargs 限制,默认通过')

                per_func=false
                print('执行用户自定义钩子函数')
                if per_hook_func:
                    per_func=per_hook_func(request)
                else:
                    per_func=true

                per_res=[args_check,kwarg_check,per_func]
                if all(per_res):
                    match_key=permission_key
                    print('权限匹配结果:',per_res)
                    break

    if all(per_res):
        appname,*per_name=match_key.split('_')
        per_obj='%s.%s'%(appname,match_key)

        if request.user.has_perm(per_obj):
            print('所有权限检查通过')
            return true
        else:
            print('权限检查未通过')
            return false
    else:
        print('未匹配到权限')
        return false




def check_per(func):
    def inner(*args,**kwargs):
        if not check_permission(*args,**kwargs):
            return httpresponse(mark_safe('<h1>403 你没有相应的权限</h1>'))
        else:

            return func(*args,**kwargs)
    return inner
view code

最后只需在views中将要使用权限控制功能的地方加上装饰器即可:

django通用权限控制框架
from kingadmin.permissions import check_per

@check_per
def table_obj_change(request):
    pass
view code