[gnome-keyring] [prompt] Restore state of prompt dialog on bad password.



commit d8c27671de495692816a9343dc03cb7ab7f3c87b
Author: Stef Walter <stef memberwebs com>
Date:   Sun Feb 7 16:22:36 2010 +0000

    [prompt] Restore state of prompt dialog on bad password.
    
    When the user types a bad password, all the other state
    of the prompt dialog should remain as selected.

 daemon/dbus/gkd-secret-change.c |    9 +++++----
 daemon/dbus/gkd-secret-create.c |    2 +-
 daemon/dbus/gkd-secret-unlock.c |   29 +++++++++++++++--------------
 daemon/prompt/gkd-prompt-tool.c |   24 ++++++++++++++++++++++++
 daemon/prompt/gkd-prompt.c      |   32 +++++++++++++++++++++++++++++---
 daemon/prompt/gkd-prompt.h      |    3 ++-
 6 files changed, 76 insertions(+), 23 deletions(-)
---
diff --git a/daemon/dbus/gkd-secret-change.c b/daemon/dbus/gkd-secret-change.c
index 35415ef..3dee7a7 100644
--- a/daemon/dbus/gkd-secret-change.c
+++ b/daemon/dbus/gkd-secret-change.c
@@ -56,7 +56,7 @@ G_DEFINE_TYPE (GkdSecretChange, gkd_secret_change, GKD_SECRET_TYPE_PROMPT);
  */
 
 static void
-prepare_change_prompt (GkdSecretChange *self, GP11Object *collection)
+prepare_change_prompt (GkdSecretChange *self, GP11Object *collection, gboolean first)
 {
 	GError *error = NULL;
 	GkdPrompt *prompt;
@@ -79,7 +79,8 @@ prepare_change_prompt (GkdSecretChange *self, GP11Object *collection)
 		label = g_strndup (data, n_data);
 	g_free (data);
 
-	gkd_prompt_reset (prompt);
+	/* Hard reset on first prompt, soft thereafter */
+	gkd_prompt_reset (prompt, first);
 
 	gkd_prompt_set_title (prompt, _("Change Keyring Password"));
 
@@ -131,7 +132,7 @@ gkd_secret_change_prompt_ready (GkdSecretPrompt *prompt)
 	}
 
 	if (!gkd_prompt_has_response (GKD_PROMPT (prompt))) {
-		prepare_change_prompt (self, collection);
+		prepare_change_prompt (self, collection, TRUE);
 		return;
 	}
 
@@ -149,7 +150,7 @@ gkd_secret_change_prompt_ready (GkdSecretPrompt *prompt)
 
 	/* The original password was incorrect */
 	} else if (dbus_error_has_name (&derr, INTERNAL_ERROR_DENIED)) {
-		prepare_change_prompt (self, collection);
+		prepare_change_prompt (self, collection, FALSE);
 		set_warning_wrong (self);
 
 	/* Other failures */
diff --git a/daemon/dbus/gkd-secret-create.c b/daemon/dbus/gkd-secret-create.c
index f5f1c68..8f0f71d 100644
--- a/daemon/dbus/gkd-secret-create.c
+++ b/daemon/dbus/gkd-secret-create.c
@@ -72,7 +72,7 @@ prepare_create_prompt (GkdSecretCreate *self)
 	if (!gp11_attributes_find_string (self->pkcs11_attrs, CKA_LABEL, &label))
 		label = g_strdup (_("Unnamed"));
 
-	gkd_prompt_reset (prompt);
+	gkd_prompt_reset (prompt, TRUE);
 
 	gkd_prompt_set_title (prompt, _("New Keyring Password"));
 	gkd_prompt_set_primary_text (prompt, _("Choose password for new keyring"));
diff --git a/daemon/dbus/gkd-secret-unlock.c b/daemon/dbus/gkd-secret-unlock.c
index f6f8f90..c50a1ce 100644
--- a/daemon/dbus/gkd-secret-unlock.c
+++ b/daemon/dbus/gkd-secret-unlock.c
@@ -131,8 +131,6 @@ prepare_unlock_login (GkdSecretUnlock *self)
 
 	prompt = GKD_PROMPT (self);
 
-	gkd_prompt_reset (prompt);
-
 	gkd_prompt_set_title (prompt, _("Unlock Login Keyring"));
 
 	text = _("Enter password for to unlock your login keyring");
@@ -150,7 +148,7 @@ prepare_unlock_login (GkdSecretUnlock *self)
 }
 
 static void
