def create_detail(self, object_list, bundle): system = self.helper.system subject = self.helper.get_subject(bundle) action = Action(self.helper.create_action) resources = self.helper.get_create_detail_resources(bundle) request = Request( system, subject, action, resources, self.helper.get_create_detail_environment(bundle), ) allowed = self.iam.is_allowed(request) logger.debug( "tastypie create_detail is_allowed request({}) result: {}".format( request.to_dict(), allowed)) if not allowed: raise ImmediateHttpResponse( IAMAuthFailedResponse( AuthFailedException(system, subject, action, resources))) return allowed
def read_list(self, object_list, bundle): request = Request( system=self.system, subject=self.get_subject(bundle), action=Action(self.read_action), resources=[], environment=self.get_read_list_environment(bundle), ) f = self.iam.make_filter(request, key_mapping=self.helper.filter_key_mapping) logger.debug( "tastypie read_list make_filter request({}) result: {}".format( request.to_dict(), f)) return object_list.filter(f)
def allow_or_raise_immediate_response_for_resources_list( iam, system, subject, action, resources_list, environment=None ): if not resources_list: return resources_map = {} for resources in resources_list: resources_map[resources[0].id] = resources request = Request(system, subject, action, [], environment) result = iam.batch_is_allowed(request, resources_list) if not result: raise MultiAuthFailedException(system, subject, action, resources_list) not_allowed_list = [] for tid, allow in result.items(): if not allow: not_allowed_list.append(resources_map[tid]) if not_allowed_list: raise MultiAuthFailedException(system, subject, action, not_allowed_list) return
def process(self, request, *args, **kwargs): data = request.data template_id_list = data["template_id_list"] subject = Subject("user", request.user.username) action = Action(IAMMeta.FLOW_VIEW_ACTION) resources_list = res_factory.resources_list_for_flows(template_id_list) if not resources_list: return resources_map = {} for resources in resources_list: resources_map[resources[0].id] = resources request = Request(IAMMeta.SYSTEM_ID, subject, action, [], {}) result = iam.batch_is_allowed(request, resources_list) if not result: raise MultiAuthFailedException(IAMMeta.SYSTEM_ID, subject, action, resources_list) not_allowed_list = [] for tid, allow in result.items(): if not allow: not_allowed_list.append(resources_map[tid]) if not_allowed_list: raise MultiAuthFailedException(IAMMeta.SYSTEM_ID, subject, action, not_allowed_list)
def _make_request(self, username: str, action_id: str, resources: Optional[List[Resource]] = None) -> Request: return Request( settings.BK_IAM_SYSTEM_ID, Subject("user", username), Action(action_id), resources, None, )
def allow_or_raise_immediate_response(iam, system, subject, action, resources, environment=None): request = Request(system, subject, action, resources, environment) allowed = iam.is_allowed(request) if not allowed: raise ImmediateHttpResponse(IAMAuthFailedResponse(AuthFailedException(system, subject, action, resources))) return
def process(self, request, *args, **kwargs): subject = Subject("user", request.user.username) action = Action(self.action) request = Request(IAMMeta.SYSTEM_ID, subject, action, [], {}) allowed = iam.is_allowed(request) if not allowed: raise AuthFailedException(IAMMeta.SYSTEM_ID, subject, action, [])
def iam_resource_auth_or_raise(username, action, resource_id=None, get_resource_func=None): iam = get_iam_client() action = Action(action) subject = Subject("user", username) resources = None if get_resource_func: resources = getattr(res_factory, get_resource_func)(resource_id) request = Request(IAMMeta.SYSTEM_ID, subject, action, resources or [], {}) if not iam.is_allowed(request): raise AuthFailedException(IAMMeta.SYSTEM_ID, subject, action, resources or [])
def process(self, request, *args, **kwargs): task_id = self.get_task_id(request, *args, **kwargs) subject = Subject("user", request.user.username) action = Action(self.action) resources = res_factory.resources_for_task(task_id) request = Request(IAMMeta.SYSTEM_ID, subject, action, resources, {}) allowed = iam.is_allowed_with_cache(request) if not allowed: raise AuthFailedException(IAMMeta.SYSTEM_ID, subject, action, resources)
def _make_request_with_resources(self, username, action_id, resources=None): request = Request( settings.APP_ID, Subject("user", username), Action(action_id), resources, None, ) return request
def process(self, request, *args, **kwargs): template_id = request.GET.get("template_id") subject = Subject("user", request.user.username) action = Action(IAMMeta.FLOW_VIEW_ACTION) resources = res_factory.resources_for_flow(template_id) request = Request(IAMMeta.SYSTEM_ID, subject, action, resources, {}) allowed = iam.is_allowed(request) if not allowed: raise AuthFailedException(IAMMeta.SYSTEM_ID, subject, action, resources)
def make_view_perm_filter(self, username: str) -> Dict: request = Request( settings.BK_IAM_SYSTEM_ID, Subject('user', username), Action(ProjectAction.VIEW), None, None, ) policies = self._do_policy_query(request) if not policies: return {} return self._make_dict_filter(policies)
def is_user_role(username, role_action): subject = Subject("user", username) action = Action(role_action) request = Request(IAMMeta.SYSTEM_ID, subject, action, [], {}) # can not raise exception at here, will cause index access error try: return iam.is_allowed(request) except Exception: logger.exception( "user {username} role action({role_action}) allow request failed.". format(username=username, role_action=role_action)) return False
def get_user_projects(username): subject = Subject("user", username) action = Action(IAMMeta.PROJECT_VIEW_ACTION) request = Request(IAMMeta.SYSTEM_ID, subject, action, [], {}) key_mapping = {"project.id": "id"} iam = get_iam_client() filters = iam.make_filter(request, key_mapping=key_mapping) if not filters: return Project.objects.none() return Project.objects.filter(filters)
def iam_multi_resource_auth_or_raise(username, action, resource_ids, get_resource_func): iam = get_iam_client() action = Action(action) subject = Subject("user", username) resource_list = getattr(res_factory, get_resource_func)(resource_ids) if not resource_list: return resource_map = {resource[0].id: resource for resource in resource_list} request = Request(IAMMeta.SYSTEM_ID, subject, action, [], {}) result = iam.batch_is_allowed(request, resource_list) if not result: raise MultiAuthFailedException(IAMMeta.SYSTEM_ID, subject, action, resource_list) not_allowed_list = [] for tid, allow in result.items(): if not allow: not_allowed_list.append(resource_map[tid]) if not_allowed_list: raise MultiAuthFailedException(IAMMeta.SYSTEM_ID, subject, action, not_allowed_list)
def is_allow(request): data = json.loads(request.body) action_id = data["action"] resources = data.get("resources", []) subject = Subject("user", request.user.username) action = Action(action_id) resource = [ Resource(r["system"], r["type"], str(r["id"]), r["attributes"]) for r in resources ] iam = get_iam_client() try: is_allow = iam.is_allowed( Request(conf.SYSTEM_ID, subject, action, resource, None)) except (AuthInvalidRequest, AuthAPIError) as e: return standard_response(False, str(e)) return standard_response(True, "success", {"is_allow": is_allow})
def alter_list_data_to_serialize(self, request, data): data = super().alter_list_data_to_serialize(request, data) # 项目流程任务 templates_id = { bundle.obj.template_id for bundle in data["objects"] if bundle.obj.template_id and bundle.obj.template_source == "project" } templates_allowed_actions = get_flow_allowed_actions_for_user( request.user.username, [IAMMeta.FLOW_VIEW_ACTION, IAMMeta.FLOW_CREATE_TASK_ACTION], templates_id ) template_info = TaskTemplate.objects.filter(id__in=templates_id).values( "id", "pipeline_template__name", "is_deleted" ) template_info_map = { str(t["id"]): {"name": t["pipeline_template__name"], "is_deleted": t["is_deleted"]} for t in template_info } # 公共流程任务 common_templates_id = { bundle.obj.template_id for bundle in data["objects"] if bundle.obj.template_id and bundle.obj.template_source == "common" } common_templates_allowed_actions = get_common_flow_allowed_actions_for_user( request.user.username, [IAMMeta.COMMON_FLOW_VIEW_ACTION], common_templates_id, ) common_template_info = CommonTemplate.objects.filter(id__in=common_templates_id).values( "id", "pipeline_template__name", "is_deleted" ) common_template_info_map = { str(t["id"]): {"name": t["pipeline_template__name"], "is_deleted": t["is_deleted"]} for t in common_template_info } for bundle in data["objects"]: if bundle.obj.template_source == "project": bundle.data["template_name"] = template_info_map.get(bundle.obj.template_id, {}).get("name") bundle.data["template_deleted"] = template_info_map.get(bundle.obj.template_id, {}).get( "is_deleted", True ) for act, allowed in templates_allowed_actions.get(str(bundle.obj.template_id), {}).items(): if allowed: bundle.data["auth_actions"].append(act) elif bundle.obj.template_source == "common": bundle.data["template_name"] = common_template_info_map.get(bundle.obj.template_id, {}).get("name") bundle.data["template_deleted"] = common_template_info_map.get(bundle.obj.template_id, {}).get( "is_deleted", True ) for act, allowed in common_templates_allowed_actions.get(str(bundle.obj.template_id), {}).items(): if allowed: bundle.data["auth_actions"].append(act) action = IAMMeta.COMMON_FLOW_CREATE_TASK_ACTION action_request = Request( system=IAMMeta.SYSTEM_ID, subject=Subject("user", request.user.username), action=Action(action), resources=[ res_factory.resources_for_project_obj(bundle.obj.project)[0], res_factory.resources_for_common_flow(bundle.obj.template_id)[0], ], environment=None, ) allowed = iam.is_allowed(action_request) if allowed: bundle.data["auth_actions"].append(action) return data
def process(self, request, *args, **kwargs): project_id = kwargs["project_id"] templates_data = read_template_data_file( request.FILES["data_file"])["data"]["template_data"] request.FILES["data_file"].seek(0) override = string_to_boolean(request.POST["override"]) check_info = TaskTemplate.objects.import_operation_check( templates_data, project_id) subject = Subject("user", request.user.username) create_action = Action(IAMMeta.FLOW_CREATE_ACTION) project_resources = res_factory.resources_for_project(project_id) create_request = Request(IAMMeta.SYSTEM_ID, subject, create_action, project_resources, {}) # check flow create permission if not override: allowed = iam.is_allowed(create_request) if not allowed: raise AuthFailedException(IAMMeta.SYSTEM_ID, subject, create_action, project_resources) else: # check flow create permission if len(check_info["new_template"]) != len( check_info["override_template"]): allowed = iam.is_allowed(create_request) if not allowed: raise AuthFailedException(IAMMeta.SYSTEM_ID, subject, create_action, project_resources) # check flow edit permission if check_info["override_template"]: tids = [ template_info["id"] for template_info in check_info["override_template"] ] resources_list = res_factory.resources_list_for_flows(tids) if not resources_list: return resources_map = {} for resources in resources_list: resources_map[resources[0].id] = resources edit_action = Action(IAMMeta.FLOW_EDIT_ACTION) edit_request = Request(IAMMeta.SYSTEM_ID, subject, edit_action, [], {}) result = iam.batch_is_allowed(edit_request, resources_list) if not result: raise MultiAuthFailedException(IAMMeta.SYSTEM_ID, subject, edit_action, resources_list) not_allowed_list = [] for tid, allow in result.items(): if not allow: not_allowed_list.append(resources_map[tid]) if not_allowed_list: raise MultiAuthFailedException(IAMMeta.SYSTEM_ID, subject, edit_action, not_allowed_list)
if __name__ == "__main__": # eval print("\nTHE EVAL EXAMPLE:\n") eval_exmaple() print_spearator() # convert to sql / django queryset print("\nTHE CONVERT EXAMPLE:\n") convert_example() # make a request print_spearator() subject = Subject("user", "admin") # action = Action("edit_app") # action = Action("access_developer_center") action = Action("develop_app") resource = Resource("bk_paas", "app", "bk_test", {}) request = Request("bk_paas", subject, action, [resource], None) print("the request: ", request.to_dict()) iam = IAM("bk_paas", "2353e89a-10a2-4f30-9f6b-8973e9cd1404", "http://127.0.0.1:8080", "https://{PAAS_DOMAIN}") # recommend if got an APIGateway # iam = IAM("bk_paas", "2353e89a-10a2-4f30-9f6b-8973e9cd1404", bk_apigateway_url="http://{IAM_APIGATEWAY_URL}") print("is_allowed: ", iam.is_allowed(request)) print("query: ", iam.make_filter(request))