def fulfill_escrow_reward_condition(event, agreement_id, service_agreement,
                                    price, consumer_address, publisher_account,
                                    condition_ids):
    """

    :param event: AttributeDict with the event data.
    :param agreement_id: id of the agreement, hex str
    :param service_agreement: ServiceAgreement instance
    :param price: Asset price, int
    :param consumer_address: ethereum account address of consumer, hex str
    :param publisher_account: Account instance of the publisher
    :param condition_ids: is a list of bytes32 content-addressed Condition IDs, bytes32
    :return:
    """
    logger.debug(f"release reward after event {event}.")
    access_id, lock_id = condition_ids[:2]
    assert price == service_agreement.get_price(), 'price mismatch.'
    try:
        tx_hash = Keeper.get_instance().escrow_reward_condition.fulfill(
            agreement_id, price, publisher_account.address, consumer_address,
            lock_id, access_id, publisher_account)
        process_tx_receipt(
            tx_hash,
            Keeper.get_instance().escrow_reward_condition.FULFILLED_EVENT,
            'EscrowReward.Fulfilled')
    except Exception as e:
        # logger.error(f'Error when doing escrow_reward_condition.fulfills: {e}')
        raise e
Esempio n. 2
0
def init_ocn_tokens(ocn, account, amount=100):
    ocn.accounts.request_tokens(account, amount)
    Keeper.get_instance().token.token_approve(
        Keeper.get_instance().dispenser.address,
        amount,
        account
    )
Esempio n. 3
0
    def get_contract_dict_by_name(contract_name):
        """
        Retrieve the Contract instance for a given contract name.

        :param contract_name: str
        :return: the smart contract's definition from the json abi file, dict
        """

        network_name = Keeper.get_network_name(Keeper.get_network_id()).lower()
        artifacts_path = ConfigProvider.get_config().keeper_path

        # file_name = '{}.{}.json'.format(contract_name, network_name)
        # path = os.path.join(keeper.artifacts_path, file_name)
        path = ContractHandler._get_contract_file_path(artifacts_path,
                                                       contract_name,
                                                       network_name)
        if not (path and os.path.exists(path)):
            path = ContractHandler._get_contract_file_path(
                artifacts_path, contract_name, network_name.lower())

        if not (path and os.path.exists(path)):
            path = ContractHandler._get_contract_file_path(
                artifacts_path, contract_name, Keeper.DEFAULT_NETWORK_NAME)

        if not (path and os.path.exists(path)):
            raise FileNotFoundError(f'Keeper contract {contract_name} file '
                                    f'not found in {artifacts_path} '
                                    f'using network name {network_name}')

        with open(path) as f:
            contract_dict = json.loads(f.read())
            return contract_dict
Esempio n. 4
0
def fulfill_access_secret_store_condition(event, agreement_id, did,
                                          service_agreement, consumer_address,
                                          publisher_account):
    """
    Fulfill the access condition.

    :param event: AttributeDict with the event data.
    :param agreement_id: id of the agreement, hex str
    :param did: DID, str
    :param service_agreement: ServiceAgreement instance
    :param consumer_address: ethereum account address of consumer, hex str
    :param publisher_account: Account instance of the publisher
    """
    logger.debug(f"release reward after event {event}.")
    name_to_parameter = {
        param.name: param
        for param in
        service_agreement.condition_by_name['accessSecretStore'].parameters
    }
    document_id = add_0x_prefix(name_to_parameter['_documentId'].value)
    asset_id = add_0x_prefix(did_to_id(did))
    assert document_id == asset_id, f'document_id {document_id} <=> asset_id {asset_id} mismatch.'
    try:
        tx_hash = Keeper.get_instance().access_secret_store_condition.fulfill(
            agreement_id, document_id, consumer_address, publisher_account)
        process_tx_receipt(
            tx_hash,
            Keeper.get_instance().access_secret_store_condition.
            FULFILLED_EVENT, 'AccessSecretStoreCondition.Fulfilled')
    except Exception as e:
        # logger.error(f'Error when calling grantAccess condition function: {e}')
        raise e
