示例#1
0
def test_did_resolver_library(publisher_account, metadata_instance,
                              ddo_sample_2):
    did_registry = keeper().did_registry
    checksum_test = Web3.keccak(text='checksum')
    value_test = metadata_instance.root_url

    did_resolver = DIDResolver(keeper().did_registry)

    did_seed = generate_prefixed_id()
    asset_id = did_registry.hash_did(did_seed, publisher_account.address)

    asset1 = ddo_sample_2
    asset1._did = DID.did(asset_id)
    did_registry.register(did_seed,
                          checksum_test,
                          url=value_test,
                          account=publisher_account)
    metadata_instance.publish_asset_ddo(asset1)

    did_resolved = did_resolver.resolve(asset1.did)
    assert did_resolved
    assert did_resolved.did == asset1.did

    with pytest.raises(ValueError):
        did_resolver.resolve(asset1.asset_id)

    metadata_instance.retire_asset_ddo(asset1.did)
示例#2
0
def execute_computation(event, agreement_id, did, service_agreement,
                        consumer_account, consume_callback, workflow_did):
    """
    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:
    :param secret_store_url: str URL of secret store node for retrieving decryption keys
    :param parity_url: str URL of parity client to use for secret store encrypt/decrypt
    :param downloads_path: str path to save downloaded files
    """
    logger.debug(
        f"consuming asset (agreementId {agreement_id}) after event {event}.")
    if consume_callback:
        gateway = GatewayProvider.get_gateway()
        consume_callback(
            agreement_id,
            DIDResolver(Keeper.get_instance().did_registry).resolve(did),
            DIDResolver(
                Keeper.get_instance().did_registry).resolve(workflow_did),
            consumer_account, gateway)
示例#3
0
 def check_ddo(self, did, agreement_id, asset_id, consumer_address, keeper, cond_ids, service_type):
     ddo = DIDResolver(keeper.did_registry).resolve(did)
     aservice = ddo.get_service(service_type)
     token_address = aservice.get_param_value_by_name('_tokenAddress')
     if token_address is None or len(token_address) == 0:
         token_address = keeper.token.address
     (id1, id2, id3) = aservice.generate_agreement_condition_ids(agreement_id, asset_id, consumer_address, keeper, token_address)
     ids = [id1, id2, id3]
     if ids != cond_ids:
         raise InvalidClientError(f"ServiceAgreement {agreement_id} doesn't match ddo")
示例#4
0
    def validate_nft_access(self, agreement_id, did, consumer_address):
        keeper = keeper_instance()

        asset = DIDResolver(keeper.did_registry).resolve(did)

        # check which nft access service type is on the ddo
        service_type = ServiceTypes.NFT_ACCESS
        if asset.get_service(ServiceTypes.NFT721_ACCESS) is not None:
            service_type = ServiceTypes.NFT721_ACCESS

        sa = ServiceAgreement.from_ddo(service_type, asset)
        return self._validate_nft_access(agreement_id, did, consumer_address, sa, service_type)
