rbac —— 权限实践

""" ASM 权限控制 """
import os
import copy
import asyncio

async def init_user_permission():
    """初始化权限表"""
    print('初始化权限表中。。。')
    role_data_data = [
        {
            "_id": 1,
            "role": "first_root",
            "role_cn": "一级管理员",
            "operate_powers": [2,3,4,5,10],
            "menu_powers": [1,4],
            "inherit": [],
        },
        {
            "_id": 2,
            "role": "second_root",
            "role_cn": "二级管理员",
            "operate_powers": [6,7,8,9],
            "menu_powers": [1,2,3,],
            "inherit": [3, 4],
        },
        {
            "_id": 2,
            "role": "common_user",
            "role_cn": "普通用户",
            "operate_powers": [],
            "menu_powers": [1,],
            "inherit": []
        },
    ]

    role_data_coll = DB['role_data']
    role_data_coll_num = await role_data_coll.count_documents({})
    print('角色表数据 role_data_coll_num: ', role_data_coll_num)
    if not role_data_coll_num:
        print('开始更新角色表数据')
        for d in role_data_data:
            _id = d.pop('_id')
            update = {"$set":d}
            await role_data_coll.update_one({"_id":_id},update,upsert=True)
    
    operate_power_data_data = [

        {
            "_id": 2,
            "operate_power": "gogogo",
            "operate_power_cn": "gogoo",
        },
    ]

    operate_power_data_coll = DB['operate_power_data']
    operate_power_data_num = await operate_power_data_coll.count_documents({})
    print('操作权限表数据 operate_power_data_num:', operate_power_data_num)
    if not operate_power_data_num:
        print('开始更新操作权限表数据')
        for d in operate_power_data_data:
            _id = d.pop('_id')
            update = {"$set":d}
            await operate_power_data_coll.update_one({"_id":_id},update,upsert=True)

    menu_power_data_data = [
        {
            "_id": 1,
            "menu_power": "one_menu",
            "menu_power_cn": "页面1",
        },
    ]

    menu_power_data_coll = DB['menu_power_data']
    menu_power_data_num = await menu_power_data_coll.count_documents({})
    print('页面权限表数据 menu_power_data_num:', menu_power_data_num)
    if not menu_power_data_num:
        print('开始更新页面权限表数据')
        for d in menu_power_data_data:
            _id = d.pop('_id')
            update = {"$set":d}
            await menu_power_data_coll.update_one({"_id":_id},update,upsert=True)

async def init_first_root():
    # 初始化一级管理员
    first_user_init = {
        "_id": 0,
        "username": "aaa",
        "groups": [],
        "is_first_role": True,
        "first_roles": [1],
    }
    
    user_data_coll = DB['user_data']
    first_user = await user_data_coll.find_one({'_id':0})
    print('first_user: ',first_user)
    if not first_user:
        print('用户表中无一级管理员,正在初始化。。。')
        await user_data_coll.insert_one(first_user_init)
    # await asyncio.sleep(1)

async def get_total_roles(user_roles):
    """获取用户的所有角色"""
    role_data_coll = DB['role_data']
    total_roles = copy.deepcopy(user_roles)
    async def inner(user_roles, total_roles):
        for r in user_roles:
            role_data = await role_data_coll.find_one({"_id":r})
            print('role_data: ',role_data)
            if role_data:
                inherit_roles = role_data.get('inherit', [])
                print('inherit_roles: ',inherit_roles)
                total_roles.extend(inherit_roles)
                if inherit_roles:
                    await inner(inherit_roles, total_roles)
    await inner(user_roles, total_roles)
    return total_roles

async def check_user_permission(username, permission, group_name=None):
    """校验操作权限"""
    # 进行权限校验
    print('校验: {} ,权限: {}'.format(username, permission))
    user_data_coll = DB['user_data']
    user = await user_data_coll.find_one({"username":username})
    if not user: return False, "用户不存在"
    print('user: ',user)

    # 如果是一级管理员
    is_first_role = user.get('is_first_role')
    if is_first_role:
        user_roles = user.get('first_roles',[1])
    else:
        if not group_name:
            return False, "非一级管理员,缺少 group_name 参数"
        user_roles = user.get('group_roles',{}).get(group_name,[])

    operate_power_data_coll = DB['operate_power_data']
    operate_power_data = await operate_power_data_coll.find_one({'operate_power': permission})
    if not operate_power_data:
        return False, "不支持该权限:{}".format(permission)
    power_id = operate_power_data.get('_id')

    total_roles = copy.deepcopy(user_roles)
    role_data_coll = DB['role_data']
    async def check_total_roles(user_roles, total_roles, is_permession_ok):
        for r in user_roles:
            role_data = await role_data_coll.find_one({"_id":r})
            print('role_data: ',role_data)
            if role_data:
                operate_powers = role_data.get('operate_powers')
                print('power_id: ', power_id)
                print('operate_powers: ', operate_powers)
                if power_id in operate_powers:
                    is_permession_ok[0] = True
                    return
                inherit_roles = role_data.get('inherit', [])
                print('inherit_roles: ',inherit_roles)
                total_roles.extend(inherit_roles)
                if inherit_roles:
                    await check_total_roles(inherit_roles, total_roles, is_permession_ok)
    
    is_permession_ok = [False]
    await check_total_roles(user_roles, total_roles, is_permession_ok)
    print('total_roles: ', total_roles)
    print('is_permession_ok: ', is_permession_ok)
    return is_permession_ok[0], '操作成功' if is_permession_ok[0] else '操作失败'

async def check_user_data_permission(login_username,group_name,login_group_name=None):
    """校验数据权限"""
    user_data_coll = DB['user_data']
    user = await user_data_coll.find_one({"username":login_username})
    if not user: return False, "用户不存在"
    print('user: ',user)

    # 如果是一级管理员
    is_first_role = user.get('is_first_role')
    if not is_first_role:
        if not login_group_name:
            return False, "非一级管理员,缺少 group_name 参数"
        if login_group_name != group_name:
            return False, "{} : {} 跨组织操作数据".format(login_group_name,group_name)
        group_roles = user.get('group_roles',{})
        has_groups_list = []
        for k,v in group_roles.items():
            v = [True for i in v if isinstance(i,int)]
            if any(v):
                has_groups_list.append(k)
        if group_name not in has_groups_list:
            return False, "该用户不在该组织,无相关组织 {} 的权限".format(group_name)
        
    return True, "操作成功"

posted @ 2022-05-26 18:04  pythoner_wl  阅读(25)  评论(0编辑  收藏  举报