Esempio n. 5
0
    def verify_contracts():
        """
        Verify that the contracts are deployed correctly in the network.

        :raise Exception: raise exception if the contracts are not deployed correctly.
        """
        artifacts_path = ConfigProvider.get_config().keeper_path
        logger.info(
            f'Keeper contract artifacts (JSON abi files) at: {artifacts_path}')

        if os.environ.get('KEEPER_NETWORK_NAME'):
            logger.warning(
                f'The `KEEPER_NETWORK_NAME` env var is set to '
                f'{os.environ.get("KEEPER_NETWORK_NAME")}. '
                f'This enables the user to override the method of how the network name '
                f'is inferred from network id.')

        # try to find contract with this network name
        contract_name = Diagnostics.TEST_CONTRACT_NAME
        network_id = Keeper.get_network_id()
        network_name = Keeper.get_network_name(network_id)
        logger.info(f'Using keeper contracts from network {network_name}, '
                    f'network id is {network_id}')
        logger.info(
            f'Looking for keeper contracts ending with ".{network_name}.json", '
            f'e.g. "{contract_name}.{network_name}.json".')
        existing_contract_names = os.listdir(artifacts_path)
        try:
            ContractHandler.get(contract_name)
        except Exception as e:
            logger.error(e)
            logger.error(
                f'Cannot find the keeper contracts. \n'
                f'Current network id is {network_id} and network name is {network_name}.'
                f'Expected to find contracts ending with ".{network_name}.json",'
                f' e.g. "{contract_name}.{network_name}.json"')
            raise OceanKeeperContractsNotFound(
                f'Keeper contracts for keeper network {network_name} were not found '
                f'in {artifacts_path}. \n'
                f'Found the following contracts: \n\t{existing_contract_names}'
            )

        keeper = Keeper.get_instance()
        contracts = [
            keeper.dispenser, keeper.token, keeper.did_registry,
            keeper.agreement_manager, keeper.template_manager,
            keeper.condition_manager, keeper.access_secret_store_condition,
            keeper.sign_condition, keeper.lock_reward_condition,
            keeper.escrow_access_secretstore_template,
            keeper.escrow_reward_condition, keeper.hash_lock_condition
        ]
        addresses = '\n'.join([f'\t{c.name}: {c.address}' for c in contracts])
        logging.info('Finished loading keeper contracts:\n' '%s', addresses)
Esempio n. 6
0
def process_agreement_events_publisher(publisher_account, agreement_id, did,
                                       service_agreement, price,
                                       consumer_address, condition_ids):
    """
    Process the agreement events during the register of the service agreement for the publisher side

    :param publisher_account: Account instance of the publisher
    :param agreement_id: id of the agreement, hex str
    :param did: DID, str
    :param service_agreement: ServiceAgreement instance
    :param price: Asset price, int
    :param consumer_address: ethereum account address of consumer, hex str
    :param condition_ids: is a list of bytes32 content-addressed Condition IDs, bytes32
    :return:
    """
    conditions_dict = service_agreement.condition_by_name
    keeper = Keeper.get_instance()
    keeper.lock_reward_condition.subscribe_condition_fulfilled(
        agreement_id, conditions_dict['lockReward'].timeout,
        access_secret_store_condition.fulfillAccessSecretStoreCondition,
        (agreement_id, did, service_agreement, consumer_address,
         publisher_account))

    keeper.access_secret_store_condition.subscribe_condition_fulfilled(
        agreement_id, conditions_dict['accessSecretStore'].timeout,
        escrow_reward_condition.fulfillEscrowRewardCondition,
        (agreement_id, service_agreement, price, consumer_address,
         publisher_account, condition_ids))

    keeper.escrow_reward_condition.subscribe_condition_fulfilled(
        agreement_id, conditions_dict['escrowReward'].timeout,
        verify_reward_condition.verifyRewardTokens,
        (agreement_id, did, service_agreement, price, consumer_address,
         publisher_account))
Esempio n. 7
0
def lock_reward(ocean, account, agreement_id):
    keeper = Keeper.get_instance()
    ocean_conditions = OceanConditions(keeper)
    amount = int(get_agreement_from_id(ocean, agreement_id).get_price())
    keeper.token.token_approve(keeper.lock_reward_condition.address, amount,
                               account)
    return ocean_conditions.lock_reward(agreement_id, amount, account)
def fulfill_lock_reward_condition(event, agreement_id, price, consumer_account):
    """
    Fulfill the lock reward condition.

    :param event: AttributeDict with the event data.
    :param agreement_id: id of the agreement, hex str
    :param price: Asset price, int
    :param consumer_account: Account instance of the consumer
    """
    logger.debug(f"about to lock reward after event {event}.")
    keeper = Keeper.get_instance()
    tx_hash = None
    try:
        keeper.token.token_approve(keeper.lock_reward_condition.address, price, consumer_account)
        tx_hash = keeper.lock_reward_condition.fulfill(
            agreement_id, keeper.escrow_reward_condition.address, price, consumer_account
        )
        process_tx_receipt(
            tx_hash,
            keeper.lock_reward_condition.FULFILLED_EVENT,
            'LockRewardCondition.Fulfilled'
        )
    except Exception as e:
        logger.debug(f'error locking reward: {e}')
        if not tx_hash:
            raise e
