[gnome-keyring] dbus: Only return one object path list from Collection.SearchItems()



commit ddb87ccad91a6ee0591439b40cbf199123a394c7
Author: Stef Walter <stefw gnome org>
Date:   Mon Mar 4 12:41:45 2013 +0100

    dbus: Only return one object path list from Collection.SearchItems()
    
    In the Secret Service dbus interface the SearchItems method
    of the Collection interface only returns one list of object
    paths, unlike SearchItems on the Service interface which
    splits its return values by locked and unlocked items.
    
    Add tests to verify this behavior.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=695115

 .gitignore                             |    5 +-
 daemon/dbus/gkd-secret-objects.c       |   38 +++--
 daemon/dbus/gkd-secret-objects.h       |    3 +-
 daemon/dbus/gkd-secret-service.c       |    2 +-
 daemon/dbus/tests/Makefile.am          |    1 +
 daemon/dbus/tests/test-secret-search.c |  263 ++++++++++++++++++++++++++++++++
 6 files changed, 293 insertions(+), 19 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index d487041..ce2595a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -105,7 +105,8 @@ p11-tests.conf
 /daemon/control/tests/frob-control-quit
 /daemon/control/tests/frob-control-unlock
 
-/daemon/dbus/tests/test-secret-signals
+/daemon/dbus/tests/test-secret-*
+!/daemon/dbus/tests/test-secret-*.c
 
 /pkcs11/gkm/tests/test-attributes
 /pkcs11/gkm/tests/test-certificate
@@ -162,8 +163,6 @@ p11-tests.conf
 /pkcs11/xdg-store/tests/test-xdg-module
 /pkcs11/xdg-store/tests/test-xdg-trust
 
-/daemon/dbus/tests/test-secret-util
-
 /ui/gnome-keyring-prompt.desktop
 /ui/gnome-keyring-prompt.desktop.in
 /ui/tests/test-util
diff --git a/daemon/dbus/gkd-secret-objects.c b/daemon/dbus/gkd-secret-objects.c
index b42c7be..7551521 100644
--- a/daemon/dbus/gkd-secret-objects.c
+++ b/daemon/dbus/gkd-secret-objects.c
@@ -542,7 +542,7 @@ collection_property_getall (GkdSecretObjects *self, GckObject *object, DBusMessa
 static DBusMessage*
 collection_method_search_items (GkdSecretObjects *self, GckObject *object, DBusMessage *message)
 {
-       return gkd_secret_objects_handle_search_items (self, message, dbus_message_get_path (message));
+       return gkd_secret_objects_handle_search_items (self, message, dbus_message_get_path (message), FALSE);
 }
 
 static GckObject*
@@ -1314,8 +1314,10 @@ gkd_secret_objects_append_collection_paths (GkdSecretObjects *self,
 }
 
 DBusMessage*
-gkd_secret_objects_handle_search_items (GkdSecretObjects *self, DBusMessage *message,
-                                        const gchar *base)
+gkd_secret_objects_handle_search_items (GkdSecretObjects *self,
+                                        DBusMessage *message,
+                                        const gchar *base,
+                                        gboolean separate_locked)
 {
        GckBuilder builder = GCK_BUILDER_INIT;
        DBusMessageIter iter;
@@ -1385,23 +1387,31 @@ gkd_secret_objects_handle_search_items (GkdSecretObjects *self, DBusMessage *mes
        items = gck_objects_from_handle_array (session, data, n_data / sizeof (CK_OBJECT_HANDLE));
        g_free (data);
 
-       /* Filter out the locked items */
-       item_cleanup_search_results (session, items, &locked, &unlocked);
-
        /* Prepare the reply message */
        reply = dbus_message_new_method_return (message);
        dbus_message_iter_init_append (reply, &iter);
 
-       dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "o", &array);
-       objects_foreach_item (self, unlocked, NULL, on_object_path_append_to_iter, &array);
-       dbus_message_iter_close_container (&iter, &array);
+       /* Filter out the locked items */
+       if (separate_locked) {
+               item_cleanup_search_results (session, items, &locked, &unlocked);
 
-       dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "o", &array);
-       objects_foreach_item (self, locked, NULL, on_object_path_append_to_iter, &array);
-       dbus_message_iter_close_container (&iter, &array);
+               dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "o", &array);
+               objects_foreach_item (self, unlocked, NULL, on_object_path_append_to_iter, &array);
+               dbus_message_iter_close_container (&iter, &array);
+
+               dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "o", &array);
+               objects_foreach_item (self, locked, NULL, on_object_path_append_to_iter, &array);
+               dbus_message_iter_close_container (&iter, &array);
+
+               g_list_free (locked);
+               g_list_free (unlocked);
+
+       } else {
+               dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "o", &array);
+               objects_foreach_item (self, items, NULL, on_object_path_append_to_iter, &array);
+               dbus_message_iter_close_container (&iter, &array);
+       }
 
-       g_list_free (locked);
-       g_list_free (unlocked);
        gck_list_unref_free (items);
 
        return reply;