-prepare_unlock_prompt (GkdSecretUnlock *self, GP11Object *coll)
+prepare_unlock_prompt (GkdSecretUnlock *self, GP11Object *coll, gboolean first)
 {
 	GP11Attributes *template;
 	GP11Attributes *attrs;
@@ -165,6 +163,9 @@ prepare_unlock_prompt (GkdSecretUnlock *self, GP11Object *coll)
 
 	prompt = GKD_PROMPT (self);
 
+	/* Hard reset on first prompt, soft on later */
+	gkd_prompt_reset (GKD_PROMPT (prompt), first);
+
 	attrs = attributes_for_collection (coll);
 	g_return_if_fail (attrs);
 
@@ -179,8 +180,6 @@ prepare_unlock_prompt (GkdSecretUnlock *self, GP11Object *coll)
 	g_free (identifier);
 	label = label_string_for_attributes (attrs);
 
-	gkd_prompt_reset (prompt);
-
 	gkd_prompt_set_title (prompt, _("Unlock Keyring"));
 
 	text = g_markup_printf_escaped (_("Enter password for keyring '%s' to unlock"), label);
@@ -201,13 +200,15 @@ prepare_unlock_prompt (GkdSecretUnlock *self, GP11Object *coll)
 	g_free (label);
 
 	/* Setup the unlock options */
-	template = gp11_object_get_template (coll, CKA_G_CREDENTIAL_TEMPLATE, &error);
-	if (template) {
-		gkd_prompt_set_unlock_options (prompt, template);
-		gp11_attributes_unref (template);
-	} else {
-		g_warning ("couldn't get credential template for collection: %s", error->message);
-		g_clear_error (&error);
+	if (first) {
+		template = gp11_object_get_template (coll, CKA_G_CREDENTIAL_TEMPLATE, &error);
+		if (template) {
+			gkd_prompt_set_unlock_options (prompt, template);
+			gp11_attributes_unref (template);
+		} else {
+			g_warning ("couldn't get credential template for collection: %s", error->message);
+			g_clear_error (&error);
+		}
 	}
 }
 
@@ -385,7 +386,7 @@ gkd_secret_unlock_prompt_ready (GkdSecretPrompt *prompt)
 
 			/* Collection still locked, prompt again */
 			} else if (locked) {
-				prepare_unlock_prompt (self, coll);
+				prepare_unlock_prompt (self, coll, FALSE);
 				set_warning_wrong (self);
 
 			/* Collection not locked, done with this one */
@@ -426,7 +427,7 @@ gkd_secret_unlock_prompt_ready (GkdSecretPrompt *prompt)
 			continue;
 		}
 
-		prepare_unlock_prompt (self, coll);
+		prepare_unlock_prompt (self, coll, TRUE);
 		g_object_unref (coll);
 		self->current = objpath;
 	}
diff --git a/daemon/prompt/gkd-prompt-tool.c b/daemon/prompt/gkd-prompt-tool.c
index 5512295..b98de97 100644
--- a/daemon/prompt/gkd-prompt-tool.c
+++ b/daemon/prompt/gkd-prompt-tool.c
@@ -341,6 +341,17 @@ prepare_lock (GtkBuilder *builder, GtkDialog *dialog)
 	              NULL);
 }
 
+static void
+prepare_details (GtkBuilder *builder, GtkDialog *dialog)
+{
+	GtkExpander *expander;
+	gboolean expanded;
+
+	expander = GTK_EXPANDER (gtk_builder_get_object (builder, "details_area"));
+	expanded = g_key_file_get_boolean (input_data, "details", "expanded", NULL);
+	gtk_expander_set_expanded (expander, expanded);
+}
+
 static GtkDialog*
 prepare_dialog (GtkBuilder *builder)
 {
@@ -364,6 +375,7 @@ prepare_dialog (GtkBuilder *builder)
 	prepare_passwords (builder, dialog);
 	prepare_security (builder, dialog);
 	prepare_lock (builder, dialog);
+	prepare_details (builder, dialog);
 
 	return dialog;
 }