Esempio n. 9
0
def test_ec_recover():
    test_values = [
        ('0xe2DD09d719Da89e5a3D0F2549c7E24566e947260',
         'c80996119e884cb38599bcd96a22ad3eea3a4734bcfb47959a5d41ecdcbdfe67',
         '0xa50427a9d5beccdea3eeabecfc1014096b35cd05965e772e8ea32477d2f217'
         'c30d0ec5dbf6b14de1d6eeff45011d17490fe5126576b20d2cbada828cb068c9f801'
         ),
        ('0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e',
         'd77c3a84cafe4cb8bc28bf41a99c63fd530c10da33a54acf94e8d1369d09fbb2',
         '0x9076b561e554cf657af333d9680ba118d556c5b697622636bce4b02f4d5632'
         '5a0ea6a474ca85291252c8c1b8637174ee32072bef357bb0c21b0db4c25b379e781b'
         ),
        ('0xe2DD09d719Da89e5a3D0F2549c7E24566e947260',
         '8d5c1065a9c74da59fbb9e41d1f196e40517e92d81b14c3a8143d6887f3f4438',
         '0x662f6cffd96ada4b6ce5497d444c92126bd053ab131915332edf0dbba716ba'
         '82662275670c95eb2a4d65245cac70313c25e34f594d7c0fbca5232c3d5701a57e00'
         )
    ]

    for expected_address, document_id, signed_document_id in test_values:
        rec_address = Keeper.get_instance().ec_recover(document_id,
                                                       signed_document_id)
        print(
            f'recovered address: {rec_address}, original address {expected_address}'
        )
        assert expected_address.lower() == rec_address.lower()
Esempio n. 10
0
def test_keeper_networks():
    keeper = Keeper()
    assert isinstance(keeper.get_network_id(), int)
    assert keeper.get_network_name(1) == Keeper._network_name_map.get(1)
    assert keeper.get_network_name(2) == Keeper._network_name_map.get(2)
    assert keeper.get_network_name(3) == Keeper._network_name_map.get(3)
    assert keeper.get_network_name(4) == Keeper._network_name_map.get(4)
    assert keeper.get_network_name(42) == Keeper._network_name_map.get(42)
    assert keeper.get_network_name(77) == Keeper._network_name_map.get(77)
    assert keeper.get_network_name(99) == Keeper._network_name_map.get(99)
    assert keeper.get_network_name(8995) == Keeper._network_name_map.get(8995)
    assert keeper.get_network_name(8996) == Keeper._network_name_map.get(8996)
    assert keeper.get_network_name(0) == 'development'
Esempio n. 11
0
def get(did):
    register_values = Keeper.get_instance().did_registry.contract_concise\
        .getDIDRegister(did_to_id(did))
    response = []
    if register_values and len(register_values) == 5:
        response = DIDRegisterValues(*register_values)._asdict()
        response['last_checksum'] = Web3Provider.get_web3()\
            .toHex(response['last_checksum'])
    return response
Esempio n. 12
0
def buy_asset():
    """
    Requires all ocean services running.

    """
    ConfigProvider.set_config(ExampleConfig.get_config())
    config = ConfigProvider.get_config()

    # make ocean instance
    ocn = Ocean()
    acc = get_publisher_account(config)
    if not acc:
        acc = ([acc for acc in ocn.accounts.list() if acc.password] or ocn.accounts.list())[0]

    # Register ddo
    ddo = ocn.assets.create(Metadata.get_example(), acc, providers=[acc.address])
    logging.info(f'registered ddo: {ddo.did}')
    # ocn here will be used only to publish the asset. Handling the asset by the publisher
    # will be performed by the Brizo server running locally
    keeper = Keeper.get_instance()
    if 'TEST_LOCAL_NILE' in os.environ and os.environ['TEST_LOCAL_NILE'] == '1':
        provider = keeper.did_registry.to_checksum_address(
            '0x413c9ba0a05b8a600899b41b0c62dd661e689354'
        )
        keeper.did_registry.add_provider(ddo.asset_id, provider, acc)
        logging.debug(f'is did provider: '
                      f'{keeper.did_registry.is_did_provider(ddo.asset_id, provider)}')

    cons_ocn = Ocean()
    consumer_account = get_account_from_config(config, 'parity.address1', 'parity.password1')

    # sign agreement using the registered asset did above
    service = ddo.get_service(service_type=ServiceTypes.ASSET_ACCESS)
    # This will send the purchase request to Brizo which in turn will execute the agreement on-chain
    cons_ocn.accounts.request_tokens(consumer_account, 100)
    sa = ServiceAgreement.from_service_dict(service.as_dictionary())

    agreement_id = cons_ocn.assets.order(
        ddo.did, sa.service_definition_id, consumer_account)
    logging.info('placed order: %s, %s', ddo.did, agreement_id)
    i = 0
    while ocn.agreements.is_access_granted(
            agreement_id, ddo.did, consumer_account.address) is not True and i < 30:
        time.sleep(1)
        i += 1

    assert ocn.agreements.is_access_granted(agreement_id, ddo.did, consumer_account.address)

    ocn.assets.consume(
        agreement_id,
        ddo.did,
        sa.service_definition_id,
        consumer_account,
        config.downloads_path)
    logging.info('Success buying asset.')
