Dehydration and cleanup of keyring attachment and checksum address selection. Touch ups.

pull/1029/head
Kieran Prasch 2019-06-10 18:31:50 -07:00 committed by David Núñez
parent add336af3f
commit 09c8847c14
12 changed files with 33 additions and 45 deletions

View File

@ -57,7 +57,6 @@ ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URI,
alice_config = AliceConfiguration(
config_root=os.path.join(TEMP_ALICE_DIR),
is_me=True,
domains={TEMPORARY_DOMAIN},
known_nodes={ursula},
start_learning_now=False,

View File

@ -56,7 +56,6 @@ power_ups = [enc_power, sig_power]
print("Creating the Doctor ...")
doctor = Bob(
is_me=True,
domains={TEMPORARY_DOMAIN},
federated_only=True,
crypto_power_ups=power_ups,

View File

@ -242,6 +242,7 @@ def make_cli_character(character_config,
# Handle Keyring
if not dev:
character_config.attach_keyring()
click_config.unlock_keyring(character_configuration=character_config,
password=click_config.get_password(confirm=False))

View File

@ -137,7 +137,7 @@ def alice(click_config,
elif action == "view":
"""Paint an existing configuration to the console"""
configuration_file_location = config_file or AliceConfiguration.generate_filepath()
configuration_file_location = config_file or AliceConfiguration.default_filepath()
response = AliceConfiguration._read_configuration_file(filepath=configuration_file_location)
click_config.emit(response)
return # Exit

View File

@ -105,6 +105,7 @@ class NucypherClickConfig:
# NuCypher
try:
character_configuration.attach_keyring()
character_configuration.keyring.unlock(password=password) # Takes ~3 seconds, ~1GB Ram
except CryptoError:
raise character_configuration.keyring.AuthenticationFailed

View File

@ -138,13 +138,12 @@ class AliceConfiguration(CharacterConfiguration):
first_period_rate: float = None,
duration: int = None,
*args, **kwargs):
super().__init__(*args, **kwargs)
self.m = m or self.DEFAULT_M
self.n = n or self.DEFAULT_N
self.rate = rate or self.DEFAULT_RATE
self.first_period_rate = first_period_rate or self.DEFAULT_FIRST_PERIOD_RATE
self.duration = duration or self.DEFAULT_DURATION
super().__init__(*args, **kwargs)
def static_payload(self) -> dict:
payload = dict(m=self.m,
@ -198,6 +197,7 @@ class FelixConfiguration(CharacterConfiguration):
certificate: Certificate = None,
*args, **kwargs) -> None:
super().__init__(*args, **kwargs)
if not rest_port:
rest_port = self.DEFAULT_REST_PORT
self.rest_port = rest_port or self.DEFAULT_REST_PORT
@ -205,7 +205,6 @@ class FelixConfiguration(CharacterConfiguration):
self.tls_curve = tls_curve or self.__DEFAULT_TLS_CURVE
self.certificate = certificate
self.db_filepath = db_filepath or os.path.join(self.config_root, self.DEFAULT_DB_NAME)
super().__init__(*args, **kwargs)
def static_payload(self) -> dict:
payload = dict(

View File

@ -386,15 +386,6 @@ class NucypherKeyring:
def checksum_address(self) -> str:
return to_checksum_address(self.__account)
@property
def federated_address(self) -> str:
signature_pubkey = self.signing_public_key
uncompressed_bytes = signature_pubkey.to_bytes(is_compressed=False)
without_prefix = uncompressed_bytes[1:]
verifying_key_as_eth_key = EthKeyAPI.PublicKey(without_prefix)
address = verifying_key_as_eth_key.to_checksum_address()
return to_checksum_address(address)
@property
def signing_public_key(self):
signature_pubkey_bytes = _read_keyfile(keypath=self.__signing_pub_keypath, deserializer=None)
@ -558,6 +549,10 @@ class NucypherKeyring:
keyring_args = dict()
if checksum_address:
# Addresses read from some node keyrings (clients) are *not* returned in checksum format.
checksum_address = to_checksum_address(checksum_address)
if encrypting is True:
signing_private_key, signing_public_key = _generate_signing_keys()
@ -575,9 +570,6 @@ class NucypherKeyring:
if not checksum_address:
raise ValueError("Checksum address must bas provided for non-federated keyring generation")
# Addresses read from some node keyrings (clients) are *not* returned in checksum format.
checksum_address = to_checksum_address(checksum_address)
__key_filepaths = cls._generate_key_filepaths(account=checksum_address,
private_key_dir=_private_key_dir,
public_key_dir=_public_key_dir)

View File

@ -222,6 +222,7 @@ class CharacterConfiguration(BaseConfiguration):
def destroy(self) -> None:
"""Parse a node configuration and remove all associated files from the filesystem"""
self.attach_keyring()
self.keyring.destroy()
os.remove(self.config_file_location)
@ -354,12 +355,12 @@ class CharacterConfiguration(BaseConfiguration):
def attach_keyring(self, checksum_address: str = None, *args, **kwargs) -> None:
account = checksum_address or self.checksum_address
if not account:
raise self.ConfigurationError("No account specified to unlock keyring")
if self.keyring is not NO_KEYRING_ATTACHED:
if self.keyring.checksum_address != account:
raise self.ConfigurationError("There is already a keyring attached to this configuration.")
return
if not account:
raise self.ConfigurationError("No account specified to unlock keyring")
self.keyring = NucypherKeyring(keyring_root=self.keyring_root, account=account, *args, **kwargs)
def derive_node_power_ups(self) -> List[CryptoPowerUp]:
@ -383,17 +384,20 @@ class CharacterConfiguration(BaseConfiguration):
def initialize(self, password: str) -> str:
"""Initialize a new configuration and write installation files to disk."""
if password is DEVELOPMENT_CONFIGURATION:
self.abort_on_learning_error = True
self.save_metadata = False
self.reload_metadata = False
alphabet = string.ascii_letters + string.digits
password = ''.join(secrets.choice(alphabet) for _ in range(32))
# Configuration Root
if self.__dev_mode:
# Development
if self.dev_mode:
if password is DEVELOPMENT_CONFIGURATION:
self.abort_on_learning_error = True
self.save_metadata = False
self.reload_metadata = False
alphabet = string.ascii_letters + string.digits
password = ''.join(secrets.choice(alphabet) for _ in range(32))
else:
raise self.ConfigurationError("Password cannot be specified for development configurations.")
self.__temp_dir = TemporaryDirectory(prefix=self.TEMP_CONFIGURATION_DIR_PREFIX)
self.config_root = self.__temp_dir.name
# Persistent
else:
self.write_config_root()
self.write_keyring(password=password)

View File

@ -248,6 +248,7 @@ def test_alices_powers_are_persistent(federated_ursulas, tmpdir):
)
# Alice unlocks her restored keyring from disk
new_alice_config.attach_keyring()
new_alice_config.keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
new_alice = new_alice_config()

View File

@ -27,7 +27,7 @@ def test_initialize_alice_defaults(click_runner, mocker):
assert 'Repeat for confirmation:' in result.output, 'User was not prompted to confirm password'
def test_alice_control_starts_mocked(click_runner, mocker):
def test_alice_control_starts_with_mocked_keyring(click_runner, mocker):
class MockKeyring:
is_unlocked = False
@ -37,8 +37,8 @@ def test_alice_control_starts_mocked(click_runner, mocker):
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')

View File

@ -48,7 +48,8 @@ def test_run_felix(click_runner,
assert result.exit_code == 0
# Felix creates a system configuration
init_args = ('felix', 'init',
init_args = ('--debug',
'felix', 'init',
'--checksum-address', testerchain.interface.w3.eth.accounts[0],
'--config-root', MOCK_CUSTOM_INSTALLATION_PATH_2,
'--network', TEMPORARY_DOMAIN,
@ -61,7 +62,8 @@ def test_run_felix(click_runner,
configuration_file_location = os.path.join(MOCK_CUSTOM_INSTALLATION_PATH_2, FelixConfiguration.generate_filename())
# Felix Creates a Database
db_args = ('felix', 'createdb',
db_args = ('--debug',
'felix', 'createdb',
'--config-file', configuration_file_location,
'--provider-uri', TEST_PROVIDER_URI)
@ -86,6 +88,8 @@ def test_run_felix(click_runner,
# Init an equal Felix to the already running one.
felix_config = FelixConfiguration.from_configuration_file(filepath=configuration_file_location)
felix_config.attach_keyring()
felix_config.keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
felix = felix_config.produce()

View File

@ -7,18 +7,6 @@ from nucypher.config.keyring import NucypherKeyring
from nucypher.crypto.powers import DelegatingPower, DecryptingPower
@pytest.mark.skip("Redacted and refactored for sensitive info leakage")
def test_validate_password():
# Password too short
password = 'x' * 5
with pytest.raises(ValueError):
_keyring = NucypherKeyring.generate(password=password)
# Empty password is provided
with pytest.raises(ValueError):
_keyring = NucypherKeyring.generate(password="")
def test_generate_alice_keyring(tmpdir):
password = 'x' * 16