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")
Exemple #2
0
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})
Exemple #4
0
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.'
        )
Exemple #6
0
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})
Exemple #8
0
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
Exemple #9
0
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))
Exemple #10
0
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")
Exemple #13
0
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})
Exemple #15
0
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))
Exemple #16
0
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")
Exemple #17
0
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")
Exemple #18
0
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