Esempio n. 13
0
def test_consume(client, publisher_ocean_instance, consumer_ocean_instance):
    Brizo.set_http_client(client)
    endpoint = BaseURLs.ASSETS_URL + '/consume'

    pub_acc = get_publisher_account(ConfigProvider.get_config())
    cons_acc = get_consumer_account(ConfigProvider.get_config())

    asset = get_registered_ddo(publisher_ocean_instance,
                               pub_acc,
                               providers=[pub_acc.address])
    metadata = Metadata.get_example()
    files = metadata['base']['files']
    urls = [_file_dict['url'] for _file_dict in files]

    # This is a trick to give access to provider through the secretstore
    publisher_ocean_instance.assets.order(asset.did,
                                          'Access',
                                          pub_acc,
                                          auto_consume=False)

    # initialize an agreement
    agreement_id = consumer_ocean_instance.assets.order(asset.did,
                                                        'Access',
                                                        cons_acc,
                                                        auto_consume=False)
    payload = dict({
        'serviceAgreementId': agreement_id,
        'consumerAddress': cons_acc.address
    })

    signature = Keeper.get_instance().sign_hash(agreement_id, cons_acc)
    index = 2

    # Consume using decrypted url
    payload['url'] = urls[index]
    request_url = endpoint + '?' + '&'.join(
        [f'{k}={v}' for k, v in payload.items()])
    i = 0
    while i < 30 and not consumer_ocean_instance.agreements.is_access_granted(
            agreement_id, asset.did, cons_acc.address):
        time.sleep(1)
        i += 1

    response = client.get(request_url)
    assert response.status == '200 OK'

    # Consume using url index and signature (let brizo do the decryption)
    payload.pop('url')
    payload['signature'] = signature
    payload['index'] = index
    request_url = endpoint + '?' + '&'.join(
        [f'{k}={v}' for k, v in payload.items()])
    response = client.get(request_url)
    assert response.status == '200 OK'
Esempio n. 14
0
def release_reward(ocn, account, agreement_id):
    if agreement_id == 'all':
        response = False
        for _agreement_id in list_agreements(ocn, account, account.address):
            try:
                response = release_reward(ocn, account, _agreement_id)
            except Exception as e:
                print(e)
        return response
    amount = int(get_agreement_from_id(ocn, agreement_id).get_price())
    ocean_conditions = OceanConditions(Keeper.get_instance())
    return ocean_conditions.release_reward(agreement_id, amount, account)
Esempio n. 15
0
    def consume_service(service_agreement_id, service_endpoint, account, files,
                        destination_folder):
        """
        Call the brizo endpoint to get access to the different files that form the asset.

        :param service_agreement_id: Service Agreement Id, str
        :param service_endpoint: Url to consume, str
        :param account: Account instance of the consumer signing this agreement, hex-str
        :param files: List containing the files to be consumed, list
        :param destination_folder: Path, str
        """
        signature = Keeper.get_instance().sign_hash(service_agreement_id,
                                                    account)
        for i, _file in enumerate(files):
            if 'url' in _file:
                url = _file['url']
                if url.startswith('"') or url.startswith("'"):
                    url = url[1:-1]

                file_name = os.path.basename(url)
                consume_url = (f'{service_endpoint}'
                               f'?url={url}'
                               f'&serviceAgreementId={service_agreement_id}'
                               f'&consumerAddress={account.address}')
            else:
                file_name = f'file.{i}'
                consume_url = (f'{service_endpoint}'
                               f'?signature={signature}'
                               f'&serviceAgreementId={service_agreement_id}'
                               f'&consumerAddress={account.address}'
                               f'&index={i}')

            logger.info(
                f'invoke consume endpoint with this url: {consume_url}')
            response = Brizo._http_client.get(consume_url, stream=True)

            total_size = response.headers.get('content-length', 0)

            logger.info(f'Total size of {file_name}: {total_size} bytes.')
            bar = tqdm(total=int(total_size),
                       unit='KB',
                       leave=False,
                       smoothing=0.1)
            if response.status_code == 200:
                with open(os.path.join(destination_folder, file_name),
                          'wb') as f:
                    for chunk in response.iter_content():
                        f.write(chunk)
                        bar.update(len(chunk))
                logger.info(f'Saved downloaded file in {f.name}')
            else:
                logger.warning(f'consume failed: {response.reason}')