@@ -574,12 +586,24 @@ gather_unlock_options (GtkBuilder *builder, GtkDialog *dialog)
 }
 
 static void
+gather_details (GtkBuilder *builder, GtkDialog *dialog)
+{
+	GtkExpander *expander;
+
+	expander = GTK_EXPANDER (gtk_builder_get_object (builder, "details_area"));
+	g_key_file_set_boolean (output_data, "details", "expanded",
+	                        gtk_expander_get_expanded (expander));
+}
+
+
+static void
 gather_dialog (GtkBuilder *builder, GtkDialog *dialog)
 {
 	gather_password (builder, "password");
 	gather_password (builder, "confirm");
 	gather_password (builder, "original");
 	gather_unlock_options (builder, dialog);
+	gather_details (builder, dialog);
 }
 
 static void
diff --git a/daemon/prompt/gkd-prompt.c b/daemon/prompt/gkd-prompt.c
index a704bfc..a8281f3 100644
--- a/daemon/prompt/gkd-prompt.c
+++ b/daemon/prompt/gkd-prompt.c
@@ -80,6 +80,14 @@ G_DEFINE_TYPE (GkdPrompt, gkd_prompt, G_TYPE_OBJECT);
 /* Forward declaration*/
 static void display_async_prompt (GkdPrompt *);
 
+/* User choices we transfer over during a soft prompt reset */
+const struct { const gchar *section; const gchar *name; } SOFT_RESET[] = {
+	{ "unlock-options", "unlock-auto"},
+	{ "unlock-options", "unlock-idle"},
+	{ "unlock-options", "unlock-timeout"},
+	{ "details", "expanded" },
+};
+
 /* -----------------------------------------------------------------------------
  * INTERNAL
  */
@@ -516,7 +524,7 @@ static void
 gkd_prompt_init (GkdPrompt *self)
 {
 	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GKD_TYPE_PROMPT, GkdPromptPrivate);
-	gkd_prompt_reset (self);
+	gkd_prompt_reset (self, TRUE);
 }
 
 static void
@@ -743,15 +751,33 @@ gkd_prompt_set_warning (GkdPrompt *self, const gchar *warning)
 }
 
 void
-gkd_prompt_reset (GkdPrompt *self)
+gkd_prompt_reset (GkdPrompt *self, gboolean hard)
 {
+	GKeyFile *input;
+	gchar *value;
+	gint i;
+
 	g_return_if_fail (GKD_IS_PROMPT (self));
 
 	kill_process (self);
 	self->pv->pid = 0;
 
+	input = g_key_file_new ();
+
+	/* If not a hard reset, copy over some user data */
+	if (!hard && self->pv->output) {
+		for (i = 0; i < G_N_ELEMENTS (SOFT_RESET); ++i) {
+			value = g_key_file_get_value (self->pv->output, SOFT_RESET[i].section,
+			                              SOFT_RESET[i].name, NULL);
+			if (value != NULL)
+				g_key_file_set_value (input, SOFT_RESET[i].section,
+				                      SOFT_RESET[i].name, value);
+			g_free (value);
+		}
+	}
+
 	clear_prompt_data (self);
-	self->pv->input = g_key_file_new ();
+	self->pv->input = input;
 }
 
 
diff --git a/daemon/prompt/gkd-prompt.h b/daemon/prompt/gkd-prompt.h
index df0a9c5..9910a9f 100644
--- a/daemon/prompt/gkd-prompt.h
+++ b/daemon/prompt/gkd-prompt.h
@@ -62,7 +62,8 @@ GType               gkd_prompt_get_type               (void);
 
 GkdPrompt*          gkd_prompt_new                    (void);
 
-void                gkd_prompt_reset                  (GkdPrompt *prompt);
+void                gkd_prompt_reset                  (GkdPrompt *prompt,
+                                                       gboolean hard);
 
 void                gkd_prompt_set_title              (GkdPrompt *prompt,
                                                        const gchar *title);



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