[libgnome-keyring] Can create a new default keyring when creating item.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgnome-keyring] Can create a new default keyring when creating item.
- Date: Thu, 18 Feb 2010 17:21:37 +0000 (UTC)
commit 5e37e8cc09712fd8cab60e42636f260f23bacd7e
Author: Stef Walter <stef memberwebs com>
Date: Thu Feb 18 17:18:48 2010 +0000
Can create a new default keyring when creating item.
When no default keyring exists, and creating an item, and
the default keyring was the desired keyring for the item,
prompt to create a new default keyring.
This mirrors the behavior in the old gnome-keyring-daemon.
However this functionality has now been moved to the library.
.gitignore | 1 +
library/gnome-keyring.c | 180 ++++++++++++++++++++++++++++++++++-----
library/tests/Makefile.am | 18 ++++
library/tests/test-prompting.c | 59 +++++++++++++
4 files changed, 235 insertions(+), 23 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index ce7365b..ae0096b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -111,6 +111,7 @@ run-auto-test.h
# /library/tests
/library/tests/Makefile
/library/tests/Makefile.in
+/library/tests/test-prompting
# /po
/po/*.gmo
diff --git a/library/gnome-keyring.c b/library/gnome-keyring.c
index 8931fe5..92dcef5 100644
--- a/library/gnome-keyring.c
+++ b/library/gnome-keyring.c
@@ -2407,6 +2407,7 @@ gnome_keyring_find_itemsv_sync (GnomeKeyringItemType type,
typedef struct _item_create_args {
DBusMessage *request;
DBusMessageIter iter;
+ gboolean is_default;
gboolean update_if_exists;
gchar *secret;
} item_create_args;
@@ -2463,17 +2464,11 @@ item_create_prepare (const gchar *path, GnomeKeyringItemType type, const gchar *
return req;
}
-static gboolean
-item_create_check_unlock (const char *path, gpointer user_data)
-{
- gboolean *unlocked = user_data;
- *unlocked = TRUE;
- return FALSE;
-}
-
static void
-item_create_4_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
+item_create_3_created_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
{
+ /* Called after trying to create item */
+
const char *path;
const char *prompt;
guint32 id;
@@ -2496,8 +2491,10 @@ item_create_4_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
}
static void
-item_create_3_reply (GkrOperation *op, GkrSession *session, gpointer data)
+item_create_2_session_reply (GkrOperation *op, GkrSession *session, gpointer data)
{
+ /* Called after we have a session, start creating item */
+
item_create_args *args = data;
dbus_bool_t replace;
@@ -2509,14 +2506,130 @@ item_create_3_reply (GkrOperation *op, GkrSession *session, gpointer data)
replace = args->update_if_exists;
dbus_message_iter_append_basic (&args->iter, DBUS_TYPE_BOOLEAN, &replace);
- gkr_operation_push (op, item_create_4_reply, GKR_CALLBACK_OP_MSG, NULL, NULL);
+ gkr_operation_push (op, item_create_3_created_reply, GKR_CALLBACK_OP_MSG, NULL, NULL);
+ gkr_operation_set_keyring_hint (op);
gkr_operation_request (op, args->request);
}
static void
-item_create_2_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
+item_create_2_session_request (GkrOperation *op, gpointer data)
{
- item_create_args *args = data;
+ /* Called to get us a valid session */
+
+ gkr_operation_push (op, item_create_2_session_reply, GKR_CALLBACK_OP_SESSION, data, NULL);
+ gkr_session_negotiate (op);
+}
+
+static void
+item_create_1_default_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
+{
+ /* Called after setting newly created keyring to default */
+
+ if (gkr_operation_handle_errors (op, reply))
+ return;
+
+ item_create_2_session_request (op, data);
+}
+
+static void
+item_create_1_default_request (GkrOperation *op, const gchar *path, gpointer data)
+{
+ /* Called to request setting newly created keyring to default */
+
+ DBusMessage *req;
+ const char *string;
+
+ req = dbus_message_new_method_call (gkr_service_name (), SERVICE_PATH,
+ SERVICE_INTERFACE, "SetAlias");
+
+ string = "default";
+ dbus_message_append_args (req, DBUS_TYPE_STRING, &string,
+ DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
+
+ gkr_operation_push (op, item_create_1_default_reply, GKR_CALLBACK_OP_MSG, data, NULL);
+ gkr_operation_set_keyring_hint (op);
+ gkr_operation_request (op, req);
+ dbus_message_unref (req);
+}
+
+static void
+item_create_1_create_prompt_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
+{
+ /* Called after prompting to create default collection for item */
+
+ DBusMessageIter iter, variant;
+ const char *path;
+
+ if (gkr_operation_handle_errors (op, reply))
+ return;
+
+ if (!dbus_message_has_signature (reply, "bv")) {
+ gkr_operation_complete (op, decode_invalid_response (reply));
+ return;
+ }
+
+ /* Skip over dismissed, already parsed */
+ if (!dbus_message_iter_init (reply, &iter) ||
+ !dbus_message_iter_next (&iter))
+ g_return_if_reached ();
+
+ /* Dig out the variant */
+ dbus_message_iter_recurse (&iter, &variant);
+ if (!g_str_equal (dbus_message_iter_get_signature (&variant), "o")) {
+ gkr_operation_complete (op, decode_invalid_response (reply));
+ return;
+ }
+
+ g_return_if_fail (dbus_message_iter_get_arg_type (&variant) == DBUS_TYPE_OBJECT_PATH);
+ dbus_message_iter_get_basic (&variant, &path);
+
+ /* Set this keyring as the default keyring */
+ item_create_1_default_request (op, path, data);
+}
+
+static void
+item_create_1_collection_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
+{
+ /* Called after trying to create default collection to create item in */
+
+ const char *collection;
+ const char *prompt;
+
+ if (gkr_operation_handle_errors (op, reply))
+ return;
+
+ /* Parse the response */
+ if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_OBJECT_PATH, &collection,
+ DBUS_TYPE_OBJECT_PATH, &prompt, DBUS_TYPE_INVALID)) {
+ g_warning ("bad response to CreateCollection from service");
+ gkr_callback_invoke_res (gkr_operation_pop (op), GNOME_KEYRING_RESULT_IO_ERROR);
+ return;
+ }
+
+ /* No prompt, set keyring as default */
+ g_return_if_fail (prompt);
+ if (g_str_equal (prompt, "/")) {
+ item_create_1_default_request (op, collection, data);
+
+ /* A prompt, display it get the response */
+ } else {
+ gkr_operation_push (op, item_create_1_create_prompt_reply, GKR_CALLBACK_OP_MSG, data, NULL);
+ gkr_operation_prompt (op, prompt);
+ }
+}
+
+static gboolean
+item_create_check_unlock (const char *path, gpointer user_data)
+{
+ gboolean *unlocked = user_data;
+ *unlocked = TRUE;
+ return FALSE;
+}
+
+static void
+item_create_1_unlock_prompt_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
+{
+ /* Called after unlocking the collection we're going to create item in */
gboolean dismissed = FALSE;
gboolean unlocked = FALSE;
@@ -2531,15 +2644,18 @@ item_create_2_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
}
/* Now that its unlocked, we need a session to transfer the secret */
- gkr_operation_push (op, item_create_3_reply, GKR_CALLBACK_OP_SESSION, args, NULL);
- gkr_session_negotiate (op);
+ item_create_2_session_request (op, data);
}
static void
-item_create_1_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
+item_create_1_unlock_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
{
+ /* Called after trying to unlock keyring we're going to create item in */
+
item_create_args *args = data;
- gboolean unlocked;
+ DBusMessageIter iter;
+ DBusMessage *req;
+ gboolean unlocked = FALSE;
const char *prompt;
if (gkr_operation_handle_errors (op, reply))
@@ -2552,13 +2668,30 @@ item_create_1_reply (GkrOperation *op, DBusMessage *reply, gpointer data)
/* Prompt to unlock the collection */
if (!g_str_equal (prompt, "/")) {
- gkr_operation_push (op, item_create_2_reply, GKR_CALLBACK_OP_MSG, args, NULL);
+ gkr_operation_push (op, item_create_1_unlock_prompt_reply, GKR_CALLBACK_OP_MSG, args, NULL);
gkr_operation_prompt (op, prompt);
- /* We need a session to transfer the secret */
+ /* No such keyring, no prompt, and not unlocked */
+ } else if (!unlocked) {
+
+ /* Caller asked for default keyring, and there is no such keyring. Create */
+ if (args->is_default) {
+ req = dbus_message_new_method_call (gkr_service_name (), SERVICE_PATH,
+ SERVICE_INTERFACE, "CreateCollection");
+ dbus_message_iter_init_append (req, &iter);
+ create_keyring_encode_properties (&iter, "default");
+ gkr_operation_push (op, item_create_1_collection_reply, GKR_CALLBACK_OP_MSG, args, NULL);
+ gkr_operation_request (op, req);
+ dbus_message_unref (req);
+
+ /* No such keyring, error */
+ } else {
+ gkr_operation_complete (op, GNOME_KEYRING_RESULT_NO_SUCH_KEYRING);
+ }
+
+ /* Successfully unlocked, or not locked. We need a session to transfer the secret */
} else {
- gkr_operation_push (op, item_create_3_reply, GKR_CALLBACK_OP_SESSION, args, NULL);
- gkr_session_negotiate (op);
+ item_create_2_session_request (op, args);
}
}
@@ -2616,6 +2749,7 @@ gnome_keyring_item_create (const char *keyring,
args = g_slice_new0 (item_create_args);
args->update_if_exists = update_if_exists;
args->secret = egg_secure_strdup (secret);
+ args->is_default = (keyring == NULL);
path = gkr_encode_keyring_name (keyring);
args->request = item_create_prepare (path, type, display_name, attributes, &args->iter);
@@ -2626,7 +2760,7 @@ gnome_keyring_item_create (const char *keyring,
g_free (path);
op = gkr_operation_new (callback, GKR_CALLBACK_RES_UINT, data, destroy_data);
- gkr_operation_push (op, item_create_1_reply, GKR_CALLBACK_OP_MSG, args, item_create_free);
+ gkr_operation_push (op, item_create_1_unlock_reply, GKR_CALLBACK_OP_MSG, args, item_create_free);
gkr_operation_set_keyring_hint (op);
gkr_operation_request (op, req);
gkr_operation_unref (op);
@@ -4379,7 +4513,7 @@ find_password_1_reply (GkrOperation *op, const char *path, gpointer user_data)
/* All done, complete the operation here */
if (path == NULL) {
cb = gkr_operation_pop (op);
- gkr_callback_invoke_ok_string (cb, NULL);
+ gkr_callback_invoke_res (cb, GNOME_KEYRING_RESULT_NO_MATCH);
/* We need a session to get the secret for this item */
} else {
diff --git a/library/tests/Makefile.am b/library/tests/Makefile.am
index 62634a9..3605fa1 100644
--- a/library/tests/Makefile.am
+++ b/library/tests/Makefile.am
@@ -10,3 +10,21 @@ UNIT_LIBS = \
$(top_builddir)/library/libgnome-keyring.la
include $(top_srcdir)/tests/gtest.make
+
+# ------------------------------------------------------------------
+
+noinst_PROGRAMS += \
+ test-prompting
+
+test_prompting_SOURCES = \
+ test-prompting.c
+
+test_prompting_CFLAGS = \
+ $(GLIB_CFLAGS)
+
+test_prompting_LDADD = \
+ $(top_builddir)/library/libgnome-keyring.la \
+ $(GLIB_LIBS)
+
+EXTRA_DIST = \
+ test-data
\ No newline at end of file
diff --git a/library/tests/test-prompting.c b/library/tests/test-prompting.c
new file mode 100644
index 0000000..bfba694
--- /dev/null
+++ b/library/tests/test-prompting.c
@@ -0,0 +1,59 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* unit-test-other.c: Test some prompts
+
+ Copyright (C) 2010 Stefan Walter
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stef memberwebs com>
+*/
+
+#include "config.h"
+#include "gnome-keyring.h"
+
+#include <glib.h>
+
+static int
+test_create_item (void)
+{
+ GnomeKeyringResult res;
+ guint32 item_id;
+
+ res = gnome_keyring_item_create_sync (NULL, GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ "Test Create Prompt Item", NULL, "secret", FALSE, &item_id);
+
+ if (res == GNOME_KEYRING_RESULT_CANCELLED)
+ g_printerr ("creating item cancelled\n");
+ else if (res != GNOME_KEYRING_RESULT_OK)
+ g_printerr ("creating item failed: %s", gnome_keyring_result_to_message (res));
+ else
+ g_print ("item id: %u", (guint)item_id);
+
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ if (argc == 2) {
+ if (g_str_equal (argv[1], "--create-item")) {
+ return test_create_item ();
+ }
+ }
+
+ g_printerr ("usage: test-prompting --create-item\n");
+ return 2;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]