def view(click_config, config_file): """ View existing Alice's configuration. """ emitter = _setup_emitter(click_config) configuration_file_location = config_file or AliceConfiguration.default_filepath() response = AliceConfiguration._read_configuration_file(filepath=configuration_file_location) return emitter.ipc(response=response, request_id=0, duration=0) # FIXME: what are request_id and duration here?
def view(general_config, config_file): """ View existing Alice's configuration. """ emitter = _setup_emitter(general_config) configuration_file_location = config_file or AliceConfiguration.default_filepath() response = AliceConfiguration._read_configuration_file(filepath=configuration_file_location) emitter.echo(f"Alice Configuration {configuration_file_location} \n {'='*55}") return emitter.echo(json.dumps(response, indent=4))
def alice( click_config, action, # Mode dev, force, dry_run, # Network teacher_uri, min_stake, federated_only, network, discovery_port, controller_port, # Filesystem config_root, config_file, # Blockchain pay_with, provider_uri, geth, sync, poa, registry_filepath, hw_wallet, # Alice bob_encrypting_key, bob_verifying_key, label, m, n, value, rate, duration_periods, expiration, message_kit, ): """ "Alice the Policy Authority" management commands. \b Actions ------------------------------------------------- \b init Create a brand new persistent Alice view View existing Alice's configuration. run Start Alice's controller. destroy Delete existing Alice's configuration. public-keys Obtain Alice's public verification and encryption keys. derive-policy-pubkey Get a policy public key from a policy label. grant Create and enact an access policy for some Bob. revoke Revoke a policy. decrypt Decrypt data encrypted under an Alice's policy public key. """ # # Validate # if federated_only and geth: raise click.BadOptionUsage( option_name="--geth", message="Federated only cannot be used with the --geth flag") # Banner emitter = click_config.emitter emitter.clear() emitter.banner(ALICE_BANNER) # # Managed Ethereum Client # ETH_NODE = NO_BLOCKCHAIN_CONNECTION if geth: ETH_NODE = actions.get_provider_process() provider_uri = ETH_NODE.provider_uri(scheme='file') # # Eager Actions (No Authentication Required) # if action == 'init': """Create a brand-new persistent Alice""" if dev: raise click.BadArgumentUsage( "Cannot create a persistent development character") if not provider_uri and not federated_only: raise click.BadOptionUsage( option_name='--provider', message= "--provider is required to create a new decentralized alice.") if not config_root: # Flag config_root = click_config.config_file # Envvar if not pay_with and not federated_only: pay_with = select_client_account(emitter=emitter, provider_uri=provider_uri) new_alice_config = AliceConfiguration.generate( password=get_nucypher_password(confirm=True), config_root=config_root, checksum_address=pay_with, domains={network} if network else None, federated_only=federated_only, registry_filepath=registry_filepath, provider_process=ETH_NODE, poa=poa, provider_uri=provider_uri, m=m, n=n, duration_periods=duration_periods, rate=rate) painting.paint_new_installation_help( emitter, new_configuration=new_alice_config) return # Exit elif action == "view": """Paint an existing configuration to the console""" configuration_file_location = config_file or AliceConfiguration.default_filepath( ) response = AliceConfiguration._read_configuration_file( filepath=configuration_file_location) return emitter.ipc( response=response, request_id=0, duration=0) # FIXME: what are request_id and duration here? # # Get Alice Configuration # if dev: alice_config = AliceConfiguration( dev_mode=True, network_middleware=click_config.middleware, domains={network}, provider_process=ETH_NODE, provider_uri=provider_uri, federated_only=True) else: try: alice_config = AliceConfiguration.from_configuration_file( dev_mode=False, filepath=config_file, domains={network} if network else None, network_middleware=click_config.middleware, rest_port=discovery_port, checksum_address=pay_with, provider_process=ETH_NODE, provider_uri=provider_uri, registry_filepath=registry_filepath) except FileNotFoundError: return actions.handle_missing_configuration_file( character_config_class=AliceConfiguration, config_file=config_file) if action == "destroy": """Delete all configuration files from the disk""" if dev: message = "'nucypher alice destroy' cannot be used in --dev mode" raise click.BadOptionUsage(option_name='--dev', message=message) return actions.destroy_configuration(emitter, character_config=alice_config, force=force) # # Produce Alice # # TODO: OH MY. client_password = None if not alice_config.federated_only: if (not hw_wallet or not dev) and not click_config.json_ipc: client_password = get_client_password( checksum_address=alice_config.checksum_address) try: ALICE = actions.make_cli_character(character_config=alice_config, click_config=click_config, dev=dev, teacher_uri=teacher_uri, min_stake=min_stake, client_password=client_password) except NucypherKeyring.AuthenticationFailed as e: emitter.echo(str(e), color='red', bold=True) click.get_current_context().exit(1) # TODO: Exit codes (not only for this, but for other exceptions) # # Admin Actions # if action == "run": """Start Alice Controller""" try: # RPC if click_config.json_ipc: rpc_controller = ALICE.make_rpc_controller() _transport = rpc_controller.make_control_transport() rpc_controller.start() return # HTTP else: emitter.message( f"Alice Verifying Key {bytes(ALICE.stamp).hex()}", color="green", bold=True) controller = ALICE.make_web_controller( crash_on_error=click_config.debug) ALICE.log.info('Starting HTTP Character Web Controller') emitter.message( f'Running HTTP Alice Controller at http://localhost:{controller_port}' ) return controller.start(http_port=controller_port, dry_run=dry_run) # Handle Crash except Exception as e: alice_config.log.critical(str(e)) emitter.message(f"{e.__class__.__name__} {e}", color='red', bold=True) if click_config.debug: raise # Crash :-( return # # Alice API # elif action == "public-keys": response = ALICE.controller.public_keys() return response elif action == "derive-policy-pubkey": # Validate if not label: raise click.BadOptionUsage( option_name='label', message= "--label is required for deriving a policy encrypting key.") # Request return ALICE.controller.derive_policy_encrypting_key(label=label) elif action == "grant": # Validate if not all((bob_verifying_key, bob_encrypting_key, label)): raise click.BadArgumentUsage( message= "--bob-verifying-key, --bob-encrypting-key, and --label are " "required options to grant (optionally --m, --n, and --expiration)." ) # Request grant_request = { 'bob_encrypting_key': bob_encrypting_key, 'bob_verifying_key': bob_verifying_key, 'label': label, 'm': m, 'n': n, 'expiration': expiration, } if not ALICE.federated_only: grant_request.update({'value': value}) return ALICE.controller.grant(request=grant_request) elif action == "revoke": # Validate if not label and bob_verifying_key: raise click.BadArgumentUsage( message= f"--label and --bob-verifying-key are required options for revoke." ) # Request revoke_request = { 'label': label, 'bob_verifying_key': bob_verifying_key } return ALICE.controller.revoke(request=revoke_request) elif action == "decrypt": # Validate if not all((label, message_kit)): input_specification, output_specification = ALICE.controller.get_specifications( interface_name=action) required_fields = ', '.join(input_specification) raise click.BadArgumentUsage( f'{required_fields} are required flags to decrypt') # Request request_data = {'label': label, 'message_kit': message_kit} response = ALICE.controller.decrypt(request=request_data) return response else: raise click.BadArgumentUsage(f"No such argument {action}")
def alice( click_config, action, # Mode dev, force, dry_run, # Network teacher_uri, min_stake, federated_only, network, discovery_port, controller_port, # Filesystem config_root, config_file, # Blockchain pay_with, provider_uri, geth, sync, poa, no_registry, registry_filepath, # Alice bob_encrypting_key, bob_verifying_key, label, m, n, value, rate, duration, expiration, message_kit): # # Validate # if federated_only and geth: raise click.BadOptionUsage( option_name="--geth", message="Federated only cannot be used with the --geth flag") # Banner click.clear() if not click_config.json_ipc and not click_config.quiet: click.secho(ALICE_BANNER) # # Managed Ethereum Client # ETH_NODE = NO_BLOCKCHAIN_CONNECTION if geth: ETH_NODE = actions.get_provider_process() provider_uri = ETH_NODE.provider_uri(scheme='file') # # Eager Actions (No Authentication Required) # if action == 'init': """Create a brand-new persistent Alice""" if dev: raise click.BadArgumentUsage( "Cannot create a persistent development character") if not config_root: # Flag config_root = click_config.config_file # Envvar new_alice_config = AliceConfiguration.generate( password=click_config.get_password(confirm=True), config_root=config_root, checksum_address=pay_with, rest_host="localhost", domains={network} if network else None, federated_only=federated_only, download_registry=no_registry, registry_filepath=registry_filepath, provider_process=ETH_NODE, poa=poa, provider_uri=provider_uri, m=m, n=n, duration=duration, rate=rate) painting.paint_new_installation_help( new_configuration=new_alice_config, config_root=config_root, config_file=config_file) return # Exit elif action == "view": """Paint an existing configuration to the console""" configuration_file_location = config_file or AliceConfiguration.DEFAULT_CONFIG_FILE_LOCATION response = AliceConfiguration._read_configuration_file( filepath=configuration_file_location) click_config.emit(response) return # Exit # # Make Alice # if dev: alice_config = AliceConfiguration( dev_mode=True, network_middleware=click_config.middleware, domains={network}, provider_process=ETH_NODE, provider_uri=provider_uri, federated_only=True) else: try: alice_config = AliceConfiguration.from_configuration_file( filepath=config_file, domains={network} if network else None, network_middleware=click_config.middleware, rest_port=discovery_port, checksum_address=pay_with, provider_process=ETH_NODE, provider_uri=provider_uri) except FileNotFoundError: return actions.handle_missing_configuration_file( character_config_class=AliceConfiguration, config_file=config_file) ALICE = actions.make_cli_character(character_config=alice_config, click_config=click_config, dev=dev, teacher_uri=teacher_uri, min_stake=min_stake, sync=sync) # # Admin Actions # if action == "run": """Start Alice Web Controller""" ALICE.controller.emitter( message=f"Alice Verifying Key {bytes(ALICE.stamp).hex()}", color="green", bold=True) controller = ALICE.make_web_controller( crash_on_error=click_config.debug) ALICE.log.info('Starting Alice Web Controller') return controller.start(http_port=controller_port or alice_config.controller_port, dry_run=dry_run) elif action == "destroy": """Delete all configuration files from the disk""" if dev: message = "'nucypher alice destroy' cannot be used in --dev mode" raise click.BadOptionUsage(option_name='--dev', message=message) return actions.destroy_configuration(character_config=alice_config, force=force) # # Alice API # elif action == "public-keys": response = ALICE.controller.public_keys() return response elif action == "derive-policy-pubkey": # Validate if not label: raise click.BadOptionUsage( option_name='label', message= "--label is required for deriving a policy encrypting key.") # Request return ALICE.controller.derive_policy_encrypting_key(label=label) elif action == "grant": # Validate if not all((bob_verifying_key, bob_encrypting_key, label)): raise click.BadArgumentUsage( message= "--bob-verifying-key, --bob-encrypting-key, and --label are " "required options to grant (optionally --m, --n, and --expiration)." ) # Request grant_request = { 'bob_encrypting_key': bob_encrypting_key, 'bob_verifying_key': bob_verifying_key, 'label': label, 'm': m, 'n': n, 'expiration': expiration, } if not ALICE.federated_only: grant_request.update({'value': value}) return ALICE.controller.grant(request=grant_request) elif action == "revoke": # Validate if not label and bob_verifying_key: raise click.BadArgumentUsage( message= f"--label and --bob-verifying-key are required options for revoke." ) # Request revoke_request = { 'label': label, 'bob_verifying_key': bob_verifying_key } return ALICE.controller.revoke(request=revoke_request) elif action == "decrypt": # Validate if not all((label, message_kit)): input_specification, output_specification = ALICE.controller.get_specifications( interface_name=action) required_fields = ', '.join(input_specification) raise click.BadArgumentUsage( f'{required_fields} are required flags to decrypt') # Request request_data = {'label': label, 'message_kit': message_kit} response = ALICE.controller.decrypt(request=request_data) return response else: raise click.BadArgumentUsage(f"No such argument {action}")
def alice(click_config, action, teacher_uri, min_stake, http_port, discovery_port, federated_only, network, config_root, config_file, provider_uri, no_registry, registry_filepath, dev, force, dry_run, bob_encrypting_key, bob_verifying_key, policy_encrypting_key, label, m, n): """ Start and manage an "Alice" character. """ if not click_config.json_ipc and not click_config.quiet: click.secho(ALICE_BANNER) if action == 'init': """Create a brand-new persistent Alice""" if not network: raise click.BadArgumentUsage( '--network is required to initialize a new configuration.') if dev: click_config.emitter( message="WARNING: Using temporary storage area", color='yellow') if not config_root: # Flag config_root = click_config.config_file # Envvar new_alice_config = AliceConfiguration.generate( password=click_config._get_password(confirm=True), config_root=config_root, rest_host="localhost", domains={network} if network else None, federated_only=federated_only, no_registry=no_registry, registry_filepath=registry_filepath, provider_uri=provider_uri) return painting.paint_new_installation_help( new_configuration=new_alice_config, config_root=config_root, config_file=config_file) elif action == "destroy": """Delete all configuration files from the disk""" if dev: message = "'nucypher ursula destroy' cannot be used in --dev mode" raise click.BadOptionUsage(option_name='--dev', message=message) destroyed_path = actions.destroy_system_configuration( config_class=AliceConfiguration, config_file=config_file, network=network, config_root=config_root, force=force) return nucypher_click_config.emitter( message=f"Destroyed {destroyed_path}", color='red') # # Get Alice Configuration # if dev: alice_config = AliceConfiguration( dev_mode=True, network_middleware=click_config.middleware, domains={network}, provider_uri=provider_uri, federated_only=True) else: alice_config = AliceConfiguration.from_configuration_file( filepath=config_file, domains={network or GLOBAL_DOMAIN}, network_middleware=click_config.middleware, rest_port=discovery_port, provider_uri=provider_uri) if not dev: click_config.unlock_keyring(character_configuration=alice_config) # Teacher Ursula teacher_uris = [teacher_uri] if teacher_uri else list() teacher_nodes = actions.load_seednodes( teacher_uris=teacher_uris, min_stake=min_stake, federated_only=federated_only, network_middleware=click_config.middleware) # Produce ALICE = alice_config(known_nodes=teacher_nodes, network_middleware=click_config.middleware) # Switch to character control emitter if click_config.json_ipc: ALICE.controller.emitter = IPCStdoutEmitter(quiet=click_config.quiet) if action == "run": """Start Alice Web Controller""" ALICE.controller.emitter( message=f"Alice Verifying Key {bytes(ALICE.stamp).hex()}", color="green", bold=True) controller = ALICE.make_web_controller( crash_on_error=click_config.debug) ALICE.log.info('Starting HTTP Character Web Controller') return controller.start(http_port=http_port, dry_run=dry_run) elif action == "view": """Paint an existing configuration to the console""" configuration_file_location = config_file or alice_config.config_file_location response = AliceConfiguration._read_configuration_file( filepath=configuration_file_location) return ALICE.controller.emitter( response=response) # TODO: Uses character control instead elif action == "public-keys": response = ALICE.controller.public_keys() return response elif action == "create-policy": if not all((bob_verifying_key, bob_encrypting_key, label)): raise click.BadArgumentUsage( message= "--bob-verifying-key, --bob-encrypting-key, and --label are " "required options to create a new policy.") create_policy_request = { 'bob_encrypting_key': bob_encrypting_key, 'bob_verifying_key': bob_verifying_key, 'label': label, 'm': m, 'n': n, } return ALICE.controller.create_policy(request=create_policy_request) elif action == "derive-policy-pubkey": return ALICE.controller.derive_policy_encrypting_key(label=label) elif action == "grant": grant_request = { 'bob_encrypting_key': bob_encrypting_key, 'bob_verifying_key': bob_verifying_key, 'label': label, 'm': m, 'n': n, 'expiration': (maya.now() + datetime.timedelta(days=3)).iso8601(), # TODO } return ALICE.controller.grant(request=grant_request) elif action == "revoke": return ALICE.controller.revoke( policy_encrypting_key=policy_encrypting_key) else: raise click.BadArgumentUsage(f"No such argument {action}")