def get_job(job_id, user): job = model.Job.query.get(job_id) if not job: return problem(404, 'Not Found', f'Job {job_id} does not exist') if not user_is_admin(user) and job.launched_by != user: return problem(403, 'Forbidden', f"You don't have permissions to view job {job_id}") try: tower_client = job.server.create_tower_client() if job.template.tower_template_is_workflow: tower_job_data = tower_client.workflow_job_get(job.tower_job_id) else: tower_job_data = tower_client.template_job_get(job.tower_job_id) return _tower_job(job, tower_job_data) | {'_href': _job_href(job)} except TowerError as e: logger.exception(f'Failed to get job data from Tower, {e}') return problem(e.response.status_code, 'Error', f'Failed to get job {job_id} data from Tower') except Exception as e: logger.exception(e) return problem(500, 'Server Error', f'Unknown server error, {e}')
def get_credentials(account_id: str, role_name: str, user: str, token_info: dict): current_span = extract_span_from_flask_request() uid = user realm = token_info['realm'] if realm != '/employees': return connexion.problem(403, 'Forbidden', 'You are not authorized to use this service') try: groups = get_groups(uid) except Exception as e: current_span.log_kv({'exception': str(e)}) logger.exception('Failed to get groups for {}'.format(uid)) return connexion.problem(500, 'Server Error', 'Failed to get groups: {}'.format(e)) allowed = False for account_role in map(map_group_to_account_role, groups): if role_name == account_role[ 'role_name'] and account_id == account_role['account_id']: allowed = True break if not allowed: current_span.set_tag('allowed', False) return connexion.problem( 403, 'Forbidden', 'Access to requested AWS account/role was denied') sts = boto3.client('sts') arn = ROLE_ARN.format(account_id=account_id, role_name=role_name) role_session_name = ROLE_SESSION_NAME_INVALID_CHARS.sub('', uid) try: role = sts.assume_role(RoleArn=arn, RoleSessionName=role_session_name) except Exception as e: error_message = 'Failed to assume role: {}'.format(e) current_span.log_kv({'exception': str(e), 'role_arn': arn}) if 'AccessDenied' in error_message: # role might not exist in target account logger.error(error_message) return connexion.problem(403, 'AWS Error', error_message) else: # something else happened current_span.set_tag('error', True) logger.exception('Failed to assume role {}'.format(arn)) return connexion.problem(500, 'AWS Error', error_message) credentials = role['Credentials'] logger.info( 'Handing out credentials for {account_id}/{role_name} to {uid}'.format( account_id=account_id, role_name=role_name, uid=uid)) return { 'access_key_id': credentials['AccessKeyId'], 'secret_access_key': credentials['SecretAccessKey'], 'session_token': credentials['SessionToken'], 'expiration': credentials['Expiration'] }
def post_items(body: dict): # connexion cannot validate this kind of entries try: bson.encode(body) except bson.InvalidDocument as e: return problem(status=422, title="Unprocessable Entity", detail=e.args[0]) except OverflowError as e: return problem(status=422, title="Unprocessable Entity", detail=e.args[0]) uuid = str(uuid4()) ts = datetime.now().isoformat() current_app.config["store"].add(uuid, dict(id=uuid, timestamp=ts, item=body)) return { "id": uuid, "timestamp": ts, "status": "success", "url": request.base_url + "/" + uuid, "debug": current_app.config["store"].list(), }
def _validating_wrapper(param): req_errors = validate_request(param.get('body', {})) if req_errors: return problem(status=400, title="The request could not be validated.", detail="There is an error in your submitted data.", ext={'errors': req_errors}) response = func(param) if not hasattr(response, 'original_data'): return response # FIXME # We need to get the "original data" somewhere and are currently "piggy-backing" # it on the response instance. This is somewhat problematic because it's not # expected behaviour and not a valid interface of Response. Needs refactoring. errors = validate_response(response.original_data) if errors: # Hope we never get here in production. return problem( status=500, title="Server was about to send an invalid response.", detail="This is an error of the implementation.", ext={'errors': errors}, ) return response
def get_template(template_id): template = model.Template.query.get(template_id) if not template: return problem(404, 'Not Found', f'Template {template_id} does not exist') try: tower_client = template.server.create_tower_client() if template.tower_template_is_workflow: tower_survey_data = tower_client.workflow_get_survey( template.tower_template_id) else: tower_survey_data = tower_client.template_get_survey( template.tower_template_id) return template.to_dict() | { 'tower_survey': tower_survey_data, '_href': _template_href(template), } except TowerError as e: logger.exception(f'Failed to get template data from Tower, {e}') return problem( e.response.status_code, 'Error', f'Failed to get template {template_id} data from Tower') except Exception as e: logger.exception(e) return problem(500, 'Server Error', f'Unknown server error, {e}')
def add(product): with dbconn() as conn: cur = conn.cursor() cur.execute( '''SELECT * FROM zsm_data.product_group WHERE pg_slug = %s''', (product['product_group'], )) row = cur.fetchone() if not row: return connexion.problem( status=404, title='Product group not found', detail='Can not find product group: {}'.format( product['product_group'])) product_group = strip_column_prefix(row._asdict()) try: cur.execute( '''INSERT INTO zsm_data.product (p_name, p_slug, p_product_group_id) VALUES (%s, %s, %s)''', ( product['name'], slugger(product['name']), product_group['id'], )) conn.commit() except IntegrityError: return connexion.problem( status=400, title='Product Already Exists', detail='Product with name: "{}" already exists!'.format( product['name'])) return NoContent, 201
def delete_member(username): # noqa: E501 """Delete member This can only be done by the logged in member. Attention! All information, events and pictures associated with this member will be deleted! # noqa: E501 :param username: The name that needs to be deleted :type username: str :rtype: Success """ deleteMember = db_session.query( dbModels.Member).filter(dbModels.Member.username == username).first() if deleteMember is None: return connexion.problem(404, "Not Found", "Username not found.", "Lookup") db_session.delete(deleteMember) try: db_session.commit() except: db_session.rollback() return connexion.problem(500, "Internal Server Error", "Database", "Database") return {"success": True, "Description": "Member has been deleted."}
def set_acknowledgement_on_host(params): """Acknowledge problems on a specific host.""" host_name = params['host_name'] host = Query([Hosts.name, Hosts.state], Hosts.name.equals(host_name)).first(sites.live()) if host is None: return problem( status=404, title=f'Host {host_name} does not exist.', detail='It is not currently monitored.', ) if host.state == 0: return problem(status=400, title=f"Host {host_name} does not have a problem.", detail="The state is UP.") acknowledge_host_problem( sites.live(), host_name, sticky=bool(params.get('sticky')), notify=bool(params.get('notify')), persistent=bool(params.get('persistent')), user=_user_id(), comment=params.get('comment', 'Acknowledged'), ) return http.Response(status=204)
def post_jobs(body, user): print(body) quota = get_user(user)['quota'] if quota['remaining'] - len(body['jobs']) < 0: max_jobs = quota['max_jobs_per_month'] message = f'Your monthly quota is {max_jobs} jobs. You have {quota["remaining"]} jobs remaining.' return problem(400, 'Bad Request', message) try: validate_jobs(body['jobs']) except requests.HTTPError as e: print(f'WARN: CMR search failed: {e}') except GranuleValidationError as e: return problem(400, 'Bad Request', str(e)) request_time = format_time(datetime.now(timezone.utc)) table = DYNAMODB_RESOURCE.Table(environ['JOBS_TABLE_NAME']) for job in body['jobs']: job['job_id'] = str(uuid4()) job['user_id'] = user job['status_code'] = 'PENDING' job['request_time'] = request_time if not body.get('validate_only'): job = convert_floats_to_decimals(job) table.put_item(Item=job) return body
def wrapper(*args, **kwargs): # validate size if kwargs["size"] > app.config["PAPI_MAX_SIZE"]: return problem( 400, "Bad Request", "Value of parameter size= must not be greater than %d" % app.config["PAPI_MAX_SIZE"] ) # validate value of sortBy sort_by, _ = split_sortby(kwargs['sortBy']) if sort_by.lower() not in [v.lower() for v in ALLOWED_SORT_BY_VALUES]: return problem( 400, "Bad Request", "Value '{}' of parameter sortBy= is not allowed. Use one of these values: {}".format( kwargs['sortBy'], ", ".join(ALLOWED_SORT_BY_VALUES))) # validate filter names (depending on compliance level) non_filters = ('size', 'page', 'sortBy', 'body') if app.config['PAPI_COMPLIANCE_LEVEL'] == 0: for kw in kwargs: if kw not in non_filters and not kw.lower() in ALLOWED_FILTERS_CL0: return problem(400, "Bad Request", "'{}' is not a valid filter for compliance level 0".format(kw)) else: # compliance level > 0 allowed_filters = ALLOWED_FILTERS_CL0 + ALLOWED_EXTRA_FILTERS for kw in kwargs: if kw not in non_filters and not kw.lower() in allowed_filters: return problem(400, "Bad Request", "'{}' is not a valid filter for compliance level {}".format(kw, app.config['PAPI_COMPLIANCE_LEVEL'])) return func(*args, **kwargs)
def delete_region(keycloak: KeycloakClient, region_id, user): region = model.Region.query.get(region_id) if not region: return problem(404, 'Not Found', f'Region {region_id} does not exist') if not keycloak.user_check_role(user, ADMIN_ROLE): if not keycloak.user_check_group(user, region.owner_group): raise Forbidden("You don't have write access to this region.") q = model.RegionProduct.query.filter( model.RegionProduct.region_id == region.id, ) if q.count() > 0: for relation in q.all(): db.session.delete(relation) db.session.flush() db.session.delete(region) try: owner_group = keycloak.group_get(region.owner_group) keycloak.group_delete(owner_group['id']) logger.info(f'Deleted owners group {owner_group["id"]}') except KeycloakGetError as e: logger.exception(e) return problem_from_keycloak_error(e) except Exception as e: logger.exception(e) return problem(500, 'Unknown Error', f'Failed to delete owner group in Keycloak, {e}') db.session.commit() logger.info( f'Region {region.name} (id {region.id}) deleted by user {user}')
def bouncer(endpoint, *args, **kwargs): """ Checks if the user making request is in the predefined list of allowed users or match the defined username parttern. """ config = Configuration() if not hasattr(connexion.request, "user"): logger.debug("User not found in the request", extra={"allowed_users": config.allowed_users}) return connexion.problem(403, "Forbidden", "Anonymous access is not allowed " "in this endpoint") if config.allowed_users is not None: logger.debug( "Checking if user is allowed", extra={"user": connexion.request.user, "allowed_users": config.allowed_users} ) if connexion.request.user not in config.allowed_users: return connexion.problem(403, "Forbidden", "User is not allowed to access " "this endpoint") if config.allowed_user_pattern is not None: logger.debug( "Checking if user pattern is allowed", extra={"user": connexion.request.user, "allowed_user_pattern": config.allowed_user_pattern}, ) if re.match(config.allowed_user_pattern, connexion.request.user) is None: return connexion.problem(403, "Forbidden", "User is not allowed to access " "this endpoint") return endpoint(*args, **kwargs)
def create_source(body): # TODO: metadata enrichment if not set? if app.config["PAPI_COMPLIANCE_LEVEL"] < 2: return problem( 501, "Not implemented", "Compliance level {} does not allow PUT requests.".format( app.config["PAPI_COMPLIANCE_LEVEL"] ), ) connector = get_connector() # it seems that connexion converts '@id' to 'id'?? # to make thing consistent for further processing, we revert this body = fix_ids(body) #if not '@id' in body and 'id' in body: # body['@id'] = body['id'] # This should be handled by spec! #if '@id' in body and not is_valid_id(body['@id']): # return problem(400, "Bad Request", 'Illegal character in id') try: data = connector.create(body) return data except CreationException as err: return problem( 409, "Conflict", str(err))
def wrapped(*args, **kwargs): api_key = request.headers.get("X-Phabricator-API-Key") if api_key is None and not self.optional: return problem( 401, "X-Phabricator-API-Key Required", ("Phabricator api key not provided in " "X-Phabricator-API-Key header"), type= "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401", ) g.phabricator = PhabricatorClient( current_app.config["PHABRICATOR_URL"], api_key or current_app.config["PHABRICATOR_UNPRIVILEGED_API_KEY"], ) if api_key is not None and not g.phabricator.verify_api_token(): return problem( 403, "X-Phabricator-API-Key Invalid", "Phabricator api key is not valid", type= "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403", ) return f(*args, **kwargs)
def _SubscriptionConfirmation( snsMessage): #logger.debug( snsMessage) if not 'SubscribeURL' in snsMessage: return connexion.problem( 400, "Subscription error", "No subscription URL was provided") subUrl = snsMessage[ 'SubscribeURL'] ''' Check subUrl is an URL ^http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+ Long live regex101!!! :) ''' if not re.match( '^http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', subUrl): logger.error ( 'SubscribeURL is not an URL') return connexion.problem( 400, "Subscription error", "'%s' is not a valid SubscribeURL" % subUrl) try: r = requests.get( subUrl) except: logger.error( 'Unable to fetch: ' + subUrl) return connexion.problem( 404, "Subscription error", "Unable to fetch: '%s'" % subUrl) logger.debug( 'And got... %s' % r) return connexion.problem( 200, "Subscription success", "Subscription done.")
def get_consent(taxCode, callback_url, consent, accept=False): user_data = _get_user_data(taxCode) if not user_data: return problem(title="User Not Found", status=404, detail="Missing user") if not accept: token = validate_token(consent, valid=False, audience=app.config["entityId"]) return problem( title="OK", status=200, detail="Do you want to give access to %r for the following jwt" % token["iss"], ext={ "_link": [{ "url": request.url + "&accept=yes" }], "callback_url": callback_url, "token": token, }, ) user_data["consent"] = time() return problem( title="Redirecting to consent", status=302, detail="Redirecto to POST", headers={"Location": callback_url}, ) raise NotImplementedError
def post(h5p_data: dict): """ The POST method for the H5P REST API. It offers client-side H5P exercises for download as ZIP archives. """ h5p_form: H5PForm = H5PForm.from_dict(h5p_data) language: Language = determine_language(h5p_form.lang) exercise: Exercise = DatabaseService.query( Exercise, filter_by=dict(eid=h5p_form.eid), first=True) if not exercise: return connexion.problem(404, Config.ERROR_TITLE_NOT_FOUND, Config.ERROR_MESSAGE_EXERCISE_NOT_FOUND) text_field_content: str = get_text_field_content(exercise, h5p_form.solution_indices) if not text_field_content: return connexion.problem(422, Config.ERROR_TITLE_UNPROCESSABLE_ENTITY, Config.ERROR_MESSAGE_UNPROCESSABLE_ENTITY) response_dict: dict = TextService.json_template_mark_words response_dict = get_response(response_dict, language, TextService.json_template_drag_text, exercise, text_field_content, TextService.feedback_template) file_name_no_ext: str = str(h5p_form.exercise_type_path) file_name: str = f"{file_name_no_ext}.{FileType.ZIP}" target_dir: str = Config.TMP_DIRECTORY make_h5p_archive(file_name_no_ext, response_dict, target_dir, file_name) return send_from_directory(target_dir, file_name, mimetype=MimeType.zip.value, as_attachment=True)
def land(data, api_key=None): """ API endpoint at /revisions/{id}/transplants to land revision. """ # get revision_id from body revision_id = data['revision_id'] try: landing = Landing.create(revision_id, api_key) except RevisionNotFoundException: # We could not find a matching revision. return problem( 404, 'Revision not found', 'The requested revision does not exist', type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404' ) except LandingNotCreatedException: # We could not find a matching revision. return problem( 502, 'Landing not created', 'The requested revision does exist, but landing failed.' 'Please retry your request at a later time.', type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502' ) return {'id': landing.id}, 202
def add_region_product(keycloak: KeycloakClient, region_id, body, user): region = model.Region.query.get(region_id) if not region: return problem(404, 'Not Found', f'Region {region_id} does not exist') if not keycloak.user_check_role(user, ADMIN_ROLE): if not keycloak.user_check_group(user, region.owner_group): raise Forbidden("You don't have write access to this region.") product = model.Product.query.get(body['id']) if not product: return problem(404, 'Not Found', f'Product {body["id"]} does not exist') q = model.RegionProduct.query.filter( sqlalchemy.and_( model.RegionProduct.region_id == region.id, model.RegionProduct.product_id == product.id, )) if q.count() == 0: relation = model.RegionProduct( region_id=region.id, product_id=product.id, enabled=body.get('enabled', True), ) db.session.add(relation) db.session.commit() logger.info( f'Added Product {product.name} (id {product.id}) to Region {region.name} ' f'(id {region.id}) by user {user}') elif 'enabled' in body: for relation in q.all(): relation.enabled = body['enabled'] db.session.commit()
def get_status(): """Ritorna lo stato dell'applicazione. Ritorna lo stato dell'applicazione. # noqa: E501 :rtype: Problem """ @after_this_request def cache_no_store(response): """Add the 'no-store' cache value to avoid clients and intermediaries to store this response. """ response.headers["Cache-Control"] = "no-store" return response if current_app.config["store"].ping(): return problem( status=200, title="Success", detail="Il servizio funziona correttamente", ext={"result": "ok"}, ) return problem( status=503, title="Service Unavailable", detail="Questo errore viene ritornato randomicamente.", headers={"Retry-After": "1"}, )
def common_error_handler(exception: BaseException) -> flask.Response: """Used to capture connexion exceptions and add link to the type field.""" if isinstance(exception, ProblemException): link = EXCEPTIONS_LINK_MAP.get(exception.status) if link: response = problem( status=exception.status, title=exception.title, detail=exception.detail, type=link, instance=exception.instance, headers=exception.headers, ext=exception.ext, ) else: response = problem( status=exception.status, title=exception.title, detail=exception.detail, type=exception.type, instance=exception.instance, headers=exception.headers, ext=exception.ext, ) else: if not isinstance(exception, werkzeug.exceptions.HTTPException): exception = werkzeug.exceptions.InternalServerError() response = problem(title=exception.name, detail=exception.description, status=exception.code) return FlaskApi.get_response(response)
def update_region(keycloak: KeycloakClient, vault: Vault, region_id, body, user): region = model.Region.query.get(region_id) if not region: return problem(404, 'Not Found', f'Region {region_id} does not exist') if not keycloak.user_check_role(user, ADMIN_ROLE): if not keycloak.user_check_group(user, region.owner_group): raise Forbidden("You don't have write access to this region.") try: if body.get('users_group'): keycloak.group_get(body['users_group']) except KeycloakGetError as e: logger.exception(e) return problem( 400, 'Users group does not exist', f'Users group {body["users_group"]} does not exist in Keycloak, ' 'you have to create group first or use existing group.') if 'quota' in body: if body['quota']: if region.quota is None: region.quota = model.Quota(**body['quota']) else: for k, v in body['quota'].items(): setattr(region.quota, k, v) else: region.quota = None del body['quota'] openstack_credentials = dpath.get(body, 'openstack/credentials', default=region.openstack_credentials) if not isinstance(openstack_credentials, str): vault.write(region.openstack_credentials, openstack_credentials) dpath.delete(body, 'openstack/credentials') satellite_credentials = dpath.get(body, 'satellite/credentials', default=region.satellite_credentials) if not isinstance(satellite_credentials, str): vault.write(region.satellite_credentials, satellite_credentials) dpath.delete(body, 'satellite/credentials') dns_server_key = dpath.get(body, 'dns_server/key', default=region.dns_server_key) if not isinstance(dns_server_key, str): vault.write(region.dns_server_key, dns_server_key) dpath.delete(body, 'dns_server/key') region.update_from_dict(body) db.session.commit() logger.info( f'Region {region.name} (id {region.id}) updated by user {user}') return region.to_dict() | {'_href': _region_href(region)}
def images(taxon=None, service=None, limit=None, offset=None): """Specimen link retrieval.""" from ..elc import subreq desc_obj = dict() t0 = time() sub_query = 'Specimen images for {0:s} retrieved through {1:s}'.format( taxon.capitalize(), 'iDigBio' if service == 'idigbio' else 'ePANDDA') try: options = params.set_options(req_args=connexion.request.args, endpoint='images') except ValueError as err: return connexion.problem(status=err.args[0], title=Status(err.args[0]).name, detail=err.args[1], type='about:blank') # Call parse function to check for parameter errors try: payload = params.parse(req_args=connexion.request.args, options=options, db='pbdb', endpoint='images') except ValueError as err: return connexion.problem(status=err.args[0], title=Status(err.args[0]).name, detail=err.args[1], type='about:blank') # Query media aggregators try: media = subreq.images_req(payload=payload, options=options) except ValueError as err: return connexion.problem(status=err.args[0], title=Status(err.args[0]).name, detail=err.args[1], type='about:blank') # Build returned metadata object desc_obj.update(aux.build_meta(options)) desc_obj.update(aux.build_meta_sub(source=sub_query, t0=t0, sub_tag='media_links', options=options, data=media)) # Return data structure to client return jsonify(metadata=desc_obj, records=media)
def mobile(taxon=None, bbox=None): """Lightweight custom response.""" from ..elc import config, subreq return_obj = list() # Set runtime options try: options = params.set_options(req_args=connexion.request.args, endpoint='occ') except ValueError as err: return connexion.problem(status=err.args[0], title=Status(err.args[0]).name, detail=err.args[1], type='about:blank') # This query only applies to Neotoma and PBDB for db in ['neotoma', 'pbdb']: # Configure parameter payload for api subquery try: payload = params.parse(req_args=connexion.request.args, options=options, db=db, endpoint='occ') except ValueError as err: return connexion.problem(status=err.args[0], title=Status(err.args[0]).name, detail=err.args[1], type='about:blank') # Database API call url_path = ''.join([config.get('resource_api', db), config.get('db_occ_endpt', db)]) try: return_obj = subreq.mobile_req(return_obj=return_obj, url_path=url_path, payload=payload, db=db) except ValueError as err: return connexion.problem(status=err.args[0], title=Status(err.args[0]).name, detail=err.args[1], type='about:blank') # Return composite data structure to client return jsonify(return_obj)
def land(data, api_key=None): """API endpoint at POST /landings to land revision.""" # get revision_id from body revision_id = data['revision_id'] diff_id = data['diff_id'] logger.info( { 'path': request.path, 'method': request.method, 'data': data, 'msg': 'landing requested by user' }, 'landing.invoke') try: landing = Landing.create(revision_id, diff_id, api_key) except RevisionNotFoundException: # We could not find a matching revision. logger.info({ 'revision': revision_id, 'msg': 'revision not found' }, 'landing.failure') return problem( 404, 'Revision not found', 'The requested revision does not exist', type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404' ) except DiffNotFoundException: # We could not find a matching diff logger.info({ 'diff': diff_id, 'msg': 'diff not found' }, 'landing.failure') return problem( 404, 'Diff not found', 'The requested diff does not exist', type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404' ) except LandingNotCreatedException as exc: # We could not find a matching revision. logger.info( { 'revision': revision_id, 'exc': exc, 'msg': 'error creating landing', }, 'landing.error') return problem( 502, 'Landing not created', 'The requested revision does exist, but landing failed.' 'Please retry your request at a later time.', type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502' ) return {'id': landing.id}, 202
def convert(amount, input_currency, output_currency=""): try: converter = Converter(amount, input_currency, output_currency) if converter.check_parameters(): return converter.convert() else: return problem(400, "Bad Request", "Wrong parameters", "about:blank") except FileNotFoundError: return problem(400, "Error", "Cannot find file with currency symbols.", "about:blank")
def bulk_set_acknowledgement_on_host_service(params): """Bulk Acknowledge specific services on specific host""" live = sites.live() body = params['body'] host_name = body['host_name'] entries = body.get('entries', []) query = Query([Services.description, Services.state], And( Services.host_name.equals(host_name), Or(*[ Services.description.equals(service_description) for service_description in entries ]))) services = query.to_dict(live) not_found = [] for service_description in entries: if service_description not in services: not_found.append(service_description) if not_found: return problem( status=400, title= f"Services {', '.join(not_found)} not found on host {host_name}", detail='Currently not monitored') up_services = [] for service_description in entries: if services[service_description] == 0: up_services.append(service_description) if up_services: return problem( status=400, title=f"Services {', '.join(up_services)} do not have a problem", detail="The states of these services are OK") for service_description in entries: acknowledge_service_problem( sites.live(), host_name, service_description, sticky=body.get('sticky', False), notify=body.get('notify', False), persistent=body.get('persistent', False), user=str(config.user.id), comment=body.get('comment', 'Acknowledged'), ) return http.Response(status=204)
def get(urn: str) -> Union[Response, ConnexionResponse]: """The GET method for the valid references REST API. It provides references for the desired text.""" try: reff: List[str] = CustomCorpusService.get_custom_corpus_reff( urn) if CustomCorpusService.is_custom_corpus_urn( urn) else CorpusService.get_standard_corpus_reff(urn) except ValueError: return connexion.problem(400, Config.ERROR_TITLE_BAD_REQUEST, Config.ERROR_MESSAGE_BAD_REQUEST) if not reff: return connexion.problem(404, Config.ERROR_TITLE_NOT_FOUND, Config.ERROR_MESSAGE_CORPUS_NOT_FOUND) return NetworkService.make_json_response(reff)
def _execute(name=None): try: return func(name), httplib.OK except error.NotFoundError: return connexion.problem( httplib.NOT_FOUND, '{} not found'.format(resource), 'Requested {} `{}` not found.'.format( resource.lower(), name)) except error.ToBeDoneError: return connexion.problem( httplib.NOT_IMPLEMENTED, '{} handler not implemented'.format(operation), 'Requested operation `{}` on {} not implemented.'.format( operation.lower(), resource.lower()))
def relaunch_job(job_id, user): job = model.Job.query.get(job_id) if not job: return problem(404, 'Not Found', f'Job {job_id} does not exist') if not user_is_admin(user) and job.launched_by != user: return problem(403, 'Forbidden', f"You don't have permissions to relaunch job {job_id}") try: tower_client = job.server.create_tower_client() if job.template.tower_template_is_workflow: tower_job_data = tower_client.workflow_job_relaunch( job.tower_job_id) else: tower_job_data = tower_client.template_job_relaunch( job.tower_job_id) relaunched_job = model.Job( template_id=job.template_id, tower_job_id=tower_job_data['id'], launched_by=user, ) db.session.add(relaunched_job) db.session.commit() return _tower_job(relaunched_job, tower_job_data) | { '_href': _job_href(job) } except TowerError as e: logger.exception(f'Failed to relaunch job, {e}') problem_ext = None try: problem_ext = e.response.json() if 'detail' in problem_ext: del problem_ext['detail'] except Exception: pass # simply ignore return problem(e.response.status_code, 'Error', f'Failed to relaunch job {job_id}', ext=problem_ext) except Exception as e: logger.exception(e) return problem(500, 'Server Error', f'Unknown server error, {e}')
def call_eureka(): if not EUREKA_URL: return connexion.problem(500, "Internal Server error", "Eureka url not set", "errors.eureka") if not ExternalServices.eureka_on: ExternalServices.init_eureka() if not ExternalServices.eureka_on: return connexion.problem( 500, "Internal Server error", "Unable to connect to eureka, the server might not be running", "errors.eureka") return "Connected to eureka", 200 return "Already connected to eureka", 200
def get_attribute_consent(taxCode): """Receives a token and asks for permission if required. Return :param taxCode: :return: """ content_type = request.headers.get("Content-Type", "") assert content_type.lower() == "application/jose" user_data = _get_user_data(taxCode) if not user_data: return problem(title="User Not Found", status=404, detail="Missing user") try: claims = validate_token(request.data, audience=app.config["entityId"]) except jwt.exceptions.InvalidTokenError as e: return invalid_token_handler(e) except Exception as e: raise ValueError(e, request.data) assert claims["v"] == "0.0.1", claims assert claims["attributes"], claims if user_data["consent"] + 30 < time(): return problem( status=403, title="ConsentRequired", detail="User consent is required for this attribute. Last given: %r" % datetime.fromtimestamp(user_data["consent"]), type="https://spid.gov.it/aa/problem/consent-required", ext={"consent_url": "https://aa/v1/consents/{taxCode}/"}, ) aa = [{ "attribute": a, "value": user_data[a] } for a in claims["attributes"] if a in user_data] token = create_token({"v": "0.0.1", "attributes": aa}) token["iss"] = app.config["entityId"] token["aud"] = claims["iss"] signed_token = sign_request(token, app_config=app.config) return Response(response=signed_token, status=200, mimetype="application/jose")
def with_problem(): return problem(type='http://www.example.com/error', title='Some Error', detail='Something went wrong somewhere', status=418, instance='instance1', headers={'x-Test-Header': 'In Test'})
def get_fragment_svg(fragment_id, width, height): """2D drawing of fragment in SVG format Args: fragment_id (str): Fragment identifier width (int): Width of SVG in pixels height (int): Height of SVG in pixels Returns: flask.Response|connexion.lifecycle.ConnexionResponse: SVG document|problem """ fragments_db_filename = current_app.config['fragments'] with FragmentsDb(fragments_db_filename) as fragmentsdb: try: fragment = fragmentsdb[fragment_id] if not fragment['mol']: title = 'Not Found' description = 'Fragment with identifier \'{0}\' has no molblock'.format(fragment_id) ext = {'identifier': fragment_id} return connexion.problem(404, title, description, ext=ext) mol = fragment['mol'] svg = mol2svg(mol, width, height) return flask.Response(svg, mimetype='image/svg+xml') except LookupError: return fragment_not_found(fragment_id)
def post(emergency_shutoff, changed_by, transaction): if shutoff_exists(emergency_shutoff["product"], emergency_shutoff["channel"]): return problem(400, "Bad Request", "Invalid Emergency shutoff data", ext={"data": "Emergency shutoff for product/channel already exists."}) inserted_shutoff = dbo.emergencyShutoffs.insert( changed_by=changed_by, transaction=transaction, product=emergency_shutoff["product"], channel=emergency_shutoff["channel"] ) return Response(status=201, content_type="application/json", response=json.dumps(inserted_shutoff))
def with_problem(): return problem( type="http://www.example.com/error", title="Some Error", detail="Something went wrong somewhere", status=418, instance="instance1", )
def get_by_id(product, channel): shutoffs = dbo.emergencyShutoffs.select(where=dict(product=product, channel=channel)) if not shutoffs: return problem(status=404, title="Not Found", detail="Requested emergency shutoff wasn't found", ext={"exception": "Requested shutoff does not exist"}) headers = {"X-Data-Version": shutoffs[0]["data_version"]} return Response(response=json.dumps(shutoffs[0]), headers=headers, mimetype="application/json")
def schedule_deletion(sc_emergency_shutoff, changed_by, transaction): if "csrf_token" in sc_emergency_shutoff: del sc_emergency_shutoff["csrf_token"] change_type = sc_emergency_shutoff.get("change_type") if change_type != "delete": return problem(400, "Bad Request", "Invalid or missing change_type") view = ScheduledChangesView("emergency_shutoff", dbo.emergencyShutoffs) return view._post(sc_emergency_shutoff, transaction, changed_by, change_type)
def schedule_deletion(sc_emergency_shutoff, changed_by, transaction): if 'csrf_token' in sc_emergency_shutoff: del sc_emergency_shutoff['csrf_token'] change_type = sc_emergency_shutoff.get('change_type') if change_type != 'delete': return problem(400, "Bad Request", "Invalid or missing change_type") view = ScheduledChangesView('emergency_shutoff', dbo.emergencyShutoffs) return view._post(sc_emergency_shutoff, transaction, changed_by, change_type)
def get_rule(id_or_alias, with_csrf_headers=False): rule = dbo.rules.getRule(id_or_alias) if not rule: return problem(status=404, title="Not Found", detail="Requested rule wasn't found", ext={"exception": "Requested rule does not exist"}) headers = {"X-Data-Version": rule["data_version"]} if with_csrf_headers: headers.update(get_csrf_headers()) return Response(response=json.dumps(rule), mimetype="application/json", headers=headers)
def post(emergency_shutoff, changed_by, transaction): if shutoff_exists(emergency_shutoff['product'], emergency_shutoff['channel']): return problem( 400, 'Bad Request', 'Invalid Emergency shutoff data', ext={'data': 'Emergency shutoff for product/channel already exists.'}) inserted_shutoff = dbo.emergencyShutoffs.insert( changed_by=changed_by, transaction=transaction, product=emergency_shutoff['product'], channel=emergency_shutoff['channel']) return Response(status=201, content_type="application/json", response=json.dumps(inserted_shutoff))
def exception_to_connexion_problem(func, *args, **kwargs): try: return func(*args, **kwargs) except ObjectNotFound as exception: problem = connexion.problem(404, 'Not Found', "Stack not found: {}".format(exception.uid), headers=_make_headers()) metrics.count('generic.{}.stack_not_found'.format(func.__name__)) return problem except ExecutionError as error: sentry_client.captureException() metrics.count('generic.{}.senza_cmd_error'.format(func.__name__)) return connexion.problem(500, title='Execution Error', detail=error.output, headers=_make_headers()) except Exception: sentry_client.captureException() raise
def get_release_single_locale(release, platform, locale, with_csrf_header=False): try: locale = dbo.releases.getLocale(release, platform, locale) except KeyError as e: return problem(404, "Not Found", json.dumps(e.args)) data_version = dbo.releases.getReleases(name=release)[0]["data_version"] headers = {"X-Data-Version": data_version} if with_csrf_header: headers.update(get_csrf_headers()) return Response(response=json.dumps(locale), mimetype="application/json", headers=headers)
def delete(product, channel, data_version, changed_by, transaction, **kwargs): if not shutoff_exists(product, channel): return problem(status=404, title="Not Found", detail="Shutoff wasn't found", ext={"exception": "Shutoff does not exist"}) where = dict(product=product, channel=channel) dbo.emergencyShutoffs.delete(where=where, changed_by=changed_by, old_data_version=data_version, transaction=transaction) return Response(status=200)
def get(animal_id): gc = global_cell.GlobalCell() q = {'animal_id': animal_id} res = [i['id'] for i in gc.find(q)] if not res: return connexion.problem( 404, 'not found', 'no global cells found for {}'.format(animal_id), __name__.split('.')[-1] ) return res
def get_release_history(release): history_table = dbo.releases.history order_by = [history_table.timestamp.desc()] history_helper = HistoryHelper(hist_table=history_table, order_by=order_by, get_object_callback=lambda: _get_release(release), history_filters_callback=_get_filters, process_revisions_callback=process_release_revisions) try: return history_helper.get_history() except (ValueError, AssertionError) as e: log.warning("Bad input: %s", json.dumps(e.args)) return problem(400, "Bad Request", "Invalid input", ext={"data": e.args})
def get(cell_id): c = cell.Cell() q = {'id': cell_id} res = c.find_one(q) if not res: return connexion.problem( 404, 'not found', 'id {} does not exist'.format(cell_id), __name__.split('.')[-1] ) del res['_id'] return res
def get(run_id): r = run.Run() q = {'id': run_id} res = r.find_one(q) if not res: return connexion.problem( 404, 'not found', 'id {} does not exist'.format(run_id), __name__.split('.')[-1] ) del res['_id'] return res
def get(cell_metric_id): pcmi = per_cell_metric.PerCellMetricInfo() q = {'id': cell_metric_id} res = pcmi.find_one(q) if not res: return connexion.problem( 404, 'not found', 'id {} does not exist'.format(cell_metric_id), __name__.split('.')[-1] ) del res['_id'] return res
def get(trial_id): t = trial.Trial() q = {'id': trial_id} res = t.find_one(q) if not res: return connexion.problem( 404, 'not found', 'id {} does not exist'.format(trial_id), __name__.split('.')[-1] ) del res['_id'] return res
def get(trial_id): ret = raw_eye_tracking.RawEyeTracking() q = {'trial_id': trial_id} res = ret.find_one(q) if not res: return connexion.problem( 404, 'not found', 'raw eye tracking data for trial {} not found'.format(trial_id), __name__.split('.')[-1] ) if res: del res['_id'] return res
def get_rule_history(rule_id): history_table = dbo.rules.history order_by = [history_table.timestamp.desc()] history_helper = HistoryHelper(hist_table=history_table, order_by=order_by, get_object_callback=lambda: dbo.rules.getRule(rule_id), history_filters_callback=_get_filters, obj_not_found_msg='Requested rule does not exist') try: return history_helper.get_history(response_key='rules') except (ValueError, AssertionError) as msg: log.warning("Bad input: %s", msg) return problem(400, "Bad Request", "Error occurred when trying to fetch" " Rule's revisions having rule_id {0}".format(rule_id), ext={"exception": str(msg)})
def get(session_id): s = session.Session() q = {'id': session_id} res = s.find_one(q) if not res: return connexion.problem( 404, 'not found', 'session id {} not found'.format(session_id), __name__.split('.')[-1] ) res['animal'] = res['animal']['id'] del res['_id'] del res['runs'] return res
def get_release(release, with_csrf_header=False): release = _get_release(release) if not release: return problem(404, "Not Found", "Release name: %s not found" % release) headers = {"X-Data-Version": release["data_version"]} if with_csrf_header: headers.update(get_csrf_headers()) if request.args.get("pretty"): indent = 4 separators = (",", ": ") else: indent = None separators = None # separators set manually due to https://bugs.python.org/issue16333 affecting Python 2 return Response(response=json.dumps(release["data"], indent=indent, separators=separators, sort_keys=True), mimetype="application/json", headers=headers)
def _get_histories(table, obj, process_revisions_callback=None): history_table = table order_by = [history_table.timestamp.desc()] history_helper = HistoryHelper(hist_table=history_table, order_by=order_by, get_object_callback=lambda: obj, history_filters_callback=_get_filters, obj_not_found_msg='No history found', process_revisions_callback=process_revisions_callback) try: return history_helper.get_history() except (ValueError, AssertionError) as msg: log.warning("Bad input: %s", msg) return problem(400, "Bad Request", "Error occurred when trying to fetch histories", ext={"exception": str(msg)})
def get(run_id, cell_id, channel_id=None, trial_id=None): ftc = functional_time_course.FunctionalTimeCourse() q = {'run_id': run_id, 'cell_id': cell_id} if trial_id: q['trial_id'] = trial_id res = ftc.find_one(q) if not res: return connexion.problem( 404, 'not found', 'time course data not found', __name__.split('.')[-1] ) if res: del res['_id'] return res
def get_fragments(fragment_ids=None, pdb_codes=None): """Retrieve fragments based on their identifier or PDB code. Args: fragment_ids (List[str]): List of fragment identifiers pdb_codes (List[str]): List of PDB codes Returns: list[dict]: List of fragment information Raises: werkzeug.exceptions.NotFound: When one of the fragments_ids or pdb_code could not be found """ fragments_db_filename = current_app.config['fragments'] with FragmentsDb(fragments_db_filename) as fragmentsdb: fragments = [] missing_ids = [] if fragment_ids: for frag_id in fragment_ids: try: fragments.append(fragmentsdb[frag_id]) except LookupError: missing_ids.append(frag_id) if pdb_codes: for pdb_code in pdb_codes: try: for fragment in fragmentsdb.by_pdb_code(pdb_code): fragments.append(fragment) except LookupError: missing_ids.append(pdb_code) # TODO if fragment_ids and pdb_codes are both None then return paged list of all fragments if missing_ids: title = 'Not found' label = 'identifiers' if pdb_codes: label = 'PDB codes' description = 'Fragments with {1} \'{0}\' not found'.format(','.join(missing_ids), label) # connexion.problem is using json.dumps instead of flask custom json encoder, so performing convert myself # TODO remove mol2string conversion when https://github.com/zalando/connexion/issues/266 is fixed for fragment in fragments: if fragment['mol']: fragment['mol'] = MolToMolBlock(fragment['mol']) ext = {'absent_identifiers': missing_ids, 'fragments': fragments} return connexion.problem(404, title, description, ext=ext) return fragments
def common_error_handler(exception): '''TODO: add description :param extension: TODO :type exception: Exception :rtype: TODO: ''' if not isinstance(exception, werkzeug.exceptions.HTTPException): exception = werkzeug.exceptions.InternalServerError() return connexion.problem( title=exception.name, detail=exception.description, status=exception.code, )
def validate_schema(self, data, url): # type: (dict, AnyStr) -> Union[ConnexionResponse, None] if self.is_null_value_valid and is_null(data): return None try: self.validator.validate(data) except JsonSchemaValidationError as exception: # Add field name to the error response exception_field = '' for i in exception.path: exception_field = i + ': ' if exception.__cause__ is not None: exception_message = str(exception.__cause__.message) + ' ' + exception_field + str(exception.message) else: exception_message = exception_field + str(exception.message) logger.error("{url} validation error: {error}". format(url=url, error=exception_message)) return problem(400, 'Bad Request', exception_message) return None
def validate_schema(self, data, url): # type: (dict, AnyStr) -> Union[ConnexionResponse, None] if self.is_null_value_valid and is_null(data): return None try: self.validator.validate(data) except jsonschema.ValidationError as exception: # Add field name to the error response exception_field = "" for i in exception.path: exception_field = i + ": " if exception.__cause__ is not None: exception_message = exception.__cause__.message + " " + exception_field + exception.message else: exception_message = exception_field + exception.message # Some exceptions could contain unicode characters - if we don't replace them # we could end up with a UnicodeEncodeError. logger.error("{url} validation error: {error}".format(url=url, error=exception_message.encode("utf-8", "replace"))) return problem(400, "Bad Request", exception_message) return None