mirror of https://github.com/nucypher/nucypher.git
tests respect the Keystore API
parent
37a944df44
commit
4f7bdf5c46
|
@ -30,7 +30,7 @@ from web3 import Web3
|
|||
|
||||
from nucypher.cli.main import nucypher_cli
|
||||
from nucypher.config.characters import AliceConfiguration, BobConfiguration
|
||||
from nucypher.config.constants import NUCYPHER_ENVVAR_KEYRING_PASSWORD, TEMPORARY_DOMAIN, \
|
||||
from nucypher.config.constants import NUCYPHER_ENVVAR_KEYSTORE_PASSWORD, TEMPORARY_DOMAIN, \
|
||||
NUCYPHER_ENVVAR_ALICE_ETH_PASSWORD, NUCYPHER_ENVVAR_BOB_ETH_PASSWORD
|
||||
from nucypher.crypto.kits import UmbralMessageKit
|
||||
from nucypher.utilities.logging import GlobalLoggerSettings
|
||||
|
@ -106,7 +106,7 @@ def run_entire_cli_lifecycle(click_runner,
|
|||
# Boring Setup Stuff
|
||||
alice_config_root = str(custom_filepath)
|
||||
bob_config_root = str(custom_filepath_2)
|
||||
envvars = {NUCYPHER_ENVVAR_KEYRING_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD,
|
||||
envvars = {NUCYPHER_ENVVAR_KEYSTORE_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD,
|
||||
NUCYPHER_ENVVAR_ALICE_ETH_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD,
|
||||
NUCYPHER_ENVVAR_BOB_ETH_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD}
|
||||
|
||||
|
|
|
@ -17,13 +17,16 @@
|
|||
|
||||
import os
|
||||
from unittest import mock
|
||||
from unittest.mock import PropertyMock
|
||||
|
||||
from nucypher.cli.commands.alice import AliceConfigOptions
|
||||
from nucypher.cli.literature import SUCCESSFUL_DESTRUCTION, COLLECT_NUCYPHER_PASSWORD
|
||||
from nucypher.cli.main import nucypher_cli
|
||||
from nucypher.config.base import CharacterConfiguration
|
||||
from nucypher.config.characters import AliceConfiguration
|
||||
from nucypher.config.constants import NUCYPHER_ENVVAR_KEYRING_PASSWORD, TEMPORARY_DOMAIN
|
||||
from nucypher.config.constants import NUCYPHER_ENVVAR_KEYSTORE_PASSWORD, TEMPORARY_DOMAIN
|
||||
from nucypher.config.storages import LocalFileBasedNodeStorage
|
||||
from nucypher.crypto.keystore import Keystore
|
||||
from nucypher.policy.identity import Card
|
||||
from tests.constants import (
|
||||
FAKE_PASSWORD_CONFIRMED,
|
||||
|
@ -41,14 +44,17 @@ def test_missing_configuration_file(default_filepath_mock, click_runner):
|
|||
assert "nucypher alice init" in result.output
|
||||
|
||||
|
||||
def test_initialize_alice_defaults(click_runner, mocker, custom_filepath, monkeypatch, blockchain_ursulas):
|
||||
monkeypatch.delenv(NUCYPHER_ENVVAR_KEYRING_PASSWORD, raising=False)
|
||||
def test_initialize_alice_defaults(click_runner, mocker, custom_filepath, monkeypatch, blockchain_ursulas, tmpdir):
|
||||
monkeypatch.delenv(NUCYPHER_ENVVAR_KEYSTORE_PASSWORD, raising=False)
|
||||
|
||||
# Mock out filesystem writes
|
||||
mocker.patch.object(AliceConfiguration, 'initialize', autospec=True)
|
||||
mocker.patch.object(AliceConfiguration, 'to_configuration_file', autospec=True)
|
||||
mocker.patch.object(LocalFileBasedNodeStorage, 'all', return_value=blockchain_ursulas)
|
||||
|
||||
# Mock Keystore init
|
||||
keystore = Keystore.generate(keystore_dir=tmpdir, password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
mocker.patch.object(CharacterConfiguration, 'keystore', return_value=keystore, new_callable=PropertyMock)
|
||||
|
||||
# Use default alice init args
|
||||
init_args = ('alice', 'init',
|
||||
|
@ -66,13 +72,13 @@ def test_initialize_alice_defaults(click_runner, mocker, custom_filepath, monkey
|
|||
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, custom_filepath):
|
||||
monkeypatch.delenv(NUCYPHER_ENVVAR_KEYRING_PASSWORD, raising=False)
|
||||
def test_alice_control_starts_with_mocked_keystore(click_runner, mocker, monkeypatch, custom_filepath):
|
||||
monkeypatch.delenv(NUCYPHER_ENVVAR_KEYSTORE_PASSWORD, raising=False)
|
||||
|
||||
class MockKeyring:
|
||||
class MockKeystore:
|
||||
is_unlocked = False
|
||||
keyring_root = custom_filepath / 'keyring'
|
||||
checksum_address = None
|
||||
keystore_dir = custom_filepath / 'keystore'
|
||||
keystore_path = custom_filepath / 'keystore' / 'path.json'
|
||||
|
||||
def derive_crypto_power(self, power_class, *args, **kwargs):
|
||||
return power_class()
|
||||
|
@ -82,8 +88,7 @@ def test_alice_control_starts_with_mocked_keyring(click_runner, mocker, monkeypa
|
|||
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())
|
||||
good_enough_config = AliceConfiguration(dev_mode=True, federated_only=True, keystore=MockKeystore())
|
||||
mocker.patch.object(AliceConfigOptions, "create_config", return_value=good_enough_config)
|
||||
init_args = ('alice', 'run', '-x', '--lonely', '--network', TEMPORARY_DOMAIN)
|
||||
result = click_runner.invoke(nucypher_cli, init_args, input=FAKE_PASSWORD_CONFIRMED)
|
||||
|
@ -91,7 +96,7 @@ def test_alice_control_starts_with_mocked_keyring(click_runner, mocker, monkeypa
|
|||
|
||||
|
||||
def test_initialize_alice_with_custom_configuration_root(custom_filepath, click_runner, monkeypatch):
|
||||
monkeypatch.delenv(NUCYPHER_ENVVAR_KEYRING_PASSWORD, raising=False)
|
||||
monkeypatch.delenv(NUCYPHER_ENVVAR_KEYSTORE_PASSWORD, raising=False)
|
||||
|
||||
# Use a custom local filepath for configuration
|
||||
init_args = ('alice', 'init',
|
||||
|
@ -109,7 +114,7 @@ def test_initialize_alice_with_custom_configuration_root(custom_filepath, click_
|
|||
|
||||
# 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, 'keystore')), 'KEYSTORE 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())
|
||||
|
|
|
@ -67,7 +67,7 @@ def test_initialize_bob_with_custom_configuration_root(custom_filepath, click_ru
|
|||
|
||||
# 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, 'keystore')), 'KEYSTORE 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())
|
||||
|
@ -143,7 +143,7 @@ def test_bob_retrieves_twice_via_cli(click_runner,
|
|||
'--config-root', bob_config_root,
|
||||
'--federated-only')
|
||||
|
||||
envvars = {'NUCYPHER_KEYRING_PASSWORD': INSECURE_DEVELOPMENT_PASSWORD}
|
||||
envvars = {'NUCYPHER_KEYSTORE_PASSWORD': INSECURE_DEVELOPMENT_PASSWORD}
|
||||
|
||||
log.info("Init'ing a normal Bob; we'll substitute the Policy Bob in shortly.")
|
||||
bob_init_response = click_runner.invoke(nucypher_cli, bob_init_args, catch_exceptions=False, env=envvars)
|
||||
|
|
|
@ -23,7 +23,7 @@ import pytest
|
|||
from nucypher.blockchain.eth.registry import InMemoryContractRegistry
|
||||
from nucypher.cli.main import nucypher_cli
|
||||
from nucypher.config.characters import AliceConfiguration, BobConfiguration, UrsulaConfiguration
|
||||
from nucypher.config.constants import NUCYPHER_ENVVAR_KEYRING_PASSWORD, TEMPORARY_DOMAIN
|
||||
from nucypher.config.constants import NUCYPHER_ENVVAR_KEYSTORE_PASSWORD, TEMPORARY_DOMAIN
|
||||
from tests.constants import (
|
||||
FAKE_PASSWORD_CONFIRMED,
|
||||
INSECURE_DEVELOPMENT_PASSWORD,
|
||||
|
@ -36,7 +36,7 @@ from tests.constants import (
|
|||
CONFIG_CLASSES = (AliceConfiguration, BobConfiguration, UrsulaConfiguration)
|
||||
|
||||
|
||||
ENV = {NUCYPHER_ENVVAR_KEYRING_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD}
|
||||
ENV = {NUCYPHER_ENVVAR_KEYSTORE_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD}
|
||||
|
||||
|
||||
@pytest.mark.parametrize('config_class', CONFIG_CLASSES)
|
||||
|
@ -64,7 +64,7 @@ def test_initialize_via_cli(config_class, custom_filepath, click_runner, monkeyp
|
|||
|
||||
# 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, 'keystore')), 'KEYSTORE does not exist'
|
||||
assert os.path.isdir(os.path.join(custom_filepath, 'known_nodes')), 'known_nodes directory does not exist'
|
||||
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ from nucypher.characters.chaotic import Felix
|
|||
from nucypher.cli.literature import SUCCESSFUL_DESTRUCTION
|
||||
from nucypher.cli.main import nucypher_cli
|
||||
from nucypher.config.characters import FelixConfiguration
|
||||
from nucypher.config.constants import NUCYPHER_ENVVAR_KEYRING_PASSWORD, TEMPORARY_DOMAIN
|
||||
from nucypher.config.constants import NUCYPHER_ENVVAR_KEYSTORE_PASSWORD, TEMPORARY_DOMAIN
|
||||
from tests.constants import (INSECURE_DEVELOPMENT_PASSWORD, MOCK_CUSTOM_INSTALLATION_PATH_2, TEST_PROVIDER_URI)
|
||||
|
||||
|
||||
|
@ -58,7 +58,7 @@ def test_run_felix(click_runner, testerchain, agency_local_registry):
|
|||
os.environ['NUCYPHER_FELIX_DB_SECRET'] = INSECURE_DEVELOPMENT_PASSWORD
|
||||
|
||||
# Test subproc (Click)
|
||||
envvars = {NUCYPHER_ENVVAR_KEYRING_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD,
|
||||
envvars = {NUCYPHER_ENVVAR_KEYSTORE_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD,
|
||||
'NUCYPHER_FELIX_DB_SECRET': INSECURE_DEVELOPMENT_PASSWORD,
|
||||
'NUCYPHER_WORKER_ETH_PASSWORD': INSECURE_DEVELOPMENT_PASSWORD,
|
||||
'FLASK_DEBUG': '1'}
|
||||
|
@ -105,8 +105,7 @@ def test_run_felix(click_runner, testerchain, agency_local_registry):
|
|||
felix_config = FelixConfiguration.from_configuration_file(filepath=configuration_file_location,
|
||||
registry_filepath=agency_local_registry.filepath)
|
||||
|
||||
felix_config.attach_keystore()
|
||||
felix_config.keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
felix_config.keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
felix = felix_config.produce()
|
||||
|
||||
# Make a flask app
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch, PropertyMock
|
||||
|
||||
import pytest
|
||||
|
||||
|
@ -26,13 +25,12 @@ from nucypher.blockchain.eth.actors import Worker
|
|||
from nucypher.cli.main import nucypher_cli
|
||||
from nucypher.config.characters import AliceConfiguration, FelixConfiguration, UrsulaConfiguration
|
||||
from nucypher.config.constants import (
|
||||
NUCYPHER_ENVVAR_KEYRING_PASSWORD,
|
||||
NUCYPHER_ENVVAR_KEYSTORE_PASSWORD,
|
||||
TEMPORARY_DOMAIN,
|
||||
NUCYPHER_ENVVAR_ALICE_ETH_PASSWORD,
|
||||
NUCYPHER_ENVVAR_BOB_ETH_PASSWORD
|
||||
)
|
||||
from nucypher.crypto.keystore import Keystore
|
||||
from nucypher.crypto.umbral_adapter import SecretKey
|
||||
from nucypher.crypto.keystore import Keystore, InvalidPassword
|
||||
from nucypher.network.nodes import Teacher
|
||||
from tests.constants import (
|
||||
INSECURE_DEVELOPMENT_PASSWORD,
|
||||
|
@ -67,7 +65,8 @@ def test_destroy_with_no_configurations(click_runner, custom_filepath):
|
|||
def test_coexisting_configurations(click_runner,
|
||||
custom_filepath,
|
||||
testerchain,
|
||||
agency_local_registry):
|
||||
agency_local_registry,
|
||||
mocker):
|
||||
#
|
||||
# Setup
|
||||
#
|
||||
|
@ -80,12 +79,12 @@ def test_coexisting_configurations(click_runner,
|
|||
# TODO: Is testerchain & Full contract deployment needed here (causes massive slowdown)?
|
||||
alice, ursula, another_ursula, felix, staker, *all_yall = testerchain.unassigned_accounts
|
||||
|
||||
envvars = {NUCYPHER_ENVVAR_KEYRING_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD,
|
||||
envvars = {NUCYPHER_ENVVAR_KEYSTORE_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD,
|
||||
NUCYPHER_ENVVAR_ALICE_ETH_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD,
|
||||
NUCYPHER_ENVVAR_BOB_ETH_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD}
|
||||
|
||||
# Future configuration filepaths for assertions...
|
||||
public_keys_dir = custom_filepath / 'keyring' / 'public'
|
||||
public_keys_dir = custom_filepath / 'keystore' / 'public'
|
||||
known_nodes_dir = custom_filepath / 'known_nodes'
|
||||
|
||||
# ... Ensure they do not exist to begin with.
|
||||
|
@ -110,7 +109,6 @@ def test_coexisting_configurations(click_runner,
|
|||
felix_file_location = custom_filepath / FelixConfiguration.generate_filename()
|
||||
alice_file_location = custom_filepath / AliceConfiguration.generate_filename()
|
||||
ursula_file_location = custom_filepath / UrsulaConfiguration.generate_filename()
|
||||
another_ursula_configuration_file_location = custom_filepath / UrsulaConfiguration.generate_filename(modifier=another_ursula)
|
||||
|
||||
# Felix creates a system configuration
|
||||
felix_init_args = ('felix', 'init',
|
||||
|
@ -127,8 +125,6 @@ def test_coexisting_configurations(click_runner,
|
|||
# All configuration files still exist.
|
||||
assert os.path.isdir(custom_filepath)
|
||||
assert os.path.isfile(felix_file_location)
|
||||
assert os.path.isdir(public_keys_dir)
|
||||
assert len(os.listdir(public_keys_dir)) == 3
|
||||
|
||||
# Use a custom local filepath to init a persistent Alice
|
||||
alice_init_args = ('alice', 'init',
|
||||
|
@ -144,7 +140,6 @@ def test_coexisting_configurations(click_runner,
|
|||
# All configuration files still exist.
|
||||
assert os.path.isfile(felix_file_location)
|
||||
assert os.path.isfile(alice_file_location)
|
||||
assert len(os.listdir(public_keys_dir)) == 5
|
||||
|
||||
# Use the same local filepath to init a persistent Ursula
|
||||
init_args = ('ursula', 'init',
|
||||
|
@ -159,36 +154,34 @@ def test_coexisting_configurations(click_runner,
|
|||
assert result.exit_code == 0, result.output
|
||||
|
||||
# All configuration files still exist.
|
||||
assert len(os.listdir(public_keys_dir)) == 8
|
||||
assert os.path.isfile(felix_file_location)
|
||||
assert os.path.isfile(alice_file_location)
|
||||
assert os.path.isfile(ursula_file_location)
|
||||
|
||||
# keyring signing key
|
||||
signing_public_key = SecretKey.random().public_key()
|
||||
with patch('nucypher.config.keyring.NucypherKeyring.signing_public_key',
|
||||
PropertyMock(return_value=signing_public_key)):
|
||||
# Use the same local filepath to init another persistent Ursula
|
||||
init_args = ('ursula', 'init',
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--worker-address', another_ursula,
|
||||
'--rest-host', MOCK_IP_ADDRESS_2,
|
||||
'--registry-filepath', agency_local_registry.filepath,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--config-root', custom_filepath)
|
||||
key_spy = mocker.spy(Keystore, 'generate')
|
||||
|
||||
result = click_runner.invoke(nucypher_cli, init_args, catch_exceptions=False, env=envvars)
|
||||
assert result.exit_code == 0
|
||||
# keystore signing key
|
||||
# Use the same local filepath to init another persistent Ursula
|
||||
init_args = ('ursula', 'init',
|
||||
'--network', TEMPORARY_DOMAIN,
|
||||
'--worker-address', another_ursula,
|
||||
'--rest-host', MOCK_IP_ADDRESS_2,
|
||||
'--registry-filepath', agency_local_registry.filepath,
|
||||
'--provider', TEST_PROVIDER_URI,
|
||||
'--config-root', custom_filepath)
|
||||
|
||||
another_ursula_configuration_file_location = custom_filepath / UrsulaConfiguration.generate_filename(
|
||||
modifier=bytes(signing_public_key).hex()[:8])
|
||||
result = click_runner.invoke(nucypher_cli, init_args, catch_exceptions=False, env=envvars)
|
||||
assert result.exit_code == 0
|
||||
|
||||
# All configuration files still exist.
|
||||
assert os.path.isfile(felix_file_location)
|
||||
assert os.path.isfile(alice_file_location)
|
||||
|
||||
kid = key_spy.spy_return.id[:8]
|
||||
another_ursula_configuration_file_location = custom_filepath / UrsulaConfiguration.generate_filename(modifier=kid)
|
||||
assert os.path.isfile(another_ursula_configuration_file_location)
|
||||
|
||||
assert os.path.isfile(ursula_file_location)
|
||||
assert len(os.listdir(public_keys_dir)) == 11
|
||||
|
||||
#
|
||||
# Run
|
||||
|
@ -215,7 +208,6 @@ def test_coexisting_configurations(click_runner,
|
|||
assert os.path.isfile(alice_file_location)
|
||||
assert os.path.isfile(another_ursula_configuration_file_location)
|
||||
assert os.path.isfile(ursula_file_location)
|
||||
assert len(os.listdir(public_keys_dir)) == 11
|
||||
|
||||
# Check that the proper Ursula console is attached
|
||||
assert another_ursula in result.output
|
||||
|
@ -229,26 +221,22 @@ def test_coexisting_configurations(click_runner,
|
|||
'--config-file', another_ursula_configuration_file_location)
|
||||
result = click_runner.invoke(nucypher_cli, another_ursula_destruction_args, catch_exceptions=False, env=envvars)
|
||||
assert result.exit_code == 0
|
||||
assert len(os.listdir(public_keys_dir)) == 8
|
||||
assert not os.path.isfile(another_ursula_configuration_file_location)
|
||||
|
||||
ursula_destruction_args = ('ursula', 'destroy', '--config-file', ursula_file_location)
|
||||
result = click_runner.invoke(nucypher_cli, ursula_destruction_args, input='Y', catch_exceptions=False, env=envvars)
|
||||
assert result.exit_code == 0
|
||||
assert 'y/N' in result.output
|
||||
assert len(os.listdir(public_keys_dir)) == 5
|
||||
assert not os.path.isfile(ursula_file_location)
|
||||
|
||||
alice_destruction_args = ('alice', 'destroy', '--force', '--config-file', alice_file_location)
|
||||
result = click_runner.invoke(nucypher_cli, alice_destruction_args, catch_exceptions=False, env=envvars)
|
||||
assert result.exit_code == 0
|
||||
assert len(os.listdir(public_keys_dir)) == 3
|
||||
assert not os.path.isfile(alice_file_location)
|
||||
|
||||
felix_destruction_args = ('felix', 'destroy', '--force', '--config-file', felix_file_location)
|
||||
result = click_runner.invoke(nucypher_cli, felix_destruction_args, catch_exceptions=False, env=envvars)
|
||||
assert result.exit_code == 0
|
||||
assert len(os.listdir(public_keys_dir)) == 0
|
||||
assert not os.path.isfile(felix_file_location)
|
||||
|
||||
|
||||
|
@ -281,9 +269,9 @@ def test_corrupted_configuration(click_runner,
|
|||
)
|
||||
|
||||
# Fails because password is too short and the command uses incomplete args (needs either -F or blockchain details)
|
||||
envvars = {NUCYPHER_ENVVAR_KEYRING_PASSWORD: ''}
|
||||
envvars = {NUCYPHER_ENVVAR_KEYSTORE_PASSWORD: ''}
|
||||
|
||||
with pytest.raises(Keystore.AuthenticationFailed):
|
||||
with pytest.raises(InvalidPassword):
|
||||
result = click_runner.invoke(nucypher_cli, init_args, catch_exceptions=False, env=envvars)
|
||||
assert result.exit_code != 0
|
||||
|
||||
|
@ -292,8 +280,8 @@ def test_corrupted_configuration(click_runner,
|
|||
assert 'ursula.config' not in top_level_config_root # no config file was created
|
||||
|
||||
assert Path(custom_filepath).exists()
|
||||
keyring = custom_filepath / 'keyring'
|
||||
assert not keyring.exists()
|
||||
keystore = custom_filepath / 'keystore'
|
||||
assert not keystore.exists()
|
||||
|
||||
known_nodes = 'known_nodes'
|
||||
path = custom_filepath / known_nodes
|
||||
|
@ -308,7 +296,7 @@ def test_corrupted_configuration(click_runner,
|
|||
'--registry-filepath', agency_local_registry.filepath,
|
||||
'--config-root', custom_filepath)
|
||||
|
||||
envvars = {NUCYPHER_ENVVAR_KEYRING_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD}
|
||||
envvars = {NUCYPHER_ENVVAR_KEYSTORE_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD}
|
||||
result = click_runner.invoke(nucypher_cli, init_args, catch_exceptions=False, env=envvars)
|
||||
assert result.exit_code == 0
|
||||
|
||||
|
@ -317,8 +305,7 @@ def test_corrupted_configuration(click_runner,
|
|||
# Ensure configuration creation
|
||||
top_level_config_root = os.listdir(custom_filepath)
|
||||
assert default_filename in top_level_config_root, "JSON configuration file was not created"
|
||||
assert len(os.listdir(custom_filepath / 'keyring' / 'private')) == 4 # keys were created
|
||||
for field in ['known_nodes', 'keyring', default_filename]:
|
||||
for field in ['known_nodes', 'keystore', default_filename]:
|
||||
assert field in top_level_config_root
|
||||
|
||||
# "Corrupt" the configuration by removing the contract registry
|
||||
|
@ -332,5 +319,4 @@ def test_corrupted_configuration(click_runner,
|
|||
|
||||
# Ensure character destruction
|
||||
top_level_config_root = os.listdir(custom_filepath)
|
||||
assert default_filename not in top_level_config_root # config file was destroyed
|
||||
assert len(os.listdir(custom_filepath / 'keyring' / 'private')) == 0 # keys were destroyed
|
||||
assert default_filename not in top_level_config_root # config file was destroyed
|
||||
|
|
|
@ -19,12 +19,16 @@ import json
|
|||
from json import JSONDecodeError
|
||||
|
||||
import os
|
||||
from unittest.mock import PropertyMock
|
||||
|
||||
import pytest
|
||||
|
||||
from nucypher.cli.literature import SUCCESSFUL_DESTRUCTION, COLLECT_NUCYPHER_PASSWORD
|
||||
from nucypher.cli.main import nucypher_cli
|
||||
from nucypher.config.base import CharacterConfiguration
|
||||
from nucypher.config.characters import UrsulaConfiguration
|
||||
from nucypher.config.constants import APP_DIR, DEFAULT_CONFIG_ROOT, NUCYPHER_ENVVAR_KEYRING_PASSWORD, TEMPORARY_DOMAIN
|
||||
from nucypher.config.constants import APP_DIR, DEFAULT_CONFIG_ROOT, NUCYPHER_ENVVAR_KEYSTORE_PASSWORD, TEMPORARY_DOMAIN
|
||||
from nucypher.crypto.keystore import Keystore
|
||||
from tests.constants import (
|
||||
FAKE_PASSWORD_CONFIRMED, INSECURE_DEVELOPMENT_PASSWORD,
|
||||
MOCK_CUSTOM_INSTALLATION_PATH,
|
||||
|
@ -32,12 +36,16 @@ from tests.constants import (
|
|||
from tests.utils.ursula import MOCK_URSULA_STARTING_PORT, select_test_port
|
||||
|
||||
|
||||
def test_initialize_ursula_defaults(click_runner, mocker):
|
||||
def test_initialize_ursula_defaults(click_runner, mocker, tmpdir):
|
||||
|
||||
# Mock out filesystem writes
|
||||
mocker.patch.object(UrsulaConfiguration, 'initialize', autospec=True)
|
||||
mocker.patch.object(UrsulaConfiguration, 'to_configuration_file', autospec=True)
|
||||
|
||||
# Mock Keystore init
|
||||
keystore = Keystore.generate(keystore_dir=tmpdir, password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
mocker.patch.object(CharacterConfiguration, 'keystore', return_value=keystore, new_callable=PropertyMock)
|
||||
|
||||
# Use default ursula init args
|
||||
init_args = ('ursula', 'init', '--network', TEMPORARY_DOMAIN, '--federated-only')
|
||||
|
||||
|
@ -73,7 +81,7 @@ def test_initialize_custom_configuration_root(custom_filepath, click_runner):
|
|||
|
||||
# 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, 'keystore')), 'KEYSTORE 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, UrsulaConfiguration.generate_filename())
|
||||
|
@ -182,7 +190,7 @@ def test_ursula_destroy_configuration(custom_filepath, click_runner):
|
|||
result = click_runner.invoke(nucypher_cli, destruction_args,
|
||||
input='Y\n'.format(INSECURE_DEVELOPMENT_PASSWORD),
|
||||
catch_exceptions=False,
|
||||
env={NUCYPHER_ENVVAR_KEYRING_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD})
|
||||
env={NUCYPHER_ENVVAR_KEYSTORE_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD})
|
||||
|
||||
# CLI Output
|
||||
assert not os.path.isfile(custom_config_filepath), 'Configuration file still exists'
|
||||
|
|
|
@ -28,7 +28,7 @@ from nucypher.blockchain.eth.token import StakeList
|
|||
from nucypher.cli.main import nucypher_cli
|
||||
from nucypher.config.characters import StakeHolderConfiguration, UrsulaConfiguration
|
||||
from nucypher.config.constants import (
|
||||
NUCYPHER_ENVVAR_KEYRING_PASSWORD,
|
||||
NUCYPHER_ENVVAR_KEYSTORE_PASSWORD,
|
||||
NUCYPHER_ENVVAR_WORKER_ETH_PASSWORD,
|
||||
TEMPORARY_DOMAIN,
|
||||
)
|
||||
|
@ -121,7 +121,7 @@ def test_ursula_and_local_keystore_signer_integration(click_runner,
|
|||
'--signer', mock_signer_uri)
|
||||
|
||||
cli_env = {
|
||||
NUCYPHER_ENVVAR_KEYRING_PASSWORD: password,
|
||||
NUCYPHER_ENVVAR_KEYSTORE_PASSWORD: password,
|
||||
NUCYPHER_ENVVAR_WORKER_ETH_PASSWORD: password,
|
||||
}
|
||||
result = click_runner.invoke(nucypher_cli, init_args, catch_exceptions=False, env=cli_env)
|
||||
|
@ -138,10 +138,9 @@ def test_ursula_and_local_keystore_signer_integration(click_runner,
|
|||
ursula_config = UrsulaConfiguration.from_configuration_file(ursula_config_path)
|
||||
assert ursula_config.signer_uri == mock_signer_uri
|
||||
|
||||
# Mock decryption of web3 client keyring
|
||||
# Mock decryption of web3 client keystore
|
||||
mocker.patch.object(Account, 'decrypt', return_value=worker_account.privateKey)
|
||||
ursula_config.attach_keystore(checksum_address=worker_account.address)
|
||||
ursula_config.keyring.unlock(password=password)
|
||||
ursula_config.keystore.unlock(password=password)
|
||||
|
||||
# Produce an Ursula with a Keystore signer correctly derived from the signer URI, and don't do anything else!
|
||||
mocker.patch.object(StakeList, 'refresh', autospec=True)
|
||||
|
|
|
@ -29,7 +29,7 @@ from nucypher.characters.base import Learner
|
|||
from nucypher.cli.literature import NO_CONFIGURATIONS_ON_DISK
|
||||
from nucypher.cli.main import nucypher_cli
|
||||
from nucypher.config.characters import UrsulaConfiguration
|
||||
from nucypher.config.constants import NUCYPHER_ENVVAR_KEYRING_PASSWORD, TEMPORARY_DOMAIN
|
||||
from nucypher.config.constants import NUCYPHER_ENVVAR_KEYSTORE_PASSWORD, TEMPORARY_DOMAIN
|
||||
from nucypher.network.nodes import Teacher
|
||||
from nucypher.utilities.networking import LOOPBACK_ADDRESS, UnknownIPAddress
|
||||
from tests.constants import (
|
||||
|
@ -162,8 +162,7 @@ def test_federated_ursula_learns_via_cli(click_runner, federated_ursulas):
|
|||
assert deploy_port not in reserved_ports
|
||||
|
||||
# Check that CLI Ursula reports that it remembers the teacher and saves the TLS certificate
|
||||
assert teacher.checksum_address in result.output
|
||||
assert f"Saved TLS certificate for {teacher.nickname}" in result.output
|
||||
assert f"Saved TLS certificate for {LOOPBACK_ADDRESS}" in result.output
|
||||
|
||||
federated_ursulas.clear()
|
||||
|
||||
|
@ -188,7 +187,7 @@ def test_persistent_node_storage_integration(click_runner,
|
|||
'--registry-filepath', agency_local_registry.filepath,
|
||||
)
|
||||
|
||||
envvars = {NUCYPHER_ENVVAR_KEYRING_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD}
|
||||
envvars = {NUCYPHER_ENVVAR_KEYSTORE_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD}
|
||||
result = click_runner.invoke(nucypher_cli, init_args, catch_exceptions=False, env=envvars)
|
||||
assert result.exit_code == 0
|
||||
|
||||
|
@ -248,7 +247,7 @@ def test_ursula_run_ip_checkup(testerchain, custom_filepath, click_runner, mocke
|
|||
staker = blockchain_ursulas.pop()
|
||||
|
||||
def set_staker_address(worker, *args, **kwargs):
|
||||
worker._checksum_address = staker.checksum_address
|
||||
worker.checksum_address = staker.checksum_address
|
||||
return True
|
||||
monkeypatch.setattr(Worker, 'block_until_ready', set_staker_address)
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ def test_staker_divide_stakes(click_runner,
|
|||
result = click_runner.invoke(nucypher_cli,
|
||||
divide_args,
|
||||
catch_exceptions=False,
|
||||
env=dict(NUCYPHER_KEYRING_PASSWORD=INSECURE_DEVELOPMENT_PASSWORD))
|
||||
env=dict(NUCYPHER_KEYSTORE_PASSWORD=INSECURE_DEVELOPMENT_PASSWORD))
|
||||
assert result.exit_code == 0
|
||||
|
||||
stake_args = ('stake', 'list', '--config-file', stakeholder_configuration_file_location)
|
||||
|
@ -377,7 +377,7 @@ def test_ursula_init(click_runner,
|
|||
|
||||
# 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, 'keystore')), 'KEYSTORE 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, UrsulaConfiguration.generate_filename())
|
||||
|
|
|
@ -24,7 +24,7 @@ from random import SystemRandom
|
|||
from web3 import Web3
|
||||
|
||||
from nucypher.blockchain.eth.token import NU
|
||||
from nucypher.config.constants import NUCYPHER_ENVVAR_KEYRING_PASSWORD, NUCYPHER_ENVVAR_WORKER_ETH_PASSWORD
|
||||
from nucypher.config.constants import NUCYPHER_ENVVAR_KEYSTORE_PASSWORD, NUCYPHER_ENVVAR_WORKER_ETH_PASSWORD
|
||||
|
||||
#
|
||||
# Ursula
|
||||
|
@ -137,7 +137,7 @@ NO_ENTER = NO + '\n'
|
|||
|
||||
FAKE_PASSWORD_CONFIRMED = '{password}\n{password}\n'.format(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
|
||||
CLI_TEST_ENV = {NUCYPHER_ENVVAR_KEYRING_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD}
|
||||
CLI_TEST_ENV = {NUCYPHER_ENVVAR_KEYSTORE_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD}
|
||||
|
||||
CLI_ENV = {NUCYPHER_ENVVAR_KEYRING_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD,
|
||||
CLI_ENV = {NUCYPHER_ENVVAR_KEYSTORE_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD,
|
||||
NUCYPHER_ENVVAR_WORKER_ETH_PASSWORD: INSECURE_DEVELOPMENT_PASSWORD}
|
||||
|
|
|
@ -58,6 +58,7 @@ from nucypher.config.characters import (
|
|||
UrsulaConfiguration
|
||||
)
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
from nucypher.crypto.keystore import Keystore
|
||||
from nucypher.crypto.powers import TransactingPower
|
||||
from nucypher.datastore import datastore
|
||||
from nucypher.network.nodes import TEACHER_NODES
|
||||
|
@ -174,7 +175,7 @@ def bob_federated_test_config():
|
|||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def ursula_decentralized_test_config(test_registry):
|
||||
def ursula_decentralized_test_config(test_registry, temp_dir_path):
|
||||
config = make_ursula_test_configuration(federated=False,
|
||||
provider_uri=TEST_PROVIDER_URI,
|
||||
test_registry=test_registry,
|
||||
|
@ -201,8 +202,7 @@ def bob_blockchain_test_config(testerchain, test_registry):
|
|||
config = make_bob_test_configuration(federated=False,
|
||||
provider_uri=TEST_PROVIDER_URI,
|
||||
test_registry=test_registry,
|
||||
checksum_address=testerchain.bob_account,
|
||||
)
|
||||
checksum_address=testerchain.bob_account)
|
||||
yield config
|
||||
config.cleanup()
|
||||
|
||||
|
@ -366,8 +366,9 @@ def blockchain_bob(bob_blockchain_test_config, testerchain):
|
|||
@pytest.fixture(scope="module")
|
||||
def federated_ursulas(ursula_federated_test_config):
|
||||
if MOCK_KNOWN_URSULAS_CACHE:
|
||||
# raise RuntimeError("Ursulas cache was unclear at fixture loading time. Did you use one of the ursula maker functions without cleaning up?")
|
||||
MOCK_KNOWN_URSULAS_CACHE.clear()
|
||||
raise RuntimeError("Ursulas cache was unclear at fixture loading time. "
|
||||
"Did you use one of the ursula maker functions without cleaning up?")
|
||||
# MOCK_KNOWN_URSULAS_CACHE.clear()
|
||||
|
||||
_ursulas = make_federated_ursulas(ursula_config=ursula_federated_test_config,
|
||||
quantity=NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK)
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
"""
|
||||
|
||||
import os
|
||||
|
||||
import pytest
|
||||
from constant_sorrow.constants import NO_PASSWORD
|
||||
from mnemonic.mnemonic import Mnemonic
|
||||
from nacl.exceptions import CryptoError
|
||||
|
||||
from nucypher.blockchain.eth.decorators import InvalidChecksumAddress
|
||||
|
@ -26,16 +28,16 @@ from nucypher.cli.actions.auth import (
|
|||
get_client_password,
|
||||
get_nucypher_password,
|
||||
get_password_from_prompt,
|
||||
unlock_nucypher_keyring
|
||||
unlock_nucypher_keystore
|
||||
)
|
||||
from nucypher.cli.literature import (
|
||||
COLLECT_ETH_PASSWORD,
|
||||
COLLECT_NUCYPHER_PASSWORD,
|
||||
DECRYPTING_CHARACTER_KEYRING,
|
||||
DECRYPTING_CHARACTER_KEYSTORE,
|
||||
GENERIC_PASSWORD_PROMPT
|
||||
)
|
||||
from nucypher.crypto.keystore import Keystore
|
||||
from nucypher.config.base import CharacterConfiguration
|
||||
from nucypher.crypto.keystore import Keystore
|
||||
from tests.constants import INSECURE_DEVELOPMENT_PASSWORD
|
||||
|
||||
|
||||
|
@ -97,14 +99,13 @@ def test_get_nucypher_password(mock_stdin, mock_account, confirm, capsys):
|
|||
captured = capsys.readouterr()
|
||||
assert COLLECT_NUCYPHER_PASSWORD in captured.out
|
||||
if confirm:
|
||||
prompt = COLLECT_NUCYPHER_PASSWORD + f" ({Keystore.MINIMUM_PASSWORD_LENGTH} character minimum)"
|
||||
prompt = COLLECT_NUCYPHER_PASSWORD + f" ({Keystore._MINIMUM_PASSWORD_LENGTH} character minimum)"
|
||||
assert prompt in captured.out
|
||||
|
||||
|
||||
def test_unlock_nucypher_keyring_invalid_password(mocker, test_emitter, alice_blockchain_test_config, capsys):
|
||||
def test_unlock_nucypher_keystore_invalid_password(mocker, test_emitter, alice_blockchain_test_config, capsys, tmpdir):
|
||||
|
||||
# Setup
|
||||
keyring_attach_spy = mocker.spy(CharacterConfiguration, 'attach_keyring')
|
||||
mocker.patch.object(Keystore, 'unlock', side_effect=CryptoError)
|
||||
mocker.patch.object(CharacterConfiguration,
|
||||
'dev_mode',
|
||||
|
@ -112,40 +113,39 @@ def test_unlock_nucypher_keyring_invalid_password(mocker, test_emitter, alice_bl
|
|||
new_callable=mocker.PropertyMock)
|
||||
|
||||
# Test
|
||||
alice_blockchain_test_config.keystore = Keystore.generate(password=INSECURE_DEVELOPMENT_PASSWORD, keystore_dir=tmpdir)
|
||||
with pytest.raises(Keystore.AuthenticationFailed):
|
||||
unlock_nucypher_keyring(emitter=test_emitter,
|
||||
unlock_nucypher_keystore(emitter=test_emitter,
|
||||
password=INSECURE_DEVELOPMENT_PASSWORD+'typo',
|
||||
character_configuration=alice_blockchain_test_config)
|
||||
keyring_attach_spy.assert_called_once()
|
||||
|
||||
captured = capsys.readouterr()
|
||||
assert DECRYPTING_CHARACTER_KEYRING.format(name=alice_blockchain_test_config.NAME.capitalize()) in captured.out
|
||||
assert DECRYPTING_CHARACTER_KEYSTORE.format(name=alice_blockchain_test_config.NAME.capitalize()) in captured.out
|
||||
|
||||
|
||||
def test_unlock_nucypher_keyring_dev_mode(mocker, test_emitter, capsys, alice_blockchain_test_config):
|
||||
def test_unlock_nucypher_keystore_dev_mode(mocker, test_emitter, capsys, alice_blockchain_test_config, tmpdir):
|
||||
|
||||
# Setup
|
||||
unlock_spy = mocker.spy(Keystore, 'unlock')
|
||||
attach_spy = mocker.spy(CharacterConfiguration, 'attach_keyring')
|
||||
mocker.patch.object(CharacterConfiguration,
|
||||
'dev_mode',
|
||||
return_value=True,
|
||||
new_callable=mocker.PropertyMock)
|
||||
# Test
|
||||
result = unlock_nucypher_keyring(emitter=test_emitter,
|
||||
alice_blockchain_test_config.keystore = Keystore.generate(password=INSECURE_DEVELOPMENT_PASSWORD, keystore_dir=tmpdir)
|
||||
result = unlock_nucypher_keystore(emitter=test_emitter,
|
||||
password=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
character_configuration=alice_blockchain_test_config)
|
||||
|
||||
assert result
|
||||
output = capsys.readouterr().out
|
||||
message = DECRYPTING_CHARACTER_KEYRING.format(name=alice_blockchain_test_config.NAME.capitalize())
|
||||
message = DECRYPTING_CHARACTER_KEYSTORE.format(name=alice_blockchain_test_config.NAME.capitalize())
|
||||
assert message in output
|
||||
|
||||
unlock_spy.assert_not_called()
|
||||
attach_spy.assert_not_called()
|
||||
|
||||
|
||||
def test_unlock_nucypher_keyring(mocker,
|
||||
def test_unlock_nucypher_keystore(mocker,
|
||||
test_emitter,
|
||||
capsys,
|
||||
alice_blockchain_test_config,
|
||||
|
@ -155,20 +155,21 @@ def test_unlock_nucypher_keyring(mocker,
|
|||
# Setup
|
||||
# Do not test "real" unlocking here, just the plumbing
|
||||
unlock_spy = mocker.patch.object(Keystore, 'unlock', return_value=True)
|
||||
attach_spy = mocker.spy(CharacterConfiguration, 'attach_keyring')
|
||||
mocker.patch.object(CharacterConfiguration,
|
||||
'dev_mode',
|
||||
return_value=False,
|
||||
new_callable=mocker.PropertyMock)
|
||||
mocker.patch.object(Mnemonic, 'detect_language', return_value='english')
|
||||
|
||||
# Test
|
||||
result = unlock_nucypher_keyring(emitter=test_emitter,
|
||||
alice_blockchain_test_config.keystore = Keystore.generate(password=INSECURE_DEVELOPMENT_PASSWORD, keystore_dir=tmpdir)
|
||||
result = unlock_nucypher_keystore(emitter=test_emitter,
|
||||
password=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
character_configuration=alice_blockchain_test_config)
|
||||
|
||||
assert result
|
||||
captured = capsys.readouterr()
|
||||
message = DECRYPTING_CHARACTER_KEYRING.format(name=alice_blockchain_test_config.NAME.capitalize())
|
||||
message = DECRYPTING_CHARACTER_KEYSTORE.format(name=alice_blockchain_test_config.NAME.capitalize())
|
||||
assert message in captured.out
|
||||
|
||||
unlock_spy.assert_called_once_with(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
attach_spy.assert_called_once()
|
||||
|
|
|
@ -26,7 +26,7 @@ from nucypher.blockchain.eth.token import StakeList
|
|||
from nucypher.cli.main import nucypher_cli
|
||||
from nucypher.config.characters import UrsulaConfiguration
|
||||
from nucypher.config.constants import (
|
||||
NUCYPHER_ENVVAR_KEYRING_PASSWORD,
|
||||
NUCYPHER_ENVVAR_KEYSTORE_PASSWORD,
|
||||
NUCYPHER_ENVVAR_WORKER_ETH_PASSWORD,
|
||||
TEMPORARY_DOMAIN
|
||||
)
|
||||
|
@ -73,7 +73,7 @@ def test_ursula_init_with_local_keystore_signer(click_runner,
|
|||
'--signer', mock_signer_uri)
|
||||
|
||||
cli_env = {
|
||||
NUCYPHER_ENVVAR_KEYRING_PASSWORD: password,
|
||||
NUCYPHER_ENVVAR_KEYSTORE_PASSWORD: password,
|
||||
NUCYPHER_ENVVAR_WORKER_ETH_PASSWORD: password,
|
||||
}
|
||||
result = click_runner.invoke(nucypher_cli,
|
||||
|
@ -93,10 +93,9 @@ def test_ursula_init_with_local_keystore_signer(click_runner,
|
|||
ursula_config = UrsulaConfiguration.from_configuration_file(custom_config_filepath, config_root=custom_filepath)
|
||||
assert ursula_config.signer_uri == mock_signer_uri
|
||||
|
||||
# Mock decryption of web3 client keyring
|
||||
# Mock decryption of web3 client keystore
|
||||
mocker.patch.object(Account, 'decrypt', return_value=worker_account.privateKey)
|
||||
ursula_config.attach_keystore(keystore_id=ursula_config.stamp)
|
||||
ursula_config.keyring.unlock(password=password)
|
||||
ursula_config.keystore.unlock(password=password)
|
||||
|
||||
# Produce an ursula with a Keystore signer correctly derived from the signer URI, and dont do anything else!
|
||||
mocker.patch.object(StakeList, 'refresh', autospec=True)
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
import os
|
||||
import tempfile
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
from constant_sorrow.constants import CERTIFICATE_NOT_SAVED, NO_KEYSTORE_ATTACHED
|
||||
|
@ -39,6 +38,7 @@ from nucypher.config.constants import TEMPORARY_DOMAIN
|
|||
from nucypher.config.storages import ForgetfulNodeStorage
|
||||
from nucypher.crypto.keystore import Keystore
|
||||
from nucypher.crypto.umbral_adapter import SecretKey
|
||||
from tests.constants import INSECURE_DEVELOPMENT_PASSWORD
|
||||
from tests.constants import MOCK_IP_ADDRESS
|
||||
|
||||
# Main Cast
|
||||
|
@ -65,7 +65,7 @@ def test_federated_development_character_configurations(character, configuration
|
|||
|
||||
assert config.is_me is True
|
||||
assert config.dev_mode is True
|
||||
assert config.keyring == NO_KEYSTORE_ATTACHED
|
||||
assert config.keystore == NO_KEYSTORE_ATTACHED
|
||||
assert config.provider_uri is None
|
||||
|
||||
# Production
|
||||
|
@ -105,7 +105,7 @@ def test_federated_development_character_configurations(character, configuration
|
|||
|
||||
# TODO: This test is unnecessarily slow due to the blockchain configurations. Perhaps we should mock them -- See #2230
|
||||
@pytest.mark.parametrize('configuration_class', all_configurations)
|
||||
def test_default_character_configuration_preservation(configuration_class, testerchain, test_registry_source_manager):
|
||||
def test_default_character_configuration_preservation(configuration_class, testerchain, test_registry_source_manager, mocker, tmpdir):
|
||||
|
||||
configuration_class.DEFAULT_CONFIG_ROOT = '/tmp'
|
||||
fake_address = '0xdeadbeef'
|
||||
|
@ -126,13 +126,13 @@ def test_default_character_configuration_preservation(configuration_class, teste
|
|||
|
||||
elif configuration_class == UrsulaConfiguration:
|
||||
# special case for rest_host & dev mode
|
||||
# use keyring
|
||||
keyring = Mock(spec=Keystore)
|
||||
keyring.signing_public_key = SecretKey.random().public_key()
|
||||
# use keystore
|
||||
keystore = Keystore.generate(password=INSECURE_DEVELOPMENT_PASSWORD, keystore_dir=tmpdir)
|
||||
keystore.signing_public_key = SecretKey.random().public_key()
|
||||
character_config = configuration_class(checksum_address=fake_address,
|
||||
domain=network,
|
||||
rest_host=MOCK_IP_ADDRESS,
|
||||
keyring=keyring)
|
||||
keystore=keystore)
|
||||
|
||||
else:
|
||||
character_config = configuration_class(checksum_address=fake_address, domain=network)
|
||||
|
@ -165,7 +165,7 @@ def test_ursula_development_configuration(federated_only=True):
|
|||
config = UrsulaConfiguration(dev_mode=True, federated_only=federated_only)
|
||||
assert config.is_me is True
|
||||
assert config.dev_mode is True
|
||||
assert config.keyring == NO_KEYSTORE_ATTACHED
|
||||
assert config.keystore == NO_KEYSTORE_ATTACHED
|
||||
|
||||
# Produce an Ursula
|
||||
ursula_one = config()
|
||||
|
@ -208,9 +208,9 @@ def test_destroy_configuration(config,
|
|||
config_file = config.filepath
|
||||
|
||||
# Isolate from filesystem and Spy on the methods we're testing here
|
||||
spy_keyring_attached = mocker.spy(CharacterConfiguration, 'attach_keyring')
|
||||
spy_keystore_attached = mocker.spy(CharacterConfiguration, 'attach_keystore')
|
||||
mock_config_destroy = mocker.patch.object(CharacterConfiguration, 'destroy')
|
||||
spy_keyring_destroy = mocker.spy(Keystore, 'destroy')
|
||||
spy_keystore_destroy = mocker.spy(Keystore, 'destroy')
|
||||
mock_os_remove = mocker.patch('os.remove')
|
||||
|
||||
# Test
|
||||
|
@ -220,8 +220,8 @@ def test_destroy_configuration(config,
|
|||
captured = capsys.readouterr()
|
||||
assert SUCCESSFUL_DESTRUCTION in captured.out
|
||||
|
||||
spy_keyring_attached.assert_called_once()
|
||||
spy_keyring_destroy.assert_called_once()
|
||||
spy_keystore_attached.assert_called_once()
|
||||
spy_keystore_destroy.assert_called_once()
|
||||
mock_os_remove.assert_called_with(str(config_file))
|
||||
|
||||
# Ensure all destroyed files belong to this Ursula
|
||||
|
|
|
@ -43,8 +43,8 @@ def test_alices_powers_are_persistent(federated_ursulas, tmpdir):
|
|||
# Generate keys and write them the disk
|
||||
alice_config.initialize(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
|
||||
# Unlock Alice's keyring
|
||||
alice_config.keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
# Unlock Alice's keystore
|
||||
alice_config.keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
|
||||
# Produce an Alice
|
||||
alice = alice_config() # or alice_config.produce()
|
||||
|
@ -98,9 +98,8 @@ def test_alices_powers_are_persistent(federated_ursulas, tmpdir):
|
|||
config_root=config_root
|
||||
)
|
||||
|
||||
# Alice unlocks her restored keyring from disk
|
||||
new_alice_config.attach_keystore()
|
||||
new_alice_config.keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
# Alice unlocks her restored keystore from disk
|
||||
new_alice_config.keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
new_alice = new_alice_config()
|
||||
|
||||
# First, we check that her public keys are correctly restored
|
||||
|
|
|
@ -36,30 +36,22 @@ from tests.constants import INSECURE_DEVELOPMENT_PASSWORD
|
|||
from tests.utils.matchers import IsType
|
||||
|
||||
|
||||
def test_generate_alice_keyring(tmpdir):
|
||||
def test_generate_alice_keystore(tmpdir):
|
||||
|
||||
keyring = Keystore.generate(
|
||||
checksum_address=FEDERATED_ADDRESS,
|
||||
keystore = Keystore.generate(
|
||||
password=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
encrypting=True,
|
||||
rest=False,
|
||||
keyring_root=tmpdir
|
||||
keystore_dir=tmpdir
|
||||
)
|
||||
|
||||
enc_pubkey = keyring.encrypting_public_key
|
||||
assert enc_pubkey is not None
|
||||
with pytest.raises(Keystore.Locked):
|
||||
_dec_keypair = keystore.derive_crypto_power(DecryptingPower).keypair
|
||||
|
||||
with pytest.raises(Keystore.KeyringLocked):
|
||||
_dec_keypair = keyring.derive_crypto_power(DecryptingPower).keypair
|
||||
|
||||
keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
dec_keypair = keyring.derive_crypto_power(DecryptingPower).keypair
|
||||
|
||||
assert enc_pubkey == dec_keypair.pubkey
|
||||
keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
assert keystore.derive_crypto_power(DecryptingPower).keypair
|
||||
|
||||
label = b'test'
|
||||
|
||||
delegating_power = keyring.derive_crypto_power(DelegatingPower)
|
||||
delegating_power = keystore.derive_crypto_power(DelegatingPower)
|
||||
delegating_pubkey = delegating_power.get_pubkey_from_label(label)
|
||||
|
||||
bob_pubkey = SecretKey.random().public_key()
|
||||
|
@ -70,26 +62,23 @@ def test_generate_alice_keyring(tmpdir):
|
|||
|
||||
assert delegating_pubkey == delegating_pubkey_again
|
||||
|
||||
another_delegating_power = keyring.derive_crypto_power(DelegatingPower)
|
||||
another_delegating_power = keystore.derive_crypto_power(DelegatingPower)
|
||||
another_delegating_pubkey = another_delegating_power.get_pubkey_from_label(label)
|
||||
|
||||
assert delegating_pubkey == another_delegating_pubkey
|
||||
|
||||
|
||||
def test_characters_use_keyring(tmpdir):
|
||||
keyring = Keystore.generate(
|
||||
checksum_address=FEDERATED_ADDRESS,
|
||||
def test_characters_use_keystore(tmpdir):
|
||||
keystore = Keystore.generate(
|
||||
password=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
encrypting=True,
|
||||
rest=True,
|
||||
host=LOOPBACK_ADDRESS,
|
||||
keyring_root=tmpdir)
|
||||
keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
alice = Alice(federated_only=True, start_learning_now=False, keyring=keyring)
|
||||
Bob(federated_only=True, start_learning_now=False, keyring=keyring)
|
||||
keystore_dir=tmpdir
|
||||
)
|
||||
keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
alice = Alice(federated_only=True, start_learning_now=False, keystore=keystore)
|
||||
Bob(federated_only=True, start_learning_now=False, keystore=keystore)
|
||||
Ursula(federated_only=True,
|
||||
start_learning_now=False,
|
||||
keyring=keyring,
|
||||
keystore=keystore,
|
||||
rest_host=LOOPBACK_ADDRESS,
|
||||
rest_port=12345,
|
||||
db_filepath=tempfile.mkdtemp(),
|
||||
|
@ -97,28 +86,26 @@ def test_characters_use_keyring(tmpdir):
|
|||
alice.disenchant() # To stop Alice's publication threadpool. TODO: Maybe only start it at first enactment?
|
||||
|
||||
|
||||
@pytest.mark.skip('Do we really though?')
|
||||
def test_tls_hosting_certificate_remains_the_same(tmpdir, mocker):
|
||||
keyring = Keystore.generate(
|
||||
checksum_address=FEDERATED_ADDRESS,
|
||||
keystore = Keystore.generate(
|
||||
password=INSECURE_DEVELOPMENT_PASSWORD,
|
||||
encrypting=True,
|
||||
rest=True,
|
||||
host=LOOPBACK_ADDRESS,
|
||||
keyring_root=tmpdir)
|
||||
keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
keystore_dir=tmpdir
|
||||
)
|
||||
keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
|
||||
rest_port = 12345
|
||||
db_filepath = tempfile.mkdtemp()
|
||||
|
||||
ursula = Ursula(federated_only=True,
|
||||
start_learning_now=False,
|
||||
keyring=keyring,
|
||||
keystore=keystore,
|
||||
rest_host=LOOPBACK_ADDRESS,
|
||||
rest_port=rest_port,
|
||||
db_filepath=db_filepath,
|
||||
domain=TEMPORARY_DOMAIN)
|
||||
|
||||
assert ursula.keyring is keyring
|
||||
assert ursula.keystore is keystore
|
||||
assert ursula.certificate == ursula._crypto_power.power_ups(TLSHostingPower).keypair.certificate
|
||||
|
||||
original_certificate_bytes = ursula.certificate.public_bytes(encoding=Encoding.PEM)
|
||||
|
@ -128,13 +115,13 @@ def test_tls_hosting_certificate_remains_the_same(tmpdir, mocker):
|
|||
spy_rest_server_init = mocker.spy(ProxyRESTServer, '__init__')
|
||||
recreated_ursula = Ursula(federated_only=True,
|
||||
start_learning_now=False,
|
||||
keyring=keyring,
|
||||
keystore=keystore,
|
||||
rest_host=LOOPBACK_ADDRESS,
|
||||
rest_port=rest_port,
|
||||
db_filepath=db_filepath,
|
||||
domain=TEMPORARY_DOMAIN)
|
||||
|
||||
assert recreated_ursula.keyring is keyring
|
||||
assert recreated_ursula.keystore is keystore
|
||||
assert recreated_ursula.certificate.public_bytes(encoding=Encoding.PEM) == original_certificate_bytes
|
||||
tls_hosting_power = recreated_ursula._crypto_power.power_ups(TLSHostingPower)
|
||||
spy_rest_server_init.assert_called_once_with(ANY, # self
|
||||
|
|
|
@ -177,7 +177,7 @@ def make_alice(known_nodes: Optional[Set[Ursula]] = None):
|
|||
)
|
||||
|
||||
alice_config.initialize(password=INSECURE_PASSWORD)
|
||||
alice_config.keyring.unlock(password=INSECURE_PASSWORD)
|
||||
alice_config.keystore.unlock(password=INSECURE_PASSWORD)
|
||||
alice = alice_config.produce()
|
||||
alice.signer.unlock(account=ALICE_ADDRESS, password=SIGNER_PASSWORD)
|
||||
alice.start_learning_loop(now=True)
|
||||
|
|
|
@ -200,7 +200,7 @@ class VerificationTracker:
|
|||
cls.metadata_verifications += 1
|
||||
|
||||
|
||||
mock_cert_generation = patch("nucypher.crypto.api.generate_self_signed_certificate", new=do_not_create_cert)
|
||||
mock_cert_generation = patch("nucypher.crypto.tls.generate_self_signed_certificate", new=do_not_create_cert)
|
||||
mock_rest_app_creation = patch("nucypher.characters.lawful.make_rest_app",
|
||||
new=NotARestApp.create_with_not_a_datastore)
|
||||
|
||||
|
|
|
@ -113,12 +113,12 @@ def test_keystore_generation_defaults(tmp_path_factory):
|
|||
assert parent in keystore.keystore_path.parents # created in the correct directory
|
||||
|
||||
|
||||
def test_keyring_invalid_password(tmpdir):
|
||||
def test_keystore_invalid_password(tmpdir):
|
||||
with pytest.raises(InvalidPassword):
|
||||
_keystore = Keystore.generate('short', keystore_dir=tmpdir)
|
||||
|
||||
|
||||
def test_keyring_derive_crypto_power_without_unlock(tmpdir):
|
||||
def test_keystore_derive_crypto_power_without_unlock(tmpdir):
|
||||
keystore = Keystore.generate(INSECURE_DEVELOPMENT_PASSWORD, keystore_dir=tmpdir)
|
||||
with pytest.raises(Keystore.Locked):
|
||||
keystore.derive_crypto_power(power_class=DecryptingPower)
|
||||
|
@ -133,7 +133,7 @@ def test_keystore_serializer():
|
|||
assert deserialized_key_data['salt'] == salt
|
||||
|
||||
|
||||
def test_keyring_lock_unlock(tmpdir):
|
||||
def test_keystore_lock_unlock(tmpdir):
|
||||
keystore = Keystore.generate(INSECURE_DEVELOPMENT_PASSWORD, keystore_dir=tmpdir)
|
||||
|
||||
# locked by default
|
||||
|
|
|
@ -14,14 +14,15 @@
|
|||
You should have received a copy of the GNU Affero General Public License
|
||||
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import tempfile
|
||||
from typing import List
|
||||
|
||||
from tests.constants import MOCK_IP_ADDRESS
|
||||
from nucypher.blockchain.eth.registry import BaseContractRegistry
|
||||
from nucypher.characters.lawful import Ursula
|
||||
from nucypher.config.characters import AliceConfiguration, BobConfiguration, UrsulaConfiguration
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
from nucypher.crypto.keystore import Keystore
|
||||
from tests.constants import INSECURE_DEVELOPMENT_PASSWORD
|
||||
from tests.utils.middleware import MockRestMiddleware
|
||||
from tests.utils.ursula import MOCK_URSULA_STARTING_PORT
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ from nucypher.crypto.utils import canonical_address_from_umbral_key
|
|||
from nucypher.policy.collections import WorkOrder
|
||||
from tests.constants import NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK
|
||||
from tests.mock.datastore import MOCK_DB
|
||||
from tests.utils.blockchain import TesterBlockchain
|
||||
|
||||
|
||||
def select_test_port() -> int:
|
||||
|
@ -64,9 +65,7 @@ def make_federated_ursulas(ursula_config: UrsulaConfiguration,
|
|||
starting_port = max(MOCK_KNOWN_URSULAS_CACHE.keys()) + 1
|
||||
|
||||
federated_ursulas = set()
|
||||
|
||||
for port in range(starting_port, starting_port+quantity):
|
||||
|
||||
ursula = ursula_config.produce(rest_port=port + 100,
|
||||
db_filepath=MOCK_DB,
|
||||
**ursula_overrides)
|
||||
|
|
Loading…
Reference in New Issue