mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-08 07:18:47 +00:00
Merge pull request #661 from PR0M3TH3AN/codex/refactor-entry-source-and-update-sync-methods
Switch entry service to background sync
This commit is contained in:
@@ -282,7 +282,7 @@ class EntryService:
|
|||||||
) -> int:
|
) -> int:
|
||||||
with self._lock:
|
with self._lock:
|
||||||
idx = self._manager.entry_manager.add_entry(label, length, username, url)
|
idx = self._manager.entry_manager.add_entry(label, length, username, url)
|
||||||
self._manager.sync_vault()
|
self._manager.start_background_vault_sync()
|
||||||
return idx
|
return idx
|
||||||
|
|
||||||
def add_totp(
|
def add_totp(
|
||||||
@@ -303,7 +303,7 @@ class EntryService:
|
|||||||
period=period,
|
period=period,
|
||||||
digits=digits,
|
digits=digits,
|
||||||
)
|
)
|
||||||
self._manager.sync_vault()
|
self._manager.start_background_vault_sync()
|
||||||
return uri
|
return uri
|
||||||
|
|
||||||
def add_ssh_key(
|
def add_ssh_key(
|
||||||
@@ -320,7 +320,7 @@ class EntryService:
|
|||||||
index=index,
|
index=index,
|
||||||
notes=notes,
|
notes=notes,
|
||||||
)
|
)
|
||||||
self._manager.sync_vault()
|
self._manager.start_background_vault_sync()
|
||||||
return idx
|
return idx
|
||||||
|
|
||||||
def add_pgp_key(
|
def add_pgp_key(
|
||||||
@@ -341,7 +341,7 @@ class EntryService:
|
|||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
notes=notes,
|
notes=notes,
|
||||||
)
|
)
|
||||||
self._manager.sync_vault()
|
self._manager.start_background_vault_sync()
|
||||||
return idx
|
return idx
|
||||||
|
|
||||||
def add_nostr_key(
|
def add_nostr_key(
|
||||||
@@ -357,7 +357,7 @@ class EntryService:
|
|||||||
index=index,
|
index=index,
|
||||||
notes=notes,
|
notes=notes,
|
||||||
)
|
)
|
||||||
self._manager.sync_vault()
|
self._manager.start_background_vault_sync()
|
||||||
return idx
|
return idx
|
||||||
|
|
||||||
def add_seed(
|
def add_seed(
|
||||||
@@ -376,13 +376,13 @@ class EntryService:
|
|||||||
words_num=words,
|
words_num=words,
|
||||||
notes=notes,
|
notes=notes,
|
||||||
)
|
)
|
||||||
self._manager.sync_vault()
|
self._manager.start_background_vault_sync()
|
||||||
return idx
|
return idx
|
||||||
|
|
||||||
def add_key_value(self, label: str, value: str, *, notes: str = "") -> int:
|
def add_key_value(self, label: str, value: str, *, notes: str = "") -> int:
|
||||||
with self._lock:
|
with self._lock:
|
||||||
idx = self._manager.entry_manager.add_key_value(label, value, notes=notes)
|
idx = self._manager.entry_manager.add_key_value(label, value, notes=notes)
|
||||||
self._manager.sync_vault()
|
self._manager.start_background_vault_sync()
|
||||||
return idx
|
return idx
|
||||||
|
|
||||||
def add_managed_account(
|
def add_managed_account(
|
||||||
@@ -399,7 +399,7 @@ class EntryService:
|
|||||||
index=index,
|
index=index,
|
||||||
notes=notes,
|
notes=notes,
|
||||||
)
|
)
|
||||||
self._manager.sync_vault()
|
self._manager.start_background_vault_sync()
|
||||||
return idx
|
return idx
|
||||||
|
|
||||||
def modify_entry(
|
def modify_entry(
|
||||||
@@ -425,17 +425,17 @@ class EntryService:
|
|||||||
digits=digits,
|
digits=digits,
|
||||||
value=value,
|
value=value,
|
||||||
)
|
)
|
||||||
self._manager.sync_vault()
|
self._manager.start_background_vault_sync()
|
||||||
|
|
||||||
def archive_entry(self, entry_id: int) -> None:
|
def archive_entry(self, entry_id: int) -> None:
|
||||||
with self._lock:
|
with self._lock:
|
||||||
self._manager.entry_manager.archive_entry(entry_id)
|
self._manager.entry_manager.archive_entry(entry_id)
|
||||||
self._manager.sync_vault()
|
self._manager.start_background_vault_sync()
|
||||||
|
|
||||||
def restore_entry(self, entry_id: int) -> None:
|
def restore_entry(self, entry_id: int) -> None:
|
||||||
with self._lock:
|
with self._lock:
|
||||||
self._manager.entry_manager.restore_entry(entry_id)
|
self._manager.entry_manager.restore_entry(entry_id)
|
||||||
self._manager.sync_vault()
|
self._manager.start_background_vault_sync()
|
||||||
|
|
||||||
def export_totp_entries(self) -> dict:
|
def export_totp_entries(self) -> dict:
|
||||||
with self._lock:
|
with self._lock:
|
||||||
|
@@ -5,6 +5,7 @@ import time
|
|||||||
|
|
||||||
import toga
|
import toga
|
||||||
from toga.style import Pack
|
from toga.style import Pack
|
||||||
|
from toga.sources import ListSource
|
||||||
from toga.style.pack import COLUMN, ROW
|
from toga.style.pack import COLUMN, ROW
|
||||||
|
|
||||||
from seedpass.core.entry_types import EntryType
|
from seedpass.core.entry_types import EntryType
|
||||||
@@ -89,8 +90,10 @@ class MainWindow(toga.Window):
|
|||||||
bus.subscribe("vault_locked", self.vault_locked)
|
bus.subscribe("vault_locked", self.vault_locked)
|
||||||
self.last_sync = None
|
self.last_sync = None
|
||||||
|
|
||||||
|
self.entry_source = ListSource(["id", "label", "kind", "info1", "info2"])
|
||||||
self.table = toga.Table(
|
self.table = toga.Table(
|
||||||
headings=["ID", "Label", "Kind", "Info 1", "Info 2"],
|
headings=["ID", "Label", "Kind", "Info 1", "Info 2"],
|
||||||
|
data=self.entry_source,
|
||||||
style=Pack(flex=1),
|
style=Pack(flex=1),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -118,7 +121,7 @@ class MainWindow(toga.Window):
|
|||||||
self.refresh_entries()
|
self.refresh_entries()
|
||||||
|
|
||||||
def refresh_entries(self) -> None:
|
def refresh_entries(self) -> None:
|
||||||
self.table.data = []
|
self.entry_source.clear()
|
||||||
for idx, label, username, url, _arch in self.entries.list_entries():
|
for idx, label, username, url, _arch in self.entries.list_entries():
|
||||||
entry = self.entries.retrieve_entry(idx)
|
entry = self.entries.retrieve_entry(idx)
|
||||||
kind = (entry or {}).get("kind", (entry or {}).get("type", ""))
|
kind = (entry or {}).get("kind", (entry or {}).get("type", ""))
|
||||||
@@ -131,7 +134,15 @@ class MainWindow(toga.Window):
|
|||||||
info1 = entry.get("value", "") if entry else ""
|
info1 = entry.get("value", "") if entry else ""
|
||||||
else:
|
else:
|
||||||
info1 = str(entry.get("index", "")) if entry else ""
|
info1 = str(entry.get("index", "")) if entry else ""
|
||||||
self.table.data.append((idx, label, kind, info1, info2))
|
self.entry_source.append(
|
||||||
|
{
|
||||||
|
"id": idx,
|
||||||
|
"label": label,
|
||||||
|
"kind": kind,
|
||||||
|
"info1": info1,
|
||||||
|
"info2": info2,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# --- Button handlers -------------------------------------------------
|
# --- Button handlers -------------------------------------------------
|
||||||
def add_entry(self, widget: toga.Widget) -> None:
|
def add_entry(self, widget: toga.Widget) -> None:
|
||||||
@@ -285,9 +296,17 @@ class SearchDialog(toga.Window):
|
|||||||
def do_search(self, widget: toga.Widget) -> None:
|
def do_search(self, widget: toga.Widget) -> None:
|
||||||
query = self.query_input.value or ""
|
query = self.query_input.value or ""
|
||||||
results = self.main.entries.search_entries(query)
|
results = self.main.entries.search_entries(query)
|
||||||
self.main.table.data = []
|
self.main.entry_source.clear()
|
||||||
for idx, label, username, url, _arch in results:
|
for idx, label, username, url, _arch in results:
|
||||||
self.main.table.data.append((idx, label, username or "", url or ""))
|
self.main.entry_source.append(
|
||||||
|
{
|
||||||
|
"id": idx,
|
||||||
|
"label": label,
|
||||||
|
"kind": "",
|
||||||
|
"info1": username or "",
|
||||||
|
"info2": url or "",
|
||||||
|
}
|
||||||
|
)
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@ def test_cli_entry_add_search_sync(monkeypatch):
|
|||||||
calls["search"] = (q, kinds)
|
calls["search"] = (q, kinds)
|
||||||
return [(1, "Label", None, None, False)]
|
return [(1, "Label", None, None, False)]
|
||||||
|
|
||||||
def sync_vault():
|
def start_background_vault_sync():
|
||||||
calls["sync"] = True
|
calls["sync"] = True
|
||||||
return {"manifest_id": "m", "chunk_ids": [], "delta_ids": []}
|
return {"manifest_id": "m", "chunk_ids": [], "delta_ids": []}
|
||||||
|
|
||||||
@@ -44,7 +44,8 @@ def test_cli_entry_add_search_sync(monkeypatch):
|
|||||||
entry_manager=SimpleNamespace(
|
entry_manager=SimpleNamespace(
|
||||||
add_entry=add_entry, search_entries=search_entries
|
add_entry=add_entry, search_entries=search_entries
|
||||||
),
|
),
|
||||||
sync_vault=sync_vault,
|
start_background_vault_sync=start_background_vault_sync,
|
||||||
|
sync_vault=lambda: {"manifest_id": "m", "chunk_ids": [], "delta_ids": []},
|
||||||
select_fingerprint=lambda fp: None,
|
select_fingerprint=lambda fp: None,
|
||||||
)
|
)
|
||||||
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
||||||
|
@@ -58,6 +58,7 @@ class DummyPM:
|
|||||||
"chunk_ids": ["c1"],
|
"chunk_ids": ["c1"],
|
||||||
"delta_ids": [],
|
"delta_ids": [],
|
||||||
}
|
}
|
||||||
|
self.start_background_vault_sync = lambda *a, **k: self.sync_vault()
|
||||||
self.config_manager = SimpleNamespace(
|
self.config_manager = SimpleNamespace(
|
||||||
load_config=lambda require_pin=False: {"inactivity_timeout": 30},
|
load_config=lambda require_pin=False: {"inactivity_timeout": 30},
|
||||||
set_inactivity_timeout=lambda v: None,
|
set_inactivity_timeout=lambda v: None,
|
||||||
|
@@ -115,14 +115,14 @@ def test_entry_add_commands(
|
|||||||
called["kwargs"] = kwargs
|
called["kwargs"] = kwargs
|
||||||
return stdout
|
return stdout
|
||||||
|
|
||||||
def sync_vault():
|
def start_background_vault_sync():
|
||||||
called["sync"] = True
|
called["sync"] = True
|
||||||
|
|
||||||
pm = SimpleNamespace(
|
pm = SimpleNamespace(
|
||||||
entry_manager=SimpleNamespace(**{method: func}),
|
entry_manager=SimpleNamespace(**{method: func}),
|
||||||
parent_seed="seed",
|
parent_seed="seed",
|
||||||
select_fingerprint=lambda fp: None,
|
select_fingerprint=lambda fp: None,
|
||||||
sync_vault=sync_vault,
|
start_background_vault_sync=start_background_vault_sync,
|
||||||
)
|
)
|
||||||
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
||||||
result = runner.invoke(app, ["entry", command] + cli_args)
|
result = runner.invoke(app, ["entry", command] + cli_args)
|
||||||
|
@@ -29,7 +29,7 @@ def test_entry_service_add_entry_and_search():
|
|||||||
called["search"] = (q, kinds)
|
called["search"] = (q, kinds)
|
||||||
return [(5, "Example", username, url, False)]
|
return [(5, "Example", username, url, False)]
|
||||||
|
|
||||||
def sync_vault():
|
def start_background_vault_sync():
|
||||||
called["sync"] = True
|
called["sync"] = True
|
||||||
|
|
||||||
username = "user"
|
username = "user"
|
||||||
@@ -38,7 +38,7 @@ def test_entry_service_add_entry_and_search():
|
|||||||
entry_manager=SimpleNamespace(
|
entry_manager=SimpleNamespace(
|
||||||
add_entry=add_entry, search_entries=search_entries
|
add_entry=add_entry, search_entries=search_entries
|
||||||
),
|
),
|
||||||
sync_vault=sync_vault,
|
start_background_vault_sync=start_background_vault_sync,
|
||||||
)
|
)
|
||||||
service = EntryService(pm)
|
service = EntryService(pm)
|
||||||
idx = service.add_entry("Example", 12, username, url)
|
idx = service.add_entry("Example", 12, username, url)
|
||||||
|
@@ -377,7 +377,7 @@ def test_entry_add(monkeypatch):
|
|||||||
pm = SimpleNamespace(
|
pm = SimpleNamespace(
|
||||||
entry_manager=SimpleNamespace(add_entry=add_entry),
|
entry_manager=SimpleNamespace(add_entry=add_entry),
|
||||||
select_fingerprint=lambda fp: None,
|
select_fingerprint=lambda fp: None,
|
||||||
sync_vault=lambda: None,
|
start_background_vault_sync=lambda: None,
|
||||||
)
|
)
|
||||||
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
||||||
result = runner.invoke(
|
result = runner.invoke(
|
||||||
@@ -408,7 +408,7 @@ def test_entry_modify(monkeypatch):
|
|||||||
pm = SimpleNamespace(
|
pm = SimpleNamespace(
|
||||||
entry_manager=SimpleNamespace(modify_entry=modify_entry),
|
entry_manager=SimpleNamespace(modify_entry=modify_entry),
|
||||||
select_fingerprint=lambda fp: None,
|
select_fingerprint=lambda fp: None,
|
||||||
sync_vault=lambda: None,
|
start_background_vault_sync=lambda: None,
|
||||||
)
|
)
|
||||||
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
||||||
result = runner.invoke(app, ["entry", "modify", "1", "--username", "alice"])
|
result = runner.invoke(app, ["entry", "modify", "1", "--username", "alice"])
|
||||||
@@ -423,7 +423,7 @@ def test_entry_modify_invalid(monkeypatch):
|
|||||||
pm = SimpleNamespace(
|
pm = SimpleNamespace(
|
||||||
entry_manager=SimpleNamespace(modify_entry=modify_entry),
|
entry_manager=SimpleNamespace(modify_entry=modify_entry),
|
||||||
select_fingerprint=lambda fp: None,
|
select_fingerprint=lambda fp: None,
|
||||||
sync_vault=lambda: None,
|
start_background_vault_sync=lambda: None,
|
||||||
)
|
)
|
||||||
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
||||||
result = runner.invoke(app, ["entry", "modify", "1", "--username", "alice"])
|
result = runner.invoke(app, ["entry", "modify", "1", "--username", "alice"])
|
||||||
@@ -440,7 +440,7 @@ def test_entry_archive(monkeypatch):
|
|||||||
pm = SimpleNamespace(
|
pm = SimpleNamespace(
|
||||||
entry_manager=SimpleNamespace(archive_entry=archive_entry),
|
entry_manager=SimpleNamespace(archive_entry=archive_entry),
|
||||||
select_fingerprint=lambda fp: None,
|
select_fingerprint=lambda fp: None,
|
||||||
sync_vault=lambda: None,
|
start_background_vault_sync=lambda: None,
|
||||||
)
|
)
|
||||||
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
||||||
result = runner.invoke(app, ["entry", "archive", "3"])
|
result = runner.invoke(app, ["entry", "archive", "3"])
|
||||||
@@ -458,7 +458,7 @@ def test_entry_unarchive(monkeypatch):
|
|||||||
pm = SimpleNamespace(
|
pm = SimpleNamespace(
|
||||||
entry_manager=SimpleNamespace(restore_entry=restore_entry),
|
entry_manager=SimpleNamespace(restore_entry=restore_entry),
|
||||||
select_fingerprint=lambda fp: None,
|
select_fingerprint=lambda fp: None,
|
||||||
sync_vault=lambda: None,
|
start_background_vault_sync=lambda: None,
|
||||||
)
|
)
|
||||||
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
||||||
result = runner.invoke(app, ["entry", "unarchive", "4"])
|
result = runner.invoke(app, ["entry", "unarchive", "4"])
|
||||||
|
Reference in New Issue
Block a user