From 7ac228b62fdf375039e6e42126cbc3e50d020c67 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Sat, 5 Nov 2011 21:50:01 +0100 Subject: [PATCH] Simple test for gsecret_service_search_paths() --- .gitignore | 3 +- library/gsecret-private.h | 2 + library/gsecret-service.c | 24 ++------ library/gsecret-util.c | 20 +++++++ library/tests/Makefile.am | 1 + library/tests/mock-service-normal.py | 11 ++++ library/tests/mock/service.py | 54 ++++++++++++++++- library/tests/test-service.c | 109 +++++++++++++++++++++++++++++++++++ library/tests/test-session.c | 2 +- po/gsecret.pot | 2 +- 10 files changed, 204 insertions(+), 24 deletions(-) create mode 100644 library/tests/test-service.c diff --git a/.gitignore b/.gitignore index c60fad5..0478592 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,5 @@ stamp* /egg/tests/test-hkdf /egg/tests/test-secmem -/library/tests/test-session +/library/tests/test-* +!/library/tests/test-*.c diff --git a/library/gsecret-private.h b/library/gsecret-private.h index b7adf65..dd2681a 100644 --- a/library/gsecret-private.h +++ b/library/gsecret-private.h @@ -30,6 +30,8 @@ G_BEGIN_DECLS gchar * _gsecret_util_parent_path (const gchar *path); +GVariant * _gsecret_util_variant_for_attributes (GHashTable *attributes); + GSecretService * _gsecret_service_bare_instance (GDBusConnection *connection, const gchar *bus_name); diff --git a/library/gsecret-service.c b/library/gsecret-service.c index 79054df..61182c9 100644 --- a/library/gsecret-service.c +++ b/library/gsecret-service.c @@ -869,24 +869,6 @@ _gsecret_service_encode_secret (GSecretService *self, return result; } -static GVariant * -_gsecret_util_variant_for_attributes (GHashTable *attributes) -{ - GHashTableIter iter; - GVariantBuilder builder; - const gchar *name; - const gchar *value; - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ssv)")); - - g_hash_table_iter_init (&iter, attributes); - while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&value)) - g_variant_builder_add (&builder, "(ss)", name, value); - - return g_variant_builder_end (&builder); - -} - static void on_search_items_complete (GObject *source, GAsyncResult *result, @@ -924,7 +906,8 @@ gsecret_service_search_paths (GSecretService *self, gsecret_service_search_paths); g_dbus_proxy_call (G_DBUS_PROXY (self), "SearchItems", - _gsecret_util_variant_for_attributes (attributes), + g_variant_new ("(@a{ss})", + _gsecret_util_variant_for_attributes (attributes)), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, on_search_items_complete, g_object_ref (res)); @@ -980,7 +963,8 @@ gsecret_service_search_paths_sync (GSecretService *self, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); response = g_dbus_proxy_call_sync (G_DBUS_PROXY (self), "SearchItems", - _gsecret_util_variant_for_attributes (attributes), + g_variant_new ("(@a{ss})", + _gsecret_util_variant_for_attributes (attributes)), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (response != NULL) { diff --git a/library/gsecret-util.c b/library/gsecret-util.c index a430504..87d594c 100644 --- a/library/gsecret-util.c +++ b/library/gsecret-util.c @@ -45,3 +45,23 @@ _gsecret_util_parent_path (const gchar *path) pos--; return g_strndup (path, pos - path); } + +GVariant * +_gsecret_util_variant_for_attributes (GHashTable *attributes) +{ + GHashTableIter iter; + GVariantBuilder builder; + const gchar *name; + const gchar *value; + + g_return_val_if_fail (attributes != NULL, NULL); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + + g_hash_table_iter_init (&iter, attributes); + while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&value)) + g_variant_builder_add (&builder, "{ss}", name, value); + + return g_variant_builder_end (&builder); + +} diff --git a/library/tests/Makefile.am b/library/tests/Makefile.am index c03176e..ffde722 100644 --- a/library/tests/Makefile.am +++ b/library/tests/Makefile.am @@ -11,6 +11,7 @@ LDADD = \ $(NULL) TEST_PROGS = \ + test-service \ test-session \ $(NULL) diff --git a/library/tests/mock-service-normal.py b/library/tests/mock-service-normal.py index 457eea6..ec0efdf 100644 --- a/library/tests/mock-service-normal.py +++ b/library/tests/mock-service-normal.py @@ -3,4 +3,15 @@ import mock service = mock.SecretService() + +collection = mock.SecretCollection(service, "collection", locked=False) +mock.SecretItem(collection, "item_one", attributes={ "number": "1", "string": "one", "parity": "odd" }) +mock.SecretItem(collection, "item_two", attributes={ "number": "2", "string": "two", "parity": "even" }) +mock.SecretItem(collection, "item_three", attributes={ "number": "3", "string": "three", "parity": "odd" }) + +collection = mock.SecretCollection(service, "second", locked=True) +mock.SecretItem(collection, "item_one", attributes={ "number": "1", "string": "one", "parity": "odd" }) +mock.SecretItem(collection, "item_two", attributes={ "number": "2", "string": "two", "parity": "even" }) +mock.SecretItem(collection, "item_three", attributes={ "number": "3", "string": "three", "parity": "odd" }) + service.listen() \ No newline at end of file diff --git a/library/tests/mock/service.py b/library/tests/mock/service.py index 4b5db12..0ae8508 100644 --- a/library/tests/mock/service.py +++ b/library/tests/mock/service.py @@ -73,6 +73,43 @@ class SecretSession(dbus.service.Object): self.remove_from_connection() self.service.remove_session(self) + +class SecretItem(dbus.service.Object): + def __init__(self, collection, identifier, label="Item", attributes={ }): + self.collection = collection + self.identifier = identifier + self.label = label + self.attributes = attributes + self.path = "/org/freedesktop/secrets/collection/%s/%s" % (collection.identifier, identifier) + dbus.service.Object.__init__(self, collection.service.bus_name, self.path) + collection.items[identifier] = self + + def match_attributes(self, attributes): + for (key, value) in attributes.items(): + if not self.attributes.get(key) == value: + return False + return True + + +class SecretCollection(dbus.service.Object): + def __init__(self, service, identifier, label="Collection", locked=False): + self.service = service + self.identifier = identifier + self.label = label + self.locked = locked + self.items = { } + self.path = "/org/freedesktop/secrets/collection/%s" % identifier + dbus.service.Object.__init__(self, service.bus_name, self.path) + service.collections[identifier] = self + + def search_items(self, attributes): + results = [] + for item in self.items.values(): + if item.match_attributes(attributes): + results.append(item) + return results + + class SecretService(dbus.service.Object): algorithms = { @@ -87,6 +124,7 @@ class SecretService(dbus.service.Object): self.bus_name = dbus.service.BusName(name, allow_replacement=True, replace_existing=True) dbus.service.Object.__init__(self, self.bus_name, '/org/freedesktop/secrets') self.sessions = { } + self.collections = { } def on_name_owner_changed(owned, old_owner, new_owner): if not new_owner: @@ -108,7 +146,7 @@ class SecretService(dbus.service.Object): def remove_session(self, session): self.sessions[session.sender].remove(session) - + @dbus.service.method('org.freedesktop.Secret.Service', byte_arrays=True, sender_keyword='sender') def OpenSession(self, algorithm, param, sender=None): assert type(algorithm) == dbus.String @@ -118,6 +156,20 @@ class SecretService(dbus.service.Object): return self.algorithms[algorithm].negotiate(self, sender, param) + @dbus.service.method('org.freedesktop.Secret.Service') + def SearchItems(self, attributes): + locked = [ ] + unlocked = [ ] + items = [ ] + for collection in self.collections.values(): + items = collection.search_items(attributes) + if collection.locked: + locked.extend(items) + else: + unlocked.extend(items) + return (dbus.Array(unlocked, "o"), dbus.Array(locked, "o")) + + def parse_options(args): global bus_name try: diff --git a/library/tests/test-service.c b/library/tests/test-service.c new file mode 100644 index 0000000..2642d41 --- /dev/null +++ b/library/tests/test-service.c @@ -0,0 +1,109 @@ +/* GSecret - GLib wrapper for Secret Service + * + * Copyright 2011 Collabora Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2 of the licence or (at + * your option) any later version. + * + * See the included COPYING file for more information. + */ + + +#include "config.h" + +#include "gsecret-service.h" +#include "gsecret-private.h" + +#include "egg/egg-testing.h" + +#include + +#include +#include + +static gchar *MOCK_NAME = "org.mock.Service"; + +typedef struct { + GPid pid; + GDBusConnection *connection; + GSecretService *service; +} Test; + +static void +setup (Test *test, + gconstpointer data) +{ + GError *error = NULL; + const gchar *mock_script = data; + gchar *argv[] = { + "python", (gchar *)mock_script, + "--name", MOCK_NAME, + NULL + }; + + g_spawn_async (SRCDIR, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &test->pid, &error); + g_assert_no_error (error); + g_usleep (200 * 1000); + + test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + + test->service = _gsecret_service_bare_instance (test->connection, MOCK_NAME); +} + +static void +teardown (Test *test, + gconstpointer unused) +{ + g_clear_object (&test->service); + g_clear_object (&test->connection); + + g_assert (test->pid); + if (kill (test->pid, SIGTERM) < 0) + g_error ("kill() failed: %s", g_strerror (errno)); + g_spawn_close_pid (test->pid); +} + +static void +test_search_paths (Test *test, + gconstpointer used) +{ + GHashTable *attributes; + gboolean ret; + gchar **locked; + gchar **unlocked; + GError *error = NULL; + + attributes = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (attributes, "number", "1"); + + ret = gsecret_service_search_paths_sync (test->service, attributes, NULL, + &unlocked, &locked, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + g_assert (locked); + g_assert_cmpstr (locked[0], ==, "/org/freedesktop/secrets/collection/second/item_one"); + + g_assert (unlocked); + g_assert_cmpstr (unlocked[0], ==, "/org/freedesktop/secrets/collection/collection/item_one"); + + g_strfreev (unlocked); + g_strfreev (locked); + + g_hash_table_unref (attributes); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + g_set_prgname ("test-service"); + g_type_init (); + + g_test_add ("/service/search-paths", Test, "mock-service-normal.py", setup, test_search_paths, teardown); + + return egg_tests_run_in_thread_with_loop (); +} diff --git a/library/tests/test-session.c b/library/tests/test-session.c index e68649e..ee15def 100644 --- a/library/tests/test-session.c +++ b/library/tests/test-session.c @@ -46,7 +46,7 @@ setup (Test *test, g_spawn_async (SRCDIR, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &test->pid, &error); g_assert_no_error (error); - g_usleep (100 * 1000); + g_usleep (200 * 1000); test->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); g_assert_no_error (error); diff --git a/po/gsecret.pot b/po/gsecret.pot index 86c4211..51190d7 100644 --- a/po/gsecret.pot +++ b/po/gsecret.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-11-05 20:58+0100\n" +"POT-Creation-Date: 2011-11-05 21:48+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" -- 2.7.4