Exemple #1
0
 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
Exemple #3
0
    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