示例#5
0
    def _validate_nft_access(self, agreement_id, did, consumer_address, service_agreement, service_type):
        keeper = keeper_instance()

        asset = DIDResolver(keeper.did_registry).resolve(did)
        asset_id = asset.asset_id
        sa_name = service_agreement.main['name']
        erc721_address = service_agreement.get_param_value_by_name('_contractAddress')

        access_granted = False

        if agreement_id is None or agreement_id == '0x':
            if sa_name == 'nftAccessAgreement':
                access_granted = is_nft_holder(keeper, asset_id, service_agreement.get_number_nfts(), consumer_address)
            elif sa_name == 'nft721AccessAgreement':
                access_granted = is_nft721_holder(keeper, asset_id, consumer_address, erc721_address)
        else:
            agreement = keeper.agreement_manager.get_agreement(agreement_id)
            cond_ids = agreement.condition_ids
            access_cond_id = cond_ids[1]
            ddo = DIDResolver(keeper.did_registry).resolve(did)

            nft_access_service_agreement = ServiceAgreement.from_ddo(service_type, ddo)

            (nft_access_cond_id, nft_holder_cond_id) = nft_access_service_agreement.generate_agreement_condition_ids(agreement_id, asset_id, consumer_address, keeper)
            if [nft_holder_cond_id, nft_access_cond_id] != cond_ids:
                raise InvalidClientError(f"ServiceAgreement {agreement_id} doesn't match ddo")

            if not is_nft_access_condition_fulfilled(
                    agreement_id,
                    access_cond_id,
                    consumer_address,
                    keeper):
                # If not granted, verification of agreement and conditions and fulfill
                # access_granted = is_nft_holder(keeper, asset_id, sa.get_number_nfts(), consumer_address)
                access_granted = fulfill_nft_holder_and_access_condition(
                    keeper,
                    agreement_id,
                    cond_ids,
                    asset_id,
                    service_agreement.get_number_nfts(),
                    consumer_address,
                    self.provider_account
                )
        if not access_granted:
            msg = ('Checking access permissions failed. Either consumer address does not have '
                   'permission to consume this NFT or consumer address and/or service '
                   'agreement '
                   'id is invalid.')
            logger.warning(msg)
            raise InvalidClientError(msg)
示例#6
0
def execute_compute_job():
    """Call the execution of a workflow.
    Method deprecated, it will be replaced by `/execute` in further versions
    swagger_from_file: docs/execute_compute_job.yml
    """
    data = request.args
    required_attributes = [
        'serviceAgreementId', 'consumerAddress', 'signature', 'workflowDID'
    ]
    msg, status = check_required_attributes(required_attributes, data,
                                            'consume')
    if msg:
        return msg, status

    if not (data.get('signature')):
        return f'`signature is required in the call to "consume".', 400

    try:
        agreement_id = data.get('serviceAgreementId')
        consumer_address = data.get('consumerAddress')
        asset_id = keeper_instance().agreement_manager.get_agreement(
            agreement_id).did
        did = id_to_did(asset_id)
        if not was_compute_triggered(agreement_id, did, consumer_address,
                                     keeper_instance()):
            msg = (
                'Checking if the compute was triggered failed. Either consumer address does not '
                'have permission to executre this workflow or consumer address and/or service '
                'agreement id is invalid.')
            logger.warning(msg)
            return msg, 401

        workflow = DIDResolver(keeper_instance().did_registry).resolve(
            data.get('workflowDID'))
        body = {
            "serviceAgreementId": agreement_id,
            "workflow": workflow.as_dictionary()
        }

        response = requests_session.post(
            get_config().compute_api_url +
            '/api/v1/nevermined-compute-api/init',
            data=json.dumps(body),
            headers={'content-type': 'application/json'})
        return jsonify({"workflowId": response.content.decode('utf-8')})
    except Exception as e:
        logger.error(f'Error- {str(e)}', exc_info=1)
        return f'Error : {str(e)}', 500
示例#7
0
def test_get_resolve_url(metadata_instance, publisher_account):
    register_account = publisher_account
    did_registry = keeper().did_registry

    did_seed = generate_prefixed_id()
    asset_id = did_registry.hash_did(did_seed, register_account.address)

    did = DID.did(asset_id)

    value_test = metadata_instance.root_url
    did_resolver = DIDResolver(keeper().did_registry)
    did_registry.register(did_seed,
                          b'test',
                          url=value_test,
                          account=register_account)
    url = did_resolver.get_resolve_url(Web3.toBytes(hexstr=asset_id))
    assert url == value_test
