Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
async def load_yml_into_cm(yml_path: str, template_file_path: str,
                           cm: Dict[str, ConfigVar]):
    try:
        data = {}
        conf_version = -1
        if isfile(yml_path):
            with open(yml_path) as stream:
                data = yaml_parser.load(stream) or {}
                conf_version = data.get("template_version", 0)

        with open(template_file_path, "r") as template_fd:
            template_data = yaml_parser.load(template_fd)
            template_version = template_data.get("template_version", 0)

        for key in template_data:
            if key in {"template_version"}:
                continue

            cvar = cm.get(key)
            if cvar is None:
                logging.getLogger().error(
                    f"Cannot find corresponding config to key {key} in template."
                )
                continue

            # Skip this step since the values are not saved in the yml file
            if cvar.is_secure:
                cvar.value = Security.decrypted_value(key)
                continue

            val_in_file = data.get(key, None)
            if (val_in_file is None
                    or val_in_file == "") and cvar.default is not None:
                cvar.value = cvar.default
                continue

            # Todo: the proper process should be first validate the value then assign it
            cvar.value = parse_cvar_value(cvar, val_in_file)
            if cvar.value is not None:
                err_msg = await cvar.validate(str(cvar.value))
                if err_msg is not None:
                    # Instead of raising an exception, simply skip over this variable and wait till the user is prompted
                    logging.getLogger().error(
                        "Invalid value %s for config variable %s: %s" %
                        (val_in_file, cvar.key, err_msg))
                    cvar.value = None

        if conf_version < template_version:
            # delete old config file
            if isfile(yml_path):
                unlink(yml_path)
            # copy the new file template
            shutil.copy(template_file_path, yml_path)
            # save the old variables into the new config file
            save_to_yml(yml_path, cm)
    except Exception as e:
        logging.getLogger().error(
            "Error loading configs. Your config file may be corrupt. %s" %
            (e, ),
            exc_info=True)
 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"))
Ejemplo n.º 4
0
 async def connect_exchange(self,  # type: HummingbotApplication
                            exchange):
     self.app.clear_input()
     self.placeholder_mode = True
     self.app.hide_input = True
     if exchange == "kraken":
         self._notify("Reminder: Please ensure your Kraken API Key Nonce Window is at least 10.")
     exchange_configs = [c for c in global_config_map.values()
                         if c.key in settings.CONNECTOR_SETTINGS[exchange].config_keys and c.is_connect_key]
     to_connect = True
     if Security.encrypted_file_exists(exchange_configs[0].key):
         await Security.wait_til_decryption_done()
         api_key_config = [c for c in exchange_configs if "api_key" in c.key]
         if api_key_config:
             api_key_config = api_key_config[0]
             api_key = Security.decrypted_value(api_key_config.key)
             prompt = f"Would you like to replace your existing {exchange} API key {api_key} (Yes/No)? >>> "
         else:
             prompt = f"Would you like to replace your existing {exchange_configs[0].key} (Yes/No)? >>> "
         answer = await self.app.prompt(prompt=prompt)
         if self.app.to_stop_config:
             self.app.to_stop_config = False
             return
         if answer.lower() not in ("yes", "y"):
             to_connect = False
     if to_connect:
         for config in exchange_configs:
             await self.prompt_a_config(config)
             if self.app.to_stop_config:
                 self.app.to_stop_config = False
                 return
             Security.update_secure_config(config.key, config.value)
         api_keys = await Security.api_keys(exchange)
         network_timeout = float(global_config_map["other_commands_timeout"].value)
         try:
             err_msg = await asyncio.wait_for(
                 UserBalances.instance().add_exchange(exchange, **api_keys), network_timeout
             )
         except asyncio.TimeoutError:
             self._notify("\nA network error prevented the connection to complete. See logs for more details.")
             self.placeholder_mode = False
             self.app.hide_input = False
             self.app.change_prompt(prompt=">>> ")
             raise
         if err_msg is None:
             self._notify(f"\nYou are now connected to {exchange}.")
         else:
             self._notify(f"\nError: {err_msg}")
     self.placeholder_mode = False
     self.app.hide_input = False
     self.app.change_prompt(prompt=">>> ")
