async def file_not_found(req_text): await logger.warning(f'Cant find {req_text}; {FileNotFoundError}') return web.HTTPBadRequest(reason=req_text)
async def create_jobs(request, userdata): app = request.app db = app['db'] log_store = app['log_store'] worker_type = app['worker_type'] worker_cores = app['worker_cores'] batch_id = int(request.match_info['batch_id']) user = userdata['username'] # restrict to what's necessary; in particular, drop the session # which is sensitive userdata = { 'username': user, 'bucket_name': userdata['bucket_name'], 'gsa_key_secret_name': userdata['gsa_key_secret_name'], 'tokens_secret_name': userdata['tokens_secret_name'] } async with LoggingTimer(f'batch {batch_id} create jobs') as timer: async with timer.step('fetch batch'): record = await db.select_and_fetchone( ''' SELECT `state`, format_version FROM batches WHERE user = %s AND id = %s AND NOT deleted; ''', (user, batch_id)) if not record: raise web.HTTPNotFound() if record['state'] != 'open': raise web.HTTPBadRequest(reason=f'batch {batch_id} is not open') batch_format_version = BatchFormatVersion(record['format_version']) async with timer.step('get request json'): job_specs = await request.json() async with timer.step('validate job_specs'): try: validate_jobs(job_specs) except ValidationError as e: raise web.HTTPBadRequest(reason=e.reason) async with timer.step('build db args'): spec_writer = SpecWriter(log_store, batch_id) jobs_args = [] job_parents_args = [] job_attributes_args = [] n_ready_jobs = 0 ready_cores_mcpu = 0 n_ready_cancellable_jobs = 0 ready_cancellable_cores_mcpu = 0 prev_job_idx = None start_job_id = None for spec in job_specs: job_id = spec['job_id'] parent_ids = spec.pop('parent_ids', []) always_run = spec.pop('always_run', False) if batch_format_version.has_full_spec_in_gcs(): attributes = spec.pop('attributes', None) else: attributes = spec.get('attributes') id = (batch_id, job_id) if start_job_id is None: start_job_id = job_id if batch_format_version.has_full_spec_in_gcs( ) and prev_job_idx: if job_id != prev_job_idx + 1: raise web.HTTPBadRequest( reason= f'noncontiguous job ids found in the spec: {prev_job_idx} -> {job_id}' ) prev_job_idx = job_id resources = spec.get('resources') if not resources: resources = {} spec['resources'] = resources if 'cpu' not in resources: resources['cpu'] = BATCH_JOB_DEFAULT_CPU if 'memory' not in resources: resources['memory'] = BATCH_JOB_DEFAULT_MEMORY req_cores_mcpu = parse_cpu_in_mcpu(resources['cpu']) req_memory_bytes = parse_memory_in_bytes(resources['memory']) if req_cores_mcpu == 0: raise web.HTTPBadRequest( reason=f'bad resource request for job {id}: ' f'cpu cannot be 0') cores_mcpu = adjust_cores_for_memory_request( req_cores_mcpu, req_memory_bytes, worker_type) if cores_mcpu > worker_cores * 1000: total_memory_available = worker_memory_per_core_gb( worker_type) * worker_cores raise web.HTTPBadRequest( reason= f'resource requests for job {id} are unsatisfiable: ' f'requested: cpu={resources["cpu"]}, memory={resources["memory"]} ' f'maximum: cpu={worker_cores}, memory={total_memory_available}G' ) secrets = spec.get('secrets') if not secrets: secrets = [] spec['secrets'] = secrets secrets.append({ 'namespace': BATCH_PODS_NAMESPACE, 'name': userdata['gsa_key_secret_name'], 'mount_path': '/gsa-key', 'mount_in_copy': True }) env = spec.get('env') if not env: env = [] spec['env'] = env if len(parent_ids) == 0: state = 'Ready' n_ready_jobs += 1 ready_cores_mcpu += cores_mcpu if not always_run: n_ready_cancellable_jobs += 1 ready_cancellable_cores_mcpu += cores_mcpu else: state = 'Pending' spec_writer.add(json.dumps(spec)) db_spec = batch_format_version.db_spec(spec) jobs_args.append((batch_id, job_id, state, json.dumps(db_spec), always_run, cores_mcpu, len(parent_ids))) for parent_id in parent_ids: job_parents_args.append((batch_id, job_id, parent_id)) if attributes: for k, v in attributes.items(): job_attributes_args.append((batch_id, job_id, k, v)) if batch_format_version.has_full_spec_in_gcs(): async with timer.step('write spec to gcs'): await spec_writer.write() rand_token = random.randint(0, app['n_tokens'] - 1) n_jobs = len(job_specs) async with timer.step('insert jobs'): @transaction(db) async def insert(tx): try: await tx.execute_many( ''' INSERT INTO jobs (batch_id, job_id, state, spec, always_run, cores_mcpu, n_pending_parents) VALUES (%s, %s, %s, %s, %s, %s, %s); ''', jobs_args) except pymysql.err.IntegrityError as err: # 1062 ER_DUP_ENTRY https://dev.mysql.com/doc/refman/5.7/en/server-error-reference.html#error_er_dup_entry if err.args[0] == 1062: log.info( f'bunch containing job {(batch_id, jobs_args[0][1])} already inserted ({err})' ) raise web.Response() raise await tx.execute_many( ''' INSERT INTO `job_parents` (batch_id, job_id, parent_id) VALUES (%s, %s, %s); ''', job_parents_args) await tx.execute_many( ''' INSERT INTO `job_attributes` (batch_id, job_id, `key`, `value`) VALUES (%s, %s, %s, %s); ''', job_attributes_args) await tx.execute_update( ''' INSERT INTO batches_staging (batch_id, token, n_jobs, n_ready_jobs, ready_cores_mcpu) VALUES (%s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE n_jobs = n_jobs + %s, n_ready_jobs = n_ready_jobs + %s, ready_cores_mcpu = ready_cores_mcpu + %s; ''', (batch_id, rand_token, n_jobs, n_ready_jobs, ready_cores_mcpu, n_jobs, n_ready_jobs, ready_cores_mcpu)) await tx.execute_update( ''' INSERT INTO batch_cancellable_resources (batch_id, token, n_ready_cancellable_jobs, ready_cancellable_cores_mcpu) VALUES (%s, %s, %s, %s) ON DUPLICATE KEY UPDATE n_ready_cancellable_jobs = n_ready_cancellable_jobs + %s, ready_cancellable_cores_mcpu = ready_cancellable_cores_mcpu + %s; ''', (batch_id, rand_token, n_ready_cancellable_jobs, ready_cancellable_cores_mcpu, n_ready_cancellable_jobs, ready_cancellable_cores_mcpu)) if batch_format_version.has_full_spec_in_gcs(): await tx.execute_update( ''' INSERT INTO batch_bunches (batch_id, token, start_job_id) VALUES (%s, %s, %s); ''', (batch_id, spec_writer.token, start_job_id)) await insert() # pylint: disable=no-value-for-parameter return web.Response()
async def presentation_exchange_send_proposal(request: web.BaseRequest): """ Request handler for sending a presentation proposal. Args: request: aiohttp request object Returns: The presentation exchange details """ r_time = get_timer() context: AdminRequestContext = request["context"] profile = context.profile outbound_handler = request["outbound_message_router"] body = await request.json() comment = body.get("comment") connection_id = body.get("connection_id") # Aries RFC 37 calls it a proposal in the proposal struct but it's of type preview presentation_preview = body.get("presentation_proposal") connection_record = None async with profile.session() as session: try: connection_record = await ConnRecord.retrieve_by_id( session, connection_id) presentation_proposal_message = PresentationProposal( comment=comment, presentation_proposal=IndyPresPreview.deserialize( presentation_preview), ) except (BaseModelError, StorageError) as err: # other party does not care about our false protocol start raise web.HTTPBadRequest(reason=err.roll_up) if not connection_record.is_ready: raise web.HTTPForbidden(reason=f"Connection {connection_id} not ready") trace_msg = body.get("trace") presentation_proposal_message.assign_trace_decorator( context.settings, trace_msg, ) auto_present = body.get( "auto_present", context.settings.get("debug.auto_respond_presentation_request")) presentation_manager = PresentationManager(profile) pres_ex_record = None try: pres_ex_record = await presentation_manager.create_exchange_for_proposal( connection_id=connection_id, presentation_proposal_message=presentation_proposal_message, auto_present=auto_present, ) result = pres_ex_record.serialize() except (BaseModelError, StorageError) as err: if pres_ex_record: async with profile.session() as session: await pres_ex_record.save_error_state(session, reason=err.roll_up) # other party does not care about our false protocol start raise web.HTTPBadRequest(reason=err.roll_up) await outbound_handler(presentation_proposal_message, connection_id=connection_id) trace_event( context.settings, presentation_proposal_message, outcome="presentation_exchange_propose.END", perf_counter=r_time, ) return web.json_response(result)
def validate_output_dir(output_dir: str): """Checks that output_dir doesn't start with 'gs://' and strips trailing slashes.""" if output_dir.startswith('gs://'): raise web.HTTPBadRequest( reason='Output directory cannot start with "gs://"') return output_dir.rstrip('/') # Strip trailing slash.
def route(request): session = yield from get_session(request) if 'uid' in session: uid = session['uid'] else: return web.HTTPForbidden() query_parameters = request.rel_url.query try: fid = int(query_parameters["fid"]) fid = str(fid).zfill(8) except: return web.HTTPBadRequest() if request.content_type != "multipart/form-data": return web.HTTPBadRequest() try: reader = yield from request.multipart() except Exception: return web.HTTPBadRequest() next = yield from reader.next() photo_dir = os.path.join(request.app["photo_dir"], fid) if os.path.exists(photo_dir) == 0: os.mkdir(photo_dir) size = 0 suffix = '' hash_calc = hashlib.md5() while True: try: chunk = yield from next.read_chunk() # 8192 bytes by default except Exception: return web.HTTPBadRequest() if not chunk: break if size == 0: if len(chunk) < 4: return web.HTTPBadRequest() top_eight_bytes = ''.join('{:02x}'.format(x) for x in chunk[0:4]).upper() if top_eight_bytes[0:6] == 'FFD8FF': suffix = "jpg" elif top_eight_bytes[0:8] == '89504E47': suffix = "png" elif top_eight_bytes[0:8] == '47494638': suffix = "gif" else: return web.HTTPBadRequest() while True: temp_name = str(int(time.time())) + str(random.randint( 0, 9999)).zfill(4) temp_file = os.path.join(photo_dir, temp_name) if not os.path.exists(temp_file): break file = open(temp_file, 'wb') size = size + len(chunk) file.write(chunk) hash_calc.update(chunk) if size / 1048576 > 2: # size limit 2MB file.close() os.remove(temp_file) return web.HTTPRequestEntityTooLarge() file.close() hash_value = hash_calc.hexdigest() formal_name = hash_value + "." + suffix formal_file = os.path.join(photo_dir, formal_name) if os.path.exists(formal_file) != 0: os.remove(temp_file) else: os.rename(temp_file, formal_file) # with (yield from request.app['pool']) as connect: # cursor = yield from connect.cursor() # try: # yield from cursor.execute(''' # INSERT INTO photo VALUES(%s,%s,%s,%s) # ''',(hash_value,fid,suffix,0)) # yield from connect.commit() # except Exception as e: # print(e) # yield from cursor.close() # connect.close() return web.Response(text=toolbox.jsonify({"filename": formal_name}), # headers = {'Access-Control-Allow-Origin':'*'} )
async def credential_exchange_send(request: web.BaseRequest): """ Request handler for sending credential from issuer to holder from attr values. If both issuer and holder are configured for automatic responses, the operation ultimately results in credential issue; otherwise, the result waits on the first response not automated; the credential exchange record retains state regardless. Args: request: aiohttp request object Returns: The credential exchange record """ r_time = get_timer() context = request.app["request_context"] outbound_handler = request.app["outbound_message_router"] body = await request.json() comment = body.get("comment") connection_id = body.get("connection_id") preview_spec = body.get("credential_proposal") if not preview_spec: raise web.HTTPBadRequest(reason="credential_proposal must be provided") auto_remove = body.get("auto_remove") trace_msg = body.get("trace") connection_record = None cred_ex_record = None try: preview = CredentialPreview.deserialize(preview_spec) connection_record = await ConnectionRecord.retrieve_by_id( context, connection_id) if not connection_record.is_ready: raise web.HTTPForbidden( reason=f"Connection {connection_id} not ready") credential_proposal = CredentialProposal( comment=comment, credential_proposal=preview, **{t: body.get(t) for t in CRED_DEF_TAGS if body.get(t)}, ) credential_proposal.assign_trace_decorator( context.settings, trace_msg, ) trace_event( context.settings, credential_proposal, outcome="credential_exchange_send.START", ) credential_manager = CredentialManager(context) ( cred_ex_record, credential_offer_message, ) = await credential_manager.prepare_send( connection_id, credential_proposal=credential_proposal, auto_remove=auto_remove, ) result = cred_ex_record.serialize() except (StorageError, BaseModelError, CredentialManagerError) as err: await internal_error( err, web.HTTPBadRequest, cred_ex_record or connection_record, outbound_handler, ) await outbound_handler(credential_offer_message, connection_id=cred_ex_record.connection_id) trace_event( context.settings, credential_offer_message, outcome="credential_exchange_send.END", perf_counter=r_time, ) return web.json_response(result)
async def credential_exchange_send_free_offer(request: web.BaseRequest): """ Request handler for sending free credential offer. An issuer initiates a such a credential offer, free from any holder-initiated corresponding credential proposal with preview. Args: request: aiohttp request object Returns: The credential exchange record """ r_time = get_timer() context = request.app["request_context"] outbound_handler = request.app["outbound_message_router"] body = await request.json() connection_id = body.get("connection_id") cred_def_id = body.get("cred_def_id") if not cred_def_id: raise web.HTTPBadRequest(reason="cred_def_id is required") auto_issue = body.get( "auto_issue", context.settings.get("debug.auto_respond_credential_request")) auto_remove = body.get("auto_remove") comment = body.get("comment") preview_spec = body.get("credential_preview") if not preview_spec: raise web.HTTPBadRequest(reason=("Missing credential_preview")) trace_msg = body.get("trace") cred_ex_record = None connection_record = None try: connection_record = await ConnectionRecord.retrieve_by_id( context, connection_id) if not connection_record.is_ready: raise web.HTTPForbidden( reason=f"Connection {connection_id} not ready") ( cred_ex_record, credential_offer_message, ) = await _create_free_offer( context, cred_def_id, connection_id, auto_issue, auto_remove, preview_spec, comment, trace_msg, ) result = cred_ex_record.serialize() except ( StorageNotFoundError, BaseModelError, CredentialManagerError, LedgerError, ) as err: await internal_error( err, web.HTTPBadRequest, cred_ex_record or connection_record, outbound_handler, ) await outbound_handler(credential_offer_message, connection_id=connection_id) trace_event( context.settings, credential_offer_message, outcome="credential_exchange_send_free_offer.END", perf_counter=r_time, ) return web.json_response(result)
async def present_proof_send_free_request(request: web.BaseRequest): """ Request handler for sending a presentation request free from any proposal. Args: request: aiohttp request object Returns: The presentation exchange details """ r_time = get_timer() context: AdminRequestContext = request["context"] outbound_handler = request["outbound_message_router"] body = await request.json() connection_id = body.get("connection_id") async with context.session() as session: try: conn_record = await ConnRecord.retrieve_by_id(session, connection_id) except StorageNotFoundError as err: raise web.HTTPBadRequest(reason=err.roll_up) from err if not conn_record.is_ready: raise web.HTTPForbidden(reason=f"Connection {connection_id} not ready") comment = body.get("comment") pres_request_spec = body.get("presentation_request") if pres_request_spec and V20PresFormat.Format.INDY.api in pres_request_spec: await _add_nonce(pres_request_spec[V20PresFormat.Format.INDY.api]) pres_request_message = V20PresRequest( comment=comment, will_confirm=True, **_formats_attach(pres_request_spec, PRES_20_REQUEST, "request_presentations"), ) trace_msg = body.get("trace") pres_request_message.assign_trace_decorator( context.settings, trace_msg, ) pres_manager = V20PresManager(context.profile) pres_ex_record = None try: pres_ex_record = await pres_manager.create_exchange_for_request( connection_id=connection_id, pres_request_message=pres_request_message, ) result = pres_ex_record.serialize() except (BaseModelError, StorageError) as err: if pres_ex_record: async with context.session() as session: await pres_ex_record.save_error_state(session, reason=err.roll_up) # other party does not care about our false protocol start raise web.HTTPBadRequest(reason=err.roll_up) await outbound_handler(pres_request_message, connection_id=connection_id) trace_event( context.settings, pres_request_message, outcome="presentation_exchange_send_request.END", perf_counter=r_time, ) return web.json_response(result)
async def present_proof_send_presentation(request: web.BaseRequest): """ Request handler for sending a presentation. Args: request: aiohttp request object Returns: The presentation exchange details """ r_time = get_timer() context: AdminRequestContext = request["context"] outbound_handler = request["outbound_message_router"] pres_ex_id = request.match_info["pres_ex_id"] body = await request.json() fmt = V20PresFormat.Format.get([f for f in body][0]) # "indy" xor "dif" pres_ex_record = None async with context.session() as session: try: pres_ex_record = await V20PresExRecord.retrieve_by_id(session, pres_ex_id) except StorageNotFoundError as err: raise web.HTTPNotFound(reason=err.roll_up) from err if pres_ex_record.state != (V20PresExRecord.STATE_REQUEST_RECEIVED): raise web.HTTPBadRequest( reason=( f"Presentation exchange {pres_ex_id} " f"in {pres_ex_record.state} state " f"(must be {V20PresExRecord.STATE_REQUEST_RECEIVED})" ) ) connection_id = pres_ex_record.connection_id try: conn_record = await ConnRecord.retrieve_by_id(session, connection_id) except StorageNotFoundError as err: raise web.HTTPBadRequest(reason=err.roll_up) from err if not conn_record.is_ready: raise web.HTTPForbidden(reason=f"Connection {connection_id} not ready") pres_manager = V20PresManager(context.profile) try: indy_spec = body.get(V20PresFormat.Format.INDY.api) # TODO: accommodate DIF pres_ex_record, pres_message = await pres_manager.create_pres( pres_ex_record, { "self_attested_attributes": indy_spec["self_attested_attributes"], "requested_attributes": indy_spec["requested_attributes"], "requested_predicates": indy_spec["requested_predicates"], }, comment=body.get("comment"), format_=fmt, ) result = pres_ex_record.serialize() except ( BaseModelError, IndyHolderError, LedgerError, StorageError, WalletNotFoundError, ) as err: async with context.session() as session: await pres_ex_record.save_error_state(session, reason=err.roll_up) # other party cares that we cannot continue protocol await report_problem( err, ProblemReportReason.ABANDONED.value, web.HTTPBadRequest, pres_ex_record, outbound_handler, ) trace_msg = body.get("trace") pres_message.assign_trace_decorator( context.settings, trace_msg, ) await outbound_handler(pres_message, connection_id=connection_id) trace_event( context.settings, pres_message, outcome="presentation_exchange_send_request.END", perf_counter=r_time, ) return web.json_response(result)
async def _handler(self, request): # 当有请求时, 从`request`中获取必要的参数, 调用URL函数 kw = None # 如果需要参数 if self.has_var_kw_arg or self.has_name_kw_args: # 有 **kw 或 命名关键字参数 if request.method == 'POST': if not request.content_type: return web.HTTPBadRequest(text='No content_type.') content_type = request.content_type.lower() if content_type.startswith('application/json'): params = await request.json() if not isinstance(params, dict): return web.HTTPBadRequest(text='Body must be json.') kw = params elif content_type.startswith( 'application/x-www-form-urlencoded' ) or content_type.startswith('multipart/form-data'): params = await request.post() kw = dict(**params) else: return web.HTTPBadRequest( text='Unsupported Content-Type: {}.'.format( request.content_type)) if request.method == 'GET': query_string = request.query_string if query_string: kw = dict() for k, v in parse.parse_qs(query_string, True).items(): kw[k] = v[0] # 不需要参数 或 没有取到参数 if kw is None: kw = dict(**request.match_info) else: # 取到参数 且没有 **kw if not self.has_var_kw_arg: copy = dict() # 只取出需要的参数 for name in self.get_name_kw_args: if name in kw: copy[name] = kw[name] kw = copy # 把request的信息添加到kw for k, v in request.match_info.items(): if k in kw: logging.warning('Duplicate arg name {}:{} --> {}.'.format( k, kw[k], v)) kw[k] = v if self.has_request_arg: kw['request'] = request # 如果存在没有默认值的必需参数 # if self.get_required_kw_args: for name in self.get_required_kw_args: if name not in kw: return web.HTTPBadRequest( text='Missing argument: {}.'.format(name)) logging.debug("[RequestHandler]:get response by: {}({})".format( self.func_name, str(kw))) try: rs = await self.func(**kw) return rs except APIError as e: logging.warning( '[APIError]: error_type:{}, error_kw:{}, message:{}'.format( e.error_type, e.error_kw, e.message)) return dict(error_type=e.error_type, error_kw=e.error_kw, message=e.message)
async def __call__(self, request): kw = None if self._has_var_kw_arg or self._has_named_kw_args or self._required_kw_args: # 当传入的处理函数具有 关键字参数集 或 命名关键字参数 或 request参数 if request.method == 'POST': # POST请求预处理 if not request.content_type: # 无正文类型信息时返回 return web.HTTPBadRequest('Missing Content-Type.') ct = request.content_type.lower() if ct.startswith('application/json'): # 处理JSON类型的数据,传入参数字典中 params = await request.json() if not isinstance(params, dict): return web.HTTPBadRequest('JSON body must be object.') kw = params elif ct.startswith('application/x-www-form-urlencoded') or ct.startswith('multipart/form-data'): # 处理表单类型的数据,传入参数字典中 params = await request.post() kw = dict(**params) else: # 暂不支持处理其他正文类型的数据 return web.HTTPBadRequest('Unsupported Content-Type: %s' % request.content_type) if request.method == 'GET': # GET请求预处理 qs = request.query_string # 获取URL中的请求参数,如 name=Justone, id=007 if qs: # 将请求参数传入参数字典中 kw = dict() for k, v in parse.parse_qs(qs, True).items(): kw[k] = v[0] if kw is None: # 请求无请求参数时 kw = dict(**request.match_info) else: # 参数字典收集请求参数 if not self._has_var_kw_arg and self._named_kw_args: # remove all unamed kw: copy = dict() for name in self._named_kw_args: if name in kw: copy[name] = kw[name] kw = copy # check named arg: for k, v in request.match_info.items(): if k in kw: logging.warning('Duplicate arg name in named arg and kw args: %s' % k) kw[k] = v if self._has_request_arg: kw['request'] = request # check required kw: if self._required_kw_args: # 收集无默认值的关键字参数 for name in self._required_kw_args: if not name in kw: # 当存在关键字参数未被赋值时返回,例如 一般的账号注册时,没填入密码就提交注册申请时,提示密码未输入 return web.HTTPBadRequest('Missing argument: %s' % name) logging.info('call with args: %s' % str(kw)) try: r = await self._func(**kw) # 最后调用处理函数,并传入请求参数,进行请求处理 return r except APIError as e: return dict(error=e.error, data=e.data, message=e.message)
async def objectsonline(request: web.Request) -> web.Response: """ --- description: Takes several paraemeters (coordinates and a heading) and determines possible objects along that line tags: - Destination Prediction parameters: - in: query name: x type: number description: X Corrdinate required: true - in: query name: y type: number description: Y Coordinate required: true - in: query name: z type: number description: Z Corrdinate required: true - in: query name: yaw type: number description: Yaw angle - in: query name: pitch type: number description: Pitch Angle - in: query name: speed description: Speed the object was travelling at type: number default: 16 - in: query name: sdist description: Distance to use as the same object (for help with clusters) default: 50 required: false type: number - in: query name: frame type: string description: Name of the empire for the frame the coordinates are in required: false - in: query name: output type: string default: csv description: Switched output from plaintext - in: query name: radius type: number description: Length of the virutal line used to determine matches default 1000 required: false default: 1000 produces: - text/plain responses: "200": description: "Successfully was able to caculate objects, even if none were returned" "400": description: "An error in the query was detected" """ frame = None x = float(request.query.get('x')) y = float(request.query.get('y')) z = float(request.query.get('z')) yaw = float(request.query.get('yaw')) pitch = float(request.query.get('pitch')) frame_slug = request.query.get('frame', None) speed = float(request.query.get('speed', 16)) output = request.query.get('output', 'csv') sdist = float(request.query.get('sdist', 50)) d = float(request.query.get('radius', 1000)) if frame_slug and frame_slug not in request.app['atsborders']: for k in request.app['atsborders'].keys(): if frame_slug.lower() in k.lower(): frame = k elif frame_slug in request.app['atsborders']: frame = frame_slug elif not frame_slug: frame = None else: return web.HTTPBadRequest( body= "Frame {} is not a valid frame, these are the currently valid frames: {}" .format(frame_slug, request.app['atsborders'].keys())) if output.lower() == "json": l = objectprediction(output.lower(), request.app['atsborders'], request.app['atsdb'], x, y, z, yaw, pitch, frame, speed, d, sdist) return web.json_response(l) else: return web.Response(body=objectprediction( output.lower(), request.app['atsborders'], request.app['atsdb'], x, y, z, yaw, pitch, frame, speed, d))
#!/usr/bin/env python3
async def __call__(self, request): ' 分析请求,request handler,must be a coroutine that accepts a request instance as its only argument and returns a streamresponse derived instance ' kw = None if self._has_var_kw_arg or self._has_named_kw_args or self._required_kw_args: # 当传入的处理函数具有 关键字参数集 或 命名关键字参数 或 request参数 if request.method == 'POST': # POST请求预处理 if not request.content_type: # 无正文类型信息时返回 return web.HTTPBadRequest('Missing Content-Type.') ct = request.content_type.lower() if ct.startswith('application/json'): # 处理JSON类型的数据,传入参数字典中 params = await request.json() if not isinstance(params, dict): return web.HTTPBadRequest('JSON body must be object.') kw = params elif ct.startswith('application/x-www-form-urlencoded') or ct.startswith('multipart/form-data'): # 处理表单类型的数据,传入参数字典中 params = await request.post() kw = dict(**params) else: # 暂不支持处理其他正文类型的数据 return web.HTTPBadRequest('Unsupported Content-Type: %s' % request.content_type) if request.method == 'GET': # GET请求预处理 qs = request.query_string # 获取URL中的请求参数,如 name=Justone, id=007 if qs: # 将请求参数传入参数字典中 kw = dict() for k, v in parse.parse_qs(qs, True).items(): # parse a query string, data are returned as a dict. the dict keys are the unique query variable names and the values are lists of values for each name # a True value indicates that blanks should be retained as blank strings kw[k] = v[0] if kw is None: # 请求无请求参数时 kw = dict(**request.match_info) # Read-only property with AbstractMatchInfo instance for result of route resolving else: # 参数字典收集请求参数 if not self._has_var_kw_arg and self._named_kw_args: copy = dict() for name in self._named_kw_args: if name in kw: copy[name] = kw[name] kw = copy for k, v in request.match_info.items(): if k in kw: logging.warning('Duplicate arg name in named arg and kw args: %s' % k) kw[k] = v if self._has_request_arg: kw['request'] = request if self._required_kw_args: # 收集无默认值的关键字参数 for name in self._required_kw_args: if not name in kw: # 当存在关键字参数未被赋值时返回,例如 一般的账号注册时,没填入密码就提交注册申请时,提示密码未输入 return web.HTTPBadRequest('Missing arguments: %s' % name) logging.info('call with args: %s' % str(kw)) try: r = await self._func(**kw) # 最后调用处理函数,并传入请求参数,进行请求处理 return r except APIError as e: return dict(error=e.error, data=e.data, message=e.message)
======= raise web.HTTPForbidden( reason="Configuration does not include introduction service" ) >>>>>>> work in progress try: await service.start_introduction( init_connection_id, target_connection_id, message, outbound_handler ) <<<<<<< HEAD except IntroductionError as err: ======= except (IntroductionError, StorageError) as err: >>>>>>> work in progress raise web.HTTPBadRequest(reason=err.roll_up) from err return web.json_response({}) async def register(app: web.Application): """Register routes.""" app.add_routes( [web.post("/connections/{conn_id}/start-introduction", introduction_start)] ) def post_process_routes(app: web.Application): """Amend swagger API."""
async def present_proof_verify_presentation(request: web.BaseRequest): """ Request handler for verifying a presentation request. Args: request: aiohttp request object Returns: The presentation exchange details """ r_time = get_timer() context: AdminRequestContext = request["context"] outbound_handler = request["outbound_message_router"] pres_ex_id = request.match_info["pres_ex_id"] pres_ex_record = None async with context.session() as session: try: pres_ex_record = await V20PresExRecord.retrieve_by_id(session, pres_ex_id) except StorageNotFoundError as err: raise web.HTTPNotFound(reason=err.roll_up) from err if pres_ex_record.state != (V20PresExRecord.STATE_PRESENTATION_RECEIVED): raise web.HTTPBadRequest( reason=( f"Presentation exchange {pres_ex_id} " f"in {pres_ex_record.state} state " f"(must be {V20PresExRecord.STATE_PRESENTATION_RECEIVED})" ) ) connection_id = pres_ex_record.connection_id try: conn_record = await ConnRecord.retrieve_by_id(session, connection_id) except StorageError as err: raise web.HTTPBadRequest(reason=err.roll_up) from err if not conn_record.is_ready: raise web.HTTPForbidden(reason=f"Connection {connection_id} not ready") pres_manager = V20PresManager(context.profile) try: pres_ex_record = await pres_manager.verify_pres(pres_ex_record) result = pres_ex_record.serialize() except (BaseModelError, LedgerError, StorageError) as err: if pres_ex_record: async with context.session() as session: await pres_ex_record.save_error_state(session, reason=err.roll_up) # other party cares that we cannot continue protocol await report_problem( err, ProblemReportReason.ABANDONED.value, web.HTTPBadRequest, pres_ex_record, outbound_handler, ) trace_event( context.settings, pres_ex_record, outcome="presentation_exchange_verify.END", perf_counter=r_time, ) return web.json_response(result)
async def credential_exchange_create(request: web.BaseRequest): """ Request handler for creating a credential from attr values. The internal credential record will be created without the credential being sent to any connection. This can be used in conjunction with the `oob` protocols to bind messages to an out of band message. Args: request: aiohttp request object Returns: The credential exchange record """ r_time = get_timer() context = request.app["request_context"] body = await request.json() comment = body.get("comment") preview_spec = body.get("credential_proposal") if not preview_spec: raise web.HTTPBadRequest(reason="credential_proposal must be provided") auto_remove = body.get("auto_remove") trace_msg = body.get("trace") try: preview = CredentialPreview.deserialize(preview_spec) credential_proposal = CredentialProposal( comment=comment, credential_proposal=preview, **{t: body.get(t) for t in CRED_DEF_TAGS if body.get(t)}, ) credential_proposal.assign_trace_decorator( context.settings, trace_msg, ) trace_event( context.settings, credential_proposal, outcome="credential_exchange_create.START", ) credential_manager = CredentialManager(context) ( credential_exchange_record, credential_offer_message, ) = await credential_manager.prepare_send( None, credential_proposal=credential_proposal, auto_remove=auto_remove, ) except (StorageError, BaseModelError) as err: raise web.HTTPBadRequest(reason=err.roll_up) from err trace_event( context.settings, credential_offer_message, outcome="credential_exchange_create.END", perf_counter=r_time, ) return web.json_response(credential_exchange_record.serialize())
async def callback(self, req: Request) -> Response: """Include correct tokens in cookies as a callback after login. Sets session information such as access_token and user_info. Sets encrypted cookie to identify clients. :raises: HTTPBadRequest in case login failed :raises: HTTPForbidden in case of bad session :param req: A HTTP request instance with callback parameters :returns: HTTPSeeOther redirect to home page """ # Response from AAI must have the query params `state` and `code` if "state" in req.query and "code" in req.query: LOG.debug("AAI response contained the correct params.") params = {"state": req.query["state"], "code": req.query["code"]} else: reason = f"AAI response is missing mandatory params, received: {req.query}" LOG.error(reason) raise web.HTTPBadRequest(reason=reason) # Verify, that states match state = await self._get_from_session(req, "oidc_state") if not secrets.compare_digest(str(state), str(params["state"])): raise web.HTTPForbidden(reason="Bad user session.") auth = BasicAuth(login=self.client_id, password=self.client_secret) data = { "grant_type": "authorization_code", "code": params["code"], "redirect_uri": self.callback_url } # Set up client authentication for request async with ClientSession(auth=auth) as sess: # Send request to AAI async with sess.post(f"{self.token_url}", data=data) as resp: LOG.debug(f"AAI response status: {resp.status}.") # Validate response from AAI if resp.status == 200: result = await resp.json() if all(x in result for x in ["id_token", "access_token"]): LOG.debug("Both ID and Access tokens received.") access_token = result["access_token"] id_token = result["id_token"] await self._validate_jwt(id_token) else: reason = "AAI response did not contain access and id tokens." LOG.error(reason) raise web.HTTPBadRequest(reason=reason) else: reason = f"Token request to AAI failed: {resp}" LOG.error(reason) raise web.HTTPBadRequest(reason=reason) await self._save_to_session(req, key="access_token", value=access_token) await self._set_user(req, access_token) response = web.HTTPSeeOther(f"{self.redirect}/home") cookie, _ = generate_cookie(req) cookie["referer"] = req.url.host cookie["signature"] = (hashlib.sha256( (cookie["id"] + cookie["referer"] + req.app["Salt"]).encode("utf-8"))).hexdigest() session = cookie["id"] cookie_crypted = req.app["Crypt"].encrypt( json.dumps(cookie).encode("utf-8")).decode("utf-8") response.headers[ "Cache-Control"] = "no-cache, no-store, must-revalidate" response.headers["Pragma"] = "no-Cache" response.headers["Expires"] = "0" trust = False if self.domain.startswith( "http://localhost:5430") else True response.set_cookie( name="MTD_SESSION", value=cookie_crypted, max_age=3600, secure=trust, # type: ignore httponly=trust, # type: ignore ) req.app["Cookies"].add(session) # done like this otherwise it will not redirect properly response.headers[ "Location"] = "/home" if self.redirect == self.domain else f"{self.redirect}/home" LOG.debug(f"cookie MTD_SESSION set {cookie_crypted}") return response
async def credential_exchange_create_free_offer(request: web.BaseRequest): """ Request handler for creating free credential offer. Unlike with `send-offer`, this credential exchange is not tied to a specific connection. It must be dispatched out-of-band by the controller. Args: request: aiohttp request object Returns: The credential exchange record """ r_time = get_timer() context = request.app["request_context"] outbound_handler = request.app["outbound_message_router"] body = await request.json() cred_def_id = body.get("cred_def_id") if not cred_def_id: raise web.HTTPBadRequest(reason="cred_def_id is required") auto_issue = body.get( "auto_issue", context.settings.get("debug.auto_respond_credential_request")) auto_remove = body.get("auto_remove") comment = body.get("comment") preview_spec = body.get("credential_preview") if not preview_spec: raise web.HTTPBadRequest(reason=("Missing credential_preview")) connection_id = body.get("connection_id") trace_msg = body.get("trace") wallet: BaseWallet = await context.inject(BaseWallet) if connection_id: try: connection_record = await ConnectionRecord.retrieve_by_id( context, connection_id) conn_did = await wallet.get_local_did(connection_record.my_did) except (WalletError, StorageError) as err: raise web.HTTPBadRequest(reason=err.roll_up) from err else: conn_did = await wallet.get_public_did() if not conn_did: raise web.HTTPBadRequest( reason=f"Wallet '{wallet.name}' has no public DID") connection_id = None did_info = await wallet.get_public_did() endpoint = did_info.metadata.get("endpoint", context.settings.get("default_endpoint")) if not endpoint: raise web.HTTPBadRequest( reason="An endpoint for the public DID is required") cred_ex_record = None try: ( cred_ex_record, credential_offer_message, ) = await _create_free_offer( context, cred_def_id, connection_id, auto_issue, auto_remove, preview_spec, comment, trace_msg, ) trace_event( context.settings, credential_offer_message, outcome="credential_exchange_create_free_offer.END", perf_counter=r_time, ) oob_url = serialize_outofband(credential_offer_message, conn_did, endpoint) result = cred_ex_record.serialize() except (BaseModelError, CredentialManagerError, LedgerError) as err: await internal_error( err, web.HTTPBadRequest, cred_ex_record or connection_record, outbound_handler, ) response = {"record": result, "oob_url": oob_url} return web.json_response(response)
def handler(request): try: yield from request.post() except ValueError: return web.HTTPOk() return web.HTTPBadRequest()
async def __call__(self, request): kw = None if self._has_var_kw_arg or self._has_named_kw_args or self._required_kw_args: if request.method == 'POST': if not request.content_type: return web.HTTPBadRequest('Missing Content-Type.') ct = request.content_type.lower() if ct.startswith('application/json'): params = await request.json() if not isinstance(params, dict): return web.HTTPBadRequest('JSON body must be object.') kw = params elif ct.startswith('application/x-www-form-rulencoded' ) or ct.startswith('multipart/form-data'): params = await request.post() kw = dict(**params) else: return web.HTTPBadRequest('Unsupported Content-Type: %s' % request.content_type) if request.method == 'GET': qs = request.query_string if qs: kw = dict() for k, v in parse.parse_qs(qs, True).items(): kw[k] = v[0] if kw is None: kw = dict(**request.match_info) #print('\nkw:\n', kw, '\nrequest.match_info:\n', request.match_info) #kw{'id':'001514861142476bd95fab85f7542178dba245d02470c57000'}, #match_info<MatchInfo {'id': '001514861142476bd95fab85f7542178dba245d02470c57000'}: <ResourceRoute [GET] <DynamicResource /blog/{id} -> <function AbstractRoute.__init__.<locals>.handler_wrapper at 0x7fc186c39f28>> #request请求就是/blog/001514861142476bd95fab85f7542178dba245d02470c57000啊 #由注册的路径后面的定义的{id}转换成id名,id变量,则是函数内部变量。。。 #应该是web.Application匹配注册的方法的/blog/{id}路径,再看这个/blog/001514861142476bd95fab85f7542178dba245d02470c57000路径,匹配上去的吧。试个/blog/{cd}? #还别说,还真成{'cd': '001514861142476bd95fab85f7542178dba245d02470c57000'}了 #<MatchInfo {'cd': '001514861142476bd95fab85f7542178dba245d02470c57000'}: <ResourceRoute [GET] <DynamicResource /blog/{cd} -> <function AbstractRoute.__init__.<locals>.handler_wrapper at 0x7f39d0a18f28>> #看来,后注册的同样路径,能覆盖之前注册的 else: if not self._has_var_kw_arg and self._named_kw_args: #remove all unamed kw: copy = dict() for name in self._named_kw_args: if name in kw: copy[name] = kw[name] kw = copy #check named arg: for k, v in request.match_info.items(): if k in kw: logging.warning( 'Duplicate arg name in named arg and kw args: %s' % k) kw[k] = v if self._has_request_arg: kw['request'] = request #check required kw: if self._required_kw_args: for name in self._required_kw_args: if not name in kw: return web.HTTPBadRequest('Missing argument: %s' % name) logging.info('call with args: %s' % str(kw)) try: #print('kw',kw) r = await self._func(**kw) #这里还没有调用哦,只是生成了这个对象 #然后,把这种方法注册到app上,调用这方法时要加request参数哦 #然后,app把request和id的值给它的吧 return r except APIError as e: return dict(error=e.error, data=e.data, message=e.message)
async def cancel_handler(self, request): if request.method == 'OPTIONS': return web.Response(status=200, headers=self.get_cors_headers(request)) return web.HTTPBadRequest(headers=self.get_cors_headers(request))
async def run_code(req: web.Request) -> web.Response: start_time = time.time() language = validate_language(req.match_info["language_name"]) body = await req.read() if not body: data: Dict[str, Any] = {} else: try: data = json.loads(body) except JSONDecodeError: raise web.HTTPBadRequest(reason="Bad json in body: unable to decode") if not isinstance(data, dict): raise web.HTTPBadRequest(reason="Bad json in body: root object is not map") payload = { "code": data.pop("code", language.example), "input": data.pop("input", ""), } if language.compiled: payload["compilers"] = data.pop("compilers", language.compilers) payload["compile_args"] = data.pop("compile_args", language.compile_args) if len(payload["compilers"]) != len(payload["compile_args"]): raise web.HTTPBadRequest(reason="Mismatch of compilers and compile_args") payload["merge_output"] = get_query_bool_flag(req, "merge", False) backend_run_url = ( f"{req.config_dict['config']['app']['run-lb-ip']}/run/{language.name}" ) log.debug("sending request to %s", backend_run_url) async with ClientSession() as cs: async with cs.post(backend_run_url, json=payload) as resp: if resp.status == 503: log.warn("status 503, no free servers") raise web.HTTPServiceUnavailable( reason="Service is too busy. Try again later" ) elif resp.status != 200: log.error("bad response status: %d: %s", resp.status, resp.reason) raise web.HTTPInternalServerError( reason=f"Backend response error: {resp.reason}" ) try: response_json = await resp.json() except JSONDecodeError: log.error("bad json returned by backend: %s", await req.text()) raise web.HTTPInternalServerError( reason="Backend response decoding error" ) return web.json_response( {"processing_time": time.time() - start_time, **response_json} )
async def handler(request): try: await request.post() except ValueError: return web.Response() raise web.HTTPBadRequest()
async def user(request): lega_instance = request.match_info['lega'] users_dir = request.match_info['users_dir'] identifier = request.match_info['identifier'] if 'idType' in request.rel_url.query and request.rel_url.query[ 'idType'] == 'username': id_type = request.rel_url.query['idType'] LOG.info( f'User ID request: {lega_instance}, in {users_dir}, with request of id type {id_type} and name {identifier}.' ) try: with open(f'{users_dir}/{identifier}.yml', 'r') as stream: data = dict() data['header'] = fixed_header d = yaml.load(stream) # We are mocking this so we only need the result to be right data['response'] = { "numTotalResults": 1, "resultType": "eu.crg.ega.microservice.dto.lega.v1.users.LocalEgaUser", "result": [{ 'username': d.get("username", None), 'passwordHash': d.get("password_hash", None), 'sshPublicKey': d.get("pubkey", None), 'uid': int(d.get("uid", None)), 'gecos': d.get("gecos", "EGA User"), "enabled": None }] } return web.json_response(data) except OSError: raise web.HTTPBadRequest( text= f'No info for user {identifier} in LocalEGA {lega_instance}... yet\n' ) elif 'idType' in request.rel_url.query and request.rel_url.query[ 'idType'] == 'uid': id_type = request.rel_url.query['idType'] LOG.info( f'User ID request: {lega_instance}, in {users_dir}, with request of id type {id_type} and UID {identifier}.' ) try: with open(f'{users_dir}_ids/{identifier}.yml', 'r') as stream: data = dict() data['header'] = fixed_header d = yaml.load(stream) # We are mocking this so we only need the result to be right data['response'] = { "numTotalResults": 1, "resultType": "eu.crg.ega.microservice.dto.lega.v1.users.LocalEgaUser", "result": [{ 'username': d.get("username", None), 'passwordHash': d.get("password_hash", None), 'sshPublicKey': d.get("pubkey", None), 'uid': int(d.get("uid", None)), 'gecos': d.get("gecos", "EGA User"), "enabled": None }] } return web.json_response(data) except OSError: raise web.HTTPBadRequest( text= f'No info for user id {identifier} in LocalEGA {lega_instance}... yet\n' ) else: raise web.HTTPBadRequest(text='Missing or wrong idType')
async def add_service(request): """ Create a new service to run a specific plugin :Example: curl -X POST http://localhost:8081/foglamp/service -d '{"name": "DHT 11", "plugin": "dht11", "type": "south", "enabled": true}' curl -sX POST http://localhost:8081/foglamp/service -d '{"name": "Sine", "plugin": "sinusoid", "type": "south", "enabled": true, "config": {"dataPointsPerSec": {"value": "10"}}}' | jq curl -X POST http://localhost:8081/foglamp/service -d '{"name": "NotificationServer", "type": "notification", "enabled": true}' | jq """ try: data = await request.json() if not isinstance(data, dict): raise ValueError('Data payload must be a valid JSON') name = data.get('name', None) plugin = data.get('plugin', None) service_type = data.get('type', None) enabled = data.get('enabled', None) config = data.get('config', None) if name is None: raise web.HTTPBadRequest(reason='Missing name property in payload.') if utils.check_reserved(name) is False: raise web.HTTPBadRequest(reason='Invalid name property in payload.') if service_type is None: raise web.HTTPBadRequest(reason='Missing type property in payload.') service_type = str(service_type).lower() if service_type == 'north': raise web.HTTPNotAcceptable(reason='north type is not supported for the time being.') if service_type not in ['south', 'notification']: raise web.HTTPBadRequest(reason='Only south and notification type are supported.') if plugin is None and service_type == 'south': raise web.HTTPBadRequest(reason='Missing plugin property for type south in payload.') if plugin and utils.check_reserved(plugin) is False: raise web.HTTPBadRequest(reason='Invalid plugin property in payload.') if enabled is not None: if enabled not in ['true', 'false', True, False]: raise web.HTTPBadRequest(reason='Only "true", "false", true, false' ' are allowed for value of enabled.') is_enabled = True if ((type(enabled) is str and enabled.lower() in ['true']) or ( (type(enabled) is bool and enabled is True))) else False # Check if a valid plugin has been provided plugin_module_path, plugin_config, process_name, script = "", {}, "", "" if service_type == 'south': # "plugin_module_path" is fixed by design. It is MANDATORY to keep the plugin in the exactly similar named # folder, within the plugin_module_path. # if multiple plugin with same name are found, then python plugin import will be tried first plugin_module_path = "foglamp.plugins.south" try: plugin_info = load_python_plugin(plugin_module_path, plugin, service_type) plugin_config = plugin_info['config'] if not plugin_config: _logger.exception("Plugin %s import problem from path %s", plugin, plugin_module_path) raise web.HTTPNotFound(reason='Plugin "{}" import problem from path "{}".'.format(plugin, plugin_module_path)) process_name = 'south_c' script = '["services/south_c"]' except ImportError as ex: # Checking for C-type plugins plugin_config = load_c_plugin(plugin, service_type) if not plugin_config: _logger.exception("Plugin %s import problem from path %s. %s", plugin, plugin_module_path, str(ex)) raise web.HTTPNotFound(reason='Plugin "{}" import problem from path "{}".'.format(plugin, plugin_module_path)) process_name = 'south_c' script = '["services/south_c"]' except TypeError as ex: _logger.exception(str(ex)) raise web.HTTPBadRequest(reason=str(ex)) except Exception as ex: _logger.exception("Failed to fetch plugin configuration. %s", str(ex)) raise web.HTTPInternalServerError(reason='Failed to fetch plugin configuration') elif service_type == 'notification': process_name = 'notification_c' script = '["services/notification_c"]' storage = connect.get_storage_async() config_mgr = ConfigurationManager(storage) # Check whether category name already exists category_info = await config_mgr.get_category_all_items(category_name=name) if category_info is not None: raise web.HTTPBadRequest(reason="The '{}' category already exists".format(name)) # Check that the schedule name is not already registered count = await check_schedules(storage, name) if count != 0: raise web.HTTPBadRequest(reason='A service with this name already exists.') # Check that the process name is not already registered count = await check_scheduled_processes(storage, process_name) if count == 0: # Now first create the scheduled process entry for the new service payload = PayloadBuilder().INSERT(name=process_name, script=script).payload() try: res = await storage.insert_into_tbl("scheduled_processes", payload) except StorageServerError as ex: _logger.exception("Failed to create scheduled process. %s", ex.error) raise web.HTTPInternalServerError(reason='Failed to create service.') except Exception as ex: _logger.exception("Failed to create scheduled process. %s", str(ex)) raise web.HTTPInternalServerError(reason='Failed to create service.') # check that notification service is not already registered, right now notification service LIMIT to 1 if service_type == 'notification': res = await check_notification_schedule(storage) for ps in res['rows']: if 'notification_c' in ps['process_name']: raise web.HTTPBadRequest(reason='A Notification service schedule already exists.') elif service_type == 'south': try: # Create a configuration category from the configuration defined in the plugin category_desc = plugin_config['plugin']['description'] await config_mgr.create_category(category_name=name, category_description=category_desc, category_value=plugin_config, keep_original_items=True) # Create the parent category for all South services await config_mgr.create_category("South", {}, "South microservices", True) await config_mgr.create_child_category("South", [name]) # If config is in POST data, then update the value for each config item if config is not None: if not isinstance(config, dict): raise ValueError('Config must be a JSON object') for k, v in config.items(): await config_mgr.set_category_item_value_entry(name, k, v['value']) except Exception as ex: await config_mgr.delete_category_and_children_recursively(name) _logger.exception("Failed to create plugin configuration. %s", str(ex)) raise web.HTTPInternalServerError(reason='Failed to create plugin configuration.') # If all successful then lastly add a schedule to run the new service at startup try: schedule = StartUpSchedule() schedule.name = name schedule.process_name = process_name schedule.repeat = datetime.timedelta(0) schedule.exclusive = True # if "enabled" is supplied, it gets activated in save_schedule() via is_enabled flag schedule.enabled = False # Save schedule await server.Server.scheduler.save_schedule(schedule, is_enabled) schedule = await server.Server.scheduler.get_schedule_by_name(name) except StorageServerError as ex: await config_mgr.delete_category_and_children_recursively(name) _logger.exception("Failed to create schedule. %s", ex.error) raise web.HTTPInternalServerError(reason='Failed to create service.') except Exception as ex: await config_mgr.delete_category_and_children_recursively(name) _logger.exception("Failed to create service. %s", str(ex)) raise web.HTTPInternalServerError(reason='Failed to create service.') except ValueError as e: raise web.HTTPBadRequest(reason=str(e)) else: return web.json_response({'name': name, 'id': str(schedule.schedule_id)})
def fetch_string(data): if data and "data" in data and len(data["data"]) > 0: return base64.b64decode(data["data"]).decode("utf-8") else: raise web.HTTPBadRequest("arithmetic string is not valid")
async def auth_middleware(request, handler): """ Проверяем токен в каждом запросе :param request: :param handler: :return: """ metrics = request.app.get('metrics') await metrics.inc('requests') # в каждый реквест будем добавлять поле auth request.auth = None if check_request( request, WHITE_LIST_ROUTES): # если белый роут, пропускаем без токена return await handler(request) if request.method == 'OPTIONS': return await handler(request) # дергаем из заголовка авторизацию if 'Authorization' not in request.headers: raise web.HTTPForbidden(reason='Please login first', ) try: scheme, jwt_token = request.headers.get('Authorization').strip().split( ' ') except ValueError: raise web.HTTPForbidden(reason='Please login first', ) if not jwt_token: msg = 'Please login!' return web.HTTPUnauthorized(reason=msg, body=msg) try: jwt_token = jwt_token.strip('"').strip("'") # так как подделать payload не могут, вся инфа у нас уже будет внутри, в БД за данными юзера ходить не надо request.auth = jwt.decode(jwt_token, JWT_SECRET, algorithms=[JWT_ALGORITHM]) # проверим, что токен выдан нами :) cache = request.app.get('cache') token_from_redis = await cache.get_cache( 'uid_token_' + str(request.auth.get('id'))) or [] if jwt_token not in token_from_redis: # если в редисе нет нашего токена, значит надо обновить юзеру профиль #TODO: на будущее - обновление токена автоматом #main_handler = Main() #return await main_handler.refresh(request) msg = 'Session expired! Please, login' return web.HTTPUnauthorized(reason=msg, body=msg) except jwt.DecodeError: msg = 'Security problem. Please, relogin!' return web.HTTPUnauthorized(reason=msg, body=msg) except jwt.ExpiredSignatureError: msg = 'Security problem. Your session has expired. Please login!' return web.HTTPUnauthorized(reason=msg, body=msg) except Exception as e: return web.HTTPBadRequest(reason=str(e), body=str(e)) return await handler(request)
async def presentation_exchange_send_free_request(request: web.BaseRequest): """ Request handler for sending a presentation request free from any proposal. Args: request: aiohttp request object Returns: The presentation exchange details """ r_time = get_timer() context: AdminRequestContext = request["context"] profile = context.profile outbound_handler = request["outbound_message_router"] body = await request.json() connection_id = body.get("connection_id") async with profile.session() as session: try: connection_record = await ConnRecord.retrieve_by_id( session, connection_id) except StorageNotFoundError as err: raise web.HTTPBadRequest(reason=err.roll_up) from err if not connection_record.is_ready: raise web.HTTPForbidden(reason=f"Connection {connection_id} not ready") comment = body.get("comment") indy_proof_request = body.get("proof_request") if not indy_proof_request.get("nonce"): indy_proof_request["nonce"] = await generate_pr_nonce() presentation_request_message = PresentationRequest( comment=comment, request_presentations_attach=[ AttachDecorator.data_base64( mapping=indy_proof_request, ident=ATTACH_DECO_IDS[PRESENTATION_REQUEST], ) ], ) trace_msg = body.get("trace") presentation_request_message.assign_trace_decorator( context.settings, trace_msg, ) auto_verify = body.get( "auto_verify", context.settings.get("debug.auto_verify_presentation")) pres_ex_record = None try: presentation_manager = PresentationManager(profile) pres_ex_record = await presentation_manager.create_exchange_for_request( connection_id=connection_id, presentation_request_message=presentation_request_message, auto_verify=auto_verify, ) result = pres_ex_record.serialize() except (BaseModelError, StorageError) as err: if pres_ex_record: async with profile.session() as session: await pres_ex_record.save_error_state(session, reason=err.roll_up) # other party does not care about our false protocol start raise web.HTTPBadRequest(reason=err.roll_up) await outbound_handler(presentation_request_message, connection_id=connection_id) trace_event( context.settings, presentation_request_message, outcome="presentation_exchange_send_request.END", perf_counter=r_time, ) return web.json_response(result)
async def bad_request(req_text): await logger.warning(f'Failed due to {req_text}') return web.HTTPBadRequest(reason=req_text) # 400