示例#8
0
def test_get_resolve_multiple_urls(publisher_account):
    register_account = publisher_account
    did_registry = keeper().did_registry
    did_resolver = DIDResolver(keeper().did_registry)

    iterations = 3
    counter = 0

    while counter < iterations:
        _seed = generate_prefixed_id()
        _asset_id = did_registry.hash_did(_seed, register_account.address)
        _url = 'http://localhost:5000/' + str(counter)
        did_registry.register(_seed,
                              b'test',
                              url=_url,
                              account=register_account)
        assert did_resolver.get_resolve_url(
            Web3.toBytes(hexstr=_asset_id)) == _url
        counter = counter + 1
示例#9
0
    def validate_access(self, agreement_id, did, consumer_address):
        keeper = keeper_instance()

        if not is_access_granted(
                agreement_id,
                did,
                consumer_address,
                keeper):
            # 3. If not granted, verification of agreement and conditions
            agreement = keeper.agreement_manager.get_agreement(agreement_id)
            cond_ids = agreement.condition_ids
            asset = DIDResolver(keeper.did_registry).resolve(did)
            asset_id = f'0x{did.replace(NEVERMINED_PREFIX, "")}'
            self.check_ddo(did, agreement_id, asset_id, consumer_address, keeper, cond_ids, ServiceTypes.ASSET_ACCESS)

            access_condition_status = keeper.condition_manager.get_condition_state(cond_ids[0])
            lock_condition_status = keeper.condition_manager.get_condition_state(cond_ids[1])
            escrow_condition_status = keeper.condition_manager.get_condition_state(
                cond_ids[2])

            logger.debug('AccessCondition: %d' % access_condition_status)
            logger.debug('LockPaymentCondition: %d' % lock_condition_status)
            logger.debug('EscrowPaymentCondition: %d' % escrow_condition_status)

            if lock_condition_status != ConditionState.Fulfilled.value:
                logger.debug('ServiceAgreement %s was not paid. Forbidden' % agreement_id)
                raise InvalidClientError(
                    f"ServiceAgreement {agreement_id} was not paid, LockPaymentCondition status is {lock_condition_status}")

            fulfilled = fulfill_access_condition(keeper, agreement_id, cond_ids, asset_id, consumer_address,
                                                 self.provider_account)
            if not fulfilled:
                raise InvalidClientError('Server error fulfilling access condition')

            fulfill_escrow_payment_condition(keeper, agreement_id, cond_ids, asset,
                                             self.provider_account)

            iteration = 0
            access_granted = False
            while iteration < ConfigSections.PING_ITERATIONS:
                iteration = iteration + 1
                logger.debug('Checking if access was granted. Iteration %d' % iteration)
                if not is_access_granted(agreement_id, did, consumer_address, keeper):
                    time.sleep(ConfigSections.PING_SLEEP / 1000)
                else:
                    access_granted = True
                    break

            if not access_granted:
                msg = ('Checking access permissions failed. Either consumer address does not have '
                       'permission to consume this asset or consumer address and/or service '
                       'agreement '
                       'id is invalid.')
                logger.warning(msg)
                raise InvalidClientError(msg)
示例#10
0
def execute(agreement_id):
    """Call the execution of a workflow.
    swagger_from_file: docs/execute.yml
    """

    consumer_address = current_token["client_id"]
    workflow_did = current_token["did"]
    agreement_id = current_token["sub"]

    try:
        keeper = keeper_instance()
        asset_id = keeper_instance().agreement_manager.get_agreement(
            agreement_id).did
        did = id_to_did(asset_id)

        signature = '0x00'

        workflow = DIDResolver(
            keeper_instance().did_registry).resolve(workflow_did)
        body = {
            "serviceAgreementId": agreement_id,
            "workflow": workflow.as_dictionary()
        }

        response = requests_session.post(
            get_config().compute_api_url +
            '/api/v1/nevermined-compute-api/init',
            data=json.dumps(body),
            headers={'content-type': 'application/json'})
        if response.status_code != 200:
            msg = f'The compute API was not able to create the workflow. {response.content}'
            logger.warning(msg)
            return msg, 401

        used_by(generate_random_id(), did, consumer_address, 'compute',
                signature, 'compute', provider_acc, keeper)
        return jsonify({"workflowId": response.content.decode('utf-8')})

    except Exception as e:
        logger.error(f'Error- {str(e)}', exc_info=1)
        return f'Error : {str(e)}', 500
