diff --git a/chia/util/dump_keyring.py b/chia/util/dump_keyring.py index 33c057414a67..6a81df074b4e 100755 --- a/chia/util/dump_keyring.py +++ b/chia/util/dump_keyring.py @@ -2,9 +2,10 @@ from __future__ import annotations +import os from io import TextIOWrapper from pathlib import Path -from typing import Optional +from typing import Optional, cast import click import colorama @@ -20,33 +21,37 @@ DEFAULT_KEYRING_YAML = DEFAULT_KEYS_ROOT_PATH / "keyring.yaml" def get_passphrase_prompt(keyring_file: str) -> str: - prompt = ( - colorama.Fore.YELLOW - + colorama.Style.BRIGHT - + "(Unlock Keyring: " - + colorama.Fore.MAGENTA - + keyring_file - + colorama.Style.RESET_ALL - + colorama.Fore.YELLOW - + colorama.Style.BRIGHT - + ")" - + colorama.Style.RESET_ALL - + " Passphrase: " - ) # noqa: E501 + # casting since the colors are Any + prompt = cast( + str, + ( + colorama.Fore.YELLOW + + colorama.Style.BRIGHT + + "(Unlock Keyring: " + + colorama.Fore.MAGENTA + + keyring_file + + colorama.Style.RESET_ALL + + colorama.Fore.YELLOW + + colorama.Style.BRIGHT + + ")" + + colorama.Style.RESET_ALL + + " Passphrase: " + ), # noqa: E501 + ) return prompt @click.command() -@click.argument("keyring_file", nargs=1, default=DEFAULT_KEYRING_YAML) +@click.argument("keyring_file", nargs=1, default=os.fspath(DEFAULT_KEYRING_YAML)) @click.option( "--full-payload", is_flag=True, default=False, help="Print the full keyring contents, including plaintext" ) @click.option("--passphrase-file", type=click.File("r"), help="File or descriptor to read the passphrase from") @click.option("--pretty-print", is_flag=True, default=False) -def dump(keyring_file, full_payload: bool, passphrase_file: Optional[TextIOWrapper], pretty_print: bool): +def dump(keyring_file: str, full_payload: bool, passphrase_file: Optional[TextIOWrapper], pretty_print: bool) -> None: saved_passphrase: Optional[str] = KeyringWrapper.get_shared_instance().get_master_passphrase_from_credential_store() passphrase: str = saved_passphrase or DEFAULT_PASSPHRASE_IF_NO_MASTER_PASSPHRASE - prompt: str = get_passphrase_prompt(str(keyring_file)) + prompt: str = get_passphrase_prompt(keyring_file) print(f"Attempting to dump contents of keyring file: {keyring_file}\n") @@ -67,9 +72,10 @@ def dump(keyring_file, full_payload: bool, passphrase_file: Optional[TextIOWrapp dump_content = data_dict if pretty_print: - dump_content = yaml.dump(dump_content) + print(yaml.dump(dump_content)) + else: + print(dump_content) - print(dump_content) break except (ValueError, InvalidTag): passphrase = prompt_for_passphrase(prompt) @@ -78,7 +84,7 @@ def dump(keyring_file, full_payload: bool, passphrase_file: Optional[TextIOWrapp break -def main(): +def main() -> None: colorama.init() dump() # pylint: disable=no-value-for-parameter diff --git a/mypy.ini b/mypy.ini index 486a2c18035f..70c64912b4ff 100644 --- a/mypy.ini +++ b/mypy.ini @@ -18,7 +18,7 @@ strict_equality = True warn_redundant_casts = True # list created by: venv/bin/mypy | sed -n 's/.py:.*//p' | sort | uniq | tr '/' '.' | tr '\n' ',' -[mypy-chia.cmds.passphrase,chia.cmds.passphrase_funcs,chia.cmds.plots,chia.cmds.plotters,chia.cmds.show,chia.cmds.start_funcs,chia.cmds.wallet,chia.cmds.wallet_funcs,chia.daemon.server,chia.farmer.farmer_api,chia.introducer.introducer,chia.introducer.introducer_api,chia.plotters.bladebit,chia.plotters.chiapos,chia.plotters.madmax,chia.plotters.plotters,chia.plotters.plotters_util,chia.plotting.create_plots,chia.plotting.manager,chia.plotting.util,chia.pools.pool_puzzles,chia.pools.pool_wallet,chia.pools.pool_wallet_info,chia.rpc.full_node_rpc_client,chia.rpc.harvester_rpc_api,chia.rpc.harvester_rpc_client,chia.rpc.rpc_client,chia.rpc.timelord_rpc_api,chia.rpc.util,chia.rpc.wallet_rpc_api,chia.rpc.wallet_rpc_client,chia.seeder.crawler,chia.seeder.crawler_api,chia.seeder.crawl_store,chia.seeder.dns_server,chia.seeder.peer_record,chia.seeder.start_crawler,chia.simulator.full_node_simulator,chia.simulator.start_simulator,chia.ssl.create_ssl,chia.timelord.iters_from_block,chia.timelord.timelord,chia.timelord.timelord_api,chia.timelord.timelord_launcher,chia.timelord.timelord_state,chia.types.blockchain_format.program,chia.util.block_cache,chia.util.check_fork_next_block,chia.util.chia_logging,chia.util.config,chia.util.db_wrapper,chia.util.dump_keyring,chia.util.hash,chia.util.json_util,chia.util.keychain,chia.util.keyring_wrapper,chia.util.log_exceptions,chia.util.make_test_constants,chia.util.merkle_set,chia.util.network,chia.util.partial_func,chia.util.profiler,chia.util.safe_cancel_task,chia.util.service_groups,chia.util.ssl_check,chia.wallet.block_record,chia.wallet.chialisp,chia.wallet.did_wallet.did_wallet,chia.wallet.did_wallet.did_wallet_puzzles,chia.wallet.key_val_store,chia.wallet.lineage_proof,chia.wallet.payment,chia.wallet.puzzles.load_clvm,chia.wallet.puzzles.p2_conditions,chia.wallet.puzzles.p2_delegated_conditions,chia.wallet.puzzles.p2_delegated_puzzle,chia.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle,chia.wallet.puzzles.p2_m_of_n_delegate_direct,chia.wallet.puzzles.p2_puzzle_hash,chia.wallet.puzzles.prefarm.spend_prefarm,chia.wallet.puzzles.puzzle_utils,chia.wallet.puzzles.singleton_top_layer,chia.wallet.puzzles.tails,chia.wallet.secret_key_store,chia.wallet.trade_record,chia.wallet.trading.trade_store,chia.wallet.transaction_record,chia.wallet.util.debug_spend_bundle,chia.wallet.util.new_peak_queue,chia.wallet.wallet,chia.wallet.wallet_coin_store,chia.wallet.wallet_interested_store,chia.wallet.wallet_node_api,chia.wallet.wallet_pool_store,chia.wallet.wallet_puzzle_store,chia.wallet.wallet_sync_store,chia.wallet.wallet_transaction_store,chia.wallet.wallet_user_store,installhelper,tests.blockchain.blockchain_test_utils,tests.blockchain.test_blockchain,chia.simulator.block_tools,tests.build-init-files,tests.build-workflows,tests.clvm.coin_store,tests.clvm.test_chialisp_deserialization,tests.clvm.test_clvm_compilation,tests.clvm.test_program,tests.clvm.test_puzzle_compression,tests.clvm.test_puzzles,tests.clvm.test_serialized_program,tests.clvm.test_singletons,tests.clvm.test_spend_sim,tests.conftest,tests.connection_utils,tests.core.cmds.test_keys,tests.core.consensus.test_pot_iterations,tests.core.custom_types.test_coin,tests.core.custom_types.test_spend_bundle,tests.core.daemon.test_daemon,tests.core.full_node.full_sync.test_full_sync,tests.core.full_node.stores.test_block_store,tests.core.full_node.stores.test_coin_store,tests.core.full_node.stores.test_full_node_store,tests.core.full_node.stores.test_hint_store,tests.core.full_node.stores.test_sync_store,tests.core.full_node.test_address_manager,tests.core.full_node.test_block_height_map,tests.core.full_node.test_conditions,tests.core.full_node.test_full_node,tests.core.mempool.test_mempool,tests.core.mempool.test_mempool_performance,tests.core.full_node.test_node_load,tests.core.full_node.test_peer_store_resolver,tests.core.full_node.test_performance,tests.core.full_node.test_transactions,tests.core.make_block_generator,tests.core.node_height,tests.core.server.test_dos,tests.core.server.test_rate_limits,tests.core.ssl.test_ssl,tests.core.test_cost_calculation,tests.core.test_crawler_rpc,tests.core.test_daemon_rpc,tests.core.test_db_conversion,tests.core.test_db_validation,tests.core.test_farmer_harvester_rpc,tests.core.test_filter,tests.core.test_full_node_rpc,tests.core.test_merkle_set,tests.core.test_setproctitle,tests.core.util.test_cached_bls,tests.core.util.test_config,tests.core.util.test_file_keyring_synchronization,tests.core.util.test_files,tests.core.util.test_keychain,tests.core.util.test_keyring_wrapper,tests.core.util.test_lru_cache,tests.core.util.test_significant_bits,tests.farmer_harvester.test_farmer_harvester,tests.generator.test_list_to_batches,tests.generator.test_scan,tests.plotting.test_plot_manager,tests.pools.test_pool_cmdline,tests.pools.test_pool_config,tests.pools.test_pool_puzzles_lifecycle,tests.pools.test_wallet_pool_store,tests.simulation.test_simulation,chia.simulator.time_out_assert,tests.tools.test_full_sync,tests.tools.test_run_block,tests.util.benchmark_cost,tests.util.build_network_protocol_files,tests.util.db_connection,tests.util.generator_tools_testing,chia.simulator.keyring,tests.util.key_tool,tests.util.test_full_block_utils,tests.util.test_lock_queue,tests.util.test_misc,tests.util.test_network,tests.util.test_network_protocol_files,tests.wallet.cat_wallet.test_cat_lifecycle,tests.wallet.cat_wallet.test_cat_wallet,tests.wallet.cat_wallet.test_offer_lifecycle,tests.wallet.cat_wallet.test_trades,tests.wallet.did_wallet.test_did,tests.wallet.did_wallet.test_did_rpc,tests.wallet.did_wallet.test_nft_rpc,tests.wallet.did_wallet.test_nft_wallet,tests.wallet.rpc.test_wallet_rpc,tests.wallet.simple_sync.test_simple_sync_protocol,tests.wallet.sync.test_wallet_sync,tests.wallet.test_bech32m,tests.wallet.test_chialisp,tests.wallet.test_puzzle_store,tests.wallet.test_singleton,tests.wallet.test_singleton_lifecycle,tests.wallet.test_singleton_lifecycle_fast,tests.wallet.test_taproot,tests.wallet.test_wallet_blockchain,tests.wallet.test_wallet_interested_store,tests.wallet.test_wallet_key_val_store,tests.wallet.test_wallet_user_store,chia.simulator.wallet_tools,tests.weight_proof.test_weight_proof,tools.analyze-chain,tools.run_block,tools.test_full_sync,tests.wallet.nft_wallet.test_nft_wallet,chia.wallet.nft_wallet.nft_puzzles,tests.wallet.nft_wallet.test_nft_puzzles] +[mypy-chia.cmds.passphrase,chia.cmds.passphrase_funcs,chia.cmds.plots,chia.cmds.plotters,chia.cmds.show,chia.cmds.start_funcs,chia.cmds.wallet,chia.cmds.wallet_funcs,chia.daemon.server,chia.farmer.farmer_api,chia.introducer.introducer,chia.introducer.introducer_api,chia.plotters.bladebit,chia.plotters.chiapos,chia.plotters.madmax,chia.plotters.plotters,chia.plotters.plotters_util,chia.plotting.create_plots,chia.plotting.manager,chia.plotting.util,chia.pools.pool_puzzles,chia.pools.pool_wallet,chia.pools.pool_wallet_info,chia.rpc.full_node_rpc_client,chia.rpc.harvester_rpc_api,chia.rpc.harvester_rpc_client,chia.rpc.rpc_client,chia.rpc.timelord_rpc_api,chia.rpc.util,chia.rpc.wallet_rpc_api,chia.rpc.wallet_rpc_client,chia.seeder.crawler,chia.seeder.crawler_api,chia.seeder.crawl_store,chia.seeder.dns_server,chia.seeder.peer_record,chia.seeder.start_crawler,chia.simulator.full_node_simulator,chia.simulator.start_simulator,chia.ssl.create_ssl,chia.timelord.iters_from_block,chia.timelord.timelord,chia.timelord.timelord_api,chia.timelord.timelord_launcher,chia.timelord.timelord_state,chia.types.blockchain_format.program,chia.util.block_cache,chia.util.check_fork_next_block,chia.util.chia_logging,chia.util.config,chia.util.db_wrapper,chia.util.hash,chia.util.json_util,chia.util.keychain,chia.util.keyring_wrapper,chia.util.log_exceptions,chia.util.make_test_constants,chia.util.merkle_set,chia.util.network,chia.util.partial_func,chia.util.profiler,chia.util.safe_cancel_task,chia.util.service_groups,chia.util.ssl_check,chia.wallet.block_record,chia.wallet.chialisp,chia.wallet.did_wallet.did_wallet,chia.wallet.did_wallet.did_wallet_puzzles,chia.wallet.key_val_store,chia.wallet.lineage_proof,chia.wallet.payment,chia.wallet.puzzles.load_clvm,chia.wallet.puzzles.p2_conditions,chia.wallet.puzzles.p2_delegated_conditions,chia.wallet.puzzles.p2_delegated_puzzle,chia.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle,chia.wallet.puzzles.p2_m_of_n_delegate_direct,chia.wallet.puzzles.p2_puzzle_hash,chia.wallet.puzzles.prefarm.spend_prefarm,chia.wallet.puzzles.puzzle_utils,chia.wallet.puzzles.singleton_top_layer,chia.wallet.puzzles.tails,chia.wallet.secret_key_store,chia.wallet.trade_record,chia.wallet.trading.trade_store,chia.wallet.transaction_record,chia.wallet.util.debug_spend_bundle,chia.wallet.util.new_peak_queue,chia.wallet.wallet,chia.wallet.wallet_coin_store,chia.wallet.wallet_interested_store,chia.wallet.wallet_node_api,chia.wallet.wallet_pool_store,chia.wallet.wallet_puzzle_store,chia.wallet.wallet_sync_store,chia.wallet.wallet_transaction_store,chia.wallet.wallet_user_store,installhelper,tests.blockchain.blockchain_test_utils,tests.blockchain.test_blockchain,chia.simulator.block_tools,tests.build-init-files,tests.build-workflows,tests.clvm.coin_store,tests.clvm.test_chialisp_deserialization,tests.clvm.test_clvm_compilation,tests.clvm.test_program,tests.clvm.test_puzzle_compression,tests.clvm.test_puzzles,tests.clvm.test_serialized_program,tests.clvm.test_singletons,tests.clvm.test_spend_sim,tests.conftest,tests.connection_utils,tests.core.cmds.test_keys,tests.core.consensus.test_pot_iterations,tests.core.custom_types.test_coin,tests.core.custom_types.test_spend_bundle,tests.core.daemon.test_daemon,tests.core.full_node.full_sync.test_full_sync,tests.core.full_node.stores.test_block_store,tests.core.full_node.stores.test_coin_store,tests.core.full_node.stores.test_full_node_store,tests.core.full_node.stores.test_hint_store,tests.core.full_node.stores.test_sync_store,tests.core.full_node.test_address_manager,tests.core.full_node.test_block_height_map,tests.core.full_node.test_conditions,tests.core.full_node.test_full_node,tests.core.mempool.test_mempool,tests.core.mempool.test_mempool_performance,tests.core.full_node.test_node_load,tests.core.full_node.test_peer_store_resolver,tests.core.full_node.test_performance,tests.core.full_node.test_transactions,tests.core.make_block_generator,tests.core.node_height,tests.core.server.test_dos,tests.core.server.test_rate_limits,tests.core.ssl.test_ssl,tests.core.test_cost_calculation,tests.core.test_crawler_rpc,tests.core.test_daemon_rpc,tests.core.test_db_conversion,tests.core.test_db_validation,tests.core.test_farmer_harvester_rpc,tests.core.test_filter,tests.core.test_full_node_rpc,tests.core.test_merkle_set,tests.core.test_setproctitle,tests.core.util.test_cached_bls,tests.core.util.test_config,tests.core.util.test_file_keyring_synchronization,tests.core.util.test_files,tests.core.util.test_keychain,tests.core.util.test_keyring_wrapper,tests.core.util.test_lru_cache,tests.core.util.test_significant_bits,tests.farmer_harvester.test_farmer_harvester,tests.generator.test_list_to_batches,tests.generator.test_scan,tests.plotting.test_plot_manager,tests.pools.test_pool_cmdline,tests.pools.test_pool_config,tests.pools.test_pool_puzzles_lifecycle,tests.pools.test_wallet_pool_store,tests.simulation.test_simulation,chia.simulator.time_out_assert,tests.tools.test_full_sync,tests.tools.test_run_block,tests.util.benchmark_cost,tests.util.build_network_protocol_files,tests.util.db_connection,tests.util.generator_tools_testing,chia.simulator.keyring,tests.util.key_tool,tests.util.test_full_block_utils,tests.util.test_lock_queue,tests.util.test_misc,tests.util.test_network,tests.util.test_network_protocol_files,tests.wallet.cat_wallet.test_cat_lifecycle,tests.wallet.cat_wallet.test_cat_wallet,tests.wallet.cat_wallet.test_offer_lifecycle,tests.wallet.cat_wallet.test_trades,tests.wallet.did_wallet.test_did,tests.wallet.did_wallet.test_did_rpc,tests.wallet.did_wallet.test_nft_rpc,tests.wallet.did_wallet.test_nft_wallet,tests.wallet.rpc.test_wallet_rpc,tests.wallet.simple_sync.test_simple_sync_protocol,tests.wallet.sync.test_wallet_sync,tests.wallet.test_bech32m,tests.wallet.test_chialisp,tests.wallet.test_puzzle_store,tests.wallet.test_singleton,tests.wallet.test_singleton_lifecycle,tests.wallet.test_singleton_lifecycle_fast,tests.wallet.test_taproot,tests.wallet.test_wallet_blockchain,tests.wallet.test_wallet_interested_store,tests.wallet.test_wallet_key_val_store,tests.wallet.test_wallet_user_store,chia.simulator.wallet_tools,tests.weight_proof.test_weight_proof,tools.analyze-chain,tools.run_block,tools.test_full_sync,tests.wallet.nft_wallet.test_nft_wallet,chia.wallet.nft_wallet.nft_puzzles,tests.wallet.nft_wallet.test_nft_puzzles] disable_error_code = annotation-unchecked disallow_any_generics = False disallow_subclassing_any = False diff --git a/tests/util/test_dump_keyring.py b/tests/util/test_dump_keyring.py new file mode 100644 index 000000000000..14b0bf8f72c1 --- /dev/null +++ b/tests/util/test_dump_keyring.py @@ -0,0 +1,60 @@ +from __future__ import annotations + +import os +import re +from dataclasses import dataclass +from typing import Sequence + +from click.testing import CliRunner + +from chia.util.dump_keyring import dump +from chia.util.keychain import Keychain +from tests.util.misc import Marks, datacases + +output_prefix = """Attempting to dump contents of keyring file: {path} + +""" + + +@dataclass +class KeyringCase: + args: Sequence[str] + regex: str + id: str + marks: Marks = () + + +@datacases( + KeyringCase( + id="empty", + args=[], + regex="\\{\\}\n", + ), + KeyringCase( + id="empty, pretty", + args=["--pretty-print"], + regex="\\{\\}\n\n", + ), + KeyringCase( + id="empty, full", + args=["--full-payload"], + regex=( + "\\{'version': 1, 'salt': '[0-9a-f]{32}', 'nonce': '[0-9a-f]{24}', 'data': \\{\\}," + " 'passphrase_hint': None\\}\n" + ), + ), + KeyringCase( + id="empty, full, pretty", + args=["--full-payload", "--pretty-print"], + regex="data: \\{\\}\nnonce: [0-9a-f]{24}\npassphrase_hint: null\nsalt: [0-9a-f]{32}\nversion: 1\n\n", + ), +) +def test_keyring_dump_empty(empty_keyring: Keychain, case: KeyringCase) -> None: + keyring_path = empty_keyring.keyring_wrapper.keyring.keyring_path + runner = CliRunner() + result = runner.invoke(dump, [*case.args, os.fspath(keyring_path)]) + + regex = re.escape(output_prefix.format(path=keyring_path)) + case.regex + + assert re.fullmatch(regex, result.output) is not None + assert result.exit_code == 0