From 5a41145d4b710de82fe5df094517e6a45d06f588 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Sat, 23 Dec 2023 08:33:07 +0100 Subject: [PATCH] Add ui functionality --- com.quexten.Goldwarden.yml | 28 ++++++++++++++++++++++++++++ ui/com.quexten.Goldwarden.desktop | 10 ++++++++++ ui/goldwarden.py | 22 ++++++++++++++++++++-- ui/main.py | 25 +++++++++++++++++++++++-- 4 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 com.quexten.Goldwarden.yml create mode 100644 ui/com.quexten.Goldwarden.desktop diff --git a/com.quexten.Goldwarden.yml b/com.quexten.Goldwarden.yml new file mode 100644 index 0000000..d571d52 --- /dev/null +++ b/com.quexten.Goldwarden.yml @@ -0,0 +1,28 @@ +id: com.quexten.Goldwarden +runtime: org.gnome.Platform +runtime-version: '45' +sdk: org.gnome.Sdk +command: main.py +finish-args: + - --share=ipc + - --share=network + - --socket=wayland + - --socket=fallback-x11 + - --filesystem=home +modules: + - name: goldwarden + buildsystem: simple + build-options: + build-args: + - "--share=network" + build-commands: + - pip3 install --prefix=/app timeago secretstorage pycryptodome chacha20 + - install -D main.py /app/bin/main.py + - install -D com.quexten.Goldwarden.desktop /app/share/applications/com.quexten.Goldwarden.desktop + - install -D goldwarden.svg /app/share/icons/hicolor/scalable/apps/com.quexten.Goldwarden.svg + - cp -R ui/ /app/bin/gui/ + - cp -R backend/ /app/bin/backend/ + - cp -R event_monitors/ /app/bin/event_monitors/ + sources: + - type: dir + path: ui \ No newline at end of file diff --git a/ui/com.quexten.Goldwarden.desktop b/ui/com.quexten.Goldwarden.desktop new file mode 100644 index 0000000..1f6cf1e --- /dev/null +++ b/ui/com.quexten.Goldwarden.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=Goldwarden +Comment=A Bitwarden compatible desktop password manager +Keywords=backup;recovery; +Exec=main.py +Terminal=false +Type=Application +Icon=com.quexten.goldwarden.svg +StartupNotify=true +Categories=GNOME;GTK;Password Manager; \ No newline at end of file diff --git a/ui/goldwarden.py b/ui/goldwarden.py index 6e4e90a..657c3ee 100644 --- a/ui/goldwarden.py +++ b/ui/goldwarden.py @@ -45,12 +45,12 @@ def login_passwordless(email): raise Exception("Failed to initialize repository, err", result.stderr) def is_pin_enabled(): - restic_cmd = f"{BINARY_PATH} vault pin" + restic_cmd = f"{BINARY_PATH} vault pin status" result = subprocess.run(restic_cmd.split(), capture_output=True, text=True) if result.returncode != 0: raise Exception("Failed to initialize repository, err", result.stderr) # check if contains enabled - return "enabled" in result.stdout + return "enabled" in result.stderr def enable_pin(): restic_cmd = f"{BINARY_PATH} vault pin set" @@ -58,6 +58,24 @@ def enable_pin(): if result.returncode != 0: raise Exception("Failed to initialize repository, err", result.stderr) +def unlock(): + restic_cmd = f"{BINARY_PATH} vault unlock" + result = subprocess.run(restic_cmd.split(), capture_output=True, text=True) + if result.returncode != 0: + raise Exception("Failed to initialize repository, err", result.stderr) + +def lock(): + restic_cmd = f"{BINARY_PATH} vault lock" + result = subprocess.run(restic_cmd.split(), capture_output=True, text=True) + if result.returncode != 0: + raise Exception("Failed to initialize repository, err", result.stderr) + +def purge(): + restic_cmd = f"{BINARY_PATH} vault purge" + result = subprocess.run(restic_cmd.split(), capture_output=True, text=True) + if result.returncode != 0: + raise Exception("Failed to initialize repository, err", result.stderr) + def get_vault_status(): restic_cmd = f"{BINARY_PATH} vault status" result = subprocess.run(restic_cmd.split(), capture_output=True, text=True) diff --git a/ui/main.py b/ui/main.py index 293b4c4..4961adc 100644 --- a/ui/main.py +++ b/ui/main.py @@ -137,7 +137,7 @@ class SettingsWinvdow(Gtk.ApplicationWindow): self.autofill_row = Adw.ActionRow() self.autofill_row.set_title("Autofill Shortcut") - self.autofill_row.set_subtitle("Unavailable") + self.autofill_row.set_subtitle("Unavailable, please set up a shortcut in your desktop environment (README)") self.preferences_group.add(self.autofill_row) self.status_row = Adw.ActionRow() @@ -163,6 +163,7 @@ class SettingsWinvdow(Gtk.ApplicationWindow): self.login_button = Gtk.Button() self.login_button.set_label("Login") self.login_button.connect("clicked", lambda button: show_login()) + self.login_button.set_sensitive(False) self.login_button.set_margin_top(10) self.preferences_group.add(self.login_button) @@ -173,18 +174,38 @@ class SettingsWinvdow(Gtk.ApplicationWindow): set_pin_thread.start() self.set_pin_button.connect("clicked", lambda button: set_pin()) self.set_pin_button.set_margin_top(10) + self.set_pin_button.set_sensitive(False) self.preferences_group.add(self.set_pin_button) self.unlock_button = Gtk.Button() self.unlock_button.set_label("Unlock") self.unlock_button.set_margin_top(10) + def unlock_button_clicked(): + action = goldwarden.unlock if self.unlock_button.get_label() == "Unlock" else goldwarden.lock + unlock_thread = Thread(target=action) + unlock_thread.start() + self.unlock_button.connect("clicked", lambda button: unlock_button_clicked()) + # set disabled + self.unlock_button.set_sensitive(False) self.preferences_group.add(self.unlock_button) + + self.logout_button = Gtk.Button() + self.logout_button.set_label("Logout") + self.logout_button.set_margin_top(10) + self.logout_button.connect("clicked", lambda button: goldwarden.purge()) + self.preferences_group.add(self.logout_button) def update_labels(): + pin_set = goldwarden.is_pin_enabled() status = goldwarden.get_vault_status() - self.status_row.set_subtitle(str("Unlocked" if status["locked"] == False else "Locked")) + locked = status["locked"] + self.login_button.set_sensitive(pin_set and not locked) + self.set_pin_button.set_sensitive(not pin_set or not locked) + self.status_row.set_subtitle(str("Unlocked" if not locked else "Locked")) self.login_row.set_subtitle(str(status["loginEntries"])) self.notes_row.set_subtitle(str(status["noteEntries"])) + self.unlock_button.set_sensitive(True) + self.unlock_button.set_label("Unlock" if locked else "Lock") GLib.timeout_add(1000, update_labels) GLib.timeout_add(1000, update_labels)