示例#11
0
    def validate_execute(self, agreement_id, workflow_did, consumer_address):
        keeper = keeper_instance()

        asset_id = keeper.agreement_manager.get_agreement(agreement_id).did
        did = id_to_did(asset_id)
        asset = DIDResolver(keeper.did_registry).resolve(did)

        if not was_compute_triggered(agreement_id, did, consumer_address, keeper):

            agreement = keeper.agreement_manager.get_agreement(agreement_id)
            cond_ids = agreement.condition_ids
            self.check_ddo(did, agreement_id, asset_id, consumer_address, keeper, cond_ids, ServiceTypes.CLOUD_COMPUTE)

            compute_condition_status = keeper.condition_manager.get_condition_state(cond_ids[0])
            lock_condition_status = keeper.condition_manager.get_condition_state(cond_ids[1])
            escrow_condition_status = keeper.condition_manager.get_condition_state(
                cond_ids[2])
            logger.debug('ComputeExecutionCondition: %d' % compute_condition_status)
            logger.debug('LockPaymentCondition: %d' % lock_condition_status)
            logger.debug('EscrowPaymentCondition: %d' % escrow_condition_status)

            if lock_condition_status != ConditionState.Fulfilled.value:
                logger.debug('ServiceAgreement %s was not paid. Forbidden' % agreement_id)
                raise InvalidClaimError(
                    f"ServiceAgreement {agreement_id} was not paid, LockPaymentCondition status is {lock_condition_status}")

            fulfill_compute_condition(keeper, agreement_id, cond_ids, asset_id, consumer_address,
                                      self.provider_account)
            fulfill_escrow_payment_condition(keeper, agreement_id, cond_ids, asset,
                                             self.provider_account,
                                             ServiceTypes.CLOUD_COMPUTE)

            iteration = 0
            access_granted = False
            while iteration < ConfigSections.PING_ITERATIONS:
                iteration = iteration + 1
                logger.debug('Checking if compute was granted. Iteration %d' % iteration)
                if not was_compute_triggered(agreement_id, did, consumer_address, keeper):
                    time.sleep(ConfigSections.PING_SLEEP / 1000)
                else:
                    access_granted = True
                    break

            if not access_granted:
                msg = (
                    'Scheduling the compute execution failed. Either consumer address does not '
                    'have permission to execute this workflow or consumer address and/or service '
                    'agreement id is invalid.')
                logger.warning(msg)
                raise InvalidClientError(msg)
