[seahorse/wip/nielsdg/copy-secret] gkr: Allow copying secret with right click



commit f2ad28d77088d639d7fa9572b5cff29ca1e60e5a
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Mon Jul 13 17:59:30 2020 +0200

    gkr: Allow copying secret with right click
    
    https://gitlab.gnome.org/GNOME/seahorse/-/issues/229

 gkr/gkr-backend.vala                | 32 +++++++++++++++++++
 gkr/gkr-item-properties.vala        | 10 +-----
 gkr/gkr-item.vala                   | 63 +++++++++++++++++++++++++++----------
 src/seahorse-key-manager-widgets.ui |  6 ++++
 4 files changed, 85 insertions(+), 26 deletions(-)
---
diff --git a/gkr/gkr-backend.vala b/gkr/gkr-backend.vala
index ad70bf6c..6f9b3fa5 100644
--- a/gkr/gkr-backend.vala
+++ b/gkr/gkr-backend.vala
@@ -215,6 +215,7 @@ public class BackendActions : Seahorse.ActionGroup {
     private const ActionEntry[] BACKEND_ACTIONS = {
         { "keyring-new",      on_new_keyring },
         { "keyring-item-new", on_new_item    },
+        { "copy-secret",      on_copy_secret },
     };
 
        construct {
@@ -260,6 +261,37 @@ public class BackendActions : Seahorse.ActionGroup {
         dialog.destroy();
     }
 
+    private void on_copy_secret(SimpleAction action, Variant? param) {
+        return_if_fail (this.catalog != null);
+
+        var selected = this.catalog.get_selected_objects();
+        // We checked for this in set_actions_for_selected_objects()
+        return_if_fail (selected.length() == 1);
+
+        var selected_item = selected.data as Gkr.Item;
+        return_if_fail (selected_item != null);
+
+        var clipboard = Gtk.Clipboard.get_default(this.catalog.get_display());
+        selected_item.copy_secret_to_clipboard.begin(clipboard, (obj, res) => {
+            try {
+                selected_item.copy_secret_to_clipboard.end(res);
+            } catch (GLib.Error e) {
+                Util.show_error(this.catalog, "Couldn't copy secret", e.message);
+            }
+        });
+    }
+
+    public override void set_actions_for_selected_objects(List<GLib.Object> objects) {
+        // Allow "copy secret" if there is only 1 Gkr.Item selected
+        bool can_copy_secret = false;
+
+        if (objects.length() == 1) {
+            can_copy_secret = objects.data is Gkr.Item;
+        }
+
+        ((SimpleAction) lookup_action("copy-secret")).set_enabled(can_copy_secret);
+    }
+
        public static ActionGroup instance(Backend backend) {
                BackendActions? actions = (BackendActions?)_instance.get();
                if (actions != null)
diff --git a/gkr/gkr-item-properties.vala b/gkr/gkr-item-properties.vala
index a26ec2f7..f809f592 100644
--- a/gkr/gkr-item-properties.vala
+++ b/gkr/gkr-item-properties.vala
@@ -236,16 +236,8 @@ public class Seahorse.Gkr.ItemProperties : Gtk.Dialog {
 
     [GtkCallback]
     private void on_copy_button_clicked() {
-        var secret = this.item.get_secret();
-        if (secret == null)
-            return;
-
-        unowned string? password = secret.get_text();
-        if (password == null)
-            return;
-
         var clipboard = Gtk.Clipboard.get_default(this.get_display());
-        clipboard.set_text(password, -1);
+        this.item.copy_secret_to_clipboard.begin(clipboard);
     }
 
     [GtkCallback]
diff --git a/gkr/gkr-item.vala b/gkr/gkr-item.vala
index dbed30eb..79d31f41 100644
--- a/gkr/gkr-item.vala
+++ b/gkr/gkr-item.vala
@@ -192,31 +192,43 @@ public class Item : Secret.Item, Deletable, Viewable {
         return new ItemInfo(label, attrs);
     }
 
-    private void load_item_secret() {
-        if (this._req_secret == null) {
-            this._req_secret = new GLib.Cancellable();
-            load_secret.begin(this._req_secret, (obj, res) => {
-                try {
-                    this._req_secret = null;
-                    load_secret.end(res);
-                    this._item_secret = base.get_secret();
-                    notify_property("has-secret");
-                } catch (GLib.Error err) {
-                    GLib.warning("Couldn't retrieve secret: %s", err.message);
-                }
-            });
-        }
+    private async void load_item_secret() throws GLib.Error {
+        if (this._req_secret != null)
+            return;
+
+        this._req_secret = new GLib.Cancellable();
+
+        yield load_secret(this._req_secret);
+        this._req_secret = null;
+        this._item_secret = base.get_secret();
+        notify_property("has-secret");
     }
 
     public new void refresh() {
         base.refresh();
+
         if (this._item_secret != null)
-            load_item_secret();
+            return;
+
+        load_item_secret.begin((obj, res) => {
+            try {
+                load_item_secret.end(res);
+            } catch (GLib.Error e) {
+                warning("Couldn't load secret: %s", e.message);
+            }
+        });
     }
 
     public new Secret.Value? get_secret() {
-        if (this._item_secret == null)
-            load_item_secret();
+        if (this._item_secret == null) {
+            load_item_secret.begin((obj, res) => {
+                try {
+                    load_item_secret.end(res);
+                } catch (GLib.Error e) {
+                    warning("Couldn't load secret: %s", e.message);
+                }
+            });
+        }
         return this._item_secret;
     }
 
@@ -233,6 +245,23 @@ public class Item : Secret.Item, Deletable, Viewable {
         notify_property("has-secret");
         return true;
     }
+
+    public async void copy_secret_to_clipboard(Gtk.Clipboard clipboard) throws GLib.Error {
+        if (this._item_secret == null)
+            yield load_item_secret();
+
+        if (this._item_secret == null) {
+            debug("Can't copy to clipboard: secret is NULL");
+            return;
+        }
+
+        unowned string? password = this._item_secret.get_text();
+        if (password == null)
+            return;
+
+        clipboard.set_text(password, -1);
+        debug("Succesfully copied secret to clipboard");
+    }
 }
 
 private const string GENERIC_SECRET = "org.freedesktop.Secret.Generic";
diff --git a/src/seahorse-key-manager-widgets.ui b/src/seahorse-key-manager-widgets.ui
index c27ba8bf..7382118b 100644
--- a/src/seahorse-key-manager-widgets.ui
+++ b/src/seahorse-key-manager-widgets.ui
@@ -2,6 +2,12 @@
 <interface>
   <menu id="context_menu">
     <section>
+      <item>
+        <!-- Translators: This is only relevant for "Password" items -->
+        <attribute name="label" translatable="yes">Copy secret</attribute>
+        <attribute name="action">gkr.copy-secret</attribute>
+        <attribute name="hidden-when">action-disabled</attribute>
+      </item>
       <item>
         <attribute name="label" translatable="yes">Export…</attribute>
         <attribute name="action">win.file-export</attribute>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]