From 9f67daeb1ea0f7a6fab24a6990959ea6a14a24d0 Mon Sep 17 00:00:00 2001 From: BaiJiangJie <32935519+BaiJiangJie@users.noreply.github.com> Date: Mon, 27 May 2019 20:04:41 +0800 Subject: [PATCH] =?UTF-8?q?[Update]=20=E4=BC=98=E5=8C=96AssetPermissionUti?= =?UTF-8?q?l=E5=8A=A8=E6=80=81=E8=AE=BE=E7=BD=AE=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E7=94=A8=E6=88=B7actions=E5=B1=9E=E6=80=A7=E9=80=BB=E8=BE=91?= =?UTF-8?q?=20(#2739)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Update] 优化AssetPermissionUtil动态设置系统用户actions属性逻辑 * [Bugfix] 修复can't pickle dict_keys objects的bug --- apps/perms/utils/asset_permission.py | 73 ++++++++++++++++------------ 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/apps/perms/utils/asset_permission.py b/apps/perms/utils/asset_permission.py index cacad1718..fb0676a5e 100644 --- a/apps/perms/utils/asset_permission.py +++ b/apps/perms/utils/asset_permission.py @@ -160,51 +160,53 @@ class AssetPermissionUtil: self._permissions = self.permissions.filter(**filters) self._filter_id = md5(filters_json.encode()).hexdigest() + @staticmethod + def _structured_system_user(system_users, actions): + """ + 结构化系统用户 + :param system_users: + :param actions: + :return: {system_user1: {'actions': set(), }, } + """ + _attr = {'actions': set(actions)} + _system_users = {system_user: _attr for system_user in system_users} + return _system_users + def get_nodes_direct(self): """ 返回用户/组授权规则直接关联的节点 - :return: {node1: set(system_user1,)} + :return: {asset1: {system_user1: {'actions': set()},}} """ - nodes = defaultdict(set) + nodes = defaultdict(dict) permissions = self.permissions.prefetch_related('nodes', 'system_users') for perm in permissions: + actions = perm.actions.all() for node in perm.nodes.all(): - nodes[node].update(perm.system_users.all()) + system_users = perm.system_users.all() + system_users = self._structured_system_user(system_users, actions) + nodes[node].update(system_users) return nodes def get_assets_direct(self): """ + 返回用户授权规则直接关联的资产 - :return: {asset1: set(system_user1,)} + :return: {asset1: {system_user1: {'actions': set()},}} """ - assets = defaultdict(set) + assets = defaultdict(dict) permissions = self.permissions.prefetch_related('assets', 'system_users') for perm in permissions: + actions = perm.actions.all() for asset in perm.assets.all().valid().prefetch_related('nodes'): - assets[asset].update( - perm.system_users.filter(protocol=asset.protocol) - ) + system_users = perm.system_users.filter(protocol=asset.protocol) + system_users = self._structured_system_user(system_users, actions) + assets[asset].update(system_users) return assets - def _setattr_actions_to_system_user(self): + def get_assets_without_cache(self): """ - 动态给system_use设置属性actions + :return: {asset1: set(system_user1,)} """ - for asset, system_users in self._assets.items(): - # 获取资产和资产的祖先节点的所有授权规则 - perms = get_asset_permissions(asset, include_node=True) - # 过滤当前self.permission的授权规则 - perms = perms.filter(id__in=[perm.id for perm in self.permissions]) - - for system_user in system_users: - actions = set() - _perms = perms.filter(system_users=system_user).\ - prefetch_related('actions') - for _perm in _perms: - actions.update(_perm.actions.all()) - setattr(system_user, 'actions', actions) - - def get_assets_without_cache(self): if self._assets: return self._assets assets = self.get_assets_direct() @@ -212,11 +214,22 @@ class AssetPermissionUtil: for node, system_users in nodes.items(): _assets = node.get_all_assets().valid().prefetch_related('nodes') for asset in _assets: - assets[asset].update( - [s for s in system_users if s.protocol == asset.protocol] - ) - self._assets = assets - self._setattr_actions_to_system_user() + for system_user, attr_dict in system_users.items(): + if system_user.protocol != asset.protocol: + continue + if system_user in assets[asset]: + actions = assets[asset][system_user]['actions'] + attr_dict['actions'].update(actions) + system_users.update({system_user: attr_dict}) + assets[asset].update(system_users) + + __assets = defaultdict(set) + for asset, system_users in assets.items(): + for system_user, attr_dict in system_users.items(): + setattr(system_user, 'actions', attr_dict['actions']) + __assets[asset] = set(system_users.keys()) + + self._assets = __assets return self._assets def get_cache_key(self, resource):