diff --git a/daemon/dbus/gkd-secret-objects.h b/daemon/dbus/gkd-secret-objects.h
index bd7f1aa..01da4d3 100644
--- a/daemon/dbus/gkd-secret-objects.h
+++ b/daemon/dbus/gkd-secret-objects.h
@@ -55,7 +55,8 @@ DBusMessage*        gkd_secret_objects_dispatch                  (GkdSecretObjec
 
 DBusMessage*        gkd_secret_objects_handle_search_items       (GkdSecretObjects *self,
                                                                   DBusMessage *message,
-                                                                  const gchar *base);
+                                                                  const gchar *base,
+                                                                  gboolean separate_locked);
 
 DBusMessage*        gkd_secret_objects_handle_get_secrets        (GkdSecretObjects *self,
                                                                   DBusMessage *message);
diff --git a/daemon/dbus/gkd-secret-service.c b/daemon/dbus/gkd-secret-service.c
index 6319f5c..11cdb60 100644
--- a/daemon/dbus/gkd-secret-service.c
+++ b/daemon/dbus/gkd-secret-service.c
@@ -913,7 +913,7 @@ service_message_handler (GkdSecretService *self, DBusMessage *message)
 
        /* org.freedesktop.Secret.Service.SearchItems() */
        if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "SearchItems"))
-               return gkd_secret_objects_handle_search_items (self->objects, message, NULL);
+               return gkd_secret_objects_handle_search_items (self->objects, message, NULL, TRUE);
 
        /* org.freedesktop.Secret.Service.GetSecrets() */
        if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "GetSecrets"))
diff --git a/daemon/dbus/tests/Makefile.am b/daemon/dbus/tests/Makefile.am
index 0cf22ac..482bf49 100644
--- a/daemon/dbus/tests/Makefile.am
+++ b/daemon/dbus/tests/Makefile.am
@@ -20,6 +20,7 @@ LDADD =  \
 
 TEST_PROGS = \
        test-secret-util \
+       test-secret-search \
        test-secret-signals
 
 check_PROGRAMS = $(TEST_PROGS)