示例#12
0
    def validate_access_proof(self, agreement_id, did, eth_address, consumer_address, jubjub_sig):
        consumer_pub = ['0x'+consumer_address[0:64], '0x'+consumer_address[64:128]]
        provider_pub = [self.provider_key.x, self.provider_key.y]

        if not keytransfer.verify([int(consumer_pub[0],16), int(consumer_pub[1],16)], int(eth_address,16), jubjub_sig):
            raise InvalidClientError(
                    f"ServiceAgreement {agreement_id}: babyjubjub signature doesn't match")

        keeper = keeper_instance()

        agreement = keeper.agreement_manager.get_agreement(agreement_id)
        cond_ids = agreement.condition_ids
        asset = DIDResolver(keeper.did_registry).resolve(did)
        asset_id = did.replace(NEVERMINED_PREFIX, "")
        self.check_ddo(did, agreement_id, asset_id, consumer_pub, keeper, cond_ids, ServiceTypes.ASSET_ACCESS_PROOF)

        access_condition_status = keeper.condition_manager.get_condition_state(cond_ids[0])
        lock_condition_status = keeper.condition_manager.get_condition_state(cond_ids[1])
        escrow_condition_status = keeper.condition_manager.get_condition_state(
                cond_ids[2])

        logger.info('AccessProofCondition: %d' % access_condition_status)
        logger.info('LockPaymentCondition: %d' % lock_condition_status)
        logger.info('EscrowPaymentCondition: %d' % escrow_condition_status)

        if lock_condition_status != ConditionState.Fulfilled.value:
            logger.debug('ServiceAgreement %s was not paid. Forbidden' % agreement_id)
            raise InvalidClientError(
                    f"ServiceAgreement {agreement_id} was not paid, LockPaymentCondition status is {lock_condition_status}")

        if escrow_condition_status != ConditionState.Fulfilled.value:
            # compute the proof
            auth_method = asset.authorization.main['service']
            url = '0x' + get_asset_url_at_index(0, asset, self.provider_account, auth_method)
            res = call_prover(consumer_pub, self.provider_key.secret, url)
            # check that the condition ID is correct
            cond_id = keeper.access_proof_condition.generate_id(
                agreement_id,
                ['bytes32', 'bytes32', 'bytes32', 'bytes32', 'bytes32'],
                [res['hash'], consumer_pub[0], consumer_pub[1], provider_pub[0], provider_pub[1]]
            )
            if cond_ids[0] != cond_id.hex():
                raise InvalidClientError(
                        f"ServiceAgreement {agreement_id}: public key doesn't match {consumer_address}")

            fulfill_access_proof_condition(keeper, agreement_id, cond_ids, res['hash'], consumer_pub, provider_pub, res['cipher'], res['proof'],
                                     self.provider_account)
            fulfill_escrow_payment_condition(keeper, agreement_id, cond_ids, asset,
                                             self.provider_account, ServiceTypes.ASSET_ACCESS_PROOF)
示例#13
0
def access(agreement_id, index=0):
    """Allows to get access to an asset data file.
    swagger_from_file: docs/access.yml
    """

    consumer_address = current_token["client_id"]
    did = current_token["did"]
    agreement_id = current_token["sub"]

    logger.info(
        'Parameters:\nAgreementId: %s\nIndex: %d\nConsumerAddress: %s\n'
        'DID: %s\n' % (agreement_id, index, consumer_address, did))

    try:
        keeper = keeper_instance()
        asset = DIDResolver(keeper.did_registry).resolve(did)

        logger.debug('AgreementID :' + agreement_id)

        file_attributes = asset.metadata['main']['files'][index]
        content_type = file_attributes.get('contentType', None)

        try:
            auth_method = asset.authorization.main['service']
        except Exception:
            auth_method = constants.ConfigSections.DEFAULT_DECRYPTION_METHOD

        if auth_method not in constants.ConfigSections.DECRYPTION_METHODS:
            msg = (
                'The Authorization Method defined in the DDO is not part of the available '
                'methods supported'
                'by the Gateway: ' + auth_method)
            logger.warning(msg)
            return msg, 400

        url = get_asset_url_at_index(index, asset, provider_acc, auth_method)
        used_by(generate_random_id(), did, consumer_address, 'access', '0x00',
                'access', provider_acc, keeper)
        return get_asset(request, requests_session, content_type, url,
                         app.config['CONFIG_FILE'])

    except (ValueError, Exception) as e:
        logger.error(f'Error- {str(e)}', exc_info=1)
        return f'Error : {str(e)}', 500
