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)
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)
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")
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)
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)
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
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
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
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)
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
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)
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)
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
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)
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)
def test_get_did_not_valid(): did_resolver = DIDResolver(keeper().did_registry) with pytest.raises(TypeError): did_resolver.get_resolve_url('not valid')
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
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}')
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