[gnome-boxes/remember-passwords] machine: Remember user credentials
- From: Felipe Borges <felipeborges src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-boxes/remember-passwords] machine: Remember user credentials
- Date: Wed, 17 Jan 2018 14:10:45 +0000 (UTC)
commit 2f51e00d0faf818099b86c671fca733918f33da9
Author: Felipe Borges <felipeborges gnome org>
Date: Wed Jan 17 13:56:14 2018 +0100
machine: Remember user credentials
It is quite inconvenient -- specially for remote machines -- having
to enter username and/or password every time we connect to the
display.
We can store this data safely in the system keyring using libsecret,
which is already a dependency added in commit 9d99c5a.
Fixes #67
src/machine.vala | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 76 insertions(+), 7 deletions(-)
---
diff --git a/src/machine.vala b/src/machine.vala
index 677101a7..dbb93d8d 100644
--- a/src/machine.vala
+++ b/src/machine.vala
@@ -20,6 +20,12 @@
public bool can_delete { get; set; default = true; }
public bool under_construction { get; protected set; default = false; }
+ private Cancellable auth_cancellable = new Cancellable ();
+ private Secret.Schema secret_auth_schema
+ = new Secret.Schema ("org.gnome.Boxes",
+ Secret.SchemaFlags.NONE,
+ "gnome-boxes-machine-uuid", Secret.SchemaAttributeType.STRING);
+
public signal void got_error (string message);
protected virtual bool should_autosave {
@@ -592,6 +598,9 @@ private void ui_state_changed () {
auth_notification.dismiss ();
disconnect_display ();
+ auth_cancellable.cancel ();
+ auth_cancellable = new Cancellable ();
+
break;
}
}
@@ -618,6 +627,34 @@ private async void try_connect_display (ConnectFlags flags = ConnectFlags.NONE)
}
}
+ private void store_auth_credentials () {
+ if (this.password == "" || this.password == null)
+ return;
+
+ var builder = new GLib.VariantBuilder (GLib.VariantType.VARDICT);
+
+ if (this.username != null)
+ builder.add ("{sv}", "username", new GLib.Variant ("s", this.username));
+
+ builder.add ("{sv}", "password", new GLib.Variant ("s", this.password));
+
+ var credentials_str = builder.end ().print (true);
+
+ var label = ("GNOME Boxes credentials for '%s'").printf (config.uuid);
+ Secret.password_store.begin (secret_auth_schema,
+ Secret.COLLECTION_DEFAULT,
+ label,
+ credentials_str,
+ null,
+ (obj, res) => {
+ try {
+ Secret.password_store.end (res);
+ } catch (GLib.Error error) {
+ warning ("Failed to store password for '%s' in the keyring: %s", config.uuid, error.message);
+ }
+ }, "gnome-boxes-machine-uuid", config.uuid);
+ }
+
private Boxes.AuthNotification auth_notification;
private void handle_auth () {
@@ -634,20 +671,52 @@ private void handle_auth () {
if (password != "")
this.password = password;
- auth_notification = null;
try_connect_display.begin ();
+
+ /* Maybe this can be an optional preference with a toggle in the UI. */
+ store_auth_credentials ();
};
+
Notification.DismissFunc dismiss_func = () => {
auth_notification = null;
window.set_state (UIState.COLLECTION);
};
- // Translators: %s => name of launched box
- var auth_string = _("ā%sā requires authentication").printf (name);
- auth_notification = window.notificationbar.display_for_auth (auth_string,
- (owned) auth_func,
- (owned) dismiss_func,
- need_username);
+ Secret.password_lookup.begin (secret_auth_schema, auth_cancellable, (obj, res) => {
+ try {
+ var parsing_error = new Boxes.Error.INVALID ("couldn't unpack a string for the machine
credentials");
+ var credentials_str = Secret.password_lookup.end (res);
+ if (credentials_str == null || credentials_str == "")
+ throw parsing_error;
+
+ try {
+ var credentials_variant = GLib.Variant.parse (null, credentials_str, null, null);
+
+ string username_str;
+ credentials_variant.lookup ("username", "s", out username_str);
+ if (username_str != null && username_str != "")
+ this.username = username_str;
+
+ string password_str;
+ credentials_variant.lookup ("password", "s", out password_str);
+ if (password_str != null && password_str != "")
+ this.password = password_str;
+
+ try_connect_display.begin ();
+ } catch (GLib.Error error) {
+ throw parsing_error;
+ }
+ } catch (GLib.Error error) {
+ debug ("No credentials found in keyring. Prompting user.");
+
+ // Translators: %s => name of launched box
+ var auth_string = _("ā%sā requires authentication").printf (name);
+ auth_notification = window.notificationbar.display_for_auth (auth_string,
+ (owned) auth_func,
+ (owned) dismiss_func,
+ need_username);
+ }
+ }, "gnome-boxes-machine-uuid", config.uuid);
}
public override int compare (CollectionItem other) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]