mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-09 15:58:48 +00:00
Add optional secondary backup location
This commit is contained in:
@@ -40,12 +40,14 @@ class BackupManager:
|
|||||||
BACKUP_FILENAME_TEMPLATE = "entries_db_backup_{timestamp}.json.enc"
|
BACKUP_FILENAME_TEMPLATE = "entries_db_backup_{timestamp}.json.enc"
|
||||||
|
|
||||||
def __init__(self, fingerprint_dir: Path, config_manager: ConfigManager):
|
def __init__(self, fingerprint_dir: Path, config_manager: ConfigManager):
|
||||||
"""
|
"""Initialize BackupManager for a specific profile.
|
||||||
Initializes the BackupManager with the fingerprint directory.
|
|
||||||
|
|
||||||
Parameters:
|
Parameters
|
||||||
fingerprint_dir (Path): The directory corresponding to the fingerprint.
|
----------
|
||||||
config_manager (ConfigManager): Configuration manager for profile settings.
|
fingerprint_dir : Path
|
||||||
|
Directory for this profile.
|
||||||
|
config_manager : ConfigManager
|
||||||
|
Configuration manager used for retrieving settings.
|
||||||
"""
|
"""
|
||||||
self.fingerprint_dir = fingerprint_dir
|
self.fingerprint_dir = fingerprint_dir
|
||||||
self.config_manager = config_manager
|
self.config_manager = config_manager
|
||||||
@@ -76,10 +78,30 @@ class BackupManager:
|
|||||||
shutil.copy2(index_file, backup_file)
|
shutil.copy2(index_file, backup_file)
|
||||||
logger.info(f"Backup created successfully at '{backup_file}'.")
|
logger.info(f"Backup created successfully at '{backup_file}'.")
|
||||||
print(colored(f"Backup created successfully at '{backup_file}'.", "green"))
|
print(colored(f"Backup created successfully at '{backup_file}'.", "green"))
|
||||||
|
|
||||||
|
self._create_additional_backup(backup_file)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to create backup: {e}", exc_info=True)
|
logger.error(f"Failed to create backup: {e}", exc_info=True)
|
||||||
print(colored(f"Error: Failed to create backup: {e}", "red"))
|
print(colored(f"Error: Failed to create backup: {e}", "red"))
|
||||||
|
|
||||||
|
def _create_additional_backup(self, backup_file: Path) -> None:
|
||||||
|
"""Write a copy of *backup_file* to the configured secondary location."""
|
||||||
|
path = self.config_manager.get_additional_backup_path()
|
||||||
|
if not path:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
dest_dir = Path(path).expanduser()
|
||||||
|
dest_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
dest_file = dest_dir / f"{self.fingerprint_dir.name}_{backup_file.name}"
|
||||||
|
shutil.copy2(backup_file, dest_file)
|
||||||
|
logger.info(f"Additional backup created at '{dest_file}'.")
|
||||||
|
except Exception as e: # pragma: no cover - best-effort logging
|
||||||
|
logger.error(
|
||||||
|
f"Failed to write additional backup to '{path}': {e}",
|
||||||
|
exc_info=True,
|
||||||
|
)
|
||||||
|
|
||||||
def restore_latest_backup(self) -> None:
|
def restore_latest_backup(self) -> None:
|
||||||
try:
|
try:
|
||||||
backup_files = sorted(
|
backup_files = sorted(
|
||||||
|
@@ -63,3 +63,24 @@ def test_backup_restore_workflow(monkeypatch):
|
|||||||
current = vault.load_index()
|
current = vault.load_index()
|
||||||
backup_mgr.restore_backup_by_timestamp(1111)
|
backup_mgr.restore_backup_by_timestamp(1111)
|
||||||
assert vault.load_index() == current
|
assert vault.load_index() == current
|
||||||
|
|
||||||
|
|
||||||
|
def test_additional_backup_location(monkeypatch):
|
||||||
|
with TemporaryDirectory() as tmpdir, TemporaryDirectory() as extra:
|
||||||
|
fp_dir = Path(tmpdir)
|
||||||
|
vault, enc_mgr = create_vault(fp_dir, TEST_SEED, TEST_PASSWORD)
|
||||||
|
cfg_mgr = ConfigManager(vault, fp_dir)
|
||||||
|
cfg_mgr.set_additional_backup_path(extra)
|
||||||
|
backup_mgr = BackupManager(fp_dir, cfg_mgr)
|
||||||
|
|
||||||
|
vault.save_index({"schema_version": 2, "entries": {"a": {}}})
|
||||||
|
|
||||||
|
monkeypatch.setattr(time, "time", lambda: 3333)
|
||||||
|
backup_mgr.create_backup()
|
||||||
|
|
||||||
|
backup = fp_dir / "backups" / "entries_db_backup_3333.json.enc"
|
||||||
|
assert backup.exists()
|
||||||
|
|
||||||
|
extra_file = Path(extra) / f"{fp_dir.name}_entries_db_backup_3333.json.enc"
|
||||||
|
assert extra_file.exists()
|
||||||
|
assert extra_file.stat().st_mode & 0o777 == 0o600
|
||||||
|
Reference in New Issue
Block a user