示例#14
0
    def process_condition_events(self,
                                 agreement_id,
                                 conditions,
                                 did,
                                 consumer_address,
                                 block_number,
                                 new_agreement=True,
                                 template_id=None):

        ddo = DIDResolver(self._keeper.did_registry).resolve(did)

        cond_order = self._get_conditions_order(template_id)
        agreement_type = self._get_agreement_type(template_id)
        service_agreement = ddo.get_service(agreement_type)
        condition_def_dict = service_agreement.condition_by_name
        price = service_agreement.get_price()
        if new_agreement:
            start_time = int(datetime.now().timestamp())
            self.db.record_service_agreement(
                agreement_id, ddo.did, service_agreement.index, price,
                ddo.metadata.get('encryptedFiles'), consumer_address,
                start_time, block_number, agreement_type,
                service_agreement.condition_by_name.keys())

        condition_ids = service_agreement.generate_agreement_condition_ids(
            agreement_id=agreement_id,
            asset_id=ddo.asset_id,
            consumer_address=consumer_address,
            publisher_address=ddo.publisher,
            keeper=self._keeper)
        cond_to_id = {
            cond_order[i]: _id
            for i, _id in enumerate(condition_ids)
        }
        for cond in conditions:

            if cond == 'lockReward':
                if agreement_type == ServiceTypes.ASSET_ACCESS:
                    condition = lockRewardCondition.fulfillAccessSecretStoreCondition
                else:
                    condition = lockRewardExecutionCondition.fulfillExecComputeCondition
                self._keeper.lock_reward_condition.subscribe_condition_fulfilled(
                    agreement_id,
                    max(condition_def_dict['lockReward'].timeout,
                        self.EVENT_WAIT_TIMEOUT),
                    condition,
                    (agreement_id, ddo.did, service_agreement,
                     consumer_address, self._account, condition_ids[0]),
                    from_block=block_number)

            elif cond == 'accessSecretStore':
                self._keeper.access_secret_store_condition.subscribe_condition_fulfilled(
                    agreement_id,
                    max(condition_def_dict['accessSecretStore'].timeout,
                        self.EVENT_WAIT_TIMEOUT),
                    accessSecretStore.fulfillEscrowRewardCondition,
                    (agreement_id, service_agreement, price, consumer_address,
                     self._account, condition_ids, condition_ids[2]),
                    from_block=block_number)
            elif cond == 'execCompute':
                self._keeper.compute_execution_condition.subscribe_condition_fulfilled(
                    agreement_id,
                    max(condition_def_dict['execCompute'].timeout,
                        self.EVENT_WAIT_TIMEOUT),
                    accessSecretStore.fulfillEscrowRewardCondition,
                    (agreement_id, service_agreement, price, consumer_address,
                     self._account, condition_ids, condition_ids[2]),
                    from_block=block_number)
            elif cond == 'escrowReward':
                self._keeper.escrow_reward_condition.subscribe_condition_fulfilled(
                    agreement_id,
                    max(condition_def_dict['escrowReward'].timeout,
                        self.EVENT_WAIT_TIMEOUT),
                    self._last_condition_fulfilled, (agreement_id, cond_to_id),
                    from_block=block_number)
示例#15
0
def test_did_not_found():
    did_resolver = DIDResolver(keeper().did_registry)
    did_id = secrets.token_hex(32)
    did_id_bytes = Web3.toBytes(hexstr=did_id)
    with pytest.raises(DIDNotFound):
        did_resolver.resolve(did_id_bytes)
示例#16
0
def test_get_did_not_valid():
    did_resolver = DIDResolver(keeper().did_registry)
    with pytest.raises(TypeError):
        did_resolver.get_resolve_url('not valid')
