def create_service_resource_view(request): """ Register a new resource directly under a service or under one of its children resources. """ service = ar.get_service_matchdict_checked(request) resource_name = ar.get_multiformat_body(request, "resource_name") resource_display_name = ar.get_multiformat_body(request, "resource_display_name", default=resource_name) resource_type = ar.get_multiformat_body(request, "resource_type") parent_id = ar.get_multiformat_body(request, "parent_id") # no check because None/empty is allowed db_session = request.db if parent_id is None: parent_id = service.resource_id else: parent_id = ax.evaluate_call(lambda: int(parent_id), http_error=HTTPUnprocessableEntity, msg_on_fail=s.ServiceResources_POST_UnprocessableEntityResponseSchema.description) # validate target service is actually the root service of the provided parent resource ID root_service = ru.get_resource_root_service_by_id(parent_id, db_session=db_session) ax.verify_param(root_service, not_none=True, param_name="parent_id", msg_on_fail=s.ServiceResources_POST_NotFoundResponseSchema.description, http_error=HTTPNotFound) ax.verify_param(root_service.resource_id, is_equal=True, param_compare=service.resource_id, param_name="parent_id", msg_on_fail=s.ServiceResources_POST_ForbiddenResponseSchema.description, http_error=HTTPForbidden) return ru.create_resource(resource_name, resource_display_name, resource_type, parent_id=parent_id, db_session=db_session)
def create_resource_view(request): """ Register a new resource. """ resource_name = ar.get_value_multiformat_post_checked(request, "resource_name") resource_display_name = ar.get_multiformat_any(request, "resource_display_name", default=resource_name) resource_type = ar.get_value_multiformat_post_checked(request, "resource_type") parent_id = ar.get_value_multiformat_post_checked(request, "parent_id") return ru.create_resource(resource_name, resource_display_name, resource_type, parent_id, request.db)
def create_service_direct_resource_view(request): """ Register a new resource directly under a service. """ service = ar.get_service_matchdict_checked(request) resource_name = ar.get_multiformat_post(request, "resource_name") resource_display_name = ar.get_multiformat_post(request, "resource_display_name", default=resource_name) resource_type = ar.get_multiformat_post(request, "resource_type") parent_id = ar.get_multiformat_post( request, "parent_id") # no check because None/empty is allowed if not parent_id: parent_id = service.resource_id return create_resource(resource_name, resource_display_name, resource_type, parent_id=parent_id, db_session=request.db)
def parse_resource_path( permission_config_entry, # type: ConfigItem entry_index, # type: int service_info, # type: ConfigItem cookies_or_session=None, # type: CookiesOrSessionType magpie_url=None, # type: Optional[Str] ): # type: (...) -> Tuple[Optional[int], bool] """ Parses the `resource` field of a permission config entry and retrieves the final resource id. Creates missing resources as necessary if they can be automatically resolved. If `cookies` are provided, uses requests to a running `Magpie` instance (with `magpie_url`) to apply permission. If `session` to db is provided, uses direct db connection instead to apply permission. :returns: tuple of found id (if any, `None` otherwise), and success status of the parsing operation (error) """ if not magpie_url and use_request(cookies_or_session): raise ValueError( "cannot use cookies without corresponding request URL") resource = None resource_path = permission_config_entry.get("resource", "") if resource_path.startswith("/"): resource_path = resource_path[1:] if resource_path.endswith("/"): resource_path = resource_path[:-1] if resource_path: try: svc_name = service_info["service_name"] svc_type = service_info["service_type"] if use_request(cookies_or_session): res_path = get_magpie_url() + ServiceResourcesAPI.path.format( service_name=svc_name) res_resp = requests.get(res_path, cookies=cookies_or_session) res_dict = get_json(res_resp)[svc_name]["resources"] else: from magpie.api.management.service.service_formats import format_service_resources svc = models.Service.by_service_name( svc_name, db_session=cookies_or_session) res_dict = format_service_resources( svc, show_all_children=True, db_session=cookies_or_session) parent = res_dict["resource_id"] child_resources = res_dict["resources"] for res in resource_path.split("/"): # search in existing children resources if len(child_resources): # noinspection PyTypeChecker res_id = list( filter( lambda r: res in [r, child_resources[r]["resource_name"]], child_resources)) if res_id: res_info = child_resources[ res_id[0]] # type: Dict[Str, JSON] child_resources = res_info[ "children"] # update next sub-resource iteration parent = res_info["resource_id"] continue # missing resource, attempt creation svc_res_types = SERVICE_TYPE_DICT[svc_type].resource_type_names type_count = len(svc_res_types) if type_count != 1: warn_permission( "Cannot automatically generate resources", entry_index, detail= "Service [{}] of type [{}] allows {} sub-resource types" .format(svc_name, svc_type, type_count)) raise Exception( "Missing resource to apply permission.") # fail fast res_type = svc_res_types[0] if use_request(cookies_or_session): body = { "resource_name": res, "resource_type": res_type, "parent_id": parent } # noinspection PyUnboundLocalVariable resp = requests.post(res_path, json=body, cookies=cookies_or_session) else: from magpie.api.management.resource.resource_utils import create_resource resp = create_resource(res, res, res_type, parent, db_session=cookies_or_session) if resp.status_code != 201: resp.raise_for_status() child_resources = {} parent = get_json(resp)["resource"]["resource_id"] resource = parent if not resource: raise Exception( "Could not extract child resource from resource path.") except Exception as ex: if isinstance(ex, HTTPException): detail = "{} ({}), {}".format( type(ex).__name__, ex.status_code, str(ex)) else: detail = repr(ex) warn_permission("Failed resources parsing.", entry_index, detail=detail) return None, False return resource, True