From 24e6d70af4fc738c77fb40f3f47202a6b604c4d8 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Wed, 2 Jul 2025 11:51:14 -0400 Subject: [PATCH] Add encryption mode migration tests --- src/tests/test_encryption_mode_migration.py | 94 +++++++++++++++++++++ src/tests/test_password_properties.py | 3 +- 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 src/tests/test_encryption_mode_migration.py diff --git a/src/tests/test_encryption_mode_migration.py b/src/tests/test_encryption_mode_migration.py new file mode 100644 index 0000000..4427f89 --- /dev/null +++ b/src/tests/test_encryption_mode_migration.py @@ -0,0 +1,94 @@ +import sys +from pathlib import Path +from tempfile import TemporaryDirectory +from types import SimpleNamespace + +import bcrypt +import pytest + +from helpers import create_vault, TEST_SEED, TEST_PASSWORD + +sys.path.append(str(Path(__file__).resolve().parents[1])) + +from password_manager.entry_management import EntryManager +from password_manager.config_manager import ConfigManager +from password_manager.vault import Vault +from password_manager.manager import PasswordManager +from utils.key_derivation import EncryptionMode + + +TRANSITIONS = [ + (EncryptionMode.SEED_ONLY, EncryptionMode.SEED_PLUS_PW), + (EncryptionMode.SEED_ONLY, EncryptionMode.PW_ONLY), + (EncryptionMode.SEED_PLUS_PW, EncryptionMode.SEED_ONLY), + (EncryptionMode.SEED_PLUS_PW, EncryptionMode.PW_ONLY), + (EncryptionMode.PW_ONLY, EncryptionMode.SEED_ONLY), + (EncryptionMode.PW_ONLY, EncryptionMode.SEED_PLUS_PW), +] + + +@pytest.mark.parametrize("start_mode,new_mode", TRANSITIONS) +def test_encryption_mode_migration(monkeypatch, start_mode, new_mode): + with TemporaryDirectory() as tmpdir: + fp = Path(tmpdir) + vault, enc_mgr = create_vault(fp, TEST_SEED, TEST_PASSWORD, start_mode) + entry_mgr = EntryManager(vault, fp) + cfg_mgr = ConfigManager(vault, fp) + + vault.save_index({"passwords": {}}) + cfg_mgr.save_config( + { + "relays": [], + "pin_hash": "", + "password_hash": bcrypt.hashpw( + TEST_PASSWORD.encode(), bcrypt.gensalt() + ).decode(), + "encryption_mode": start_mode.value, + } + ) + + pm = PasswordManager.__new__(PasswordManager) + pm.encryption_manager = enc_mgr + pm.entry_manager = entry_mgr + pm.config_manager = cfg_mgr + pm.vault = vault + pm.password_generator = SimpleNamespace(encryption_manager=enc_mgr) + pm.fingerprint_dir = fp + pm.current_fingerprint = "fp" + pm.parent_seed = TEST_SEED + pm.encryption_mode = start_mode + pm.nostr_client = SimpleNamespace(publish_json_to_nostr=lambda *a, **k: None) + + monkeypatch.setattr( + "password_manager.manager.prompt_existing_password", + lambda *_: TEST_PASSWORD, + ) + monkeypatch.setattr( + "password_manager.manager.NostrClient", + lambda *a, **kw: SimpleNamespace( + publish_json_to_nostr=lambda *a, **k: None + ), + ) + + pm.change_encryption_mode(new_mode) + + assert pm.encryption_mode is new_mode + cfg = cfg_mgr.load_config(require_pin=False) + assert cfg["encryption_mode"] == new_mode.value + + pm.lock_vault() + + monkeypatch.setattr( + "password_manager.manager.prompt_existing_password", + lambda *_: TEST_PASSWORD, + ) + monkeypatch.setattr(PasswordManager, "initialize_bip85", lambda self: None) + monkeypatch.setattr(PasswordManager, "initialize_managers", lambda self: None) + + pm.unlock_vault() + + assert pm.parent_seed == TEST_SEED + assert not pm.locked + assert pm.encryption_mode is new_mode + assert pm.vault.load_index()["passwords"] == {} + assert pm.verify_password(TEST_PASSWORD) diff --git a/src/tests/test_password_properties.py b/src/tests/test_password_properties.py index 3a226b6..aa48621 100644 --- a/src/tests/test_password_properties.py +++ b/src/tests/test_password_properties.py @@ -1,7 +1,7 @@ import sys import string from pathlib import Path -from hypothesis import given, strategies as st +from hypothesis import given, strategies as st, settings sys.path.append(str(Path(__file__).resolve().parents[1])) @@ -29,6 +29,7 @@ def make_generator(): length=st.integers(min_value=8, max_value=64), index=st.integers(min_value=0, max_value=1000), ) +@settings(deadline=None) def test_password_properties(length, index): pg = make_generator() pw1 = pg.generate_password(length=length, index=index)