def refund_reward(event, agreement_id, did, service_agreement, price,
                  consumer_account, publisher_address, condition_ids):
    """
    Refund the reward to the publisher address.

    :param event: AttributeDict with the event data.
    :param agreement_id: id of the agreement, hex str
    :param did: DID, str
    :param service_agreement: ServiceAgreement instance
    :param price: Asset price, int
    :param consumer_account: Account instance of the consumer
    :param publisher_address: ethereum account address of publisher, hex str
    :param condition_ids: is a list of bytes32 content-addressed Condition IDs, bytes32
    """
    logger.debug(f"trigger refund after event {event}.")
    access_id, lock_id = condition_ids[:2]
    name_to_parameter = {
        param.name: param
        for param in
        service_agreement.condition_by_name['escrowReward'].parameters
    }
    document_id = add_0x_prefix(name_to_parameter['_documentId'].value)
    asset_id = add_0x_prefix(did_to_id(did))
    assert document_id == asset_id, f'document_id {document_id} <=> asset_id {asset_id} mismatch.'
    assert price == service_agreement.get_price(), 'price mismatch.'
    # logger.info(f'About to do grantAccess: account {account.address},
    # saId {service_agreement_id}, '
    #             f'documentKeyId {document_key_id}')
    try:
        tx_hash = Keeper.get_instance().escrow_reward_condition.fulfill(
            agreement_id, price, publisher_address, consumer_account.address,
            lock_id, access_id, consumer_account)
        process_tx_receipt(
            tx_hash,
            Keeper.get_instance().escrow_reward_condition.FULFILLED_EVENT,
            'EscrowReward.Fulfilled')
    except Exception as e:
        # logger.error(f'Error when doing escrow_reward_condition.fulfills: {e}')
        raise e
Esempio n. 17
0
def handle_lock_reward(agreement_id=None,
                       agreement=None,
                       ocean=None,
                       *args,
                       **kwargs):
    ocean_conditions = OceanConditions(Keeper.get_instance())
    consumer = agreement['consumer']
    did = agreement['did']
    print(
        f'Access: {agreement_id} for {consumer}',
        ocean_conditions.grant_access(agreement_id, did, consumer,
                                      ocean.account))
    print(f'Release: {agreement_id}', release_reward(agreement_id,
                                                     ocean=ocean))
Esempio n. 18
0
def access(ocn, account, agreement_id, consumer):
    if agreement_id == 'all':
        response = False
        for _agreement_id in list_agreements(ocn, account, account.address):
            try:
                response = access(ocn, account, _agreement_id, consumer)
            except Exception as e:
                print(e)
        return response
    ocean_conditions = OceanConditions(Keeper.get_instance())
    agreement = ocn.agreements.get(agreement_id)
    return ocean_conditions.grant_access(agreement_id,
                                         id_to_did(agreement.did), consumer,
                                         account)
def ocean_agreements():
    keeper = Keeper.get_instance()
    w3 = Web3Provider.get_web3()
    did_resolver = Mock()
    ddo = get_ddo_sample()
    service = ddo.get_service(ServiceTypes.ASSET_ACCESS)
    service.update_value(
        ServiceAgreementTemplate.TEMPLATE_ID_KEY,
        w3.toChecksumAddress("0x00bd138abd70e2f00903268f3db08f2d25677c9e"))
    did_resolver.resolve = MagicMock(return_value=ddo)
    consumer_class = Mock
    consumer_class.download = MagicMock(return_value='')
    return OceanAgreements(keeper, did_resolver, AssetConsumer,
                           ConfigProvider.get_config())
Esempio n. 20
0
def get_account_from_config(config, config_account_key, config_account_password_key):
    address = None
    if config.has_option('keeper-contracts', config_account_key):
        address = config.get('keeper-contracts', config_account_key)

    if not address:
        return None

    password = None
    address = Web3Provider.get_web3().toChecksumAddress(address) if address else None
    if (address
            and address in Keeper.get_instance().accounts
            and config.has_option('keeper-contracts', config_account_password_key)):
        password = config.get('keeper-contracts', config_account_password_key)

    return Account(address, password)
