mirror of https://github.com/nucypher/nucypher.git
177 lines
7.4 KiB
Python
177 lines
7.4 KiB
Python
import os
|
|
from unittest import mock
|
|
|
|
from nucypher.cli.main import nucypher_cli
|
|
from nucypher.config.characters import AliceConfiguration
|
|
from nucypher.config.constants import NUCYPHER_ENVVAR_KEYRING_PASSWORD
|
|
from nucypher.utilities.sandbox.constants import (
|
|
INSECURE_DEVELOPMENT_PASSWORD,
|
|
MOCK_IP_ADDRESS,
|
|
MOCK_CUSTOM_INSTALLATION_PATH,
|
|
TEMPORARY_DOMAIN
|
|
)
|
|
from nucypher.cli.actions import SUCCESSFUL_DESTRUCTION
|
|
|
|
|
|
@mock.patch('nucypher.config.characters.AliceConfiguration.default_filepath', return_value='/non/existent/file')
|
|
def test_missing_configuration_file(default_filepath_mock, click_runner):
|
|
cmd_args = ('alice', 'run', '--network', TEMPORARY_DOMAIN)
|
|
result = click_runner.invoke(nucypher_cli, cmd_args, catch_exceptions=False)
|
|
assert result.exit_code != 0
|
|
assert default_filepath_mock.called
|
|
assert "run: 'nucypher alice init'" in result.output
|
|
|
|
|
|
def test_initialize_alice_defaults(click_runner, mocker, custom_filepath, monkeypatch):
|
|
monkeypatch.delenv(NUCYPHER_ENVVAR_KEYRING_PASSWORD, raising=False)
|
|
|
|
# Mock out filesystem writes
|
|
mocker.patch.object(AliceConfiguration, 'initialize', autospec=True)
|
|
mocker.patch.object(AliceConfiguration, 'to_configuration_file', autospec=True)
|
|
|
|
# Use default alice init args
|
|
init_args = ('alice', 'init',
|
|
'--network', TEMPORARY_DOMAIN,
|
|
'--config-root', custom_filepath,
|
|
'--federated-only')
|
|
|
|
user_input = '{password}\n{password}\n'.format(password=INSECURE_DEVELOPMENT_PASSWORD)
|
|
result = click_runner.invoke(nucypher_cli, init_args, input=user_input, catch_exceptions=False)
|
|
assert result.exit_code == 0
|
|
|
|
# REST Host
|
|
assert "nucypher alice run" in result.output
|
|
|
|
# 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_alice_control_starts_with_mocked_keyring(click_runner, mocker, monkeypatch):
|
|
monkeypatch.delenv(NUCYPHER_ENVVAR_KEYRING_PASSWORD, raising=False)
|
|
|
|
class MockKeyring:
|
|
is_unlocked = False
|
|
|
|
@classmethod
|
|
def unlock(cls, password, *args, **kwargs):
|
|
assert password == INSECURE_DEVELOPMENT_PASSWORD
|
|
cls.is_unlocked = True
|
|
|
|
mocker.patch.object(AliceConfiguration, "attach_keyring", return_value=None)
|
|
good_enough_config = AliceConfiguration(dev_mode=True, federated_only=True, keyring=MockKeyring)
|
|
mocker.patch.object(AliceConfiguration, "from_configuration_file", return_value=good_enough_config)
|
|
init_args = ('alice', 'run', '-x', '--network', TEMPORARY_DOMAIN)
|
|
|
|
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
|
|
|
|
|
|
def test_initialize_alice_with_custom_configuration_root(custom_filepath, click_runner, monkeypatch):
|
|
monkeypatch.delenv(NUCYPHER_ENVVAR_KEYRING_PASSWORD, raising=False)
|
|
|
|
# Use a custom local filepath for configuration
|
|
init_args = ('alice', '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
|
|
|
|
# CLI Output
|
|
assert MOCK_CUSTOM_INSTALLATION_PATH in result.output, "Configuration not in system temporary directory"
|
|
assert "nucypher alice 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, AliceConfiguration.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_alice_control_starts_with_preexisting_configuration(click_runner, custom_filepath):
|
|
|
|
custom_config_filepath = os.path.join(custom_filepath, AliceConfiguration.generate_filename())
|
|
|
|
run_args = ('alice', '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, run_args, input=user_input)
|
|
assert result.exit_code == 0
|
|
|
|
|
|
def test_alice_cannot_init_with_dev_flag(click_runner):
|
|
init_args = ('alice', 'init',
|
|
'--network', TEMPORARY_DOMAIN,
|
|
'--federated-only',
|
|
'--dev')
|
|
result = click_runner.invoke(nucypher_cli, init_args, catch_exceptions=False)
|
|
assert result.exit_code == 2
|
|
assert 'Cannot create a persistent development character' in result.output, \
|
|
'Missing or invalid error message was produced.'
|
|
|
|
|
|
def test_alice_derive_policy_pubkey(click_runner):
|
|
label = 'random_label'
|
|
derive_key_args = ('alice', 'derive-policy-pubkey',
|
|
'--label', label,
|
|
'--dev')
|
|
|
|
result = click_runner.invoke(nucypher_cli, derive_key_args, catch_exceptions=False)
|
|
|
|
assert result.exit_code == 0
|
|
assert "policy_encrypting_key" in result.output
|
|
assert "label" in result.output
|
|
assert label in result.output
|
|
|
|
|
|
def test_alice_public_keys(click_runner):
|
|
derive_key_args = ('alice', 'public-keys',
|
|
'--dev')
|
|
|
|
result = click_runner.invoke(nucypher_cli, derive_key_args, catch_exceptions=False)
|
|
|
|
assert result.exit_code == 0
|
|
assert "alice_verifying_key" in result.output
|
|
|
|
|
|
def test_alice_view_preexisting_configuration(click_runner, custom_filepath):
|
|
custom_config_filepath = os.path.join(custom_filepath, AliceConfiguration.generate_filename())
|
|
|
|
view_args = ('alice', '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
|
|
assert "checksum_address" in result.output
|
|
assert "domains" in result.output
|
|
assert TEMPORARY_DOMAIN in result.output
|
|
assert custom_filepath in result.output
|
|
|
|
|
|
def test_alice_destroy(click_runner, custom_filepath):
|
|
"""Should be the last test since it deletes the configuration file"""
|
|
custom_config_filepath = os.path.join(custom_filepath, AliceConfiguration.generate_filename())
|
|
destroy_args = ('alice', 'destroy',
|
|
'--config-file', custom_config_filepath,
|
|
'--force')
|
|
|
|
result = click_runner.invoke(nucypher_cli, destroy_args, catch_exceptions=False)
|
|
assert result.exit_code == 0
|
|
assert SUCCESSFUL_DESTRUCTION in result.output
|
|
assert not os.path.exists(custom_config_filepath), "Alice config file was deleted"
|