def validate_fields(required_fields, request_json): try: for field in required_fields: if request_json.get(field) is None: raise ApiBadRequest("{} is required".format(field)) except (ValueError, AttributeError): raise ApiBadRequest("Improper JSON format")
def validate_fields(required_fields, body): try: for field in required_fields: if body.get(field) is None: raise ApiBadRequest( "Bad Request: {} field is required".format(field)) except ValueError: raise ApiBadRequest("Bad Request: Improper JSON format")
async def get_block(request, block_id): if '?head=' in request.url: raise ApiBadRequest( "Bad Request: 'head' parameter should not be specified") block_resource = await blocks_query.fetch_block_by_id( request.app.config.DB_CONN, block_id) return json({'data': block_resource, 'link': request.url})
def proto_wrap_rules(rules): rule_protos = [] if rules is not None: for rule in rules: try: rule_proto = rule_pb2.Rule(type=rule['type']) except IndexError: raise ApiBadRequest("Improper rule format") except ValueError: raise ApiBadRequest("Invalid rule type") except KeyError: raise ApiBadRequest("Rule type is required") if rule.get('value') is not None: rule_proto.value = value_to_csv(rule['value']) rule_protos.append(rule_proto) return rule_protos
async def send(conn, batch_list, timeout): batch_request = client_pb2.ClientBatchSubmitRequest() batch_request.batches.extend(list(batch_list.batches)) batch_request.wait_for_commit = True validator_response = await conn.send( validator_pb2.Message.CLIENT_BATCH_SUBMIT_REQUEST, batch_request.SerializeToString(), timeout ) client_response = client_pb2.ClientBatchSubmitResponse() client_response.ParseFromString(validator_response.content) resp = client_response.batch_statuses[0] if resp.status == client_pb2.BatchStatus.COMMITTED: return resp elif resp.status == client_pb2.BatchStatus.INVALID: raise ApiBadRequest('Bad Request: {}'.format( resp.invalid_transactions[0].message )) elif resp.status == client_pb2.BatchStatus.PENDING: raise ApiInternalError( 'Internal Error: Transaction submitted but timed out.' ) elif resp.status == client_pb2.BatchStatus.UNKNOWN: raise ApiInternalError( 'Internal Error: Something went wrong. Try again later.' )
async def send(conn, batch_list, timeout): batch_request = client_batch_submit_pb2.ClientBatchSubmitRequest() batch_request.batches.extend(list(batch_list.batches)) validator_response = await conn.send( validator_pb2.Message.CLIENT_BATCH_SUBMIT_REQUEST, batch_request.SerializeToString(), timeout) client_response = client_batch_submit_pb2.ClientBatchSubmitResponse() client_response.ParseFromString(validator_response.content) if client_response.status == client_batch_submit_pb2.ClientBatchSubmitResponse.INTERNAL_ERROR: raise ApiInternalError('Internal Error') elif client_response.status == client_batch_submit_pb2.ClientBatchSubmitResponse.INVALID_BATCH: raise ApiBadRequest('Invalid Batch') elif client_response.status == client_batch_submit_pb2.ClientBatchSubmitResponse.QUEUE_FULL: raise ApiInternalError('Queue Full') status_request = client_batch_submit_pb2.ClientBatchStatusRequest() status_request.batch_ids.extend( list(b.header_signature for b in batch_list.batches)) status_request.wait = True status_request.timeout = timeout validator_response = await conn.send( validator_pb2.Message.CLIENT_BATCH_STATUS_REQUEST, status_request.SerializeToString(), timeout) status_response = client_batch_submit_pb2.ClientBatchStatusResponse() status_response.ParseFromString(validator_response.content) if status_response.status != client_batch_submit_pb2.ClientBatchStatusResponse.OK: raise ApiInternalError('Internal Error') resp = status_response.batch_statuses[0] if resp.status == client_batch_submit_pb2.ClientBatchStatus.COMMITTED: return resp elif resp.status == client_batch_submit_pb2.ClientBatchStatus.INVALID: raise ApiBadRequest('Bad Request: {}'.format( resp.invalid_transactions[0].message)) elif resp.status == client_batch_submit_pb2.ClientBatchStatus.PENDING: raise ApiInternalError( 'Internal Error: Transaction submitted but timed out.') elif resp.status == client_batch_submit_pb2.ClientBatchStatus.UNKNOWN: raise ApiInternalError( 'Internal Error: Something went wrong. Try again later.')
async def get_latest_block(request): if '?head=' in request.url: raise ApiBadRequest( "Bad Request: 'head' parameter should not be specified") block_resource = await blocks_query.fetch_latest_block( request.app.config.DB_CONN) url = request.url.replace('latest', block_resource.get('id')) return json({'data': block_resource, 'link': url})
def _create_offer_dict(body, public_key): keys = ['label', 'description', 'source', 'target', 'sourceQuantity', 'targetQuantity'] offer = {k: body[k] for k in keys if body.get(k) is not None} if offer['sourceQuantity'] < 1: raise ApiBadRequest("sourceQuantity must be a positive integer") if offer.get('targetQuantity') and offer['targetQuantity'] < 1: raise ApiBadRequest("targetQuantity must be a positive integer") offer['id'] = str(uuid4()) offer['owners'] = [public_key] offer['status'] = "OPEN" if body.get('rules'): offer['rules'] = common.proto_wrap_rules(body['rules']) return offer
async def fetch_feedback_resource(conn, asset): try: return await r.table('feedbacks')\ .get_all(asset, index='asset')\ .max('start_block_num')\ .do(lambda feedback: (feedback['text'] == "").branch( feedback.without('text'), feedback))\ .without('start_block_num', 'end_block_num', 'delta_id')\ .run(conn) except ReqlNonExistenceError: raise ApiBadRequest( "Bad Request: " "No feedback with the asset name {} exists".format(asset))
async def update_auth_info(conn, email, public_key, update): result = await r.table('auth')\ .get(email)\ .do(lambda auth_info: r.expr(update.get('email')).branch( r.expr(r.table('auth').insert(auth_info.merge(update), return_changes=True)), r.table('auth').get(email).update(update, return_changes=True)))\ .do(lambda auth_info: auth_info['errors'].gt(0).branch( auth_info, auth_info['changes'][0]['new_val'].pluck('email')))\ .merge(_fetch_account_info(public_key))\ .run(conn) if result.get('errors'): if "Duplicate primary key `email`" in result.get('first_error'): raise ApiBadRequest( "Bad Request: A user with that email already exists") else: raise ApiBadRequest("Bad Request: {}".format( result.get('first_error'))) if update.get('email'): await remove_auth_entry(conn, email) return result
async def fetch_asset_resource(conn, name): try: return await r.table('assets')\ .get_all(name, index='name')\ .max('start_block_num')\ .do(lambda asset: (asset['description'] == "").branch( asset.without('description'), asset))\ .do(lambda asset: (asset['rules'] == []).branch( asset, asset.merge(parse_rules(asset['rules']))))\ .without('start_block_num', 'end_block_num', 'delta_id')\ .run(conn) except ReqlNonExistenceError: raise ApiBadRequest("Bad Request: " "No asset with the name {} exists".format(name))
async def check_batch_status(conn, batch_id): status_request = client_batch_submit_pb2.ClientBatchStatusRequest( batch_ids=[batch_id], wait=True) validator_response = await conn.send( validator_pb2.Message.CLIENT_BATCH_STATUS_REQUEST, status_request.SerializeToString()) status_response = client_batch_submit_pb2.ClientBatchStatusResponse() status_response.ParseFromString(validator_response.content) batch_status = status_response.batch_statuses[0].status if batch_status == client_batch_submit_pb2.ClientBatchStatus.INVALID: invalid = status_response.batch_statuses[0].invalid_transactions[0] raise ApiBadRequest(invalid.message) elif batch_status == client_batch_submit_pb2.ClientBatchStatus.PENDING: raise ApiInternalError("Transaction submitted but timed out") elif batch_status == client_batch_submit_pb2.ClientBatchStatus.UNKNOWN: raise ApiInternalError("Something went wrong. Try again later")
async def fetch_account_resource(conn, public_key, auth_key): try: return await r.table('accounts')\ .get_all(public_key, index='public_key')\ .max('start_block_num')\ .merge({'publicKey': r.row['public_key']})\ .merge({'holdings': fetch_holdings(r.row['holdings'])})\ .do(lambda account: (r.expr(auth_key).eq(public_key)).branch( account.merge(_fetch_email(public_key)), account))\ .do(lambda account: (account['label'] == "").branch( account.without('label'), account))\ .do(lambda account: (account['description'] == "").branch( account.without('description'), account))\ .without('public_key', 'delta_id', 'start_block_num', 'end_block_num')\ .run(conn) except ReqlNonExistenceError: raise ApiBadRequest( "No account with the public key {} exists".format(public_key))
async def update_proposal(request, proposal_id): required_fields = ['reason', 'status'] utils.validate_fields(required_fields, request.json) if request.json['status'] not in [Status.REJECTED, Status.APPROVED]: raise ApiBadRequest( "Bad Request: status must be either 'REJECTED' or 'APPROVED'") txn_key = await utils.get_transactor_key(request=request) block = await utils.get_request_block(request) proposal_resource = await proposals_query.fetch_proposal_resource( request.app.config.DB_CONN, proposal_id=proposal_id, head_block_num=block.get('num')) batch_list, _ = PROPOSAL_TRANSACTION[proposal_resource.get('type')][ request.json['status']](txn_key, request.app.config.BATCHER_KEY_PAIR, proposal_id, proposal_resource.get('object'), proposal_resource.get('target'), request.json.get('reason')) await utils.send(request.app.config.VAL_CONN, batch_list, request.app.config.TIMEOUT) return json({'proposal_id': proposal_id})
async def fetch_offer_resource(conn, offer_id): try: return await r.table('offers')\ .get_all(offer_id, index='id')\ .max('start_block_num')\ .do(lambda offer: (offer['label'] == "").branch( offer.without('label'), offer))\ .do(lambda offer: (offer['description'] == "").branch( offer.without('description'), offer))\ .merge({'sourceQuantity': r.row['source_quantity']})\ .do(lambda offer: (offer['target'] == "").branch( offer.without('target'), offer))\ .do(lambda offer: (offer['target_quantity'] == "").branch( offer, offer.merge({'targetQuantity': offer['target_quantity']})))\ .do(lambda offer: (offer['rules'] == []).branch( offer, offer.merge(parse_rules(offer['rules']))))\ .without('delta_id', 'start_block_num', 'end_block_num', 'source_quantity', 'target_quantity')\ .run(conn) except ReqlNonExistenceError: raise ApiBadRequest("No offer with the id {} exists".format(offer_id))
async def create_auth_entry(conn, auth_entry): result = await r.table('auth').insert(auth_entry).run(conn) if result.get('errors') > 0 and \ "Duplicate primary key `email`" in result.get('first_error'): raise ApiBadRequest("A user with that email already exists")
def value_to_csv(value): if isinstance(value, (list, tuple)): csv = ",".join(map(str, value)) return bytes(csv, 'utf-8') else: raise ApiBadRequest("Rule value must be a JSON array")
def check_hash(file_bytes, hash): calculated_hash = hashlib.sha3_224(file_bytes).hexdigest() if calculated_hash != hash: raise ApiBadRequest( "File hash doesnt Match, Please send the right sha3_224 hash") return True