diff --git a/src/password_manager/backup.py b/src/password_manager/backup.py index 5a9e5c8..95dacbd 100644 --- a/src/password_manager/backup.py +++ b/src/password_manager/backup.py @@ -19,6 +19,8 @@ import traceback from pathlib import Path from termcolor import colored +from password_manager.config_manager import ConfigManager + from utils.file_lock import exclusive_lock from constants import APP_DIR @@ -37,14 +39,16 @@ class BackupManager: BACKUP_FILENAME_TEMPLATE = "entries_db_backup_{timestamp}.json.enc" - def __init__(self, fingerprint_dir: Path): + def __init__(self, fingerprint_dir: Path, config_manager: ConfigManager): """ Initializes the BackupManager with the fingerprint directory. Parameters: fingerprint_dir (Path): The directory corresponding to the fingerprint. + config_manager (ConfigManager): Configuration manager for profile settings. """ self.fingerprint_dir = fingerprint_dir + self.config_manager = config_manager self.backup_dir = self.fingerprint_dir / "backups" self.backup_dir.mkdir(parents=True, exist_ok=True) self.index_file = self.fingerprint_dir / "seedpass_entries_db.json.enc" diff --git a/src/password_manager/manager.py b/src/password_manager/manager.py index 0d6afe2..0750457 100644 --- a/src/password_manager/manager.py +++ b/src/password_manager/manager.py @@ -751,7 +751,14 @@ class PasswordManager: raise ValueError("EncryptionManager is not initialized.") # Reinitialize the managers with the updated EncryptionManager and current fingerprint context - self.backup_manager = BackupManager(fingerprint_dir=self.fingerprint_dir) + self.config_manager = ConfigManager( + vault=self.vault, + fingerprint_dir=self.fingerprint_dir, + ) + self.backup_manager = BackupManager( + fingerprint_dir=self.fingerprint_dir, + config_manager=self.config_manager, + ) self.entry_manager = EntryManager( vault=self.vault, backup_manager=self.backup_manager, @@ -764,10 +771,6 @@ class PasswordManager: ) # Load relay configuration and initialize NostrClient - self.config_manager = ConfigManager( - vault=self.vault, - fingerprint_dir=self.fingerprint_dir, - ) config = self.config_manager.load_config() relay_list = config.get("relays", list(DEFAULT_RELAYS)) self.inactivity_timeout = config.get( diff --git a/src/tests/test_backup_restore.py b/src/tests/test_backup_restore.py index ac61b46..95e0ff3 100644 --- a/src/tests/test_backup_restore.py +++ b/src/tests/test_backup_restore.py @@ -9,13 +9,15 @@ from helpers import create_vault, TEST_SEED, TEST_PASSWORD sys.path.append(str(Path(__file__).resolve().parents[1])) from password_manager.backup import BackupManager +from password_manager.config_manager import ConfigManager def test_backup_restore_workflow(monkeypatch): with TemporaryDirectory() as tmpdir: fp_dir = Path(tmpdir) vault, enc_mgr = create_vault(fp_dir, TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(fp_dir) + cfg_mgr = ConfigManager(vault, fp_dir) + backup_mgr = BackupManager(fp_dir, cfg_mgr) index_file = fp_dir / "seedpass_entries_db.json.enc" diff --git a/src/tests/test_concurrency_stress.py b/src/tests/test_concurrency_stress.py index 109e337..da79dd4 100644 --- a/src/tests/test_concurrency_stress.py +++ b/src/tests/test_concurrency_stress.py @@ -9,6 +9,7 @@ sys.path.append(str(Path(__file__).resolve().parents[1])) from password_manager.encryption import EncryptionManager from password_manager.vault import Vault from password_manager.backup import BackupManager +from password_manager.config_manager import ConfigManager from utils.key_derivation import derive_index_key, derive_key_from_password @@ -34,9 +35,12 @@ def _reader(index_key: bytes, dir_path: Path, loops: int, out: Queue) -> None: out.put(repr(e)) -def _backup(dir_path: Path, loops: int, out: Queue) -> None: +def _backup(index_key: bytes, dir_path: Path, loops: int, out: Queue) -> None: try: - bm = BackupManager(dir_path) + enc = EncryptionManager(index_key, dir_path) + vault = Vault(enc, dir_path) + cfg = ConfigManager(vault, dir_path) + bm = BackupManager(dir_path, cfg) for _ in range(loops): bm.create_backup() except Exception as e: # pragma: no cover - capture @@ -58,7 +62,7 @@ def test_concurrency_stress(tmp_path: Path, loops: int, _): Process(target=_writer, args=(index_key, tmp_path, loops, q)), Process(target=_reader, args=(index_key, tmp_path, loops, q)), Process(target=_reader, args=(index_key, tmp_path, loops, q)), - Process(target=_backup, args=(tmp_path, loops, q)), + Process(target=_backup, args=(index_key, tmp_path, loops, q)), ] for p in procs: diff --git a/src/tests/test_entries_empty.py b/src/tests/test_entries_empty.py index b3ac16e..f9700a5 100644 --- a/src/tests/test_entries_empty.py +++ b/src/tests/test_entries_empty.py @@ -8,12 +8,14 @@ sys.path.append(str(Path(__file__).resolve().parents[1])) from password_manager.entry_management import EntryManager from password_manager.backup import BackupManager from password_manager.vault import Vault +from password_manager.config_manager import ConfigManager def test_list_entries_empty(): with TemporaryDirectory() as tmpdir: vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(Path(tmpdir)) + cfg_mgr = ConfigManager(vault, Path(tmpdir)) + backup_mgr = BackupManager(Path(tmpdir), cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) entries = entry_mgr.list_entries() diff --git a/src/tests/test_entry_add.py b/src/tests/test_entry_add.py index f5cb1f4..b1f625d 100644 --- a/src/tests/test_entry_add.py +++ b/src/tests/test_entry_add.py @@ -11,12 +11,14 @@ sys.path.append(str(Path(__file__).resolve().parents[1])) from password_manager.entry_management import EntryManager from password_manager.backup import BackupManager from password_manager.vault import Vault +from password_manager.config_manager import ConfigManager def test_add_and_retrieve_entry(): with TemporaryDirectory() as tmpdir: vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(Path(tmpdir)) + cfg_mgr = ConfigManager(vault, Path(tmpdir)) + backup_mgr = BackupManager(Path(tmpdir), cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) index = entry_mgr.add_entry("example.com", 12, "user") @@ -49,7 +51,8 @@ def test_add_and_retrieve_entry(): def test_round_trip_entry_types(method, expected_type): with TemporaryDirectory() as tmpdir: vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(Path(tmpdir)) + cfg_mgr = ConfigManager(vault, Path(tmpdir)) + backup_mgr = BackupManager(Path(tmpdir), cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) if method == "add_entry": @@ -71,7 +74,8 @@ def test_round_trip_entry_types(method, expected_type): def test_legacy_entry_defaults_to_password(): with TemporaryDirectory() as tmpdir: vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(Path(tmpdir)) + cfg_mgr = ConfigManager(vault, Path(tmpdir)) + backup_mgr = BackupManager(Path(tmpdir), cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) index = entry_mgr.add_entry("example.com", 8) diff --git a/src/tests/test_entry_management_checksum_path.py b/src/tests/test_entry_management_checksum_path.py index 05e8d97..7f75b65 100644 --- a/src/tests/test_entry_management_checksum_path.py +++ b/src/tests/test_entry_management_checksum_path.py @@ -8,13 +8,15 @@ sys.path.append(str(Path(__file__).resolve().parents[1])) from password_manager.entry_management import EntryManager from password_manager.backup import BackupManager from password_manager.vault import Vault +from password_manager.config_manager import ConfigManager def test_update_checksum_writes_to_expected_path(): with TemporaryDirectory() as tmpdir: tmp_path = Path(tmpdir) vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(tmp_path) + cfg_mgr = ConfigManager(vault, tmp_path) + backup_mgr = BackupManager(tmp_path, cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) # create an empty index file @@ -29,7 +31,8 @@ def test_backup_index_file_creates_backup_in_directory(): with TemporaryDirectory() as tmpdir: tmp_path = Path(tmpdir) vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(tmp_path) + cfg_mgr = ConfigManager(vault, tmp_path) + backup_mgr = BackupManager(tmp_path, cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) vault.save_index({"entries": {}}) diff --git a/src/tests/test_export_totp_codes.py b/src/tests/test_export_totp_codes.py index 5250d28..2f474da 100644 --- a/src/tests/test_export_totp_codes.py +++ b/src/tests/test_export_totp_codes.py @@ -11,6 +11,7 @@ sys.path.append(str(Path(__file__).resolve().parents[1])) from password_manager.entry_management import EntryManager from password_manager.backup import BackupManager from password_manager.manager import PasswordManager, EncryptionMode +from password_manager.config_manager import ConfigManager from password_manager.totp import TotpManager @@ -21,7 +22,8 @@ class FakeNostrClient: def test_handle_export_totp_codes(monkeypatch, tmp_path): vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(tmp_path) + cfg_mgr = ConfigManager(vault, tmp_path) + backup_mgr = BackupManager(tmp_path, cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) pm = PasswordManager.__new__(PasswordManager) diff --git a/src/tests/test_manager_add_totp.py b/src/tests/test_manager_add_totp.py index 0a1e102..56bec5a 100644 --- a/src/tests/test_manager_add_totp.py +++ b/src/tests/test_manager_add_totp.py @@ -10,6 +10,7 @@ sys.path.append(str(Path(__file__).resolve().parents[1])) from password_manager.entry_management import EntryManager from password_manager.backup import BackupManager from password_manager.manager import PasswordManager, EncryptionMode +from password_manager.config_manager import ConfigManager class FakeNostrClient: @@ -25,7 +26,8 @@ def test_handle_add_totp(monkeypatch, capsys): with TemporaryDirectory() as tmpdir: tmp_path = Path(tmpdir) vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(tmp_path) + cfg_mgr = ConfigManager(vault, tmp_path) + backup_mgr = BackupManager(tmp_path, cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) pm = PasswordManager.__new__(PasswordManager) diff --git a/src/tests/test_manager_display_totp_codes.py b/src/tests/test_manager_display_totp_codes.py index 0c52bfe..bff96e8 100644 --- a/src/tests/test_manager_display_totp_codes.py +++ b/src/tests/test_manager_display_totp_codes.py @@ -9,6 +9,7 @@ sys.path.append(str(Path(__file__).resolve().parents[1])) from password_manager.entry_management import EntryManager from password_manager.backup import BackupManager from password_manager.manager import PasswordManager, EncryptionMode +from password_manager.config_manager import ConfigManager class FakeNostrClient: @@ -24,7 +25,8 @@ def test_handle_display_totp_codes(monkeypatch, capsys): with TemporaryDirectory() as tmpdir: tmp_path = Path(tmpdir) vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(tmp_path) + cfg_mgr = ConfigManager(vault, tmp_path) + backup_mgr = BackupManager(tmp_path, cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) pm = PasswordManager.__new__(PasswordManager) @@ -62,7 +64,8 @@ def test_display_totp_codes_excludes_blacklisted(monkeypatch, capsys): with TemporaryDirectory() as tmpdir: tmp_path = Path(tmpdir) vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(tmp_path) + cfg_mgr = ConfigManager(vault, tmp_path) + backup_mgr = BackupManager(tmp_path, cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) pm = PasswordManager.__new__(PasswordManager) diff --git a/src/tests/test_manager_retrieve_totp.py b/src/tests/test_manager_retrieve_totp.py index 4b28bfc..0ee97e8 100644 --- a/src/tests/test_manager_retrieve_totp.py +++ b/src/tests/test_manager_retrieve_totp.py @@ -9,6 +9,7 @@ sys.path.append(str(Path(__file__).resolve().parents[1])) from password_manager.entry_management import EntryManager from password_manager.backup import BackupManager from password_manager.manager import PasswordManager, EncryptionMode, TotpManager +from password_manager.config_manager import ConfigManager class FakeNostrClient: @@ -24,7 +25,8 @@ def test_handle_retrieve_totp_entry(monkeypatch, capsys): with TemporaryDirectory() as tmpdir: tmp_path = Path(tmpdir) vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(tmp_path) + cfg_mgr = ConfigManager(vault, tmp_path) + backup_mgr = BackupManager(tmp_path, cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) pm = PasswordManager.__new__(PasswordManager) diff --git a/src/tests/test_manager_workflow.py b/src/tests/test_manager_workflow.py index 8d00a8c..60ccf14 100644 --- a/src/tests/test_manager_workflow.py +++ b/src/tests/test_manager_workflow.py @@ -9,6 +9,7 @@ from password_manager.entry_management import EntryManager from password_manager.vault import Vault from password_manager.backup import BackupManager from password_manager.manager import PasswordManager, EncryptionMode +from password_manager.config_manager import ConfigManager class FakePasswordGenerator: @@ -29,7 +30,8 @@ def test_manager_workflow(monkeypatch): with TemporaryDirectory() as tmpdir: tmp_path = Path(tmpdir) vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(tmp_path) + cfg_mgr = ConfigManager(vault, tmp_path) + backup_mgr = BackupManager(tmp_path, cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) monkeypatch.setattr("password_manager.manager.NostrClient", FakeNostrClient) diff --git a/src/tests/test_nostr_backup.py b/src/tests/test_nostr_backup.py index 0d0ab9d..b4ca998 100644 --- a/src/tests/test_nostr_backup.py +++ b/src/tests/test_nostr_backup.py @@ -10,6 +10,7 @@ sys.path.append(str(Path(__file__).resolve().parents[1])) from password_manager.entry_management import EntryManager from password_manager.backup import BackupManager from password_manager.vault import Vault +from password_manager.config_manager import ConfigManager from nostr.client import NostrClient @@ -17,7 +18,8 @@ def test_backup_and_publish_to_nostr(): with TemporaryDirectory() as tmpdir: tmp_path = Path(tmpdir) vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(tmp_path) + cfg_mgr = ConfigManager(vault, tmp_path) + backup_mgr = BackupManager(tmp_path, cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) # create an index by adding an entry diff --git a/src/tests/test_nostr_dummy_client.py b/src/tests/test_nostr_dummy_client.py index 0f94836..89bc250 100644 --- a/src/tests/test_nostr_dummy_client.py +++ b/src/tests/test_nostr_dummy_client.py @@ -5,12 +5,14 @@ import math from helpers import create_vault, dummy_nostr_client from password_manager.entry_management import EntryManager from password_manager.backup import BackupManager +from password_manager.config_manager import ConfigManager from nostr.client import prepare_snapshot def test_manifest_generation(tmp_path): vault, enc_mgr = create_vault(tmp_path) - backup_mgr = BackupManager(tmp_path) + cfg_mgr = ConfigManager(vault, tmp_path) + backup_mgr = BackupManager(tmp_path, cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) entry_mgr.add_entry("example.com", 12) entry_mgr.add_entry("test.com", 12) diff --git a/src/tests/test_nostr_index_size.py b/src/tests/test_nostr_index_size.py index 7860cad..cb93229 100644 --- a/src/tests/test_nostr_index_size.py +++ b/src/tests/test_nostr_index_size.py @@ -18,6 +18,7 @@ from password_manager.encryption import EncryptionManager from password_manager.entry_management import EntryManager from password_manager.backup import BackupManager from password_manager.vault import Vault +from password_manager.config_manager import ConfigManager from nostr.client import NostrClient, Kind, KindStandard @@ -41,7 +42,8 @@ def test_nostr_index_size_limits(): ) npub = client.key_manager.get_npub() vault = Vault(enc_mgr, tmpdir) - backup_mgr = BackupManager(Path(tmpdir)) + cfg_mgr = ConfigManager(vault, Path(tmpdir)) + backup_mgr = BackupManager(Path(tmpdir), cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) delay = float(os.getenv("NOSTR_TEST_DELAY", "5")) diff --git a/src/tests/test_password_change.py b/src/tests/test_password_change.py index a3880a8..7401559 100644 --- a/src/tests/test_password_change.py +++ b/src/tests/test_password_change.py @@ -19,9 +19,9 @@ def test_change_password_triggers_nostr_backup(monkeypatch): with TemporaryDirectory() as tmpdir: fp = Path(tmpdir) vault, enc_mgr = create_vault(fp, TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(fp) - entry_mgr = EntryManager(vault, backup_mgr) cfg_mgr = ConfigManager(vault, fp) + backup_mgr = BackupManager(fp, cfg_mgr) + entry_mgr = EntryManager(vault, backup_mgr) pm = PasswordManager.__new__(PasswordManager) pm.encryption_mode = EncryptionMode.SEED_ONLY diff --git a/src/tests/test_password_unlock_after_change.py b/src/tests/test_password_unlock_after_change.py index f2d6126..22b8d6c 100644 --- a/src/tests/test_password_unlock_after_change.py +++ b/src/tests/test_password_unlock_after_change.py @@ -30,9 +30,9 @@ def test_password_change_and_unlock(monkeypatch): enc_mgr = EncryptionManager(index_key, fp) seed_mgr = EncryptionManager(seed_key, fp) vault = Vault(enc_mgr, fp) - backup_mgr = BackupManager(fp) - entry_mgr = EntryManager(vault, backup_mgr) cfg_mgr = ConfigManager(vault, fp) + backup_mgr = BackupManager(fp, cfg_mgr) + entry_mgr = EntryManager(vault, backup_mgr) vault.save_index({"entries": {}}) cfg_mgr.save_config( diff --git a/src/tests/test_portable_backup.py b/src/tests/test_portable_backup.py index 674e841..b22feb7 100644 --- a/src/tests/test_portable_backup.py +++ b/src/tests/test_portable_backup.py @@ -11,6 +11,7 @@ sys.path.append(str(Path(__file__).resolve().parents[1])) from password_manager.encryption import EncryptionManager from password_manager.vault import Vault from password_manager.backup import BackupManager +from password_manager.config_manager import ConfigManager from password_manager.portable_backup import export_backup, import_backup from utils.key_derivation import derive_index_key, derive_key_from_password @@ -27,7 +28,8 @@ def setup_vault(tmp: Path): index_key = derive_index_key(SEED) enc_mgr = EncryptionManager(index_key, tmp) vault = Vault(enc_mgr, tmp) - backup = BackupManager(tmp) + cfg = ConfigManager(vault, tmp) + backup = BackupManager(tmp, cfg) return vault, backup diff --git a/src/tests/test_profile_management.py b/src/tests/test_profile_management.py index 21707ed..ae5dcce 100644 --- a/src/tests/test_profile_management.py +++ b/src/tests/test_profile_management.py @@ -16,6 +16,7 @@ from password_manager.vault import Vault from password_manager.entry_management import EntryManager from password_manager.backup import BackupManager from password_manager.manager import EncryptionMode +from password_manager.config_manager import ConfigManager def test_add_and_delete_entry(monkeypatch): @@ -52,7 +53,8 @@ def test_add_and_delete_entry(monkeypatch): assert pm.fingerprint_manager.current_fingerprint == fingerprint vault, enc_mgr = create_vault(fingerprint_dir, TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(fingerprint_dir) + cfg_mgr = ConfigManager(vault, fingerprint_dir) + backup_mgr = BackupManager(fingerprint_dir, cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) pm.encryption_manager = enc_mgr diff --git a/src/tests/test_totp_entry.py b/src/tests/test_totp_entry.py index 27b752c..4051505 100644 --- a/src/tests/test_totp_entry.py +++ b/src/tests/test_totp_entry.py @@ -12,6 +12,7 @@ sys.path.append(str(Path(__file__).resolve().parents[1])) from password_manager.entry_management import EntryManager from password_manager.backup import BackupManager from password_manager.vault import Vault +from password_manager.config_manager import ConfigManager from password_manager.totp import TotpManager import pyotp @@ -19,7 +20,8 @@ import pyotp def test_add_totp_and_get_code(): with TemporaryDirectory() as tmpdir: vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(Path(tmpdir)) + cfg_mgr = ConfigManager(vault, Path(tmpdir)) + backup_mgr = BackupManager(Path(tmpdir), cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) uri = entry_mgr.add_totp("Example", TEST_SEED) @@ -43,7 +45,8 @@ def test_add_totp_and_get_code(): def test_totp_time_remaining(monkeypatch): with TemporaryDirectory() as tmpdir: vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(Path(tmpdir)) + cfg_mgr = ConfigManager(vault, Path(tmpdir)) + backup_mgr = BackupManager(Path(tmpdir), cfg_mgr) entry_mgr = EntryManager(vault, backup_mgr) entry_mgr.add_totp("Example", TEST_SEED) @@ -55,7 +58,8 @@ def test_totp_time_remaining(monkeypatch): def test_add_totp_imported(tmp_path): vault, enc = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD) - backup_mgr = BackupManager(tmp_path) + cfg_mgr = ConfigManager(vault, tmp_path) + backup_mgr = BackupManager(tmp_path, cfg_mgr) em = EntryManager(vault, backup_mgr) secret = "JBSWY3DPEHPK3PXP" em.add_totp("Imported", TEST_SEED, secret=secret)