def create_config(self, emitter, config_file): if self.dev: return BobConfiguration(emitter=emitter, dev_mode=True, domains={TEMPORARY_DOMAIN}, provider_uri=self.provider_uri, gas_strategy=self.gas_strategy, signer_uri=self.signer_uri, federated_only=True, checksum_address=self.checksum_address, network_middleware=self.middleware) else: try: return BobConfiguration.from_configuration_file( emitter=emitter, filepath=config_file, domains=self.domains, checksum_address=self.checksum_address, rest_port=self.discovery_port, provider_uri=self.provider_uri, signer_uri=self.signer_uri, gas_strategy=self.gas_strategy, registry_filepath=self.registry_filepath, network_middleware=self.middleware) except FileNotFoundError: return actions.handle_missing_configuration_file( character_config_class=BobConfiguration, config_file=config_file)
def create_config(self, emitter: StdoutEmitter, config_file: str) -> BobConfiguration: if self.dev: return BobConfiguration(emitter=emitter, dev_mode=True, domain=TEMPORARY_DOMAIN, provider_uri=self.provider_uri, gas_strategy=self.gas_strategy, max_gas_price=self.max_gas_price, signer_uri=self.signer_uri, federated_only=True, checksum_address=self.checksum_address, network_middleware=self.middleware, lonely=self.lonely) else: try: return BobConfiguration.from_configuration_file( emitter=emitter, filepath=config_file, domain=self.domain, checksum_address=self.checksum_address, rest_port=self.discovery_port, provider_uri=self.provider_uri, signer_uri=self.signer_uri, gas_strategy=self.gas_strategy, max_gas_price=self.max_gas_price, registry_filepath=self.registry_filepath, network_middleware=self.middleware, lonely=self.lonely) except FileNotFoundError: handle_missing_configuration_file( character_config_class=BobConfiguration, config_file=config_file)
def _get_bob_config(click_config, dev, provider_uri, network, registry_filepath, checksum_address, config_file, discovery_port): if dev: bob_config = BobConfiguration( dev_mode=True, domains={network}, provider_uri=provider_uri, federated_only=True, checksum_address=checksum_address, network_middleware=click_config.middleware) else: try: bob_config = BobConfiguration.from_configuration_file( filepath=config_file, domains={network} if network else None, checksum_address=checksum_address, rest_port=discovery_port, provider_uri=provider_uri, registry_filepath=registry_filepath, network_middleware=click_config.middleware) except FileNotFoundError: return actions.handle_missing_configuration_file( character_config_class=BobConfiguration, config_file=config_file) return bob_config
def bob_federated_test_config(): config = BobConfiguration(temp=True, auto_initialize=True, network_middleware=MockRestMiddleware(), start_learning_now=False, abort_on_learning_error=True, federated_only=True) yield config config.cleanup()
def bob_federated_test_config(): config = BobConfiguration(dev_mode=True, network_middleware=MockRestMiddleware(), start_learning_now=False, abort_on_learning_error=True, federated_only=True, save_metadata=False, reload_metadata=False) yield config config.cleanup()
def highperf_mocked_bob(fleet_of_highperf_mocked_ursulas): config = BobConfiguration(dev_mode=True, domains={TEMPORARY_DOMAIN}, network_middleware=MockRestMiddlewareForLargeFleetTests(), federated_only=True, abort_on_learning_error=True, save_metadata=False, reload_metadata=False) with mock_cert_storage, mock_verify_node, mock_record_fleet_state: bob = config.produce(known_nodes=list(fleet_of_highperf_mocked_ursulas)[:1]) return bob
def bob_federated_test_config(): config = BobConfiguration(temp=True, auto_initialize=True, auto_generate_keys=True, passphrase=TEST_URSULA_INSECURE_DEVELOPMENT_PASSWORD, network_middleware=MockRestMiddleware(), start_learning_now=False, abort_on_learning_error=True, federated_only=True, save_metadata=False, load_metadata=False) yield config config.cleanup()
def bob_blockchain_test_config(blockchain_ursulas, three_agents): token_agent, miner_agent, policy_agent = three_agents etherbase, alice_address, bob_address, *everyone_else = token_agent.blockchain.interface.w3.eth.accounts config = BobConfiguration(temp=True, auto_initialize=True, checksum_address=bob_address, network_middleware=MockRestMiddleware(), known_nodes=blockchain_ursulas, start_learning_now=False, abort_on_learning_error=True, federated_only=False) yield config config.cleanup()
def bob_blockchain_test_config(blockchain_ursulas, testerchain, test_registry): config = BobConfiguration(dev_mode=True, provider_uri=TEST_PROVIDER_URI, checksum_address=testerchain.bob_account, network_middleware=MockRestMiddleware(), known_nodes=blockchain_ursulas, start_learning_now=False, abort_on_learning_error=True, federated_only=False, save_metadata=False, reload_metadata=False, registry=test_registry) yield config config.cleanup()
def test_initialize_bob_with_custom_configuration_root(custom_filepath, click_runner): # Use a custom local filepath for configuration init_args = ('bob', 'init', '--network', TEMPORARY_DOMAIN, '--federated-only', '--config-root', custom_filepath) user_input = '{password}\n{password}'.format(password=INSECURE_DEVELOPMENT_PASSWORD, ip=MOCK_IP_ADDRESS) result = click_runner.invoke(nucypher_cli, init_args, input=user_input, catch_exceptions=False) assert result.exit_code == 0, result.exception # CLI Output assert MOCK_CUSTOM_INSTALLATION_PATH in result.output, "Configuration not in system temporary directory" assert "nucypher bob run" in result.output, 'Help message is missing suggested command' assert 'IPv4' not in result.output # Files and Directories assert os.path.isdir(custom_filepath), 'Configuration file does not exist' assert os.path.isdir(os.path.join(custom_filepath, 'keyring')), 'Keyring does not exist' assert os.path.isdir(os.path.join(custom_filepath, 'known_nodes')), 'known_nodes directory does not exist' custom_config_filepath = os.path.join(custom_filepath, BobConfiguration.generate_filename()) assert os.path.isfile(custom_config_filepath), 'Configuration file does not exist' # Auth assert 'Enter NuCypher keyring password' in result.output, 'WARNING: User was not prompted for password' assert 'Repeat for confirmation:' in result.output, 'User was not prompted to confirm password'
def test_bob_control_starts_with_preexisting_configuration(click_runner, custom_filepath: Path): custom_config_filepath = custom_filepath / BobConfiguration.generate_filename() init_args = ('bob', 'run', '--dry-run', '--lonely', '--config-file', str(custom_config_filepath.absolute())) result = click_runner.invoke(nucypher_cli, init_args, input=FAKE_PASSWORD_CONFIRMED) assert result.exit_code == 0, result.exception assert "Bob Verifying Key" in result.output assert "Bob Encrypting Key" in result.output
def test_bob_destroy(click_runner, custom_filepath: Path): custom_config_filepath = custom_filepath / BobConfiguration.generate_filename() destroy_args = ('bob', 'destroy', '--config-file', str(custom_config_filepath.absolute()), '--force') result = click_runner.invoke(nucypher_cli, destroy_args, catch_exceptions=False) assert result.exit_code == 0, result.exception assert SUCCESSFUL_DESTRUCTION in result.output assert not custom_config_filepath.exists(), "Bob config file was deleted"
def bob_blockchain_test_config(blockchain_ursulas, three_agents): token_agent, miner_agent, policy_agent = three_agents config = BobConfiguration( dev_mode=True, provider_uri="tester://pyevm", checksum_public_address=token_agent.blockchain.bob_account, network_middleware=MockRestMiddleware(), known_nodes=blockchain_ursulas, start_learning_now=False, abort_on_learning_error=True, federated_only=False, import_seed_registry=False, save_metadata=False, reload_metadata=False) yield config config.cleanup()
def view( click_config, # API Options provider_uri, network, registry_filepath, checksum_address, dev, config_file, discovery_port, teacher_uri, min_stake): """ View existing Bob's configuration. """ ### Setup ### _setup_emitter(click_config) bob_config = _get_bob_config(click_config, dev, provider_uri, network, registry_filepath, checksum_address, config_file, discovery_port) ############# BOB = actions.make_cli_character(character_config=bob_config, click_config=click_config, dev=dev, teacher_uri=teacher_uri, min_stake=min_stake) response = BobConfiguration._read_configuration_file( filepath=config_file or bob_config.config_file_location) return BOB.controller.emitter.ipc( response, request_id=0, duration=0) # FIXME: #1216 - what are request_id and duration here?
def charlie_blockchain_test_config(blockchain_ursulas, agency): token_agent, staking_agent, policy_agent = agency etherbase, alice_address, bob_address, *everyone_else = token_agent.blockchain.client.accounts config = BobConfiguration(dev_mode=True, provider_uri=TEST_PROVIDER_URI, checksum_address=bob_address, network_middleware=MockRestMiddleware(), known_nodes=blockchain_ursulas, start_learning_now=False, abort_on_learning_error=True, federated_only=False, save_metadata=False, reload_metadata=False) yield config config.cleanup()
def test_initialize_bob_with_custom_configuration_root(click_runner, custom_filepath: Path): # Use a custom local filepath for configuration init_args = ('bob', 'init', '--network', TEMPORARY_DOMAIN, '--federated-only', '--config-root', str(custom_filepath.absolute())) result = click_runner.invoke(nucypher_cli, init_args, input=FAKE_PASSWORD_CONFIRMED, catch_exceptions=False) assert result.exit_code == 0, result.exception # CLI Output assert str(MOCK_CUSTOM_INSTALLATION_PATH) in result.output, "Configuration not in system temporary directory" assert "nucypher bob run" in result.output, 'Help message is missing suggested command' assert 'IPv4' not in result.output # Files and Directories assert custom_filepath.is_dir(), 'Configuration file does not exist' assert (custom_filepath / 'keystore').is_dir(), 'Keystore does not exist' assert (custom_filepath / 'known_nodes').is_dir(), 'known_nodes directory does not exist' custom_config_filepath = custom_filepath / BobConfiguration.generate_filename() assert custom_config_filepath.is_file(), 'Configuration file does not exist' # Auth assert COLLECT_NUCYPHER_PASSWORD in result.output, 'WARNING: User was not prompted for password' assert 'Repeat for confirmation:' in result.output, 'User was not prompted to confirm password'
def init( click_config, # Admin Options provider_uri, network, registry_filepath, checksum_address, # Other federated_only, config_root): """ Create a brand new persistent Bob. """ emitter = _setup_emitter(click_config) if not config_root: # Flag config_root = click_config.config_file # Envvar if not checksum_address and not federated_only: checksum_address = select_client_account(emitter=emitter, provider_uri=provider_uri) new_bob_config = BobConfiguration.generate( password=get_nucypher_password(confirm=True), config_root=config_root or DEFAULT_CONFIG_ROOT, checksum_address=checksum_address, domains={network} if network else None, federated_only=federated_only, registry_filepath=registry_filepath, provider_uri=provider_uri) return painting.paint_new_installation_help( emitter, new_configuration=new_bob_config)
def test_bob_make_card(click_runner, custom_filepath: Path, mocker): mock_save_card = mocker.patch.object(Card, 'save') custom_config_filepath = custom_filepath / BobConfiguration.generate_filename() command = ('bob', 'make-card', '--nickname', 'anders', '--config-file', str(custom_config_filepath.absolute())) result = click_runner.invoke(nucypher_cli, command, input=FAKE_PASSWORD_CONFIRMED, catch_exceptions=False) assert result.exit_code == 0 assert "Saved new character card " in result.output mock_save_card.assert_called_once()
def test_bob_view_with_preexisting_configuration(click_runner, custom_filepath: Path): custom_config_filepath = custom_filepath / BobConfiguration.generate_filename() view_args = ('bob', 'config', '--config-file', str(custom_config_filepath.absolute())) result = click_runner.invoke(nucypher_cli, view_args, input=FAKE_PASSWORD_CONFIRMED) assert result.exit_code == 0, result.exception assert "checksum_address" in result.output assert "domain" in result.output assert TEMPORARY_DOMAIN in result.output assert str(custom_filepath) in result.output
def view(general_config, config_options, config_file): """ View existing Bob's configuration. """ emitter = _setup_emitter(general_config) bob_config = config_options.create_config(emitter, config_file) filepath = config_file or bob_config.config_file_location emitter.echo(f"Bob Configuration {filepath} \n {'='*55}") response = BobConfiguration._read_configuration_file(filepath=filepath) return emitter.echo(json.dumps(response, indent=4))
def bob_blockchain_test_config(blockchain_ursulas, three_agents): token_agent, miner_agent, policy_agent = three_agents etherbase, alice_address, bob_address, *everyone_else = token_agent.blockchain.interface.w3.eth.accounts config = BobConfiguration(temp=True, auto_initialize=True, auto_generate_keys=True, checksum_address=bob_address, passphrase=TEST_URSULA_INSECURE_DEVELOPMENT_PASSWORD, network_middleware=MockRestMiddleware(), known_nodes=blockchain_ursulas, start_learning_now=False, abort_on_learning_error=True, federated_only=False, import_seed_registry=False, save_metadata=False, load_metadata=False) yield config config.cleanup()
def test_bob_make_card(click_runner, custom_filepath): custom_config_filepath = os.path.join(custom_filepath, BobConfiguration.generate_filename()) command = ('bob', 'make-card', '--nickname', 'anders', '--config-file', custom_config_filepath) result = click_runner.invoke(nucypher_cli, command, input=FAKE_PASSWORD_CONFIRMED, catch_exceptions=False) assert result.exit_code == 0 assert "Saved new character card " in result.output
def test_bob_control_starts_with_preexisting_configuration(click_runner, custom_filepath): custom_config_filepath = os.path.join(custom_filepath, BobConfiguration.generate_filename()) init_args = ('bob', 'run', '--dry-run', '--config-file', custom_config_filepath) user_input = '{password}\n{password}\n'.format(password=INSECURE_DEVELOPMENT_PASSWORD) result = click_runner.invoke(nucypher_cli, init_args, input=user_input) assert result.exit_code == 0, result.exception assert "Bob Verifying Key" in result.output assert "Bob Encrypting Key" in result.output
def test_bob_view_with_preexisting_configuration(click_runner, custom_filepath): custom_config_filepath = os.path.join(custom_filepath, BobConfiguration.generate_filename()) view_args = ('bob', 'config', '--config-file', custom_config_filepath) user_input = '{password}\n{password}\n'.format(password=INSECURE_DEVELOPMENT_PASSWORD) result = click_runner.invoke(nucypher_cli, view_args, input=user_input) assert result.exit_code == 0, result.exception assert "checksum_address" in result.output assert "domains" in result.output assert TEMPORARY_DOMAIN in result.output assert custom_filepath in result.output
def generate_config(self, emitter, config_root, federated_only): checksum_address = self.checksum_address if not checksum_address and not federated_only: checksum_address = select_client_account( emitter=emitter, provider_uri=self.provider_uri, show_balances=False) return BobConfiguration.generate( password=get_nucypher_password(confirm=True), config_root=config_root, checksum_address=checksum_address, domains=self.domains, federated_only=federated_only, registry_filepath=self.registry_filepath, provider_uri=self.provider_uri)
def generate_config(self, emitter: StdoutEmitter, config_root: str) -> BobConfiguration: checksum_address = self.checksum_address if not checksum_address and not self.federated_only: checksum_address = select_client_account(emitter=emitter, signer_uri=self.signer_uri, provider_uri=self.provider_uri) # TODO: See #1888 return BobConfiguration.generate( password=get_nucypher_password(confirm=True), config_root=config_root, checksum_address=checksum_address, domains=self.domains, federated_only=self.federated_only, registry_filepath=self.registry_filepath, provider_uri=self.provider_uri, signer_uri=self.signer_uri, gas_strategy=self.gas_strategy, )
def generate_config(self, emitter: StdoutEmitter, config_root: Path, key_material: str) -> BobConfiguration: checksum_address = self.checksum_address if not checksum_address and not self.federated_only: checksum_address = select_client_account( emitter=emitter, signer_uri=self.signer_uri, provider_uri=self.provider_uri) # TODO: See #1888 return BobConfiguration.generate( password=get_nucypher_password(emitter=emitter, confirm=True), key_material=bytes.fromhex(key_material) if key_material else None, config_root=config_root, checksum_address=checksum_address, domain=self.domain, federated_only=self.federated_only, registry_filepath=self.registry_filepath, provider_uri=self.provider_uri, signer_uri=self.signer_uri, gas_strategy=self.gas_strategy, max_gas_price=self.max_gas_price, lonely=self.lonely)
def _get_bob(self, passphrase) -> object: ''' :param passphrase: Passpharse for new Bob instance :return: None ''' try: bob_config_file = os.path.join(self.TEMP_BOB_DIR, "config_root", "bob.config") bob_config = BobConfiguration.from_configuration_file( filepath=bob_config_file, network_middleware=RestMiddleware(), start_learning_now=False, save_metadata=False, ) bob_config.keyring.unlock(password=passphrase) bob = bob_config.produce() except: shutil.rmtree(self.TEMP_BOB_DIR, ignore_errors=True) os.mkdir(self.TEMP_BOB_DIR) bob_config = BobConfiguration( config_root=os.path.join(self.TEMP_BOB_DIR, "config_root"), is_me=True, known_nodes={self.ursula}, start_learning_now=True, federated_only=True, learn_on_same_thread=True, ) bob_config.initialize(password=passphrase) bob_config.keyring.unlock(password=passphrase) bob = bob_config.produce() bob_config_file = bob_config.to_configuration_file() return bob
def test_cli_lifecycle(click_runner, testerchain, random_policy_label, federated_ursulas, blockchain_ursulas, custom_filepath, custom_filepath_2, federated): """ This is an end to end integration test that runs each cli call in it's own process using only CLI character control entry points, and a mock side channel that runs in the control process """ # Boring Setup Stuff alice_config_root = custom_filepath bob_config_root = custom_filepath_2 envvars = {'NUCYPHER_KEYRING_PASSWORD': INSECURE_DEVELOPMENT_PASSWORD} # A side channel exists - Perhaps a dApp side_channel = MockSideChannel() shutil.rmtree(custom_filepath, ignore_errors=True) shutil.rmtree(custom_filepath_2, ignore_errors=True) """ Scene 1: Alice Installs nucypher to a custom filepath and examines her configuration """ # Alice performs an installation for the first time alice_init_args = ('alice', 'init', '--network', TEMPORARY_DOMAIN, '--config-root', alice_config_root) if federated: alice_init_args += ('--federated-only', ) else: alice_init_args += ('--provider', TEST_PROVIDER_URI, '--no-registry', '--pay-with', testerchain.alice_account) alice_init_response = click_runner.invoke(nucypher_cli, alice_init_args, catch_exceptions=False, env=envvars) assert alice_init_response.exit_code == 0 # Alice uses her configuration file to run the character "view" command alice_configuration_file_location = os.path.join( alice_config_root, AliceConfiguration.generate_filename()) alice_view_args = ('alice', 'public-keys', '--json-ipc', '--config-file', alice_configuration_file_location) alice_view_result = click_runner.invoke( nucypher_cli, alice_view_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False, env=envvars) assert alice_view_result.exit_code == 0 alice_view_response = json.loads(alice_view_result.output) # Alice expresses her desire to participate in data sharing with nucypher # by saving her public key somewhere Bob and Enrico can find it. side_channel.save_alice_pubkey( alice_view_response['result']['alice_verifying_key']) """ Scene 2: Bob installs nucypher, examines his configuration and expresses his interest to participate in data retrieval by posting his public keys somewhere public (side-channel). """ bob_init_args = ('bob', 'init', '--network', TEMPORARY_DOMAIN, '--config-root', bob_config_root) if federated: bob_init_args += ('--federated-only', ) else: bob_init_args += ('--provider', TEST_PROVIDER_URI, '--no-registry', '--checksum-address', testerchain.bob_account) bob_init_response = click_runner.invoke(nucypher_cli, bob_init_args, catch_exceptions=False, env=envvars) assert bob_init_response.exit_code == 0 # Alice uses her configuration file to run the character "view" command bob_configuration_file_location = os.path.join( bob_config_root, BobConfiguration.generate_filename()) bob_view_args = ('bob', 'public-keys', '--json-ipc', '--config-file', bob_configuration_file_location) bob_view_result = click_runner.invoke(nucypher_cli, bob_view_args, catch_exceptions=False, env=envvars) assert bob_view_result.exit_code == 0 bob_view_response = json.loads(bob_view_result.output) # Bob interacts with the sidechannel bob_public_keys = MockSideChannel.BobPublicKeys( bob_view_response['result']['bob_encrypting_key'], bob_view_response['result']['bob_verifying_key']) side_channel.save_bob_public_keys(bob_public_keys) """ Scene 3: Alice derives a policy keypair, and saves it's public key to a sidechannel. """ random_label = random_policy_label.decode() # Unicode string derive_args = ('alice', 'derive-policy-pubkey', '--mock-networking', '--json-ipc', '--config-file', alice_configuration_file_location, '--label', random_label) derive_response = click_runner.invoke(nucypher_cli, derive_args, catch_exceptions=False, env=envvars) assert derive_response.exit_code == 0 derive_response = json.loads(derive_response.output) assert derive_response['result']['label'] == random_label # Alice and the sidechannel: at Tinagre policy = MockSideChannel.PolicyAndLabel( encrypting_key=derive_response['result']['policy_encrypting_key'], label=derive_response['result']['label']) side_channel.save_policy(policy=policy) """ Scene 4: Enrico encrypts some data for some policy public key and saves it to a side channel. """ def enrico_encrypts(): # Fetch! policy = side_channel.fetch_policy() enrico_args = ('enrico', 'encrypt', '--json-ipc', '--policy-encrypting-key', policy.encrypting_key, '--message', PLAINTEXT) encrypt_result = click_runner.invoke(nucypher_cli, enrico_args, catch_exceptions=False, env=envvars) assert encrypt_result.exit_code == 0 encrypt_result = json.loads(encrypt_result.output) encrypted_message = encrypt_result['result'][ 'message_kit'] # type: str side_channel.save_message_kit(message_kit=encrypted_message) return encrypt_result def _alice_decrypts(encrypt_result): """ alice forgot what exactly she encrypted for bob. she decrypts it just to make sure. """ policy = side_channel.fetch_policy() alice_signing_key = side_channel.fetch_alice_pubkey() message_kit = encrypt_result['result']['message_kit'] decrypt_args = ( 'alice', 'decrypt', '--mock-networking', '--json-ipc', '--config-file', alice_configuration_file_location, '--message-kit', message_kit, '--label', policy.label, ) if federated: decrypt_args += ('--federated-only', ) decrypt_response_fail = click_runner.invoke(nucypher_cli, decrypt_args[0:7], catch_exceptions=False, env=envvars) assert decrypt_response_fail.exit_code == 2 decrypt_response = click_runner.invoke(nucypher_cli, decrypt_args, catch_exceptions=False, env=envvars) decrypt_result = json.loads(decrypt_response.output) for cleartext in decrypt_result['result']['cleartexts']: assert b64decode(cleartext.encode()).decode() == PLAINTEXT # replenish the side channel side_channel.save_policy(policy=policy) side_channel.save_alice_pubkey(alice_signing_key) return encrypt_result """ Scene 5: Alice grants access to Bob: We catch up with Alice later on, but before she has learned about existing Ursulas... """ if federated: teacher = list(federated_ursulas)[0] else: teacher = list(blockchain_ursulas)[1] teacher_uri = teacher.seed_node_metadata(as_teacher_uri=True) # Some Ursula is running somewhere def _run_teacher(_encrypt_result): start_pytest_ursula_services(ursula=teacher) return teacher_uri def _grant(teacher_uri): # Alice fetched Bob's public keys from the side channel bob_keys = side_channel.fetch_bob_public_keys() bob_encrypting_key = bob_keys.bob_encrypting_key bob_verifying_key = bob_keys.bob_verifying_key grant_args = ('alice', 'grant', '--mock-networking', '--json-ipc', '--network', TEMPORARY_DOMAIN, '--teacher', teacher_uri, '--config-file', alice_configuration_file_location, '--m', 2, '--n', 3, '--value', Web3.toWei(1, 'ether'), '--expiration', (maya.now() + datetime.timedelta(days=3)).iso8601(), '--label', random_label, '--bob-encrypting-key', bob_encrypting_key, '--bob-verifying-key', bob_verifying_key) if federated: grant_args += ('--federated-only', ) else: grant_args += ('--provider', TEST_PROVIDER_URI) grant_result = click_runner.invoke(nucypher_cli, grant_args, catch_exceptions=False, env=envvars) assert grant_result.exit_code == 0 grant_result = json.loads(grant_result.output) # TODO: Expand test to consider manual treasure map handing # # Alice puts the Treasure Map somewhere Bob can get it. # side_channel.save_treasure_map(treasure_map=grant_result['result']['treasure_map']) return grant_result def _bob_retrieves(_grant_result): """ Scene 6: Bob retrieves encrypted data from the side channel and uses nucypher to re-encrypt it """ # Bob interacts with a sidechannel ciphertext_message_kit = side_channel.fetch_message_kit() policy = side_channel.fetch_policy() policy_encrypting_key, label = policy alice_signing_key = side_channel.fetch_alice_pubkey() retrieve_args = ('bob', 'retrieve', '--mock-networking', '--json-ipc', '--teacher', teacher_uri, '--config-file', bob_configuration_file_location, '--message-kit', ciphertext_message_kit, '--label', label, '--policy-encrypting-key', policy_encrypting_key, '--alice-verifying-key', alice_signing_key) if federated: retrieve_args += ('--federated-only', ) retrieve_response = click_runner.invoke(nucypher_cli, retrieve_args, catch_exceptions=False, env=envvars) assert retrieve_response.exit_code == 0 retrieve_response = json.loads(retrieve_response.output) for cleartext in retrieve_response['result']['cleartexts']: assert b64decode(cleartext.encode()).decode() == PLAINTEXT return # Run the Callbacks d = threads.deferToThread(enrico_encrypts) # scene 4 d.addCallback(_alice_decrypts) # scene 5 (uncertainty) d.addCallback(_run_teacher) # scene 6 (preamble) d.addCallback(_grant) # scene 7 d.addCallback(_bob_retrieves) # scene 8 yield d
def bob(click_config, action, quiet, teacher_uri, min_stake, http_port, discovery_port, federated_only, network, config_root, config_file, pay_with, provider_uri, registry_filepath, dev, force, dry_run, label, policy_encrypting_key, alice_verifying_key, message_kit): """ Start and manage a "Bob" character. """ # # Validate # # Banner click.clear() if not click_config.json_ipc and not click_config.quiet: click.secho(BOB_BANNER) # # Eager Actions # if action == 'init': """Create a brand-new persistent Bob""" if dev: raise click.BadArgumentUsage("Cannot create a persistent development character") if not config_root: # Flag config_root = click_config.config_file # Envvar new_bob_config = BobConfiguration.generate(password=get_password(confirm=True), config_root=config_root or DEFAULT_CONFIG_ROOT, checksum_address=pay_with, domains={network} if network else None, federated_only=federated_only, download_registry=click_config.no_registry, registry_filepath=registry_filepath, provider_uri=provider_uri) return painting.paint_new_installation_help(new_configuration=new_bob_config) # TODO # elif action == "view": # """Paint an existing configuration to the console""" # response = BobConfiguration._read_configuration_file(filepath=config_file or bob_config.config_file_location) # return BOB.controller.emitter(response=response) # # Make Bob # if dev: bob_config = BobConfiguration(dev_mode=True, domains={network}, provider_uri=provider_uri, federated_only=True, checksum_address=pay_with, network_middleware=click_config.middleware) else: try: bob_config = BobConfiguration.from_configuration_file( filepath=config_file, domains={network} if network else None, checksum_address=pay_with, rest_port=discovery_port, provider_uri=provider_uri, network_middleware=click_config.middleware) except FileNotFoundError: return actions.handle_missing_configuration_file(character_config_class=BobConfiguration, config_file=config_file) BOB = actions.make_cli_character(character_config=bob_config, click_config=click_config, dev=dev, teacher_uri=teacher_uri, min_stake=min_stake) # # Admin Action # if action == "run": # Echo Public Keys click_config.emit(message=f"Bob Verifying Key {bytes(BOB.stamp).hex()}", color='green', bold=True) # RPC if click_config.json_ipc: rpc_controller = BOB.make_rpc_controller() _transport = rpc_controller.make_control_transport() rpc_controller.start() return click_config.emit(message=f"Bob Verifying Key {bytes(BOB.stamp).hex()}", color='green', bold=True) bob_encrypting_key = bytes(BOB.public_keys(DecryptingPower)).hex() click_config.emit(message=f"Bob Encrypting Key {bob_encrypting_key}", color="blue", bold=True) # Start Controller controller = BOB.make_control_transport() BOB.log.info('Starting HTTP Character Web Controller') return controller.start(http_port=http_port, dry_run=dry_run) elif action == "destroy": """Delete Bob's character configuration files from the disk""" # Validate if dev: message = "'nucypher bob destroy' cannot be used in --dev mode" raise click.BadOptionUsage(option_name='--dev', message=message) # Request return actions.destroy_configuration(character_config=bob_config) # # Bob API Actions # elif action == "public-keys": response = BOB.controller.public_keys() return response elif action == "retrieve": # Validate if not all((label, policy_encrypting_key, alice_verifying_key, message_kit)): input_specification, output_specification = BOB.control.get_specifications(interface_name='retrieve') required_fields = ', '.join(input_specification) raise click.BadArgumentUsage(f'{required_fields} are required flags to retrieve') # Request bob_request_data = { 'label': label, 'policy_encrypting_key': policy_encrypting_key, 'alice_verifying_key': alice_verifying_key, 'message_kit': message_kit, } response = BOB.controller.retrieve(request=bob_request_data) return response else: raise click.BadArgumentUsage(f"No such argument {action}")