Пример #1
0
    def _make_dict_filter(policies: Dict) -> Dict:
        """
        基于策略规则, 生成 project_id 过滤器

        :param policies: 权限中心返回的策略规则, 如 {'op': OP.IN, 'value': [2, 1], 'field': 'project.id'}
        :return: project_id 过滤器, 如 {'value': [1, 2], 'op': OP.IN}
        """
        op = policies['op']
        if op not in [OP.IN, OP.EQ, OP.ANY, OP.OR, OP.AND]:
            raise AuthInvalidRequest(
                f'make_dict_filter does not support op:{op}')

        if op == OP.EQ:
            return {'value': [policies['value']], 'op': OP.IN}

        if op in [OP.IN, OP.ANY]:
            return {'value': policies['value'] or [], 'op': op}

        # 如果 op 是 OP.OR 或 OP.AND,只处理一级,不考虑嵌套的情况
        value_list = []
        for policy in policies['content']:
            if policy['field'] != 'project.id':
                continue

            op = policy['op']
            if op == OP.ANY:
                return {'value': policy['value'] or [], 'op': op}

            value = policy['value']
            if op == OP.IN:
                value_list.extend(value)
            elif op == OP.EQ:
                value_list.append(value)

        return {'value': list(set(value_list)), 'op': OP.IN}
Пример #2
0
    def make_dict_filter(self, request, key_mapping=None):
        """
        仅支持{'op': 'in', 'field': 'project.id', 'value': [1, 2, 3]}
        或者{'op': 'eq', 'field': 'project.id', 'value': 1}
        """
        # 1. validate
        if not isinstance(request, Request):
            raise AuthInvalidRequest(
                "request should be instance of iam.auth.models.Request")

        request.validate()

        # 2. _client.policy_query
        policies = self._do_policy_query(request)

        # the polices maybe none
        if not policies:
            return None

        op = policies["op"]
        if op not in [OP.IN, OP.EQ, OP.ANY]:
            raise AuthInvalidRequest(
                "make_dict_filter only support OP.IN or OP.EQ or OP.ANY")

        value = policies["value"]
        if op == OP.EQ:
            value = [
                value,
            ]

        field = policies["field"]
        if key_mapping:
            k = key_mapping.get(field) or field
            return {k: value, "op": op}

        return {field: value, "op": op}
Пример #3
0
    def _do_policy_query(self, request) -> Optional[Dict]:
        # 1. validate
        if not isinstance(request, Request):
            raise AuthInvalidRequest(
                'request should be instance of iam.auth.models.Request')

        request.validate()

        # 2. _client.policy_query
        policies = self.iam._do_policy_query(request)

        # the polices maybe none
        if not policies:
            return None

        return policies
Пример #4
0
    def _make_dict_filter(self, policies: Dict) -> Dict:
        """
        基于策略规则, 生成 project_id 过滤器。

        :params policies: 权限中心返回的策略规则,如 {'op': OP.IN, 'value': [2, 1], 'field': 'project.id'}
        :returns : project_id 过滤器, 如 {'project_id_list': [1, 2], 'op': OP.IN}
        """
        op = policies["op"]
        if op not in [OP.IN, OP.EQ, OP.ANY, OP.OR, OP.AND]:
            raise AuthInvalidRequest(
                f"make_dict_filter does not support op:{op}")

        field, key = "project.id", "project_id_list"

        if op == OP.EQ:
            return {key: [policies["value"]], "op": OP.IN}

        if op in [OP.IN, OP.ANY]:
            return {key: policies["value"] or [], "op": op}

        # 如果 op 是 OP.OR 或 OP.AND,只处理一级,不考虑嵌套的情况
        value_list = []
        for policy in policies["content"]:
            if policy["field"] != field:
                continue

            op = policy["op"]
            if op == OP.ANY:
                return {key: policy["value"] or [], "op": op}

            value = policy["value"]
            if op == OP.IN:
                value_list.extend(value)
            elif op == OP.EQ:
                value_list.append(value)

        return {key: list(set(value_list)), "op": OP.IN}