From 9c02a19710b237d8bd9f3dea4ee220c5755b385e Mon Sep 17 00:00:00 2001 From: oupson Date: Sun, 5 Mar 2023 09:38:38 +0100 Subject: [PATCH] Add server deletion --- src/newpane.vala | 63 +++++++++++++++++++++++++-------------- src/services/Config.vala | 60 +++++++++++++++++++++++++++++++++++-- src/services/Secrets.vala | 8 +++++ 3 files changed, 106 insertions(+), 25 deletions(-) diff --git a/src/newpane.vala b/src/newpane.vala index 7f110b7..ee51329 100644 --- a/src/newpane.vala +++ b/src/newpane.vala @@ -19,7 +19,7 @@ */ namespace Footerm { - [GtkTemplate (ui = "/fr/oupson/FooTerm/newpane.ui")] + [GtkTemplate(ui = "/fr/oupson/FooTerm/newpane.ui")] public class NewPane : Gtk.Box { [GtkChild] private unowned Adw.PreferencesGroup server_list; @@ -33,39 +33,56 @@ namespace Footerm { [GtkChild] private unowned Gtk.Button newpane_add_button; - public signal void on_server_selected (Footerm.Model.Server server); + public signal void on_server_selected(Footerm.Model.Server server); + + private Footerm.Services.Config config; construct { - this.new_server.on_new_server.connect ((server) => { - this.newpane_stack.set_visible_child (server_list.get_parent ()); - var action_row = new Adw.ActionRow (); - action_row.set_title (server.name); - action_row.set_activatable (true); - action_row.activated.connect (() => { - this.on_server_selected (server); - }); - server_list.add (action_row); + this.new_server.on_new_server.connect((server) => { + this.newpane_stack.set_visible_child(server_list.get_parent()); + server_list.add(this.build_action_row(server)); }); - this.newpane_add_button.clicked.connect (() => { - this.newpane_stack.set_visible_child (new_server.get_parent ()); + this.newpane_add_button.clicked.connect(() => { + this.newpane_stack.set_visible_child(new_server.get_parent()); }); try { - var config = Footerm.Services.Config.get_instance (); + this.config = Footerm.Services.Config.get_instance(); - var stored_server_list = config.get_server_list (); + var stored_server_list = this.config.get_server_list(); foreach (var server in stored_server_list) { - var action_row = new Adw.ActionRow (); - action_row.set_title (server.name); - action_row.set_activatable (true); - action_row.activated.connect (() => { - this.on_server_selected (server); - }); - server_list.add (action_row); + this.server_list.add(this.build_action_row(server)); } } catch (Error e) { - GLib.warning ("Failed to read server list : %s", e.message); + GLib.warning("Failed to read server list : %s", e.message); } } + + private Adw.ActionRow build_action_row(Footerm.Model.Server server) { + var action_row = new Adw.ActionRow(); + action_row.set_title(server.name); + action_row.set_activatable(true); + action_row.activated.connect(() => { + this.on_server_selected(server); + }); + var delete_button = new Gtk.Button(); + delete_button.set_icon_name("edit-delete-symbolic"); + delete_button.set_valign(Gtk.Align.CENTER); + delete_button.add_css_class("edit-icon"); + delete_button.add_css_class("flat"); + delete_button.clicked.connect(() => { + this.config.delete_server.begin(server, (obj, res) => { + try { + this.config.delete_server.end(res); + this.server_list.remove(action_row); + } catch (Error e) { + // TODO WARN USER + warning("Failed to delete : %s", e.message); + } + }); + }); + action_row.add_suffix(delete_button); + return action_row; + } } } diff --git a/src/services/Config.vala b/src/services/Config.vala index 890e4a1..8f0be8f 100644 --- a/src/services/Config.vala +++ b/src/services/Config.vala @@ -160,7 +160,63 @@ namespace Footerm.Services { throw new ConfigError.DATABASE(@"Can't insert server: $(db.errcode ()): $(db.errmsg ())"); } - server.id = (int)this.db.last_insert_rowid(); - } + server.id = (int) this.db.last_insert_rowid(); + } + + public async void delete_server(Footerm.Model.Server server) throws ConfigError, SecretError, Error { + var stm_str = "SELECT COUNT(serverId) FROM SERVER WHERE serverHostName = ? AND serverPort = ? AND serverUsername = ? AND serverAuthentificationType = 'password'"; + Sqlite.Statement stm; + + var ec = this.db.prepare_v2(stm_str, stm_str.length, out stm); + if (ec != Sqlite.OK) { + throw new ConfigError.DATABASE(@"Can't delete server: $(db.errcode ()): $(db.errmsg ())"); + } + + ec = stm.bind_text(1, server.hostname); + if (ec != Sqlite.OK) { + throw new ConfigError.DATABASE(@"Can't delete server: $(db.errcode ()): $(db.errmsg ())"); + } + + ec = stm.bind_int(2, server.port); + if (ec != Sqlite.OK) { + throw new ConfigError.DATABASE(@"Can't delete server: $(db.errcode ()): $(db.errmsg ())"); + } + + ec = stm.bind_text(3, server.username); + if (ec != Sqlite.OK) { + throw new ConfigError.DATABASE(@"Can't delete server: $(db.errcode ()): $(db.errmsg ())"); + } + + ec = stm.step(); + if (ec != Sqlite.ROW) { + throw new ConfigError.DATABASE(@"Can't delete server: $(db.errcode ()): $(db.errmsg ())"); + } + + var delete_from_secret = stm.column_int(0) == 1; + stm.reset(); + + stm_str = "DELETE FROM SERVER WHERE serverId = ?"; + + ec = this.db.prepare_v2(stm_str, stm_str.length, out stm); + if (ec != Sqlite.OK) { + throw new ConfigError.DATABASE(@"Can't delete server: $(db.errcode ()): $(db.errmsg ())"); + } + + ec = stm.bind_int(1, server.id); + if (ec != Sqlite.OK) { + throw new ConfigError.DATABASE(@"Can't delete server: $(db.errcode ()): $(db.errmsg ())"); + } + + ec = stm.step(); + if (ec != Sqlite.DONE) { + throw new ConfigError.DATABASE(@"Can't delete server: $(db.errcode ()): $(db.errmsg ())"); + } + stm.reset(); + + if (delete_from_secret) { + var secrets = Secrets.get_instance(); + yield secrets.delete_password(server); + } + } } } diff --git a/src/services/Secrets.vala b/src/services/Secrets.vala index 6fb308c..63ce78f 100644 --- a/src/services/Secrets.vala +++ b/src/services/Secrets.vala @@ -64,5 +64,13 @@ namespace Footerm.Services { return yield Secret.password_lookupv(this.password_schema, attributes, null); } + + public async void delete_password(Footerm.Model.Server server) throws Error { + var attributes = new GLib.HashTable (str_hash, str_equal); + attributes["hostname"] = server.hostname; + attributes["port"] = server.port.to_string(); + attributes["username"] = server.username; + yield Secret.password_clearv(this.password_schema, attributes, null); + } } }