Esempio n. 21
0
def execute_pending_service_agreements(storage_path, account, actor_type,
                                       did_resolver_fn):
    """
     Iterates over pending service agreements recorded in the local storage,
    fetches their service definitions, and subscribes to service agreement events.

    :param storage_path: storage path for the internal db, str
    :param account:
    :param actor_type:
    :param did_resolver_fn:
    :return:
    """
    keeper = Keeper.get_instance()
    # service_agreement_id, did, service_definition_id, price, files, start_time, status
    for (agreement_id, did, _, price, files, start_time,
         _) in get_service_agreements(storage_path):

        ddo = did_resolver_fn(did)
        for service in ddo.services:
            if service.type != 'Access':
                continue

            consumer_provider_tuple = keeper.escrow_access_secretstore_template.get_agreement_data(
                agreement_id)
            if not consumer_provider_tuple:
                continue

            consumer, provider = consumer_provider_tuple
            did = ddo.did
            service_agreement = ServiceAgreement.from_service_dict(
                service.as_dictionary())
            condition_ids = service_agreement.generate_agreement_condition_ids(
                agreement_id, did, consumer, provider, keeper)

            if actor_type == 'consumer':
                assert account.address == consumer
                process_agreement_events_consumer(provider, agreement_id, did,
                                                  service_agreement, price,
                                                  account, condition_ids, None)
            else:
                assert account.address == provider
                process_agreement_events_publisher(account, agreement_id, did,
                                                   service_agreement, price,
                                                   consumer, condition_ids)
Esempio n. 22
0
def process_agreement_events_consumer(publisher_address, agreement_id, did,
                                      service_agreement, price,
                                      consumer_account, condition_ids,
                                      consume_callback):
    """
    Process the agreement events during the register of the service agreement for the consumer side.

    :param publisher_address: ethereum account address of publisher, hex str
    :param agreement_id: id of the agreement, hex str
    :param did: DID, str
    :param service_agreement: ServiceAgreement instance
    :param price: Asset price, int
    :param consumer_account: Account instance of the consumer
    :param condition_ids: is a list of bytes32 content-addressed Condition IDs, bytes32
    :param consume_callback:
    :return:
    """
    conditions_dict = service_agreement.condition_by_name
    keeper = Keeper.get_instance()
    keeper.escrow_access_secretstore_template.subscribe_agreement_created(
        agreement_id, 60, lock_reward_condition.fulfillLockRewardCondition,
        (agreement_id, price, consumer_account))

    if consume_callback:

        def _refund_callback(_price, _publisher_address, _condition_ids):
            def do_refund(_event, _agreement_id, _did, _service_agreement,
                          _consumer_account, *_):
                escrow_reward_condition.refund_reward(
                    _event, _agreement_id, _did, _service_agreement, _price,
                    _consumer_account, _publisher_address, _condition_ids)

            return do_refund

        keeper.access_secret_store_condition.subscribe_condition_fulfilled(
            agreement_id, conditions_dict['accessSecretStore'].timeout,
            escrow_reward_condition.consume_asset,
            (agreement_id, did, service_agreement, consumer_account,
             consume_callback),
            _refund_callback(price, publisher_address, condition_ids))
Esempio n. 23
0
    def build_access_service(did, price, purchase_endpoint, service_endpoint,
                             timeout, template_id):
        """
        Build the access service.

        :param did: DID, str
        :param price: Asset price, int
        :param purchase_endpoint: url of the service provider, str
        :param service_endpoint: identifier of the service inside the asset DDO, str
        :param timeout: amount of time in seconds before the agreement expires, int
        :param template_id: id of the template use to create the service, str
        :return: ServiceAgreement
        """
        # TODO fill all the possible mappings
        param_map = {
            '_documentId':
            did_to_id(did),
            '_amount':
            price,
            '_rewardAddress':
            Keeper.get_instance().escrow_reward_condition.address,
        }
        sla_template_path = get_sla_template_path()
        sla_template = ServiceAgreementTemplate.from_json_file(
            sla_template_path)
        sla_template.template_id = template_id
        conditions = sla_template.conditions[:]
        for cond in conditions:
            for param in cond.parameters:
                param.value = param_map.get(param.name, '')

            if cond.timeout > 0:
                cond.timeout = timeout

        sla_template.set_conditions(conditions)
        sa = ServiceAgreement(1, sla_template, purchase_endpoint,
                              service_endpoint, ServiceTypes.ASSET_ACCESS)
        sa.set_did(did)
        return sa
