mirror of https://github.com/nucypher/nucypher.git
Improve keyring creation prompts and warnings
parent
e96b1d7748
commit
5575c2c135
|
@ -21,18 +21,19 @@ import os
|
|||
from constant_sorrow.constants import NO_PASSWORD
|
||||
from nacl.exceptions import CryptoError
|
||||
|
||||
from nucypher.blockchain.eth.signers.software import ClefSigner
|
||||
from nucypher.blockchain.eth.decorators import validate_checksum_address
|
||||
from nucypher.blockchain.eth.signers.software import ClefSigner
|
||||
from nucypher.characters.control.emitters import StdoutEmitter
|
||||
from nucypher.cli.literature import (
|
||||
COLLECT_ETH_PASSWORD,
|
||||
COLLECT_NUCYPHER_PASSWORD,
|
||||
DECRYPTING_CHARACTER_KEYRING,
|
||||
GENERIC_PASSWORD_PROMPT
|
||||
GENERIC_PASSWORD_PROMPT,
|
||||
PASSWORD_COLLECTION_NOTICE
|
||||
)
|
||||
from nucypher.config.base import CharacterConfiguration
|
||||
from nucypher.config.constants import NUCYPHER_ENVVAR_KEYRING_PASSWORD
|
||||
from nucypher.config.keyring import NucypherKeyring
|
||||
from nucypher.config.base import CharacterConfiguration
|
||||
|
||||
|
||||
def get_password_from_prompt(prompt: str = GENERIC_PASSWORD_PROMPT, envvar: str = None, confirm: bool = False) -> str:
|
||||
|
@ -77,11 +78,12 @@ def unlock_signer_account(config: CharacterConfiguration, json_ipc: bool) -> Non
|
|||
config.signer.unlock_account(account=config.checksum_address, password=__password)
|
||||
|
||||
|
||||
def get_nucypher_password(confirm: bool = False, envvar=NUCYPHER_ENVVAR_KEYRING_PASSWORD) -> str:
|
||||
def get_nucypher_password(emitter, confirm: bool = False, envvar=NUCYPHER_ENVVAR_KEYRING_PASSWORD) -> str:
|
||||
"""Interactively collect a nucypher password"""
|
||||
prompt = COLLECT_NUCYPHER_PASSWORD
|
||||
if confirm:
|
||||
from nucypher.config.keyring import NucypherKeyring
|
||||
emitter.message(PASSWORD_COLLECTION_NOTICE)
|
||||
prompt += f" ({NucypherKeyring.MINIMUM_PASSWORD_LENGTH} character minimum)"
|
||||
keyring_password = get_password_from_prompt(prompt=prompt, confirm=confirm, envvar=envvar)
|
||||
return keyring_password
|
||||
|
|
|
@ -206,7 +206,7 @@ class AliceFullConfigOptions:
|
|||
network=opts.domain)
|
||||
|
||||
return AliceConfiguration.generate(
|
||||
password=get_nucypher_password(confirm=True),
|
||||
password=get_nucypher_password(emitter=emitter, confirm=True),
|
||||
config_root=config_root,
|
||||
checksum_address=pay_with,
|
||||
domain=opts.domain,
|
||||
|
|
|
@ -141,7 +141,7 @@ class BobConfigOptions:
|
|||
provider_uri=self.provider_uri) # TODO: See #1888
|
||||
|
||||
return BobConfiguration.generate(
|
||||
password=get_nucypher_password(confirm=True),
|
||||
password=get_nucypher_password(emitter=emitter, confirm=True),
|
||||
config_root=config_root,
|
||||
checksum_address=checksum_address,
|
||||
domain=self.domain,
|
||||
|
|
|
@ -16,10 +16,10 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
|||
"""
|
||||
|
||||
|
||||
import click
|
||||
import os
|
||||
|
||||
import click
|
||||
|
||||
from nucypher.characters.control.emitters import StdoutEmitter
|
||||
from nucypher.cli.actions.auth import (
|
||||
get_client_password,
|
||||
get_nucypher_password,
|
||||
|
@ -116,7 +116,7 @@ class FelixConfigOptions:
|
|||
|
||||
def generate_config(self, config_root, discovery_port):
|
||||
return FelixConfiguration.generate(
|
||||
password=get_nucypher_password(confirm=True),
|
||||
password=get_nucypher_password(emitter=StdoutEmitter(), confirm=True),
|
||||
config_root=config_root,
|
||||
rest_host=self.host,
|
||||
rest_port=discovery_port,
|
||||
|
@ -163,7 +163,7 @@ class FelixCharacterOptions:
|
|||
# Authenticate
|
||||
unlock_nucypher_keyring(emitter,
|
||||
character_configuration=felix_config,
|
||||
password=get_nucypher_password(confirm=False))
|
||||
password=get_nucypher_password(emitter=emitter, confirm=False))
|
||||
|
||||
client_password = get_client_password(checksum_address=felix_config.checksum_address,
|
||||
envvar=NUCYPHER_ENVVAR_WORKER_ETH_PASSWORD)
|
||||
|
|
|
@ -179,7 +179,7 @@ class UrsulaConfigOptions:
|
|||
if not self.rest_host:
|
||||
self.rest_host = collect_worker_ip_address(emitter, network=self.domain, force=force)
|
||||
|
||||
return UrsulaConfiguration.generate(password=get_nucypher_password(confirm=True),
|
||||
return UrsulaConfiguration.generate(password=get_nucypher_password(emitter=emitter, confirm=True),
|
||||
config_root=config_root,
|
||||
rest_host=self.rest_host,
|
||||
rest_port=self.rest_port,
|
||||
|
@ -301,6 +301,8 @@ def init(general_config, config_options, force, config_root):
|
|||
_pre_launch_warnings(emitter, dev=None, force=force)
|
||||
if not config_root:
|
||||
config_root = general_config.config_root
|
||||
if not config_options.federated_only and not config_options.provider_uri:
|
||||
raise click.BadOptionUsage('--provider', message="--provider is required to initialize a new ursula.")
|
||||
if not config_options.federated_only and not config_options.domain:
|
||||
config_options.domain = select_network(emitter)
|
||||
ursula_config = config_options.generate_config(emitter, config_root, force)
|
||||
|
|
|
@ -210,6 +210,7 @@ SUCCESSFUL_DISABLE_RESTAKING = 'Successfully disabled re-staking for {staking_ad
|
|||
#
|
||||
# Snapshots
|
||||
#
|
||||
|
||||
SNAPSHOTS_DISABLING_AGREEMENT = """
|
||||
By disabling snapshots, staker {staking_address} will be excluded from all future DAO validations
|
||||
until snapshots are enabled.
|
||||
|
@ -380,6 +381,11 @@ DEFAULT_TO_LONE_CONFIG_FILE = "Defaulting to {config_class} configuration file:
|
|||
# Authentication
|
||||
#
|
||||
|
||||
PASSWORD_COLLECTION_NOTICE = f"""
|
||||
Please provide a password to lock Worker keys.
|
||||
Do not forget this password, and ideally store it using a password manager.
|
||||
"""
|
||||
|
||||
COLLECT_ETH_PASSWORD = "Enter ethereum account password ({checksum_address})"
|
||||
|
||||
COLLECT_NUCYPHER_PASSWORD = 'Enter nucypher keyring password'
|
||||
|
|
|
@ -55,7 +55,18 @@ def paint_new_installation_help(emitter, new_configuration, filepath):
|
|||
character_config_class = new_configuration.__class__
|
||||
character_name = character_config_class.NAME.lower()
|
||||
|
||||
emitter.message(f"Generated keyring {new_configuration.keyring_root}", color='green')
|
||||
emitter.message(f"Generated keyring", color='green')
|
||||
emitter.message(f"""
|
||||
|
||||
Public key (stamp): {bytes(new_configuration.keyring.signing_public_key).hex()}
|
||||
Path to keyring: {new_configuration.keyring_root}
|
||||
|
||||
- You can share your public key with anyone. Others need it to interact with you.
|
||||
- Never share secret keys with anyone! Character keys are required to interact with the network!
|
||||
- Backup your keyring! Without the keyring you wil not be able to use existing network policies.
|
||||
- Remember your password! Without the password, it's impossible to decrypt the key!
|
||||
|
||||
""")
|
||||
|
||||
default_config_filepath = True
|
||||
if new_configuration.default_filepath() != filepath:
|
||||
|
|
|
@ -84,7 +84,7 @@ def make_cli_character(character_config,
|
|||
if unlock_keyring:
|
||||
unlock_nucypher_keyring(emitter,
|
||||
character_configuration=character_config,
|
||||
password=get_nucypher_password(confirm=False))
|
||||
password=get_nucypher_password(emitter=emitter, confirm=False))
|
||||
|
||||
# Handle Signer/Wallet
|
||||
if unlock_signer:
|
||||
|
|
|
@ -21,6 +21,7 @@ from constant_sorrow.constants import NO_PASSWORD
|
|||
from nacl.exceptions import CryptoError
|
||||
|
||||
from nucypher.blockchain.eth.decorators import InvalidChecksumAddress
|
||||
from nucypher.characters.control.emitters import StdoutEmitter
|
||||
from nucypher.cli.actions.auth import (
|
||||
get_client_password,
|
||||
get_nucypher_password,
|
||||
|
@ -90,7 +91,7 @@ def test_get_client_password(mock_stdin, mock_account, confirm, capsys):
|
|||
@pytest.mark.parametrize('confirm', (True, False))
|
||||
def test_get_nucypher_password(mock_stdin, mock_account, confirm, capsys):
|
||||
mock_stdin.password(INSECURE_DEVELOPMENT_PASSWORD, confirm=confirm)
|
||||
result = get_nucypher_password(confirm=confirm)
|
||||
result = get_nucypher_password(emitter=StdoutEmitter(), confirm=confirm)
|
||||
assert result == INSECURE_DEVELOPMENT_PASSWORD
|
||||
assert mock_stdin.empty()
|
||||
captured = capsys.readouterr()
|
||||
|
|
Loading…
Reference in New Issue