示例#17
0
def nft_transfer():
    """Allows the provider transfer and release the rewards.
    swagger_from_file: docs/nft_transfer.yml
    """
    required_attributes = [
        'agreementId', 'nftHolder', 'nftReceiver', 'nftAmount'
    ]
    data = request.json

    msg, status = check_required_attributes(required_attributes, data,
                                            'nft-transfer')
    if msg:
        return msg, status

    agreement_id = data.get('agreementId')
    nft_holder_address = data.get('nftHolder')
    nft_receiver_address = data.get('nftReceiver')
    nft_amount = data.get('nftAmount')

    keeper = keeper_instance()
    agreement = keeper.agreement_manager.get_agreement(agreement_id)
    did = id_to_did(agreement.did)
    ddo = DIDResolver(keeper.did_registry).resolve(did)

    try:
        ServiceAgreement.from_ddo(ServiceTypes.NFT_SALES, ddo)
    except ValueError as e:
        logger.error('nft-sales service not found on ddo for %s', did)
        return str(e), 400

    (lock_payment_condition_id, nft_transfer_condition_id,
     escrow_payment_condition_id) = agreement.condition_ids

    if not is_nft_holder(keeper, agreement.did, nft_amount,
                         nft_holder_address):
        msg = f'Holder {nft_holder_address} does not have enough NFTs to transfer'
        logger.warning(msg)
        return msg, 406

    if not is_lock_payment_condition_fulfilled(lock_payment_condition_id,
                                               keeper):
        msg = f'lockPayment condition for agreement_id={agreement_id} is not fulfilled'
        logger.warning(msg)
        return msg, 402

    if not is_nft_transfer_approved(nft_holder_address,
                                    get_provider_account().address, keeper):
        msg = f'Gateway ({get_provider_account().address}) is not approved to transfer nfts from {nft_holder_address}'
        logger.warning(msg)
        return msg, 405

    # fulfill transferNFT condition
    if not is_nft_transfer_condition_fulfilled(nft_transfer_condition_id,
                                               keeper):
        logger.debug('NFTTransfer condition not fulfilled')
        result = fulfill_for_delegate_nft_transfer_condition(
            agreement_id, agreement.did,
            Web3.toChecksumAddress(nft_holder_address),
            Web3.toChecksumAddress(nft_receiver_address), nft_amount,
            lock_payment_condition_id, keeper)
        if result is False:
            msg = f'There was an error fulfilling the NFTTransfer condition for agreement_id={agreement_id}'
            logger.error(msg)
            return msg, 500

    # fulfill escrowPayment condition
    if not is_escrow_payment_condition_fulfilled(escrow_payment_condition_id,
                                                 keeper):
        logger.debug('EscrowPayment condition not fulfilled')
        result = fulfill_escrow_payment_condition(
            keeper,
            agreement_id, [
                nft_transfer_condition_id, lock_payment_condition_id,
                escrow_payment_condition_id
            ],
            ddo,
            get_provider_account(),
            service_type=ServiceTypes.NFT_SALES)
        if result is False:
            msg = f'There was an error fulfilling the EscrowPayment condition for agreement_id={agreement_id}'
            logger.error(msg)
            return msg, 500

    return 'success', 200
