async def quick_start(args): config_file_name = args.config_file_name wallet = args.wallet password = args.config_password if args.auto_set_permissions is not None: autofix_permissions(args.auto_set_permissions) if password is not None and not Security.login(password): logging.getLogger().error("Invalid password.") return await Security.wait_til_decryption_done() await create_yml_files() init_logging("hummingbot_logs.yml") read_system_configs_from_yml() hb = HummingbotApplication.main_application() # Todo: validate strategy and config_file_name before assinging if config_file_name is not None: hb.strategy_file_name = config_file_name hb.strategy_name = update_strategy_config_map_from_file( os.path.join(CONF_FILE_PATH, config_file_name)) # To ensure quickstart runs with the default value of False for kill_switch_enabled if not present if not global_config_map.get("kill_switch_enabled"): global_config_map.get("kill_switch_enabled").value = False if wallet and password: global_config_map.get("ethereum_wallet").value = wallet if hb.strategy_name and hb.strategy_file_name: if not all_configs_complete(hb.strategy_name): hb.status() with patch_stdout(log_field=hb.app.log_field): dev_mode = check_dev_mode() if dev_mode: hb.app.log( "Running from dev branches. Full remote logging will be enabled." ) log_level = global_config_map.get("log_level").value init_logging("hummingbot_logs.yml", override_log_level=log_level, dev_mode=dev_mode) if hb.strategy_file_name is not None and hb.strategy_name is not None: await write_config_to_yml(hb.strategy_name, hb.strategy_file_name) hb.start(log_level) tasks: List[Coroutine] = [hb.run()] if global_config_map.get("debug_console").value: management_port: int = detect_available_port(8211) tasks.append( start_management_console(locals(), host="localhost", port=management_port)) await safe_gather(*tasks)
def test_login(self): password = "******" secrets_manager = ETHKeyFileSecretManger(password) store_password_verification(secrets_manager) Security.login(secrets_manager) config_map = self.store_binance_config() self.async_run_with_timeout(Security.wait_til_decryption_done(), timeout=2) self.assertTrue(Security.is_decryption_done()) self.assertTrue(Security.any_secure_configs()) self.assertTrue(Security.connector_config_file_exists(self.connector)) api_keys = Security.api_keys(self.connector) expected_keys = api_keys_from_connector_config_map(config_map) self.assertEqual(expected_keys, api_keys)
def test_new_password_process(self): # empty folder, new password is required self.assertFalse(Security.any_encryped_files()) self.assertTrue(Security.new_password_required()) # login will pass with any password result = Security.login("a") self.assertTrue(result) Security.update_secure_config("new_key", "new_value") self.assertTrue(os.path.exists(f"{temp_folder}encrypted_new_key.json")) self.assertTrue(Security.encrypted_file_exists("new_key"))
def login_prompt(): from hummingbot.client.config.security import Security err_msg = None if Security.new_password_required(): show_welcome() password = input_dialog( title="Set Password", text="Create a password to protect your sensitive data. " "This password is not shared with us nor with anyone else, so please store it securely." "\n\nEnter your new password:"******"Set Password", text="Please re-enter your password:"******"Passwords entered do not match, please try again." else: Security.login(password) else: password = input_dialog( title="Welcome back to Hummingbot", text="Enter your password:"******"Invalid password - please try again." if err_msg is not None: message_dialog( title='Error', text=err_msg, style=dialog_style).run() return login_prompt() return True
def login_prompt(): from hummingbot.client.config.security import Security import time err_msg = None if Security.new_password_required(): show_welcome() password = input_dialog( title="Set Password", text="Create a password to protect your sensitive data. " "This password is not shared with us nor with anyone else, so please store it securely." "\n\nEnter your new password:"******"Set Password", text="Please re-enter your password:"******"Passwords entered do not match, please try again." else: Security.login(password) # encrypt current timestamp as a dummy to prevent promping for password if bot exits without connecting an exchange dummy = f"{time.time()}" Security.update_secure_config("default", dummy) else: password = input_dialog(title="Welcome back to Hummingbot", text="Enter your password:"******"Invalid password - please try again." if err_msg is not None: message_dialog(title='Error', text=err_msg, style=dialog_style).run() return login_prompt() return True
async def quick_start(args): config_file_name = args.config_file_name wallet = args.wallet password = args.config_password if args.auto_set_permissions is not None: autofix_permissions(args.auto_set_permissions) if password is not None and not Security.login(password): logging.getLogger().error("Invalid password.") return await Security.wait_til_decryption_done() await create_yml_files() init_logging("hummingbot_logs.yml") await read_system_configs_from_yml() AllConnectorSettings.initialize_paper_trade_settings( global_config_map.get("paper_trade_exchanges").value) hb = HummingbotApplication.main_application() # Todo: validate strategy and config_file_name before assinging if config_file_name is not None: hb.strategy_file_name = config_file_name hb.strategy_name = await update_strategy_config_map_from_file( os.path.join(CONF_FILE_PATH, config_file_name)) # To ensure quickstart runs with the default value of False for kill_switch_enabled if not present if not global_config_map.get("kill_switch_enabled"): global_config_map.get("kill_switch_enabled").value = False if wallet and password: global_config_map.get("ethereum_wallet").value = wallet if hb.strategy_name and hb.strategy_file_name: if not all_configs_complete(hb.strategy_name): hb.status() # The listener needs to have a named variable for keeping reference, since the event listener system # uses weak references to remove unneeded listeners. start_listener: UIStartListener = UIStartListener(hb) hb.app.add_listener(HummingbotUIEvent.Start, start_listener) tasks: List[Coroutine] = [hb.run()] if global_config_map.get("debug_console").value: management_port: int = detect_available_port(8211) tasks.append( start_management_console(locals(), host="localhost", port=management_port)) await safe_gather(*tasks)
async def quick_start(args: argparse.Namespace, secrets_manager: BaseSecretsManager): config_file_name = args.config_file_name client_config = load_client_config_map_from_file() if args.auto_set_permissions is not None: autofix_permissions(args.auto_set_permissions) if not Security.login(secrets_manager): logging.getLogger().error("Invalid password.") return await Security.wait_til_decryption_done() await create_yml_files_legacy() init_logging("hummingbot_logs.yml", client_config) await read_system_configs_from_yml() AllConnectorSettings.initialize_paper_trade_settings( client_config.paper_trade.paper_trade_exchanges) hb = HummingbotApplication.main_application() # Todo: validate strategy and config_file_name before assinging strategy_config = None if config_file_name is not None: hb.strategy_file_name = config_file_name strategy_config = await load_strategy_config_map_from_file( STRATEGIES_CONF_DIR_PATH / config_file_name) hb.strategy_name = (strategy_config.strategy if isinstance( strategy_config, BaseStrategyConfigMap) else strategy_config.get("strategy").value) hb.strategy_config_map = strategy_config if strategy_config is not None: if not all_configs_complete(strategy_config, hb.client_config_map): hb.status() # The listener needs to have a named variable for keeping reference, since the event listener system # uses weak references to remove unneeded listeners. start_listener: UIStartListener = UIStartListener(hb) hb.app.add_listener(HummingbotUIEvent.Start, start_listener) tasks: List[Coroutine] = [ hb.run(), start_existing_gateway_container(client_config) ] if client_config.debug_console: management_port: int = detect_available_port(8211) tasks.append( start_management_console(locals(), host="localhost", port=management_port)) await safe_gather(*tasks)
def test_update_secure_config(self): password = "******" secrets_manager = ETHKeyFileSecretManger(password) store_password_verification(secrets_manager) Security.login(secrets_manager) binance_config = ClientConfigAdapter( BinanceConfigMap(binance_api_key=self.api_key, binance_api_secret=self.api_secret) ) self.async_run_with_timeout(Security.wait_til_decryption_done()) Security.update_secure_config(binance_config) self.reset_security() Security.login(secrets_manager) self.async_run_with_timeout(Security.wait_til_decryption_done(), timeout=2) binance_loaded_config = Security.decrypted_value(binance_config.connector) self.assertEqual(binance_config, binance_loaded_config) binance_config.binance_api_key = "someOtherApiKey" Security.update_secure_config(binance_config) self.reset_security() Security.login(secrets_manager) self.async_run_with_timeout(Security.wait_til_decryption_done(), timeout=2) binance_loaded_config = Security.decrypted_value(binance_config.connector) self.assertEqual(binance_config, binance_loaded_config)
async def _test_existing_password(self): # check the 2 encrypted files exist self.assertTrue( os.path.exists(f"{temp_folder}encrypted_test_key_1.json")) self.assertTrue( os.path.exists(f"{temp_folder}encrypted_test_key_2.json")) self.assertTrue(Security.any_encryped_files()) self.assertFalse(Security.new_password_required()) # login fails with incorrect password result = Security.login("b") self.assertFalse(result) # login passes with correct password result = Security.login("a") self.assertTrue(result) # right after logging in, the decryption shouldn't finished yet self.assertFalse(Security.is_decryption_done()) await Security.wait_til_decryption_done() self.assertEqual(len(Security.all_decrypted_values()), 2) config_value = Security.decrypted_value("test_key_1") self.assertEqual("test_value_1", config_value) Security.update_secure_config("test_key_1", "new_value") self.assertEqual("new_value", Security.decrypted_value("test_key_1"))
def login_prompt(secrets_manager_cls: Type[BaseSecretsManager], style: Style): err_msg = None secrets_manager = None if Security.new_password_required() and legacy_confs_exist(): secrets_manager = migrate_configs_prompt(secrets_manager_cls, style) if Security.new_password_required(): show_welcome(style) password = input_dialog(title="Set Password", text=""" Create a password to protect your sensitive data. This password is not shared with us nor with anyone else, so please store it securely. If you have used hummingbot before and already have secure configs stored, input your previous password in this prompt. The next step will automatically migrate your existing configs. Enter your new password:""", password=True, style=style).run() if password is None: return None re_password = input_dialog(title="Set Password", text="Please re-enter your password:"******"Passwords entered do not match, please try again." else: secrets_manager = secrets_manager_cls(password) store_password_verification(secrets_manager) migrate_non_secure_only_prompt(style) else: password = input_dialog(title="Welcome back to Hummingbot", text="Enter your password:"******"Invalid password - please try again." if err_msg is not None: message_dialog(title='Error', text=err_msg, style=style).run() return login_prompt(secrets_manager_cls, style) return secrets_manager