Ejemplo n.º 5
0
 async def connect_exchange(
         self,  # type: HummingbotApplication
         exchange):
     self.app.clear_input()
     self.placeholder_mode = True
     self.app.hide_input = True
     if exchange == "kraken":
         self._notify(
             "Reminder: Please ensure your Kraken API Key Nonce Window is at least 10."
         )
     exchange_configs = [
         c for c in global_config_map.values()
         if c.key in settings.CONNECTOR_SETTINGS[exchange].config_keys
         and c.is_connect_key
     ]
     to_connect = True
     if Security.encrypted_file_exists(exchange_configs[0].key):
         await Security.wait_til_decryption_done()
         api_key_config = [
             c for c in exchange_configs if "api_key" in c.key
         ][0]
         api_key = Security.decrypted_value(api_key_config.key)
         answer = await self.app.prompt(
             prompt=
             f"Would you like to replace your existing {exchange} API key "
             f"{api_key} (Yes/No)? >>> ")
         if self.app.to_stop_config:
             self.app.to_stop_config = False
             return
         if answer.lower() not in ("yes", "y"):
             to_connect = False
     if to_connect:
         for config in exchange_configs:
             await self.prompt_a_config(config)
             if self.app.to_stop_config:
                 self.app.to_stop_config = False
                 return
             Security.update_secure_config(config.key, config.value)
         api_keys = await Security.api_keys(exchange)
         err_msg = await UserBalances.instance().add_exchange(
             exchange, **api_keys)
         if err_msg is None:
             self._notify(f"\nYou are now connected to {exchange}.")
         else:
             self._notify(f"\nError: {err_msg}")
     self.placeholder_mode = False
     self.app.hide_input = False
     self.app.change_prompt(prompt=">>> ")
Ejemplo n.º 6
0
 async def validate_n_connect_celo(self, to_reconnect: bool = False, celo_address: str = None,
                                   celo_password: str = None) -> Optional[str]:
     if celo_address is None:
         celo_address = global_config_map["celo_address"].value
     if celo_password is None:
         await Security.wait_til_decryption_done()
         celo_password = Security.decrypted_value("celo_password")
     if celo_address is None or celo_password is None:
         return "Celo address and/or password have not been added."
     if CeloCLI.unlocked and not to_reconnect:
         return None
     err_msg = CeloCLI.validate_node_synced()
     if err_msg is not None:
         return err_msg
     err_msg = CeloCLI.unlock_account(celo_address, celo_password)
     return err_msg
Ejemplo n.º 7
0
 async def connect_exchange(
         self,  # type: HummingbotApplication
         exchange):
     self.app.clear_input()
     self.placeholder_mode = True
     self.app.hide_input = True
     exchange_configs = [
         c for c in global_config_map.values()
         if exchange in c.key and c.is_connect_key
     ]
     to_connect = True
     if Security.encrypted_file_exists(exchange_configs[0].key):
         await Security.wait_til_decryption_done()
         api_key_config = [
             c for c in exchange_configs if "api_key" in c.key
         ][0]
         api_key = Security.decrypted_value(api_key_config.key)
         answer = await self.app.prompt(
             prompt=
             f"Would you like to replace your existing {exchange} API key "
             f"...{api_key[-4:]} (Yes/No)? >>> ")
         if answer.lower() not in ("yes", "y"):
             to_connect = False
     if to_connect:
         for config in exchange_configs:
             await self.prompt_a_config(config)
             Security.update_secure_config(config.key, config.value)
         api_keys = (await Security.api_keys(exchange)).values()
         err_msg = await UserBalances.instance().add_exchange(
             exchange, *api_keys)
         if err_msg is None:
             self._notify(f"\nYou are now connected to {exchange}.")
         else:
             self._notify(f"\nError: {err_msg}")
     self.placeholder_mode = False
     self.app.hide_input = False
     self.app.change_prompt(prompt=">>> ")
Ejemplo n.º 8
0
def load_secure_values(config_map):
    for key, config in config_map.items():
        if config.is_secure:
            config.value = Security.decrypted_value(key)