Exemplo n.º 1
0
 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)
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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()
Exemplo n.º 5
0
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()
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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()
Exemplo n.º 8
0
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()
Exemplo n.º 9
0
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()
Exemplo n.º 10
0
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'
Exemplo n.º 11
0
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
Exemplo n.º 12
0
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"
Exemplo n.º 13
0
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()
Exemplo n.º 14
0
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?
Exemplo n.º 15
0
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()
Exemplo n.º 16
0
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'
Exemplo n.º 17
0
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)
Exemplo n.º 18
0
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()
Exemplo n.º 19
0
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
Exemplo n.º 20
0
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))
Exemplo n.º 21
0
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()
Exemplo n.º 22
0
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
Exemplo n.º 23
0
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
Exemplo n.º 24
0
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
Exemplo n.º 25
0
    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)
Exemplo n.º 26
0
    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,
        )
Exemplo n.º 27
0
    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)
Exemplo n.º 28
0
    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
Exemplo n.º 29
0
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
Exemplo n.º 30
0
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}")