Esempio n. 24
0
def test_publish(client, publisher_ocean_instance):
    ocn = publisher_ocean_instance
    endpoint = BaseURLs.ASSETS_URL + '/publish'
    did = DID.did()
    asset_id = did_to_id(did)
    account = get_provider_account(ocn)
    test_urls = ['url 0', 'url 1', 'url 2']
    urls_json = json.dumps(test_urls)
    signature = Keeper.get_instance().sign_hash(asset_id, account)
    address = Web3Provider.get_web3().personal.ecRecover(asset_id, signature)
    assert address.lower() == account.address.lower()

    payload = {
        'documentId': asset_id,
        'signedDocumentId': signature,
        'document': urls_json,
        'publisherAddress': account.address
    }
    post_response = client.post(endpoint,
                                data=json.dumps(payload),
                                content_type='application/json')
    encrypted_url = post_response.data.decode('utf-8')
    assert encrypted_url.startswith('0x')
Esempio n. 25
0
def setup_things():
    config = ConfigProvider.get_config()
    consumer_acc = get_consumer_account(config)
    publisher_acc = get_publisher_account(config)
    keeper = Keeper.get_instance()

    service_definition_id = 'Access'

    ddo = get_ddo_sample()
    ddo._did = DID.did()
    keeper.did_registry.register(ddo.did,
                                 checksum=Web3Provider.get_web3().sha3(
                                     text=ddo.metadata['base']['checksum']),
                                 url='aquarius:5000',
                                 account=publisher_acc,
                                 providers=None)

    registered_ddo = ddo
    asset_id = registered_ddo.asset_id
    service_agreement = ServiceAgreement.from_ddo(service_definition_id, ddo)
    agreement_id = ServiceAgreement.create_new_agreement_id()
    price = service_agreement.get_price()
    access_cond_id, lock_cond_id, escrow_cond_id = \
        service_agreement.generate_agreement_condition_ids(
            agreement_id, asset_id, consumer_acc.address, publisher_acc.address, keeper
        )

    return (
        keeper,
        publisher_acc,
        consumer_acc,
        agreement_id,
        asset_id,
        price,
        service_agreement,
        (lock_cond_id, access_cond_id, escrow_cond_id),
    )
def consume_asset(event, agreement_id, did, service_agreement,
                  consumer_account, consume_callback):
    """
    Consumption of an asset after get the event call.

    :param event: AttributeDict with the event data.
    :param agreement_id: id of the agreement, hex str
    :param did: DID, str
    :param service_agreement: ServiceAgreement instance
    :param consumer_account: Account instance of the consumer
    :param consume_callback:
    """
    logger.debug(f"consuming asset after event {event}.")
    if consume_callback:
        config = ConfigProvider.get_config()
        secret_store = SecretStoreProvider.get_secret_store(
            config.secret_store_url, config.parity_url, consumer_account)
        brizo = BrizoProvider.get_brizo()

        consume_callback(
            agreement_id, service_agreement.service_definition_id,
            DIDResolver(Keeper.get_instance().did_registry).resolve(did),
            consumer_account,
            ConfigProvider.get_config().downloads_path, brizo, secret_store)
Esempio n. 27
0
def get_consumer_account(config):
    acc = get_account_from_config(config, 'parity.address1',
                                  'parity.password1')
    if acc is None:
        acc = Account(Keeper.get_instance().accounts[1])
    return acc
Esempio n. 28
0
def publish():
    """Encrypt document using the SecretStore and keyed by the given documentId.

    This can be used by the publisher of an asset to encrypt the urls of the
    asset data files before publishing the asset ddo. The publisher to use this
    service is one that is using a front-end with a wallet app such as MetaMask.
    In such scenario the publisher is not able to encrypt the urls using the
    SecretStore interface and this service becomes necessary.

    tags:
      - services
    consumes:
      - application/json
    parameters:
      - in: body
        name: body
        required: true
        description: Asset urls encryption.
        schema:
          type: object
          required:
            - documentId
            - signedDocumentId
            - document
            - publisherAddress:
          properties:
            documentId:
              description: Identifier of the asset to be registered in ocean.
              type: string
              example: 'did:op:08a429b8529856d59867503f8056903a680935a76950bb9649785cc97869a43d'
            signedDocumentId:
              description: Publisher signature of the documentId
              type: string
              example: ''
            document:
              description: document
              type: string
              example: '/some-url'
            publisherAddress:
              description: Publisher address.
              type: string
              example: '0x00a329c0648769A73afAc7F9381E08FB43dBEA72'
    responses:
      201:
        description: document successfully encrypted.
      500:
        description: Error

    return: the encrypted document (hex str)
    """
    required_attributes = [
        'documentId', 'signedDocumentId', 'document', 'publisherAddress'
    ]
    data = request.json
    msg, status = check_required_attributes(required_attributes, data,
                                            'publish')
    if msg:
        return msg, status

    provider_acc = get_provider_account(ocn)
    did = data.get('documentId')
    signed_did = data.get('signedDocumentId')
    document = data.get('document')
    publisher_address = data.get('publisherAddress')

    try:
        address = Keeper.get_instance().ec_recover(did, signed_did)
        if address.lower() != publisher_address.lower():
            msg = f'Invalid signature {signed_did} for ' \
                f'publisherAddress {publisher_address} and documentId {did}.'
            raise ValueError(msg)

        encrypted_document = ocn.secret_store.encrypt(did, document,
                                                      provider_acc)
        logger.info(f'encrypted urls {encrypted_document}, '
                    f'publisher {publisher_address}, '
                    f'documentId {did}')
        return encrypted_document, 201
    except Exception as e:
        logger.error(
            f'Error encrypting document: {e}. \nPayload was: documentId={did}, '
            f'publisherAddress={publisher_address}',
            exc_info=1)
        return "Error: " + str(e), 500