diff --git a/daemon/dbus/tests/test-secret-search.c b/daemon/dbus/tests/test-secret-search.c
new file mode 100644
index 0000000..1a6b55e
--- /dev/null
+++ b/daemon/dbus/tests/test-secret-search.c
@@ -0,0 +1,263 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* test-secret-search.c: Test secret search
+
+   Copyright (C) 2013 Red Hat Inc
+
+   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 <stefw gnome org>
+*/
+
+#include "config.h"
+
+#include "gkd-secret-types.h"
+
+#include "egg/egg-testing.h"
+
+#include <gcr/gcr-base.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gio/gio.h>
+
+#include <fcntl.h>
+
+typedef struct {
+       GDBusConnection *connection;
+       gchar *service_name;
+       GPid service_pid;
+       gboolean service_available;
+       gchar *service_session;
+       guint watch_id;
+       guint signal_id;
+       gchar *directory;
+} Test;
+
+static void
+on_test_service_appeared (GDBusConnection *connection,
+                          const gchar *name,
+                          const gchar *name_owner,
+                          gpointer user_data)
+{
+       Test *test = user_data;
+       if (!test->connection)
+               test->connection = g_object_ref (connection);
+       test->service_available = TRUE;
+       egg_test_wait_stop ();
+}
+
+static void
+on_test_service_vanished (GDBusConnection *connection,
+                          const gchar *name,
+                          gpointer user_data)
+{
+       Test *test = user_data;
+       if (test->service_available) {
+               test->service_available = FALSE;
+               egg_test_wait_stop ();
+       }
+}
+
+static void
+on_service_spawned (gpointer user_data)
+{
+       Test *test = user_data;
+       int fd;
+
+       g_setenv ("GNOME_KEYRING_TEST_PATH", test->directory, TRUE);
+       g_setenv ("GNOME_KEYRING_TEST_SERVICE", test->service_name, TRUE);
+
+       fd = g_open ("/dev/null", O_WRONLY, 0);
+       if (fd != -1)
+               dup2 (fd, 1);
+}
+
+static void
+setup (Test *test,
+       gconstpointer unused)
+{
+       GError *error = NULL;
+       GVariant *retval;
+       GVariant *output;
+
+       gchar *args[] = {
+               TOP_BUILDDIR "/daemon/gnome-keyring-daemon",
+               "--foreground",
+               "--control-directory",
+               "/tmp/keyring-test",
+               "--components",
+               "secrets",
+               NULL,
+       };
+
+       test->service_name = g_strdup_printf ("org.gnome.keyring.Test.t%d", getpid ());
+
+       test->watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, test->service_name,
+                                          G_BUS_NAME_WATCHER_FLAGS_NONE,
+                                          on_test_service_appeared,
+                                          on_test_service_vanished,
+                                          test, NULL);
+
+       test->directory = egg_tests_create_scratch_directory (
+               SRCDIR "/files/test.keyring",
+               NULL);
+
+       if (!g_spawn_async (NULL, args, NULL,
+                           G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD,
+                           on_service_spawned, test, &test->service_pid, &error)) {
+               g_error ("couldn't start gnome-keyring-daemon for testing: %s", error->message);
+               g_assert_not_reached ();
+       }
+
+       if (!test->service_available) {
+               egg_test_wait ();
+
+               if (!test->service_available) {
+                       g_warning ("Couldn't start gnome-keyring-daemon test service. ");
+                       g_assert_not_reached ();
+               }
+       }
+
+       /* Set by on_test_service_appeared */
+       g_assert (test->connection != NULL);
+
+       /* Establish a plain session with the daemon */
+       retval = g_dbus_connection_call_sync (test->connection,
+                                             test->service_name,
+                                             SECRET_SERVICE_PATH,
+                                             SECRET_SERVICE_INTERFACE,
+                                             "OpenSession",
+                                             g_variant_new ("(s v)", "plain",
+                                                            g_variant_new_variant (g_variant_new_string 
(""))),
+                                             G_VARIANT_TYPE ("(vo)"),
+                                             G_DBUS_CALL_FLAGS_NO_AUTO_START,
+                                             -1, NULL, &error);
+       g_assert_no_error (error);
+
+       g_variant_get (retval, "(@vo)", &output, &test->service_session);
+       g_variant_unref (output);
+       g_variant_unref (retval);
+}
+
+static void
+teardown (Test *test,
+          gconstpointer unused)
+{
+       g_dbus_connection_signal_unsubscribe (test->connection, test->signal_id);
+
+       if (test->service_pid)
+               kill (test->service_pid, SIGTERM);
+
+       if (test->service_available) {
+               egg_test_wait ();
+               if (test->service_available) {
+                       g_warning ("Couldn't stop gnome-keyring-daemon test service.");
+                       g_assert_not_reached ();
+               }
+       }
+
+       if (test->watch_id)
+               g_bus_unwatch_name (test->watch_id);
+
+       g_free (test->service_name);
+       g_free (test->service_session);
+
+       if (test->connection)
+               g_object_unref (test->connection);
+
+       egg_tests_remove_scratch_directory (test->directory);
+       g_free (test->directory);
+}
+
+static void
+test_service_search_items_unlocked_separate (Test *test,
+                                             gconstpointer unused)
+{
+       GVariantBuilder builder;
+       GError *error = NULL;
+       GVariant *retval;
+       GVariant *attrs;
+       GVariant *unlocked;
+       GVariant *locked;
+
+       g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
+       attrs = g_variant_builder_end (&builder);
+
+       retval = g_dbus_connection_call_sync (test->connection, test->service_name,
+                                             "/org/freedesktop/secrets",
+                                             SECRET_SERVICE_INTERFACE,
+                                             "SearchItems",
+                                             g_variant_new ("(@a{ss})", attrs),
+                                             G_VARIANT_TYPE ("(aoao)"),
+                                             G_DBUS_CALL_FLAGS_NO_AUTO_START,
+                                             -1, NULL, &error);
+       g_assert_no_error (error);
+
+       g_variant_get (retval, "(@ao ao)", &unlocked, &locked);
+       g_variant_unref (retval);
+
+       g_assert_cmpuint (g_variant_n_children (unlocked), ==, 0);
+       g_assert_cmpuint (g_variant_n_children (locked), ==, 1);
+
+       g_variant_unref (unlocked);
+       g_variant_unref (locked);
+}
+
+static void
+test_collection_search_items_combined (Test *test,
+                                       gconstpointer unused)
+{
+       GVariantBuilder builder;
+       GError *error = NULL;
+       GVariant *retval;
+       GVariant *attrs;
+       GVariant *items;
+
+       g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
+       attrs = g_variant_builder_end (&builder);
+
+       retval = g_dbus_connection_call_sync (test->connection, test->service_name,
+                                             "/org/freedesktop/secrets/collection/test",
+                                             SECRET_COLLECTION_INTERFACE,
+                                             "SearchItems",
+                                             g_variant_new ("(@a{ss})", attrs),
+                                             G_VARIANT_TYPE ("(ao)"),
+                                             G_DBUS_CALL_FLAGS_NO_AUTO_START,
+                                             -1, NULL, &error);
+       g_assert_no_error (error);
+
+       g_variant_get (retval, "(@ao)", &items);
+       g_variant_unref (retval);
+
+       g_assert_cmpuint (g_variant_n_children (items), ==, 1);
+       g_variant_unref (items);
+}
+
+int
+main (int argc, char **argv)
+{
+#if !GLIB_CHECK_VERSION(2,35,0)
+       g_type_init ();
+#endif
+       g_test_init (&argc, &argv, NULL);
+
+       g_test_add ("/secret-search/service-search-items-unlocked-separate", Test, NULL,
+                   setup, test_service_search_items_unlocked_separate, teardown);
+       g_test_add ("/secret-search/collection-search-items-combined", Test, NULL,
+                   setup, test_collection_search_items_combined, teardown);
+
+       return egg_tests_run_with_loop ();
+}


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