def get_context_data(self, **kwargs): nodes_remain = Node.objects.exclude(id__in=self.object.nodes.all( ).values_list('id', flat=True)).only('key') util = NodeUtil() nodes_remain = util.get_nodes_by_queryset(nodes_remain) context = { 'app': _('Perms'), 'action': _('Asset permission asset list'), 'nodes_remain': nodes_remain, } kwargs.update(context) return super().get_context_data(**kwargs)
def __init__(self, obj, cache_policy='0'): self.object = obj self.obj_id = str(obj.id) self._permissions = None self._permissions_id = None # 标记_permission的唯一值 self._assets = None self._filter_id = 'None' # 当通过filter更改 permission是标记 self.cache_policy = cache_policy self.tree = GenerateTree() self.change_org_if_need() self.nodes = None self._nodes = None self._assets_direct = None self._nodes_direct = None self.node_util = NodeUtil() self.tree._node_util = self.node_util
def get_nodes_family_and_system_users(self, nodes_with_system_users): """ 返回所有nodes_with_system_users中的node的家族节点的信息, 并子会继承祖先的系统用户和actions信息 :param nodes_with_system_users: {node.key: {system_user.id: actions,}, } :return: {node.key: {system_user.id: actions,}, } """ node_util = NodeUtil() _nodes_keys = nodes_with_system_users.keys() family_keys = node_util.get_some_nodes_family_keys_by_keys(_nodes_keys) nodes_items = [] for i in family_keys: system_users = nodes_with_system_users.get(i, defaultdict(int)) item = {"key": i, "system_users": system_users} nodes_items.append(item) # 按照父子关系排序 nodes_items.sort(key=self.sorted_by) nodes_items.append({"key": "", "system_users": defaultdict(int)}) self.stack = Stack() for item in nodes_items: self.debug("准备: {} 栈顶: {}".format( item['key'], self.stack.top["key"] if self.stack.top else None)) # 入栈之前检查,该节点是不是栈顶节点的子节点 # 如果不是,则栈顶出栈 while self.stack.top and not self.is_children( self.stack.top, item): # 出栈 self.pop_from_stack_system_users() # 入栈 self.push_to_stack_system_users(item) # 出栈最后一个 self.debug("剩余: {}".format(', '.join([n["key"] for n in self.stack]))) return self._nodes
def node_util(self): if not self._node_util: self._node_util = NodeUtil() return self._node_util
class AssetPermissionUtil(AssetPermissionCacheMixin): get_permissions_map = { "User": get_user_permissions, "UserGroup": get_user_group_permissions, "Asset": get_asset_permissions, "Node": get_node_permissions, "SystemUser": get_system_user_permissions, } assets_only = ('id', 'hostname', 'ip', "platform", "domain_id", 'comment', 'is_active', 'os', 'org_id') def __init__(self, obj, cache_policy='0'): self.object = obj self.obj_id = str(obj.id) self._permissions = None self._permissions_id = None # 标记_permission的唯一值 self._assets = None self._filter_id = 'None' # 当通过filter更改 permission是标记 self.cache_policy = cache_policy self.tree = GenerateTree() self.change_org_if_need() self.nodes = None self._nodes = None self._assets_direct = None self._nodes_direct = None self.node_util = NodeUtil() self.tree._node_util = self.node_util @staticmethod def change_org_if_need(): set_to_root_org() @property def permissions(self): if self._permissions: return self._permissions object_cls = self.object.__class__.__name__ func = self.get_permissions_map[object_cls] permissions = func(self.object) self._permissions = permissions return permissions @timeit def filter_permissions(self, **filters): filters_json = json.dumps(filters, sort_keys=True) self._permissions = self.permissions.filter(**filters) self._filter_id = md5(filters_json.encode()).hexdigest() @timeit def get_nodes_direct(self): """ 返回直接授权的节点, 并将节点添加到tree.nodes中,并将节点下的资产添加到tree.assets中 :return: {node.key: {system_user.id: actions,}, } """ if self._nodes_direct: return self._nodes_direct nodes_keys = defaultdict(lambda: defaultdict(int)) for perm in self.permissions: actions = [perm.actions] system_users_ids = [s.id for s in perm.system_users.all()] _nodes_keys = [n.key for n in perm.nodes.all()] iterable = itertools.product(_nodes_keys, system_users_ids, actions) for node_key, sys_id, action in iterable: nodes_keys[node_key][sys_id] |= action self.tree.add_nodes(nodes_keys) all_nodes_keys = set() for key in nodes_keys: children_keys = self.node_util.get_all_children_keys_by_key(key) all_nodes_keys.update(set(children_keys)) if all_nodes_keys: assets_ids = Asset.objects.filter( nodes__key__in=all_nodes_keys).valid().values_list( "id", flat=True).distinct() else: assets_ids = [] self.tree.add_assets_without_system_users(assets_ids) self._nodes_direct = nodes_keys return nodes_keys def get_nodes_without_cache(self): self.get_assets_without_cache() return self.tree.get_nodes() @timeit def get_assets_direct(self): """ 返回直接授权的资产, 并添加到tree.assets中 :return: {asset.id: {system_user.id: actions, }, } """ if self._assets_direct: return self._assets_direct assets_ids = defaultdict(lambda: defaultdict(int)) for perm in self.permissions: actions = [perm.actions] _assets_ids = perm.assets.valid().values_list("id", flat=True) system_users_ids = perm.system_users.values_list("id", flat=True) iterable = itertools.product(_assets_ids, system_users_ids, actions) for asset_id, sys_id, action in iterable: assets_ids[asset_id][sys_id] |= action self.tree.add_assets(assets_ids) self._assets_direct = assets_ids return assets_ids @timeit def get_assets_without_cache(self): """ :return: [ {"id": asset.id, "system_users": {system_user.id: actions, }}, ] """ if self._assets: return self._assets self.get_nodes_direct() self.get_assets_direct() assets = self.tree.get_assets() self._assets = assets return assets @timeit def get_nodes_with_assets_without_cache(self): self.get_assets_without_cache() nodes_assets = self.tree.get_nodes_with_assets() return nodes_assets def get_system_users_without_cache(self): system_users = set() permissions = self.permissions.prefetch_related('system_users') for perm in permissions: system_users.update(perm.system_users.all()) return system_users