Add ssh key and keyboard shortcut windows

This commit is contained in:
Bernd Schoolmann 2024-02-17 11:00:33 +01:00
parent 9ac1d8100a
commit c15447aab3
No known key found for this signature in database
3 changed files with 199 additions and 110 deletions

View file

@ -5,7 +5,7 @@ gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1') gi.require_version('Adw', '1')
import gc import gc
from gi.repository import Gtk, Adw, GLib, Gdk from gi.repository import Gtk, Adw, GLib, Gdk, Gio
from ..services import goldwarden from ..services import goldwarden
from threading import Thread from threading import Thread
import subprocess import subprocess
@ -16,6 +16,30 @@ root_path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file_
token = sys.stdin.readline() token = sys.stdin.readline()
goldwarden.create_authenticated_connection(None) goldwarden.create_authenticated_connection(None)
def quickaccess_button_clicked():
p = subprocess.Popen(["python3", "-m", "src.gui.quickaccess"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
p.stdin.write(f"{token}\n".encode())
p.stdin.flush()
def shortcuts_button_clicked():
p = subprocess.Popen(["python3", "-m", "src.gui.shortcuts"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
p.stdin.write(f"{token}\n".encode())
p.stdin.flush()
def ssh_button_clicked():
p = subprocess.Popen(["python3", "-m", "src.gui.ssh"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
p.stdin.write(f"{token}\n".encode())
p.stdin.flush()
def add_action_row(parent, title, subtitle, icon=None):
row = Adw.ActionRow()
row.set_title(title)
row.set_subtitle(subtitle)
if icon != None:
row.set_icon_name(icon)
parent.add(row)
return row
class SettingsWinvdow(Gtk.ApplicationWindow): class SettingsWinvdow(Gtk.ApplicationWindow):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -50,10 +74,7 @@ class SettingsWinvdow(Gtk.ApplicationWindow):
self.autotype_button = Gtk.Button() self.autotype_button = Gtk.Button()
self.autotype_button.set_label("Quick Access") self.autotype_button.set_label("Quick Access")
self.autotype_button.set_margin_top(10) self.autotype_button.set_margin_top(10)
def quickaccess_button_clicked():
p = subprocess.Popen(["python3", "-m", "src.gui.quickaccess"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
p.stdin.write(f"{token}\n".encode())
p.stdin.flush()
self.autotype_button.connect("clicked", lambda button: quickaccess_button_clicked()) self.autotype_button.connect("clicked", lambda button: quickaccess_button_clicked())
self.autotype_button.get_style_context().add_class("suggested-action") self.autotype_button.get_style_context().add_class("suggested-action")
self.action_preferences_group.add(self.autotype_button) self.action_preferences_group.add(self.autotype_button)
@ -98,119 +119,47 @@ class SettingsWinvdow(Gtk.ApplicationWindow):
self.wiki_button.set_margin_top(10) self.wiki_button.set_margin_top(10)
self.action_preferences_group.add(self.wiki_button) self.action_preferences_group.add(self.wiki_button)
self.shortcut_preferences_group = Adw.PreferencesGroup()
self.shortcut_preferences_group.set_title("Shortcuts")
self.preferences_page.add(self.shortcut_preferences_group)
self.autofill_row = Adw.ActionRow()
self.autofill_row.set_title("Autofill Shortcut")
self.autofill_row.set_subtitle("Unavailable, please set up a shortcut in your desktop environment (README)")
self.shortcut_preferences_group.add(self.autofill_row)
self.autofill_icon = components.StatusIcon()
self.autofill_icon.set_icon("dialog-warning", "warning")
self.autofill_row.add_prefix(self.autofill_icon)
self.copy_username_shortcut_row = Adw.ActionRow()
self.copy_username_shortcut_row.set_title("Copy Username Shortcut")
self.copy_username_shortcut_row.set_subtitle("U")
self.shortcut_preferences_group.add(self.copy_username_shortcut_row)
self.copy_password_shortcut_row = Adw.ActionRow()
self.copy_password_shortcut_row.set_title("Copy Password Shortcut")
self.copy_password_shortcut_row.set_subtitle("P")
self.shortcut_preferences_group.add(self.copy_password_shortcut_row)
self.copy_totp_shortcut_row = Adw.ActionRow()
self.copy_totp_shortcut_row.set_title("Copy TOTP Shortcut")
self.copy_totp_shortcut_row.set_subtitle("T")
self.shortcut_preferences_group.add(self.copy_totp_shortcut_row)
self.launch_uri_shortcut_row = Adw.ActionRow()
self.launch_uri_shortcut_row.set_title("Launch URI Shortcut")
self.launch_uri_shortcut_row.set_subtitle("L")
self.shortcut_preferences_group.add(self.launch_uri_shortcut_row)
self.launch_web_vault_shortcut_row = Adw.ActionRow()
self.launch_web_vault_shortcut_row.set_title("Launch Web Vault Shortcut")
self.launch_web_vault_shortcut_row.set_subtitle("V")
self.shortcut_preferences_group.add(self.launch_web_vault_shortcut_row)
self.focus_search_shortcut_row = Adw.ActionRow()
self.focus_search_shortcut_row.set_title("Focus Search Shortcut")
self.focus_search_shortcut_row.set_subtitle("F")
self.shortcut_preferences_group.add(self.focus_search_shortcut_row)
self.quit_shortcut_row = Adw.ActionRow()
self.quit_shortcut_row.set_title("Quit Shortcut")
self.quit_shortcut_row.set_subtitle("Esc")
self.shortcut_preferences_group.add(self.quit_shortcut_row)
self.vault_status_preferences_group = Adw.PreferencesGroup() self.vault_status_preferences_group = Adw.PreferencesGroup()
self.vault_status_preferences_group.set_title("Vault Status") self.vault_status_preferences_group.set_title("Vault Status")
self.preferences_page.add(self.vault_status_preferences_group) self.preferences_page.add(self.vault_status_preferences_group)
self.status_row = Adw.ActionRow() self.status_row = add_action_row(self.vault_status_preferences_group, "Vault Status", "Locked")
self.status_row.set_title("Vault Status")
self.status_row.set_subtitle("Locked")
self.vault_status_preferences_group.add(self.status_row)
self.vault_status_icon = components.StatusIcon() self.vault_status_icon = components.StatusIcon()
self.vault_status_icon.set_icon("dialog-error", "error") self.vault_status_icon.set_icon("dialog-error", "error")
self.status_row.add_prefix(self.vault_status_icon) self.status_row.add_prefix(self.vault_status_icon)
self.last_sync_row = Adw.ActionRow() self.last_sync_row = add_action_row(self.vault_status_preferences_group, "Last Sync", "Never", "emblem-synchronizing-symbolic")
self.last_sync_row.set_title("Last Sync") self.websocket_connected_row = add_action_row(self.vault_status_preferences_group, "Websocket Connected", "False")
self.last_sync_row.set_subtitle("Never")
self.last_sync_row.set_icon_name("emblem-synchronizing-symbolic")
self.vault_status_preferences_group.add(self.last_sync_row)
self.websocket_connected_row = Adw.ActionRow()
self.websocket_connected_row.set_title("Websocket Connected")
self.websocket_connected_row.set_subtitle("False")
self.vault_status_preferences_group.add(self.websocket_connected_row)
self.websocket_connected_status_icon = components.StatusIcon() self.websocket_connected_status_icon = components.StatusIcon()
self.websocket_connected_status_icon.set_icon("dialog-error", "error") self.websocket_connected_status_icon.set_icon("dialog-error", "error")
self.websocket_connected_row.add_prefix(self.websocket_connected_status_icon) self.websocket_connected_row.add_prefix(self.websocket_connected_status_icon)
self.login_row = Adw.ActionRow() self.login_row = add_action_row(self.vault_status_preferences_group, "Vault Login Entries", "0", "dialog-password-symbolic")
self.login_row.set_title("Vault Login Entries") self.notes_row = add_action_row(self.vault_status_preferences_group, "Vault Notes", "0", "emblem-documents-symbolic")
self.login_row.set_subtitle("0")
self.login_row.set_icon_name("dialog-password-symbolic")
self.vault_status_preferences_group.add(self.login_row)
self.notes_row = Adw.ActionRow() self.header = Gtk.HeaderBar()
self.notes_row.set_title("Vault Notes") self.set_titlebar(self.header)
self.notes_row.set_subtitle("0")
self.notes_row.set_icon_name("emblem-documents-symbolic")
self.vault_status_preferences_group.add(self.notes_row)
self.preferences_group = Adw.PreferencesGroup() action = Gio.SimpleAction.new("shortcuts", None)
self.preferences_group.set_title("Services") action.connect("activate", lambda action, parameter: shortcuts_button_clicked())
self.preferences_page.add(self.preferences_group) self.add_action(action)
menu = Gio.Menu.new()
menu.append("Keyboard Shortcuts", "win.shortcuts")
self.popover = Gtk.PopoverMenu()
self.popover.set_menu_model(menu)
self.ssh_row = Adw.ActionRow() action = Gio.SimpleAction.new("ssh", None)
self.ssh_row.set_title("SSH Daemon") action.connect("activate", lambda action, parameter: ssh_button_clicked())
self.ssh_row.set_subtitle("Getting status...") self.add_action(action)
self.ssh_row.set_icon_name("emblem-default") menu.append("SSH Agent", "win.ssh")
self.preferences_group.add(self.ssh_row)
self.goldwarden_daemon_row = Adw.ActionRow() self.hamburger = Gtk.MenuButton()
self.goldwarden_daemon_row.set_title("Goldwarden Daemon") self.hamburger.set_popover(self.popover)
self.goldwarden_daemon_row.set_subtitle("Getting status...") self.hamburger.set_icon_name("open-menu-symbolic")
self.goldwarden_daemon_row.set_icon_name("emblem-default") self.header.pack_start(self.hamburger)
self.preferences_group.add(self.goldwarden_daemon_row)
self.login_with_device = Adw.ActionRow()
self.login_with_device.set_title("Login with device")
self.login_with_device.set_subtitle("Waiting for requests...")
self.preferences_group.add(self.login_with_device)
self.status_row = Adw.ActionRow()
self.status_row.set_title("DBUS Service")
self.status_row.set_subtitle("Listening")
self.preferences_group.add(self.status_row)
def update_labels(): def update_labels():
pin_set = goldwarden.is_pin_enabled() pin_set = goldwarden.is_pin_enabled()
@ -276,16 +225,10 @@ class SettingsWinvdow(Gtk.ApplicationWindow):
GLib.timeout_add(5000, update_labels) GLib.timeout_add(5000, update_labels)
GLib.timeout_add(1000, update_labels) GLib.timeout_add(1000, update_labels)
self.set_default_size(400, 700) self.set_default_size(400, 700)
self.set_title("Goldwarden") self.set_title("Goldwarden")
#add title buttons
self.title_bar = Gtk.HeaderBar()
self.set_titlebar(self.title_bar)
class MyApp(Adw.Application): class MyApp(Adw.Application):
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
@ -372,6 +315,5 @@ Gtk.StyleContext.add_provider_for_display(
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
) )
app = MyApp(application_id="com.quexten.Goldwarden.settings") app = MyApp(application_id="com.quexten.Goldwarden.settings")
app.run(sys.argv) app.run(sys.argv)

80
gui/src/gui/shortcuts.py Normal file
View file

@ -0,0 +1,80 @@
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
import gc
import time
from gi.repository import Gtk, Adw, GLib, Notify, Gdk
from threading import Thread
import sys
import os
from . import components
def add_action_row(parent, title, subtitle, icon=None):
row = Adw.ActionRow()
row.set_title(title)
row.set_subtitle(subtitle)
if icon != None:
row.set_icon_name(icon)
parent.add(row)
return row
class MyApp(Adw.Application):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.connect('activate', self.on_activate)
def on_activate(self, app):
self.pinentry_window = MainWindow(application=app)
self.pinentry_window.present()
self.app = app
class MainWindow(Gtk.ApplicationWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# vertical box
self.box = Gtk.Box()
self.box.set_orientation(Gtk.Orientation.VERTICAL)
self.set_child(self.box)
self.stack = Gtk.Stack()
self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
self.box.append(self.stack)
self.preferences_page = Adw.PreferencesPage()
self.preferences_page.set_title("General")
self.stack.add_named(self.preferences_page, "preferences_page")
self.global_preferences_group = Adw.PreferencesGroup()
self.global_preferences_group.set_title("Global Shortcuts")
self.preferences_page.add(self.global_preferences_group)
self.autofill_row = Adw.ActionRow()
self.autofill_row.set_title("Autofill Shortcut")
self.autofill_row.set_subtitle("Not implemented - check the wiki for manual setup")
self.global_preferences_group.add(self.autofill_row)
self.autofill_icon = components.StatusIcon()
self.autofill_icon.set_icon("dialog-warning", "warning")
self.autofill_row.add_prefix(self.autofill_icon)
self.quickaccess_preferences_group = Adw.PreferencesGroup()
self.quickaccess_preferences_group.set_title("Quick Access Shortcuts")
self.preferences_page.add(self.quickaccess_preferences_group)
add_action_row(self.quickaccess_preferences_group, "Copy Username Shortcut", "CTRL + U")
add_action_row(self.quickaccess_preferences_group, "Autotype Username Shortcut", "CTRL + ALT + U")
add_action_row(self.quickaccess_preferences_group, "Copy Password Shortcut", "CTRL + P")
add_action_row(self.quickaccess_preferences_group, "Autotype Password Shortcut", "CTRL + ALT + P")
add_action_row(self.quickaccess_preferences_group, "Copy TOTP Shortcut", "CTRL + T")
add_action_row(self.quickaccess_preferences_group, "Autotype TOTP Shortcut", "CTRL + ALT + T")
add_action_row(self.quickaccess_preferences_group, "Launch URI Shortcut", "CTRL+L")
add_action_row(self.quickaccess_preferences_group, "Launch Web Vault Shortcut", "CTRL+V")
add_action_row(self.quickaccess_preferences_group, "Focus Search Shortcut", "F")
add_action_row(self.quickaccess_preferences_group, "Quit Shortcut", "Esc")
self.set_default_size(700, 700)
self.set_title("Goldwarden Shortcuts")
app = MyApp(application_id="com.quexten.Goldwarden.shortcuts")
app.run(sys.argv)

67
gui/src/gui/ssh.py Normal file
View file

@ -0,0 +1,67 @@
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
import gc
import time
from gi.repository import Gtk, Adw, GLib, Notify, Gdk
from threading import Thread
import sys
import os
from . import components
class MyApp(Adw.Application):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.connect('activate', self.on_activate)
def on_activate(self, app):
self.pinentry_window = MainWindow(application=app)
self.pinentry_window.present()
self.app = app
class MainWindow(Gtk.ApplicationWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# vertical box
self.box = Gtk.Box()
self.box.set_orientation(Gtk.Orientation.VERTICAL)
self.set_child(self.box)
self.stack = Gtk.Stack()
self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
self.box.append(self.stack)
self.preferences_page = Adw.PreferencesPage()
self.preferences_page.set_title("General")
self.stack.add_named(self.preferences_page, "preferences_page")
self.add_ssh_key_group = Adw.PreferencesGroup()
self.add_ssh_key_group.set_title("Add an SSH Key")
self.preferences_page.add(self.add_ssh_key_group)
self.add_ssh_key_row = Adw.ActionRow()
self.add_ssh_key_row.set_subtitle("flatpak run --command=goldwarden com.quexten.Goldwarden ssh add --name MY_KEY_NAME")
self.add_ssh_key_row.set_subtitle_selectable(True)
self.add_ssh_key_group.add(self.add_ssh_key_row)
self.ssh_socket_path_group = Adw.PreferencesGroup()
self.ssh_socket_path_group.set_title("SSH Socket Path")
self.ssh_socket_path_group.set_description("Add this to your your enviorment variables")
self.preferences_page.add(self.ssh_socket_path_group)
self.ssh_socket_path_row = Adw.ActionRow()
self.ssh_socket_path_row.set_subtitle("export SSH_AUTH_SOCK=/home/$USER/.var/app/com.quexten.Goldwarden/data/ssh-auth-sock")
self.ssh_socket_path_row.set_subtitle_selectable(True)
self.ssh_socket_path_group.add(self.ssh_socket_path_row)
self.git_signing_group = Adw.PreferencesGroup()
self.git_signing_group.set_title("Git Signing")
self.git_signing_group.set_description("Check the wiki for more information")
self.preferences_page.add(self.git_signing_group)
self.set_default_size(400, 700)
self.set_title("Goldwarden SSH Setup")
app = MyApp(application_id="com.quexten.Goldwarden.sshsetup")
app.run(sys.argv)