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}
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}
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
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}