Esempio n. 29
0
def get_publisher_account(config):
    acc = get_account_from_config(config, 'parity.address', 'parity.password')
    if acc is None:
        acc = Account(Keeper.get_instance().accounts[0])
    return acc
Esempio n. 30
0
def consume():
    """Allows download of asset data file.

    ---
    tags:
      - services
    consumes:
      - application/json
    parameters:
      - name: consumerAddress
        in: query
        description: The consumer address.
        required: true
        type: string
      - name: serviceAgreementId
        in: query
        description: The ID of the service agreement.
        required: true
        type: string
      - name: url
        in: query
        description: This URL is only valid if Brizo acts as a proxy.
                     Consumer can't download using the URL if it's not through Brizo.
        required: true
        type: string
    responses:
      200:
        description: Redirect to valid asset url.
      400:
        description: One of the required attributes is missing.
      401:
        description: Invalid asset data.
      500:
        description: Error
    """
    data = request.args
    required_attributes = ['serviceAgreementId', 'consumerAddress']
    msg, status = check_required_attributes(required_attributes, data,
                                            'consume')
    if msg:
        return msg, status

    if not (data.get('url') or (data.get('signature') and data.get('index'))):
        return f'Either `url` or `signature and index` are required in the call to "consume".', 400

    try:
        provider_account = get_provider_account(ocn)
        agreement_id = data.get('serviceAgreementId')
        consumer_address = data.get('consumerAddress')
        asset_id = ocn.agreements.get(agreement_id).did
        did = id_to_did(asset_id)
        if ocn.agreements.is_access_granted(agreement_id, did,
                                            consumer_address):
            logger.info('Connecting through Osmosis to generate the sign url.')
            url = data.get('url')
            try:
                if not url:
                    signature = data.get('signature')
                    index = int(data.get('index'))
                    address = Keeper.get_instance().ec_recover(
                        agreement_id, signature)
                    if address.lower() != consumer_address.lower():
                        msg = f'Invalid signature {signature} for ' \
                            f'consumerAddress {consumer_address} and documentId {did}.'
                        raise ValueError(msg)

                    asset = ocn.assets.resolve(did)
                    urls_str = ocn.secret_store.decrypt(
                        asset_id, asset.encrypted_files, provider_account)
                    urls = json.loads(urls_str)
                    if index >= len(urls):
                        raise ValueError(f'url index "{index}"" is invalid.')
                    url = urls[index]['url']

                osm = Osmosis(url, config_file)
                download_url = osm.data_plugin.generate_url(url)
                logger.debug("Osmosis generate the url: %s", download_url)
                try:
                    if request.range:
                        headers = {"Range": request.headers.get('range')}
                        response = requests_session.get(download_url,
                                                        headers=headers,
                                                        stream=True)
                    else:
                        headers = {
                            "Content-Disposition":
                            f'attachment;filename={url.split("/")[-1]}'
                        }
                        response = requests_session.get(download_url,
                                                        headers=headers,
                                                        stream=True)
                    return Response(io.BytesIO(response.content).read(),
                                    response.status_code,
                                    headers=headers)
                except Exception as e:
                    logger.error(e)
                    return "Error getting the url content: %s" % e, 401
            except Exception as e:
                logger.error(e)
                return "Error generating url: %s" % e, 401
        else:
            msg = "Invalid consumer address and/or service agreement id, " \
                  "or consumer address does not have permission to consume this asset."
            logger.warning(msg)
            return msg, 401
    except Exception as e:
        logger.error("Error- " + str(e))
        return "Error : " + str(e), 500