mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-08 15:28:44 +00:00
Refactor EntryManager to use BackupManager
This commit is contained in:
@@ -4,6 +4,7 @@ from cryptography.fernet import Fernet
|
|||||||
from password_manager.encryption import EncryptionManager
|
from password_manager.encryption import EncryptionManager
|
||||||
from password_manager.vault import Vault
|
from password_manager.vault import Vault
|
||||||
from password_manager.entry_management import EntryManager
|
from password_manager.entry_management import EntryManager
|
||||||
|
from password_manager.backup import BackupManager
|
||||||
from constants import initialize_app
|
from constants import initialize_app
|
||||||
|
|
||||||
|
|
||||||
@@ -13,7 +14,8 @@ def main() -> None:
|
|||||||
key = Fernet.generate_key()
|
key = Fernet.generate_key()
|
||||||
enc = EncryptionManager(key, Path("."))
|
enc = EncryptionManager(key, Path("."))
|
||||||
vault = Vault(enc, Path("."))
|
vault = Vault(enc, Path("."))
|
||||||
manager = EntryManager(vault, Path("."))
|
backup_mgr = BackupManager(Path("."))
|
||||||
|
manager = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
index = manager.add_entry(
|
index = manager.add_entry(
|
||||||
"Example Website",
|
"Example Website",
|
||||||
|
@@ -19,10 +19,7 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
import hashlib
|
import hashlib
|
||||||
import sys
|
import sys
|
||||||
import os
|
|
||||||
import shutil
|
import shutil
|
||||||
import time
|
|
||||||
import traceback
|
|
||||||
from typing import Optional, Tuple, Dict, Any, List
|
from typing import Optional, Tuple, Dict, Any, List
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -32,7 +29,7 @@ from password_manager.entry_types import EntryType
|
|||||||
from password_manager.totp import TotpManager
|
from password_manager.totp import TotpManager
|
||||||
|
|
||||||
from password_manager.vault import Vault
|
from password_manager.vault import Vault
|
||||||
from utils.file_lock import exclusive_lock
|
from password_manager.backup import BackupManager
|
||||||
|
|
||||||
|
|
||||||
# Instantiate the logger
|
# Instantiate the logger
|
||||||
@@ -40,15 +37,16 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class EntryManager:
|
class EntryManager:
|
||||||
def __init__(self, vault: Vault, fingerprint_dir: Path):
|
def __init__(self, vault: Vault, backup_manager: BackupManager):
|
||||||
"""
|
"""Initialize the EntryManager.
|
||||||
Initializes the EntryManager with the EncryptionManager and fingerprint directory.
|
|
||||||
|
|
||||||
:param vault: The Vault instance for file access.
|
Parameters:
|
||||||
:param fingerprint_dir: The directory corresponding to the fingerprint.
|
vault: The Vault instance for file access.
|
||||||
|
backup_manager: Manages creation of entry database backups.
|
||||||
"""
|
"""
|
||||||
self.vault = vault
|
self.vault = vault
|
||||||
self.fingerprint_dir = fingerprint_dir
|
self.backup_manager = backup_manager
|
||||||
|
self.fingerprint_dir = backup_manager.fingerprint_dir
|
||||||
|
|
||||||
# Use paths relative to the fingerprint directory
|
# Use paths relative to the fingerprint directory
|
||||||
self.index_file = self.fingerprint_dir / "seedpass_entries_db.json.enc"
|
self.index_file = self.fingerprint_dir / "seedpass_entries_db.json.enc"
|
||||||
@@ -141,7 +139,7 @@ class EntryManager:
|
|||||||
|
|
||||||
self._save_index(data)
|
self._save_index(data)
|
||||||
self.update_checksum()
|
self.update_checksum()
|
||||||
self.backup_index_file()
|
self.backup_manager.create_backup()
|
||||||
|
|
||||||
logger.info(f"Entry added successfully at index {index}.")
|
logger.info(f"Entry added successfully at index {index}.")
|
||||||
print(colored(f"[+] Entry added successfully at index {index}.", "green"))
|
print(colored(f"[+] Entry added successfully at index {index}.", "green"))
|
||||||
@@ -203,7 +201,7 @@ class EntryManager:
|
|||||||
|
|
||||||
self._save_index(data)
|
self._save_index(data)
|
||||||
self.update_checksum()
|
self.update_checksum()
|
||||||
self.backup_index_file()
|
self.backup_manager.create_backup()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return TotpManager.make_otpauth_uri(label, secret, period, digits)
|
return TotpManager.make_otpauth_uri(label, secret, period, digits)
|
||||||
@@ -219,7 +217,7 @@ class EntryManager:
|
|||||||
data["entries"][str(index)] = {"type": EntryType.SSH.value, "notes": notes}
|
data["entries"][str(index)] = {"type": EntryType.SSH.value, "notes": notes}
|
||||||
self._save_index(data)
|
self._save_index(data)
|
||||||
self.update_checksum()
|
self.update_checksum()
|
||||||
self.backup_index_file()
|
self.backup_manager.create_backup()
|
||||||
raise NotImplementedError("SSH key entry support not implemented yet")
|
raise NotImplementedError("SSH key entry support not implemented yet")
|
||||||
|
|
||||||
def add_seed(self, notes: str = "") -> int:
|
def add_seed(self, notes: str = "") -> int:
|
||||||
@@ -230,7 +228,7 @@ class EntryManager:
|
|||||||
data["entries"][str(index)] = {"type": EntryType.SEED.value, "notes": notes}
|
data["entries"][str(index)] = {"type": EntryType.SEED.value, "notes": notes}
|
||||||
self._save_index(data)
|
self._save_index(data)
|
||||||
self.update_checksum()
|
self.update_checksum()
|
||||||
self.backup_index_file()
|
self.backup_manager.create_backup()
|
||||||
raise NotImplementedError("Seed entry support not implemented yet")
|
raise NotImplementedError("Seed entry support not implemented yet")
|
||||||
|
|
||||||
def get_totp_code(
|
def get_totp_code(
|
||||||
@@ -355,7 +353,7 @@ class EntryManager:
|
|||||||
|
|
||||||
self._save_index(data)
|
self._save_index(data)
|
||||||
self.update_checksum()
|
self.update_checksum()
|
||||||
self.backup_index_file()
|
self.backup_manager.create_backup()
|
||||||
|
|
||||||
logger.info(f"Entry at index {index} modified successfully.")
|
logger.info(f"Entry at index {index} modified successfully.")
|
||||||
print(
|
print(
|
||||||
@@ -445,7 +443,7 @@ class EntryManager:
|
|||||||
logger.debug(f"Deleted entry at index {index}.")
|
logger.debug(f"Deleted entry at index {index}.")
|
||||||
self.vault.save_index(data)
|
self.vault.save_index(data)
|
||||||
self.update_checksum()
|
self.update_checksum()
|
||||||
self.backup_index_file()
|
self.backup_manager.create_backup()
|
||||||
logger.info(f"Entry at index {index} deleted successfully.")
|
logger.info(f"Entry at index {index} deleted successfully.")
|
||||||
print(
|
print(
|
||||||
colored(
|
colored(
|
||||||
@@ -491,35 +489,6 @@ class EntryManager:
|
|||||||
logger.error(f"Failed to update checksum: {e}", exc_info=True)
|
logger.error(f"Failed to update checksum: {e}", exc_info=True)
|
||||||
print(colored(f"Error: Failed to update checksum: {e}", "red"))
|
print(colored(f"Error: Failed to update checksum: {e}", "red"))
|
||||||
|
|
||||||
def backup_index_file(self) -> None:
|
|
||||||
"""
|
|
||||||
Creates a backup of the encrypted JSON index file to prevent data loss.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# self.index_file already includes the fingerprint directory
|
|
||||||
index_file_path = self.index_file
|
|
||||||
if not index_file_path.exists():
|
|
||||||
logger.warning(
|
|
||||||
f"Index file '{index_file_path}' does not exist. No backup created."
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
timestamp = int(time.time())
|
|
||||||
backup_filename = f"entries_db_backup_{timestamp}.json.enc"
|
|
||||||
backup_path = self.fingerprint_dir / backup_filename
|
|
||||||
|
|
||||||
with open(index_file_path, "rb") as original_file, open(
|
|
||||||
backup_path, "wb"
|
|
||||||
) as backup_file:
|
|
||||||
shutil.copyfileobj(original_file, backup_file)
|
|
||||||
|
|
||||||
logger.debug(f"Backup created at '{backup_path}'.")
|
|
||||||
print(colored(f"[+] Backup created at '{backup_path}'.", "green"))
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Failed to create backup: {e}", exc_info=True)
|
|
||||||
print(colored(f"Warning: Failed to create backup: {e}", "yellow"))
|
|
||||||
|
|
||||||
def restore_from_backup(self, backup_path: str) -> None:
|
def restore_from_backup(self, backup_path: str) -> None:
|
||||||
"""
|
"""
|
||||||
Restores the index file from a specified backup file.
|
Restores the index file from a specified backup file.
|
||||||
|
@@ -751,9 +751,10 @@ class PasswordManager:
|
|||||||
raise ValueError("EncryptionManager is not initialized.")
|
raise ValueError("EncryptionManager is not initialized.")
|
||||||
|
|
||||||
# Reinitialize the managers with the updated EncryptionManager and current fingerprint context
|
# Reinitialize the managers with the updated EncryptionManager and current fingerprint context
|
||||||
|
self.backup_manager = BackupManager(fingerprint_dir=self.fingerprint_dir)
|
||||||
self.entry_manager = EntryManager(
|
self.entry_manager = EntryManager(
|
||||||
vault=self.vault,
|
vault=self.vault,
|
||||||
fingerprint_dir=self.fingerprint_dir,
|
backup_manager=self.backup_manager,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.password_generator = PasswordGenerator(
|
self.password_generator = PasswordGenerator(
|
||||||
@@ -762,8 +763,6 @@ class PasswordManager:
|
|||||||
bip85=self.bip85,
|
bip85=self.bip85,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.backup_manager = BackupManager(fingerprint_dir=self.fingerprint_dir)
|
|
||||||
|
|
||||||
# Load relay configuration and initialize NostrClient
|
# Load relay configuration and initialize NostrClient
|
||||||
self.config_manager = ConfigManager(
|
self.config_manager = ConfigManager(
|
||||||
vault=self.vault,
|
vault=self.vault,
|
||||||
|
@@ -6,13 +6,15 @@ from helpers import create_vault, TEST_SEED, TEST_PASSWORD
|
|||||||
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
||||||
|
|
||||||
from password_manager.entry_management import EntryManager
|
from password_manager.entry_management import EntryManager
|
||||||
|
from password_manager.backup import BackupManager
|
||||||
from password_manager.vault import Vault
|
from password_manager.vault import Vault
|
||||||
|
|
||||||
|
|
||||||
def test_list_entries_empty():
|
def test_list_entries_empty():
|
||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, Path(tmpdir))
|
backup_mgr = BackupManager(Path(tmpdir))
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
entries = entry_mgr.list_entries()
|
entries = entry_mgr.list_entries()
|
||||||
assert entries == []
|
assert entries == []
|
||||||
|
@@ -9,13 +9,15 @@ from helpers import create_vault, TEST_SEED, TEST_PASSWORD
|
|||||||
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
||||||
|
|
||||||
from password_manager.entry_management import EntryManager
|
from password_manager.entry_management import EntryManager
|
||||||
|
from password_manager.backup import BackupManager
|
||||||
from password_manager.vault import Vault
|
from password_manager.vault import Vault
|
||||||
|
|
||||||
|
|
||||||
def test_add_and_retrieve_entry():
|
def test_add_and_retrieve_entry():
|
||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, Path(tmpdir))
|
backup_mgr = BackupManager(Path(tmpdir))
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
index = entry_mgr.add_entry("example.com", 12, "user")
|
index = entry_mgr.add_entry("example.com", 12, "user")
|
||||||
entry = entry_mgr.retrieve_entry(index)
|
entry = entry_mgr.retrieve_entry(index)
|
||||||
@@ -47,7 +49,8 @@ def test_add_and_retrieve_entry():
|
|||||||
def test_round_trip_entry_types(method, expected_type):
|
def test_round_trip_entry_types(method, expected_type):
|
||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, Path(tmpdir))
|
backup_mgr = BackupManager(Path(tmpdir))
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
if method == "add_entry":
|
if method == "add_entry":
|
||||||
index = entry_mgr.add_entry("example.com", 8)
|
index = entry_mgr.add_entry("example.com", 8)
|
||||||
@@ -68,7 +71,8 @@ def test_round_trip_entry_types(method, expected_type):
|
|||||||
def test_legacy_entry_defaults_to_password():
|
def test_legacy_entry_defaults_to_password():
|
||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, Path(tmpdir))
|
backup_mgr = BackupManager(Path(tmpdir))
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
index = entry_mgr.add_entry("example.com", 8)
|
index = entry_mgr.add_entry("example.com", 8)
|
||||||
|
|
||||||
|
@@ -6,6 +6,7 @@ from helpers import create_vault, TEST_SEED, TEST_PASSWORD
|
|||||||
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
||||||
|
|
||||||
from password_manager.entry_management import EntryManager
|
from password_manager.entry_management import EntryManager
|
||||||
|
from password_manager.backup import BackupManager
|
||||||
from password_manager.vault import Vault
|
from password_manager.vault import Vault
|
||||||
|
|
||||||
|
|
||||||
@@ -13,7 +14,8 @@ def test_update_checksum_writes_to_expected_path():
|
|||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
tmp_path = Path(tmpdir)
|
tmp_path = Path(tmpdir)
|
||||||
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, tmp_path)
|
backup_mgr = BackupManager(tmp_path)
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
# create an empty index file
|
# create an empty index file
|
||||||
vault.save_index({"entries": {}})
|
vault.save_index({"entries": {}})
|
||||||
@@ -27,10 +29,12 @@ def test_backup_index_file_creates_backup_in_directory():
|
|||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
tmp_path = Path(tmpdir)
|
tmp_path = Path(tmpdir)
|
||||||
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, tmp_path)
|
backup_mgr = BackupManager(tmp_path)
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
vault.save_index({"entries": {}})
|
vault.save_index({"entries": {}})
|
||||||
entry_mgr.backup_index_file()
|
entry_mgr.backup_manager.create_backup()
|
||||||
|
|
||||||
backups = list(tmp_path.glob("entries_db_backup_*.json.enc"))
|
backup_dir = tmp_path / "backups"
|
||||||
|
backups = list(backup_dir.glob("entries_db_backup_*.json.enc"))
|
||||||
assert len(backups) == 1
|
assert len(backups) == 1
|
||||||
|
@@ -21,8 +21,8 @@ class FakeNostrClient:
|
|||||||
|
|
||||||
def test_handle_export_totp_codes(monkeypatch, tmp_path):
|
def test_handle_export_totp_codes(monkeypatch, tmp_path):
|
||||||
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, tmp_path)
|
|
||||||
backup_mgr = BackupManager(tmp_path)
|
backup_mgr = BackupManager(tmp_path)
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
pm = PasswordManager.__new__(PasswordManager)
|
pm = PasswordManager.__new__(PasswordManager)
|
||||||
pm.encryption_mode = EncryptionMode.SEED_ONLY
|
pm.encryption_mode = EncryptionMode.SEED_ONLY
|
||||||
|
@@ -25,8 +25,8 @@ def test_handle_add_totp(monkeypatch, capsys):
|
|||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
tmp_path = Path(tmpdir)
|
tmp_path = Path(tmpdir)
|
||||||
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, tmp_path)
|
|
||||||
backup_mgr = BackupManager(tmp_path)
|
backup_mgr = BackupManager(tmp_path)
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
pm = PasswordManager.__new__(PasswordManager)
|
pm = PasswordManager.__new__(PasswordManager)
|
||||||
pm.encryption_mode = EncryptionMode.SEED_ONLY
|
pm.encryption_mode = EncryptionMode.SEED_ONLY
|
||||||
|
@@ -24,8 +24,8 @@ def test_handle_display_totp_codes(monkeypatch, capsys):
|
|||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
tmp_path = Path(tmpdir)
|
tmp_path = Path(tmpdir)
|
||||||
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, tmp_path)
|
|
||||||
backup_mgr = BackupManager(tmp_path)
|
backup_mgr = BackupManager(tmp_path)
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
pm = PasswordManager.__new__(PasswordManager)
|
pm = PasswordManager.__new__(PasswordManager)
|
||||||
pm.encryption_mode = EncryptionMode.SEED_ONLY
|
pm.encryption_mode = EncryptionMode.SEED_ONLY
|
||||||
@@ -62,8 +62,8 @@ def test_display_totp_codes_excludes_blacklisted(monkeypatch, capsys):
|
|||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
tmp_path = Path(tmpdir)
|
tmp_path = Path(tmpdir)
|
||||||
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, tmp_path)
|
|
||||||
backup_mgr = BackupManager(tmp_path)
|
backup_mgr = BackupManager(tmp_path)
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
pm = PasswordManager.__new__(PasswordManager)
|
pm = PasswordManager.__new__(PasswordManager)
|
||||||
pm.encryption_mode = EncryptionMode.SEED_ONLY
|
pm.encryption_mode = EncryptionMode.SEED_ONLY
|
||||||
|
@@ -24,8 +24,8 @@ def test_handle_retrieve_totp_entry(monkeypatch, capsys):
|
|||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
tmp_path = Path(tmpdir)
|
tmp_path = Path(tmpdir)
|
||||||
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, tmp_path)
|
|
||||||
backup_mgr = BackupManager(tmp_path)
|
backup_mgr = BackupManager(tmp_path)
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
pm = PasswordManager.__new__(PasswordManager)
|
pm = PasswordManager.__new__(PasswordManager)
|
||||||
pm.encryption_mode = EncryptionMode.SEED_ONLY
|
pm.encryption_mode = EncryptionMode.SEED_ONLY
|
||||||
|
@@ -29,8 +29,8 @@ def test_manager_workflow(monkeypatch):
|
|||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
tmp_path = Path(tmpdir)
|
tmp_path = Path(tmpdir)
|
||||||
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, tmp_path)
|
|
||||||
backup_mgr = BackupManager(tmp_path)
|
backup_mgr = BackupManager(tmp_path)
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
monkeypatch.setattr("password_manager.manager.NostrClient", FakeNostrClient)
|
monkeypatch.setattr("password_manager.manager.NostrClient", FakeNostrClient)
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ def test_manager_workflow(monkeypatch):
|
|||||||
|
|
||||||
pm.handle_add_password()
|
pm.handle_add_password()
|
||||||
assert pm.is_dirty is False
|
assert pm.is_dirty is False
|
||||||
backups = list(tmp_path.glob("entries_db_backup_*.json.enc"))
|
backups = list((tmp_path / "backups").glob("entries_db_backup_*.json.enc"))
|
||||||
assert len(backups) == 1
|
assert len(backups) == 1
|
||||||
checksum_file = tmp_path / "seedpass_entries_db_checksum.txt"
|
checksum_file = tmp_path / "seedpass_entries_db_checksum.txt"
|
||||||
assert checksum_file.exists()
|
assert checksum_file.exists()
|
||||||
|
@@ -8,6 +8,7 @@ from helpers import create_vault, TEST_SEED, TEST_PASSWORD
|
|||||||
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
||||||
|
|
||||||
from password_manager.entry_management import EntryManager
|
from password_manager.entry_management import EntryManager
|
||||||
|
from password_manager.backup import BackupManager
|
||||||
from password_manager.vault import Vault
|
from password_manager.vault import Vault
|
||||||
from nostr.client import NostrClient
|
from nostr.client import NostrClient
|
||||||
|
|
||||||
@@ -16,7 +17,8 @@ def test_backup_and_publish_to_nostr():
|
|||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
tmp_path = Path(tmpdir)
|
tmp_path = Path(tmpdir)
|
||||||
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, tmp_path)
|
backup_mgr = BackupManager(tmp_path)
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
# create an index by adding an entry
|
# create an index by adding an entry
|
||||||
entry_mgr.add_entry("example.com", 12)
|
entry_mgr.add_entry("example.com", 12)
|
||||||
@@ -34,7 +36,7 @@ def test_backup_and_publish_to_nostr():
|
|||||||
enc_mgr, "decrypt_parent_seed", return_value="seed"
|
enc_mgr, "decrypt_parent_seed", return_value="seed"
|
||||||
):
|
):
|
||||||
nostr_client = NostrClient(enc_mgr, "fp")
|
nostr_client = NostrClient(enc_mgr, "fp")
|
||||||
entry_mgr.backup_index_file()
|
entry_mgr.backup_manager.create_backup()
|
||||||
result = asyncio.run(nostr_client.publish_snapshot(encrypted_index))
|
result = asyncio.run(nostr_client.publish_snapshot(encrypted_index))
|
||||||
|
|
||||||
mock_publish.assert_awaited_with(encrypted_index)
|
mock_publish.assert_awaited_with(encrypted_index)
|
||||||
|
@@ -4,12 +4,14 @@ import math
|
|||||||
|
|
||||||
from helpers import create_vault, dummy_nostr_client
|
from helpers import create_vault, dummy_nostr_client
|
||||||
from password_manager.entry_management import EntryManager
|
from password_manager.entry_management import EntryManager
|
||||||
|
from password_manager.backup import BackupManager
|
||||||
from nostr.client import prepare_snapshot
|
from nostr.client import prepare_snapshot
|
||||||
|
|
||||||
|
|
||||||
def test_manifest_generation(tmp_path):
|
def test_manifest_generation(tmp_path):
|
||||||
vault, enc_mgr = create_vault(tmp_path)
|
vault, enc_mgr = create_vault(tmp_path)
|
||||||
entry_mgr = EntryManager(vault, tmp_path)
|
backup_mgr = BackupManager(tmp_path)
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
entry_mgr.add_entry("example.com", 12)
|
entry_mgr.add_entry("example.com", 12)
|
||||||
entry_mgr.add_entry("test.com", 12)
|
entry_mgr.add_entry("test.com", 12)
|
||||||
encrypted = vault.get_encrypted_index()
|
encrypted = vault.get_encrypted_index()
|
||||||
|
@@ -16,6 +16,7 @@ sys.path.append(str(Path(__file__).resolve().parents[1]))
|
|||||||
|
|
||||||
from password_manager.encryption import EncryptionManager
|
from password_manager.encryption import EncryptionManager
|
||||||
from password_manager.entry_management import EntryManager
|
from password_manager.entry_management import EntryManager
|
||||||
|
from password_manager.backup import BackupManager
|
||||||
from password_manager.vault import Vault
|
from password_manager.vault import Vault
|
||||||
from nostr.client import NostrClient, Kind, KindStandard
|
from nostr.client import NostrClient, Kind, KindStandard
|
||||||
|
|
||||||
@@ -40,7 +41,8 @@ def test_nostr_index_size_limits():
|
|||||||
)
|
)
|
||||||
npub = client.key_manager.get_npub()
|
npub = client.key_manager.get_npub()
|
||||||
vault = Vault(enc_mgr, tmpdir)
|
vault = Vault(enc_mgr, tmpdir)
|
||||||
entry_mgr = EntryManager(vault, Path(tmpdir))
|
backup_mgr = BackupManager(Path(tmpdir))
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
delay = float(os.getenv("NOSTR_TEST_DELAY", "5"))
|
delay = float(os.getenv("NOSTR_TEST_DELAY", "5"))
|
||||||
size = 16
|
size = 16
|
||||||
|
@@ -10,6 +10,7 @@ sys.path.append(str(Path(__file__).resolve().parents[1]))
|
|||||||
|
|
||||||
from password_manager.entry_management import EntryManager
|
from password_manager.entry_management import EntryManager
|
||||||
from password_manager.config_manager import ConfigManager
|
from password_manager.config_manager import ConfigManager
|
||||||
|
from password_manager.backup import BackupManager
|
||||||
from password_manager.vault import Vault
|
from password_manager.vault import Vault
|
||||||
from password_manager.manager import PasswordManager, EncryptionMode
|
from password_manager.manager import PasswordManager, EncryptionMode
|
||||||
|
|
||||||
@@ -18,7 +19,8 @@ def test_change_password_triggers_nostr_backup(monkeypatch):
|
|||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
fp = Path(tmpdir)
|
fp = Path(tmpdir)
|
||||||
vault, enc_mgr = create_vault(fp, TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(fp, TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, fp)
|
backup_mgr = BackupManager(fp)
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
cfg_mgr = ConfigManager(vault, fp)
|
cfg_mgr = ConfigManager(vault, fp)
|
||||||
|
|
||||||
pm = PasswordManager.__new__(PasswordManager)
|
pm = PasswordManager.__new__(PasswordManager)
|
||||||
|
@@ -10,6 +10,7 @@ sys.path.append(str(Path(__file__).resolve().parents[1]))
|
|||||||
from password_manager.encryption import EncryptionManager
|
from password_manager.encryption import EncryptionManager
|
||||||
from password_manager.vault import Vault
|
from password_manager.vault import Vault
|
||||||
from password_manager.entry_management import EntryManager
|
from password_manager.entry_management import EntryManager
|
||||||
|
from password_manager.backup import BackupManager
|
||||||
from password_manager.config_manager import ConfigManager
|
from password_manager.config_manager import ConfigManager
|
||||||
from password_manager.manager import PasswordManager, EncryptionMode
|
from password_manager.manager import PasswordManager, EncryptionMode
|
||||||
from utils.key_derivation import derive_index_key, derive_key_from_password
|
from utils.key_derivation import derive_index_key, derive_key_from_password
|
||||||
@@ -29,7 +30,8 @@ def test_password_change_and_unlock(monkeypatch):
|
|||||||
enc_mgr = EncryptionManager(index_key, fp)
|
enc_mgr = EncryptionManager(index_key, fp)
|
||||||
seed_mgr = EncryptionManager(seed_key, fp)
|
seed_mgr = EncryptionManager(seed_key, fp)
|
||||||
vault = Vault(enc_mgr, fp)
|
vault = Vault(enc_mgr, fp)
|
||||||
entry_mgr = EntryManager(vault, fp)
|
backup_mgr = BackupManager(fp)
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
cfg_mgr = ConfigManager(vault, fp)
|
cfg_mgr = ConfigManager(vault, fp)
|
||||||
|
|
||||||
vault.save_index({"entries": {}})
|
vault.save_index({"entries": {}})
|
||||||
|
@@ -14,6 +14,7 @@ import constants
|
|||||||
import password_manager.manager as manager_module
|
import password_manager.manager as manager_module
|
||||||
from password_manager.vault import Vault
|
from password_manager.vault import Vault
|
||||||
from password_manager.entry_management import EntryManager
|
from password_manager.entry_management import EntryManager
|
||||||
|
from password_manager.backup import BackupManager
|
||||||
from password_manager.manager import EncryptionMode
|
from password_manager.manager import EncryptionMode
|
||||||
|
|
||||||
|
|
||||||
@@ -51,7 +52,8 @@ def test_add_and_delete_entry(monkeypatch):
|
|||||||
assert pm.fingerprint_manager.current_fingerprint == fingerprint
|
assert pm.fingerprint_manager.current_fingerprint == fingerprint
|
||||||
|
|
||||||
vault, enc_mgr = create_vault(fingerprint_dir, TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(fingerprint_dir, TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, fingerprint_dir)
|
backup_mgr = BackupManager(fingerprint_dir)
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
pm.encryption_manager = enc_mgr
|
pm.encryption_manager = enc_mgr
|
||||||
pm.vault = vault
|
pm.vault = vault
|
||||||
|
@@ -10,6 +10,7 @@ from helpers import create_vault, TEST_SEED, TEST_PASSWORD
|
|||||||
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
||||||
|
|
||||||
from password_manager.entry_management import EntryManager
|
from password_manager.entry_management import EntryManager
|
||||||
|
from password_manager.backup import BackupManager
|
||||||
from password_manager.vault import Vault
|
from password_manager.vault import Vault
|
||||||
from password_manager.totp import TotpManager
|
from password_manager.totp import TotpManager
|
||||||
import pyotp
|
import pyotp
|
||||||
@@ -18,7 +19,8 @@ import pyotp
|
|||||||
def test_add_totp_and_get_code():
|
def test_add_totp_and_get_code():
|
||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, Path(tmpdir))
|
backup_mgr = BackupManager(Path(tmpdir))
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
uri = entry_mgr.add_totp("Example", TEST_SEED)
|
uri = entry_mgr.add_totp("Example", TEST_SEED)
|
||||||
assert uri.startswith("otpauth://totp/")
|
assert uri.startswith("otpauth://totp/")
|
||||||
@@ -41,7 +43,8 @@ def test_add_totp_and_get_code():
|
|||||||
def test_totp_time_remaining(monkeypatch):
|
def test_totp_time_remaining(monkeypatch):
|
||||||
with TemporaryDirectory() as tmpdir:
|
with TemporaryDirectory() as tmpdir:
|
||||||
vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD)
|
vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD)
|
||||||
entry_mgr = EntryManager(vault, Path(tmpdir))
|
backup_mgr = BackupManager(Path(tmpdir))
|
||||||
|
entry_mgr = EntryManager(vault, backup_mgr)
|
||||||
|
|
||||||
entry_mgr.add_totp("Example", TEST_SEED)
|
entry_mgr.add_totp("Example", TEST_SEED)
|
||||||
|
|
||||||
@@ -52,7 +55,8 @@ def test_totp_time_remaining(monkeypatch):
|
|||||||
|
|
||||||
def test_add_totp_imported(tmp_path):
|
def test_add_totp_imported(tmp_path):
|
||||||
vault, enc = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
vault, enc = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
|
||||||
em = EntryManager(vault, tmp_path)
|
backup_mgr = BackupManager(tmp_path)
|
||||||
|
em = EntryManager(vault, backup_mgr)
|
||||||
secret = "JBSWY3DPEHPK3PXP"
|
secret = "JBSWY3DPEHPK3PXP"
|
||||||
em.add_totp("Imported", TEST_SEED, secret=secret)
|
em.add_totp("Imported", TEST_SEED, secret=secret)
|
||||||
entry = em.retrieve_entry(0)
|
entry = em.retrieve_entry(0)
|
||||||
|
Reference in New Issue
Block a user