示例#18
0
    def __init__(self, config=None):
        """
        Initialize Nevermined class.
           >> # Make a new Nevermined instance
           >> nevermined = Nevermined({...})

        This class provides the main top-level functions in nevermined protocol:
         * Publish assets metadata and associated services
            * Each asset is assigned a unique DID and a DID Document (DDO)
            * The DDO contains the asset's services including the metadata
            * The DID is registered on-chain with a URL of the metadata store
              to retrieve the DDO from

            >> ddo = nevermined.assets.create(metadata, publisher_account)

         * Discover/Search assets via the current configured metadata store.
            >> assets_list = nevermined.assets.search('search text')

         * Purchase asset services by choosing a service agreement from the
           asset's DDO. Purchase goes through the service agreements interface
           and starts by signing a service agreement then sending the signature
           to the publisher's Gateway server via the `purchaseEndpoint` in the service
           definition:

           >> service_def_id = ddo.get_service(ServiceTypes.ASSET_ACCESS).service_definition_id
           >> service_agreement_id = nevermined.assets.order(did, service_def_id, consumer_account)

        An instance of Nevermined is parameterized by a `Config` instance.

        :param config: Config instance
        """
        # Configuration information for the market is stored in the Config class
        # config = Config(filename=config_file, options_dict=config_dict)
        if not config:
            config = ConfigProvider.get_config()

        self._config = config
        self._web3 = Web3Provider.get_web3(self._config.keeper_url)
        ContractHandler.artifacts_path = self._config.keeper_path
        contracts = [
            'DIDRegistry', 'Dispenser', 'TemplateStoreManager',
            'NeverminedToken', 'ConditionStoreManager',
            'EscrowAccessSecretStoreTemplate', 'AgreementStoreManager',
            'AgreementStoreManager', 'AccessSecretStoreCondition',
            'LockRewardCondition', 'HashLockCondition', 'SignCondition',
            'EscrowReward'
        ]
        self._keeper = Keeper.get_instance(self._config.keeper_path, contracts)
        self._did_resolver = DIDResolver(self._keeper.did_registry)

        # Initialize the public sub-modules
        self.tokens = Tokens(self._keeper)
        self.accounts = Accounts(self._keeper, self._config, self.tokens,
                                 Faucet)
        self.templates = Templates(self._keeper, config)
        self.agreements = self._make_agreements()
        self.assets = Assets(self._keeper, self._did_resolver, self.agreements,
                             AssetConsumer, AssetExecutor, self._config)
        self.nfts = NFTs(self._keeper)
        self.services = Services()
        self.secret_store = SecretStore(self._config)
        self.providers = Providers(self._keeper, self._did_resolver,
                                   self._config)
        self.auth = Auth(self._keeper, self._config.storage_path)
        self.provenance = Provenance(self._keeper, self._config)
        self.files = Files(self._config)

        logger.debug('Nevermined instance initialized: ')
        logger.debug(
            f'\tOther accounts: {sorted([a.address for a in self.accounts.list()])}'
        )
        logger.debug(f'\tDIDRegistry @ {self._keeper.did_registry.address}')
示例#19
0
def consume():
    """Allows download of asset data file.
    Method deprecated, it will be replaced by `/access` in further versions
    swagger_from_file: docs/consume.yml
    """
    data = request.args
    required_attributes = [
        'serviceAgreementId', 'consumerAddress', 'signature', 'index'
    ]
    msg, status = check_required_attributes(required_attributes, data,
                                            'consume')
    if msg:
        return msg, status

    try:
        keeper = keeper_instance()
        agreement_id = data.get('serviceAgreementId')
        consumer_address = data.get('consumerAddress')
        asset_id = keeper.agreement_manager.get_agreement(agreement_id).did
        did = id_to_did(asset_id)

        if not is_access_granted(agreement_id, did, consumer_address, keeper):
            msg = (
                'Checking access permissions failed. Either consumer address does not have '
                'permission to consume this asset or consumer address and/or service agreement '
                'id is invalid.')
            logger.warning(msg)
            return msg, 401

        asset = DIDResolver(keeper.did_registry).resolve(did)
        signature = data.get('signature')
        index = int(data.get('index'))

        if not verify_signature(keeper, consumer_address, signature,
                                agreement_id):
            msg = f'Invalid signature {signature} for ' \
                  f'publisherAddress {consumer_address} and documentId {agreement_id}.'
            raise ValueError(msg)

        file_attributes = asset.metadata['main']['files'][index]
        content_type = file_attributes.get('contentType', None)

        try:
            auth_method = asset.authorization.main['service']
        except Exception:
            auth_method = constants.ConfigSections.DEFAULT_DECRYPTION_METHOD

        if auth_method not in constants.ConfigSections.DECRYPTION_METHODS:
            msg = (
                'The Authorization Method defined in the DDO is not part of the available '
                'methods supported'
                'by the Gateway: ' + auth_method)
            logger.warning(msg)
            return msg, 400

        url = get_asset_url_at_index(index, asset, provider_acc, auth_method)
        return get_asset(request, requests_session, content_type, url,
                         app.config['CONFIG_FILE'])
    except (ValueError, Exception) as e:
        logger.error(f'Error- {str(e)}', exc_info=1)
        return f'Error : {str(e)}', 500