async def set_keyring_passphrase(self, request: Dict[str, Any]) -> Dict[str, Any]: success: bool = False error: Optional[str] = None current_passphrase: Optional[str] = None new_passphrase: Optional[str] = None if using_default_passphrase(): current_passphrase = default_passphrase() if Keychain.has_master_passphrase() and not current_passphrase: current_passphrase = request.get("current_passphrase", None) if type(current_passphrase) is not str: return {"success": False, "error": "missing current_passphrase"} new_passphrase = request.get("new_passphrase", None) if type(new_passphrase) is not str: return {"success": False, "error": "missing new_passphrase"} if not Keychain.passphrase_meets_requirements(new_passphrase): return {"success": False, "error": "passphrase doesn't satisfy requirements"} try: assert new_passphrase is not None # mypy, I love you Keychain.set_master_passphrase(current_passphrase, new_passphrase, allow_migration=False) except KeyringRequiresMigration: error = "keyring requires migration" except KeyringCurrentPassphaseIsInvalid: error = "current passphrase is invalid" except Exception as e: tb = traceback.format_exc() self.log.error(f"Failed to set keyring passphrase: {e} {tb}") else: success = True # Inform the GUI of keyring status changes self.keyring_status_changed(await self.keyring_status(), "wallet_ui") response: Dict[str, Any] = {"success": success, "error": error} return response
async def migrate_keyring(self, request: Dict[str, Any]) -> Dict[str, Any]: if Keychain.needs_migration() is False: # If the keyring has already been migrated, we'll raise an error to the client. # The reason for raising an error is because the migration request has side- # effects beyond copying keys from the legacy keyring to the new keyring. The # request may have set a passphrase and indicated that keys should be cleaned # from the legacy keyring. If we were to return early and indicate success, # the client and user's expectations may not match reality (were my keys # deleted from the legacy keyring? was my passphrase set?). return {"success": False, "error": "migration not needed"} success: bool = False error: Optional[str] = None passphrase: Optional[str] = request.get("passphrase", None) cleanup_legacy_keyring: bool = request.get("cleanup_legacy_keyring", False) if passphrase is not None and type(passphrase) is not str: return {"success": False, "error": 'expected string value for "passphrase"'} if not Keychain.passphrase_meets_requirements(passphrase): return {"success": False, "error": "passphrase doesn't satisfy requirements"} if type(cleanup_legacy_keyring) is not bool: return {"success": False, "error": 'expected bool value for "cleanup_legacy_keyring"'} try: Keychain.migrate_legacy_keyring(passphrase=passphrase, cleanup_legacy_keyring=cleanup_legacy_keyring) success = True # Inform the GUI of keyring status changes self.keyring_status_changed(await self.keyring_status(), "wallet_ui") except Exception as e: tb = traceback.format_exc() self.log.error(f"Legacy keyring migration failed: {e} {tb}") error = f"keyring migration failed: {e}" response: Dict[str, Any] = {"success": success, "error": error} return response