Merge pull request #157 from PR0M3TH3AN/codex/refactor-password-manager-and-encryption-modes

Drop encryption mode selection
This commit is contained in:
thePR0M3TH3AN
2025-07-02 19:19:29 -04:00
committed by GitHub
2 changed files with 23 additions and 65 deletions

View File

@@ -29,7 +29,6 @@ from utils.key_derivation import (
derive_key_from_parent_seed, derive_key_from_parent_seed,
derive_key_from_password, derive_key_from_password,
derive_index_key, derive_index_key,
DEFAULT_ENCRYPTION_MODE,
EncryptionMode, EncryptionMode,
) )
from utils.checksum import calculate_checksum, verify_checksum from utils.checksum import calculate_checksum, verify_checksum
@@ -79,11 +78,9 @@ class PasswordManager:
verification, ensuring the integrity and confidentiality of the stored password database. verification, ensuring the integrity and confidentiality of the stored password database.
""" """
def __init__( def __init__(self) -> None:
self, encryption_mode: EncryptionMode = DEFAULT_ENCRYPTION_MODE
) -> None:
"""Initialize the PasswordManager.""" """Initialize the PasswordManager."""
self.encryption_mode: EncryptionMode = encryption_mode self.encryption_mode: EncryptionMode = EncryptionMode.SEED_ONLY
self.encryption_manager: Optional[EncryptionManager] = None self.encryption_manager: Optional[EncryptionManager] = None
self.entry_manager: Optional[EntryManager] = None self.entry_manager: Optional[EntryManager] = None
self.password_generator: Optional[PasswordGenerator] = None self.password_generator: Optional[PasswordGenerator] = None
@@ -115,15 +112,6 @@ class PasswordManager:
"""Record the current time as the last user activity.""" """Record the current time as the last user activity."""
self.last_activity = time.time() self.last_activity = time.time()
def prompt_encryption_mode(self) -> EncryptionMode:
"""Prompt the user to select an encryption mode.
Returns:
EncryptionMode: The chosen encryption mode.
"""
# Only seed-only mode is supported
return EncryptionMode.SEED_ONLY
def lock_vault(self) -> None: def lock_vault(self) -> None:
"""Clear sensitive information from memory.""" """Clear sensitive information from memory."""
self.parent_seed = None self.parent_seed = None
@@ -210,7 +198,6 @@ class PasswordManager:
it from a seed phrase. it from a seed phrase.
""" """
try: try:
self.encryption_mode = self.prompt_encryption_mode()
choice = input( choice = input(
"Do you want to (1) Enter an existing seed or (2) Generate a new seed? (1/2): " "Do you want to (1) Enter an existing seed or (2) Generate a new seed? (1/2): "
).strip() ).strip()
@@ -487,8 +474,6 @@ class PasswordManager:
""" """
print(colored("No existing seed found. Let's set up a new one!", "yellow")) print(colored("No existing seed found. Let's set up a new one!", "yellow"))
self.encryption_mode = self.prompt_encryption_mode()
choice = input( choice = input(
"Do you want to (1) Enter an existing BIP-85 seed or (2) Generate a new BIP-85 seed? (1/2): " "Do you want to (1) Enter an existing BIP-85 seed or (2) Generate a new BIP-85 seed? (1/2): "
).strip() ).strip()
@@ -1403,7 +1388,6 @@ class PasswordManager:
config_data = self.config_manager.load_config(require_pin=False) config_data = self.config_manager.load_config(require_pin=False)
# Create a new encryption manager with the new password # Create a new encryption manager with the new password
mode = getattr(self, "encryption_mode", DEFAULT_ENCRYPTION_MODE)
new_key = derive_index_key(self.parent_seed) new_key = derive_index_key(self.parent_seed)
seed_key = derive_key_from_password(new_password) seed_key = derive_key_from_password(new_password)
@@ -1444,47 +1428,3 @@ class PasswordManager:
except Exception as e: except Exception as e:
logging.error(f"Failed to change password: {e}", exc_info=True) logging.error(f"Failed to change password: {e}", exc_info=True)
print(colored(f"Error: Failed to change password: {e}", "red")) print(colored(f"Error: Failed to change password: {e}", "red"))
def change_encryption_mode(self, new_mode: EncryptionMode) -> None:
"""Re-encrypt the index using a different encryption mode."""
try:
password = prompt_existing_password("Enter your current master password: ")
if not self.verify_password(password):
print(colored("Incorrect password.", "red"))
return
index_data = self.vault.load_index()
config_data = self.config_manager.load_config(require_pin=False)
new_key = derive_index_key(self.parent_seed)
new_mgr = EncryptionManager(new_key, self.fingerprint_dir)
self.vault.set_encryption_manager(new_mgr)
self.vault.save_index(index_data)
self.config_manager.vault = self.vault
self.config_manager.save_config(config_data)
self.encryption_manager = new_mgr
self.password_generator.encryption_manager = new_mgr
self.encryption_mode = new_mode
relay_list = config_data.get("relays", list(DEFAULT_RELAYS))
self.nostr_client = NostrClient(
encryption_manager=self.encryption_manager,
fingerprint=self.current_fingerprint,
relays=relay_list,
parent_seed=getattr(self, "parent_seed", None),
)
print(colored("Encryption mode changed successfully.", "green"))
try:
summary = f"mode-change-{int(time.time())}"
self.sync_vault(alt_summary=summary)
except Exception as nostr_error:
logging.error(
f"Failed to post updated index to Nostr after encryption mode change: {nostr_error}"
)
except Exception as e:
logging.error(f"Failed to change encryption mode: {e}", exc_info=True)
print(colored(f"Error: Failed to change encryption mode: {e}", "red"))

View File

@@ -3,9 +3,27 @@ from pathlib import Path
sys.path.append(str(Path(__file__).resolve().parents[1])) sys.path.append(str(Path(__file__).resolve().parents[1]))
from types import SimpleNamespace
from pathlib import Path
from password_manager.manager import PasswordManager from password_manager.manager import PasswordManager
from utils.key_derivation import DEFAULT_ENCRYPTION_MODE from utils.key_derivation import EncryptionMode
def test_default_encryption_mode(): def test_default_encryption_mode(monkeypatch):
assert PasswordManager.__init__.__defaults__[0] is DEFAULT_ENCRYPTION_MODE monkeypatch.setattr(
PasswordManager,
"initialize_fingerprint_manager",
lambda self: setattr(
self,
"fingerprint_manager",
SimpleNamespace(
get_current_fingerprint_dir=lambda: Path("./"),
list_fingerprints=lambda: [],
),
),
)
monkeypatch.setattr(PasswordManager, "setup_parent_seed", lambda self: None)
pm = PasswordManager()
assert pm.encryption_mode is EncryptionMode.SEED_ONLY