From 4c80765ef814cf1f1d55d14f65403250b01b3258 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Thu, 26 Jan 2012 14:34:37 +0100 Subject: [PATCH] More testing, and more bug fixes --- library/gsecret-collection.c | 5 +- library/gsecret-item.c | 4 +- library/gsecret-private.h | 21 +- library/gsecret-service.c | 195 ++++-- library/gsecret-service.h | 4 +- library/gsecret-util.c | 1 - library/tests/mock-service-lock.py | 17 + library/tests/mock/service.py | 96 ++- library/tests/test-collection.c | 209 +++++- library/tests/test-item.c | 84 ++- library/tests/test-service.c | 1018 ++++++++++++++++++++++++++-- 11 files changed, 1452 insertions(+), 202 deletions(-) create mode 100644 library/tests/mock-service-lock.py diff --git a/library/gsecret-collection.c b/library/gsecret-collection.c index 6c4bc81..b7404d9 100644 --- a/library/gsecret-collection.c +++ b/library/gsecret-collection.c @@ -394,7 +394,6 @@ gsecret_collection_properties_changed (GDBusProxy *proxy, g_variant_iter_init (&iter, changed_properties); while (g_variant_iter_loop (&iter, "{sv}", &property_name, &value)) - // TODO: zzzz; handle_property_changed (self, property_name, value); g_object_thaw_notify (G_OBJECT (self)); @@ -678,8 +677,8 @@ gsecret_collection_delete (GSecretCollection *self, g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (self)); - gsecret_service_delete_path (self->pv->service, object_path, cancellable, - callback, user_data); + _gsecret_service_delete_path (self->pv->service, object_path, FALSE, + cancellable, callback, user_data); } gboolean diff --git a/library/gsecret-item.c b/library/gsecret-item.c index 0190629..ca445f0 100644 --- a/library/gsecret-item.c +++ b/library/gsecret-item.c @@ -476,8 +476,8 @@ gsecret_item_delete (GSecretItem *self, res = g_simple_async_result_new (G_OBJECT (self), callback, user_data, gsecret_item_delete); - gsecret_service_delete_path (self->pv->service, object_path, cancellable, - on_item_deleted, g_object_ref (res)); + _gsecret_service_delete_path (self->pv->service, object_path, TRUE, + cancellable, on_item_deleted, g_object_ref (res)); g_object_unref (res); } diff --git a/library/gsecret-private.h b/library/gsecret-private.h index 1a74f35..cea72f5 100644 --- a/library/gsecret-private.h +++ b/library/gsecret-private.h @@ -99,25 +99,18 @@ gboolean _gsecret_util_have_cached_properties (GDBusProxy *prox void _gsecret_service_set_default_bus_name (const gchar *bus_name); -#if 0 -GSecretService * _gsecret_service_bare_instance (GDBusConnection *connection, - const gchar *bus_name); - -void _gsecret_service_bare_connect (const gchar *bus_name, - gboolean ensure_session, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -GSecretService * _gsecret_service_bare_connect_finish (GAsyncResult *result, - GError **error); -#endif - GSecretSession * _gsecret_service_get_session (GSecretService *self); void _gsecret_service_take_session (GSecretService *self, GSecretSession *session); +void _gsecret_service_delete_path (GSecretService *self, + const gchar *object_path, + gboolean is_an_item, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GSecretItem * _gsecret_service_find_item_instance (GSecretService *self, const gchar *item_path); diff --git a/library/gsecret-service.c b/library/gsecret-service.c index 1cbc5ac..24b1a0a 100644 --- a/library/gsecret-service.c +++ b/library/gsecret-service.c @@ -395,6 +395,8 @@ on_init_base (GObject *source, result, &error)) { g_simple_async_result_take_error (res, error); g_simple_async_result_complete (res); + } else { + } service_ensure_for_flags_async (self, self->pv->init_flags, res); @@ -506,6 +508,7 @@ gsecret_service_get (GSecretServiceFlags flags, service_ensure_for_flags_async (service, flags, res); + g_object_unref (service); g_object_unref (res); } } @@ -530,6 +533,15 @@ gsecret_service_get_finish (GAsyncResult *result, /* Creating a whole new service */ } else { service = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), result, error); + + if (service) { + G_LOCK (service_instance); + if (service_instance == NULL) { + service_instance = service; + g_object_weak_ref (G_OBJECT (service), on_service_instance_gone, NULL); + } + G_UNLOCK (service_instance); + } } if (source_object) @@ -563,15 +575,15 @@ gsecret_service_get_sync (GSecretServiceFlags flags, "g-interface-name", GSECRET_SERVICE_INTERFACE, "flags", flags, NULL); - if (service == NULL) - return NULL; - G_LOCK (service_instance); - if (service_instance == NULL) { - service_instance = service; - g_object_weak_ref (G_OBJECT (service), on_service_instance_gone, NULL); + if (service != NULL) { + G_LOCK (service_instance); + if (service_instance == NULL) { + service_instance = service; + g_object_weak_ref (G_OBJECT (service), on_service_instance_gone, NULL); + } + G_UNLOCK (service_instance); } - G_UNLOCK (service_instance); } else { if (!service_ensure_for_flags_sync (service, flags, cancellable, error)) { @@ -696,16 +708,18 @@ GSecretItem * _gsecret_service_find_item_instance (GSecretService *self, const gchar *item_path) { - GSecretCollection *collection; + GSecretCollection *collection = NULL; gchar *collection_path; GSecretItem *item; collection_path = _gsecret_util_parent_path (item_path); g_mutex_lock (&self->pv->mutex); - collection = g_hash_table_lookup (self->pv->collections, collection_path); - if (collection != NULL) - g_object_ref (collection); + if (self->pv->collections) { + collection = g_hash_table_lookup (self->pv->collections, collection_path); + if (collection != NULL) + g_object_ref (collection); + } g_mutex_unlock (&self->pv->mutex); g_free (collection_path); @@ -965,7 +979,7 @@ gsecret_service_ensure_collections (GSecretService *self, g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); paths = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Collections"); - g_return_if_fail (paths == NULL); + g_return_if_fail (paths != NULL); res = g_simple_async_result_new (G_OBJECT (self), callback, user_data, gsecret_service_ensure_collections); @@ -1030,7 +1044,7 @@ gsecret_service_ensure_collections_sync (GSecretService *self, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); paths = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Collections"); - g_return_val_if_fail (paths == NULL, FALSE); + g_return_val_if_fail (paths != NULL, FALSE); collections = collections_table_new (); @@ -1193,8 +1207,8 @@ search_closure_free (gpointer data) } static void -search_closure_add_item (SearchClosure *closure, - GSecretItem *item) +search_closure_take_item (SearchClosure *closure, + GSecretItem *item) { const gchar *path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (item)); g_hash_table_insert (closure->items, (gpointer)path, item); @@ -1217,7 +1231,7 @@ on_search_loaded (GObject *source, g_simple_async_result_take_error (res, error); if (item != NULL) - search_closure_add_item (closure, item); + search_closure_take_item (closure, item); if (closure->loading == 0) g_simple_async_result_complete (res); @@ -1225,21 +1239,20 @@ on_search_loaded (GObject *source, } static void -search_load_item (GSecretService *self, - GSimpleAsyncResult *res, - SearchClosure *closure, - const gchar *path) +search_load_item_async (GSecretService *self, + GSimpleAsyncResult *res, + SearchClosure *closure, + const gchar *path) { GSecretItem *item; item = _gsecret_service_find_item_instance (self, path); if (item == NULL) { - // TODO: xxxxxxxxxx; gsecret_item_new (self, path, closure->cancellable, on_search_loaded, g_object_ref (res)); closure->loading++; } else { - search_closure_add_item (closure, item); + search_closure_take_item (closure, item); } } @@ -1261,9 +1274,9 @@ on_search_paths (GObject *source, } for (i = 0; closure->unlocked[i] != NULL; i++) - search_load_item (self, res, closure, closure->unlocked[i]); + search_load_item_async (self, res, closure, closure->unlocked[i]); for (i = 0; closure->locked[i] != NULL; i++) - search_load_item (self, res, closure, closure->locked[i]); + search_load_item_async (self, res, closure, closure->locked[i]); if (closure->loading == 0) g_simple_async_result_complete (res); @@ -1344,6 +1357,33 @@ gsecret_service_search_finish (GSecretService *self, return TRUE; } +static gboolean +service_load_items_sync (GSecretService *self, + GCancellable *cancellable, + gchar **paths, + GList **items, + GError **error) +{ + GSecretItem *item; + GList *result = NULL; + guint i; + + for (i = 0; paths[i] != NULL; i++) { + item = _gsecret_service_find_item_instance (self, paths[i]); + if (item == NULL) + item = gsecret_item_new_sync (self, paths[i], cancellable, error); + if (item == NULL) { + g_list_free_full (result, g_object_unref); + return FALSE; + } else { + result = g_list_prepend (result, item); + } + } + + *items = g_list_reverse (result); + return TRUE; +} + gboolean gsecret_service_search_sync (GSecretService *self, GHashTable *attributes, @@ -1352,25 +1392,28 @@ gsecret_service_search_sync (GSecretService *self, GList **locked, GError **error) { - GSecretSync *sync; + gchar **unlocked_paths = NULL; + gchar **locked_paths = NULL; gboolean ret; g_return_val_if_fail (GSECRET_IS_SERVICE (self), FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - sync = _gsecret_sync_new (); - g_main_context_push_thread_default (sync->context); + if (!gsecret_service_search_for_paths_sync (self, attributes, cancellable, + unlocked ? &unlocked_paths : NULL, + locked ? &locked_paths : NULL, error)) + return FALSE; - gsecret_service_search (self, attributes, cancellable, - _gsecret_sync_on_result, sync); + ret = TRUE; - g_main_loop_run (sync->loop); + if (unlocked) + ret = service_load_items_sync (self, cancellable, unlocked_paths, unlocked, error); + if (ret && locked) + ret = service_load_items_sync (self, cancellable, locked_paths, locked, error); - ret = gsecret_service_search_finish (self, sync->result, unlocked, locked, error); - - g_main_context_pop_thread_default (sync->context); - _gsecret_sync_free (sync); + g_strfreev (unlocked_paths); + g_strfreev (locked_paths); return ret; } @@ -1454,7 +1497,7 @@ gsecret_service_get_secret_for_path (GSecretService *self, res = g_simple_async_result_new (G_OBJECT (self), callback, user_data, gsecret_service_get_secret_for_path); - closure = g_slice_new (GetClosure); + closure = g_slice_new0 (GetClosure); closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; closure->in = g_variant_ref_sink (g_variant_new_objv (&object_path, 1)); g_simple_async_result_set_op_res_gpointer (res, closure, get_closure_free); @@ -1471,7 +1514,7 @@ service_decode_get_secrets_first (GSecretService *self, GVariant *out) { GSecretSession *session; - GSecretValue *value; + GSecretValue *value = NULL; GVariantIter *iter; GVariant *variant; const gchar *path; @@ -1579,7 +1622,7 @@ gsecret_service_get_secrets_for_paths (GSecretService *self, res = g_simple_async_result_new (G_OBJECT (self), callback, user_data, gsecret_service_get_secret_for_path); - closure = g_slice_new (GetClosure); + closure = g_slice_new0 (GetClosure); closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; closure->in = g_variant_ref_sink (g_variant_new_objv (object_paths, -1)); g_simple_async_result_set_op_res_gpointer (res, closure, get_closure_free); @@ -1659,7 +1702,7 @@ gsecret_service_get_secrets (GSecretService *self, res = g_simple_async_result_new (G_OBJECT (self), callback, user_data, gsecret_service_get_secrets); - closure = g_slice_new (GetClosure); + closure = g_slice_new0 (GetClosure); closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; closure->items = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); @@ -1700,7 +1743,7 @@ gsecret_service_get_secrets_finish (GSecretService *self, g_return_val_if_fail (GSECRET_IS_SERVICE (self), NULL); g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), - gsecret_service_get_secret_for_path), NULL); + gsecret_service_get_secrets), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); res = G_SIMPLE_ASYNC_RESULT (result); @@ -1859,8 +1902,9 @@ service_xlock_paths_async (GSecretService *self, res = g_simple_async_result_new (G_OBJECT (self), callback, user_data, service_xlock_paths_async); - closure = g_slice_new (XlockClosure); + closure = g_slice_new0 (XlockClosure); closure->cancellable = cancellable ? g_object_ref (cancellable) : cancellable; + closure->xlocked = g_ptr_array_new_with_free_func (g_free); g_simple_async_result_set_op_res_gpointer (res, closure, xlock_closure_free); g_dbus_proxy_call (G_DBUS_PROXY (self), method, @@ -2172,7 +2216,7 @@ gsecret_service_unlock_finish (GSecretService *self, g_return_val_if_fail (GSECRET_IS_SERVICE (self), -1); g_return_val_if_fail (error == NULL || *error == NULL, -1); g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), - gsecret_service_unlock_paths), -1); + service_xlock_paths_async), -1); return service_xlock_finish (self, result, unlocked, error); } @@ -2529,7 +2573,8 @@ static void lookup_closure_free (gpointer data) { LookupClosure *closure = data; - gsecret_value_unref (closure->value); + if (closure->value) + gsecret_value_unref (closure->value); g_clear_object (&closure->cancellable); g_slice_free (LookupClosure, closure); } @@ -2826,6 +2871,37 @@ on_delete_complete (GObject *source, g_object_unref (res); } +void +_gsecret_service_delete_path (GSecretService *self, + const gchar *object_path, + gboolean is_an_item, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *res; + DeleteClosure *closure; + + g_return_if_fail (GSECRET_IS_SERVICE (self)); + g_return_if_fail (object_path != NULL); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + res = g_simple_async_result_new (G_OBJECT (self), callback, user_data, + _gsecret_service_delete_path); + closure = g_slice_new0 (DeleteClosure); + closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + g_simple_async_result_set_op_res_gpointer (res, closure, delete_closure_free); + + g_dbus_connection_call (g_dbus_proxy_get_connection (G_DBUS_PROXY (self)), + g_dbus_proxy_get_name (G_DBUS_PROXY (self)), object_path, + is_an_item ? GSECRET_ITEM_INTERFACE : GSECRET_COLLECTION_INTERFACE, + "Delete", g_variant_new ("()"), G_VARIANT_TYPE ("(o)"), + G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, + cancellable, on_delete_complete, g_object_ref (res)); + + g_object_unref (res); +} + void gsecret_service_delete_path (GSecretService *self, const gchar *item_path, @@ -2833,27 +2909,11 @@ gsecret_service_delete_path (GSecretService *self, GAsyncReadyCallback callback, gpointer user_data) { - GSimpleAsyncResult *res; - DeleteClosure *closure; - g_return_if_fail (GSECRET_IS_SERVICE (self)); g_return_if_fail (item_path != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); - res = g_simple_async_result_new (G_OBJECT (self), callback, user_data, - gsecret_service_delete_path); - closure = g_slice_new0 (DeleteClosure); - closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; - g_simple_async_result_set_op_res_gpointer (res, closure, delete_closure_free); - - g_dbus_connection_call (g_dbus_proxy_get_connection (G_DBUS_PROXY (self)), - g_dbus_proxy_get_name (G_DBUS_PROXY (self)), - item_path, GSECRET_ITEM_INTERFACE, - "Delete", g_variant_new ("()"), G_VARIANT_TYPE ("(o)"), - G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, - cancellable, on_delete_complete, g_object_ref (res)); - - g_object_unref (res); + _gsecret_service_delete_path (self, item_path, TRUE, cancellable, callback, user_data); } gboolean @@ -2867,7 +2927,7 @@ gsecret_service_delete_path_finish (GSecretService *self, g_return_val_if_fail (GSECRET_IS_SERVICE (self), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), - gsecret_service_delete_path), FALSE); + _gsecret_service_delete_path), FALSE); res = G_SIMPLE_ASYNC_RESULT (result); if (g_simple_async_result_propagate_error (res, error)) @@ -2879,7 +2939,7 @@ gsecret_service_delete_path_finish (GSecretService *self, gboolean gsecret_service_delete_path_sync (GSecretService *self, - const gchar *item_path, + const gchar *object_path, GCancellable *cancellable, GError **error) { @@ -2887,14 +2947,15 @@ gsecret_service_delete_path_sync (GSecretService *self, gboolean result; g_return_val_if_fail (GSECRET_IS_SERVICE (self), FALSE); - g_return_val_if_fail (item_path != NULL, FALSE); + g_return_val_if_fail (object_path != NULL, FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); sync = _gsecret_sync_new (); g_main_context_push_thread_default (sync->context); - gsecret_service_delete_path (self, item_path, cancellable, _gsecret_sync_on_result, sync); + gsecret_service_delete_path (self, object_path, cancellable, + _gsecret_sync_on_result, sync); g_main_loop_run (sync->loop); @@ -2959,10 +3020,10 @@ on_search_delete_password (GObject *source, /* Delete the first path */ } else { closure->deleted = TRUE; - gsecret_service_delete_path (self, path, - closure->cancellable, - on_delete_password_complete, - g_object_ref (res)); + _gsecret_service_delete_path (self, path, TRUE, + closure->cancellable, + on_delete_password_complete, + g_object_ref (res)); } } diff --git a/library/gsecret-service.h b/library/gsecret-service.h index b2eb012..4e98b0b 100644 --- a/library/gsecret-service.h +++ b/library/gsecret-service.h @@ -366,7 +366,7 @@ GSecretValue * gsecret_service_lookupv_sync (GSecretServi GError **error); void gsecret_service_delete_path (GSecretService *self, - const gchar *item_path, + const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); @@ -376,7 +376,7 @@ gboolean gsecret_service_delete_path_finish (GSecretServi GError **error); gboolean gsecret_service_delete_path_sync (GSecretService *self, - const gchar *item_path, + const gchar *object_path, GCancellable *cancellable, GError **error); diff --git a/library/gsecret-util.c b/library/gsecret-util.c index b558b51..046302f 100644 --- a/library/gsecret-util.c +++ b/library/gsecret-util.c @@ -76,7 +76,6 @@ _gsecret_util_parent_path (const gchar *path) g_return_val_if_fail (pos != NULL, NULL); g_return_val_if_fail (pos != path, NULL); - pos--; return g_strndup (path, pos - path); } diff --git a/library/tests/mock-service-lock.py b/library/tests/mock-service-lock.py new file mode 100644 index 0000000..96bdbe2 --- /dev/null +++ b/library/tests/mock-service-lock.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + +import dbus +import mock +import sys + +service = mock.SecretService() +service.add_standard_objects() + +collection = mock.SecretCollection(service, "lock_one", locked=False, confirm=False) +mock.SecretItem(collection, "item", attributes={ "number": "1", "string": "one", "even": "false" }, secret="uno") +mock.SecretItem(collection, "confirm", attributes={ "number": "2", "string": "two", "even": "true" }, secret="dos", confirm=True) + +collection = mock.SecretCollection(service, "lock_prompt", locked=True, confirm=True) +mock.SecretItem(collection, "locked", attributes={ "number": "3", "string": "three", "even": "false" }, secret="tres") + +service.listen() \ No newline at end of file diff --git a/library/tests/mock/service.py b/library/tests/mock/service.py index eac037a..0b85f3b 100644 --- a/library/tests/mock/service.py +++ b/library/tests/mock/service.py @@ -181,6 +181,12 @@ class SecretItem(dbus.service.Object): return False return True + def get_locked(self): + return self.collection.locked + + def perform_xlock(self, lock): + return self.collection.perform_xlock(lock) + def perform_delete(self): del self.collection.items[self.identifier] del objects[self.path] @@ -191,7 +197,7 @@ class SecretItem(dbus.service.Object): session = objects.get(session_path, None) if not session or session.sender != sender: raise InvalidArgs("session invalid: %s" % session_path) - if self.collection.locked: + if self.get_locked(): raise IsLocked("secret is locked: %s" % self.path) return session.encode_secret(self.secret, self.content_type) @@ -213,7 +219,7 @@ class SecretItem(dbus.service.Object): def GetAll(self, interface_name): if interface_name == 'org.freedesktop.Secret.Item': return { - 'Locked': self.collection.locked, + 'Locked': self.get_locked(), 'Attributes': dbus.Dictionary(self.attributes, signature='ss'), 'Label': self.label, 'Created': dbus.UInt64(self.created), @@ -260,6 +266,15 @@ class SecretCollection(dbus.service.Object): results.append(item) return results + def get_locked(self): + return self.locked + + def perform_xlock(self, lock): + self.locked = lock + for item in self.items.values(): + self.PropertiesChanged('org.freedesktop.Secret.Item', { "Locked" : lock }, []) + self.PropertiesChanged('org.freedesktop.Secret.Collection', { "Locked" : lock }, []) + def perform_delete(self): for item in self.items.values(): item.perform_delete() @@ -285,11 +300,11 @@ class SecretCollection(dbus.service.Object): def GetAll(self, interface_name): if interface_name == 'org.freedesktop.Secret.Collection': return { - 'Locked': self.locked, + 'Locked': self.get_locked(), 'Label': self.label, 'Created': dbus.UInt64(self.created), 'Modified': dbus.UInt64(self.modified), - 'Items': [dbus.ObjectPath(i.path) for i in self.items.values()] + 'Items': dbus.Array([dbus.ObjectPath(i.path) for i in self.items.values()], signature='o') } else: raise InvalidArgs('Unknown %s interface' % interface_name) @@ -301,7 +316,7 @@ class SecretCollection(dbus.service.Object): if property_name == "Label": self.label = str(new_value) else: - raise InvalidArgs('Unknown %s interface' % property_name) + raise InvalidArgs('Not a writable property %s' % property_name) self.PropertiesChanged(interface_name, { property_name: new_value }, []) @dbus.service.signal(dbus.PROPERTIES_IFACE, signature='sa{sv}as') @@ -336,15 +351,17 @@ class SecretService(dbus.service.Object): 'org.freedesktop.DBus') def add_standard_objects(self): - collection = SecretCollection(self, "collection", label="Collection One", locked=False) - SecretItem(collection, "item_one", label="Item One", attributes={ "number": "1", "string": "one", "parity": "odd" }, secret="uno") - SecretItem(collection, "item_two", attributes={ "number": "2", "string": "two", "parity": "even" }, secret="dos") - SecretItem(collection, "item_three", attributes={ "number": "3", "string": "three", "parity": "odd" }, secret="tres") + collection = SecretCollection(self, "english", label="Collection One", locked=False) + SecretItem(collection, "item_one", label="Item One", attributes={ "number": "1", "string": "one", "even": "false" }, secret="111") + SecretItem(collection, "item_two", attributes={ "number": "2", "string": "two", "even": "true" }, secret="222") + SecretItem(collection, "item_three", attributes={ "number": "3", "string": "three", "even": "false" }, secret="3333") - collection = SecretCollection(self, "second", locked=True) - SecretItem(collection, "item_one", attributes={ "number": "1", "string": "one", "parity": "odd" }) - SecretItem(collection, "item_two", attributes={ "number": "2", "string": "two", "parity": "even" }) - SecretItem(collection, "item_three", attributes={ "number": "3", "string": "three", "parity": "odd" }) + collection = SecretCollection(self, "spanish", locked=True) + SecretItem(collection, "item_one", attributes={ "number": "1", "string": "uno", "even": "false" }, secret="111") + SecretItem(collection, "item_two", attributes={ "number": "2", "string": "dos", "even": "true" }, secret="222") + SecretItem(collection, "item_three", attributes={ "number": "3", "string": "tres", "even": "false" }, secret="3333") + + collection = SecretCollection(self, "empty", locked=False) def listen(self): global ready_pipe @@ -378,6 +395,36 @@ class SecretService(dbus.service.Object): return self.collections[parts[0]].get(parts[1], None) return None + @dbus.service.method('org.freedesktop.Secret.Service', sender_keyword='sender') + def Lock(self, paths, lock=True, sender=None): + locked = [] + prompts = [] + for path in paths: + if path not in objects: + continue + object = objects[path] + if object.get_locked() == lock: + locked.append(path) + elif not object.confirm: + object.perform_xlock(lock) + locked.append(path) + else: + prompts.append(object) + def prompt_callback(): + for object in prompts: + object.perform_xlock(lock) + locked = dbus.Array(locked, signature='o') + if prompts: + prompt = SecretPrompt(self, sender, dismiss=False, action=prompt_callback, + result=dbus.Array([o.path for o in prompts], signature='o')) + return (locked, dbus.ObjectPath(prompt.path)) + else: + return (locked, dbus.ObjectPath("/")) + + @dbus.service.method('org.freedesktop.Secret.Service', sender_keyword='sender') + def Unlock(self, paths, sender=None): + return self.Lock(paths, lock=False, sender=sender) + @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 @@ -394,7 +441,7 @@ class SecretService(dbus.service.Object): items = [ ] for collection in self.collections.values(): items = collection.search_items(attributes) - if collection.locked: + if collection.get_locked(): locked.extend(items) else: unlocked.extend(items) @@ -408,10 +455,29 @@ class SecretService(dbus.service.Object): results = dbus.Dictionary(signature="o(oayays)") for item_path in item_paths: item = objects.get(item_path, None) - if item and not item.collection.locked: + if item and not item.get_locked(): results[item_path] = item.GetSecret(session_path, sender) return results + @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v') + def Get(self, interface_name, property_name): + return self.GetAll(interface_name)[property_name] + + @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}') + def GetAll(self, interface_name): + if interface_name == 'org.freedesktop.Secret.Service': + return { + 'Collections': dbus.Array([dbus.ObjectPath(c.path) for c in self.collections.values()], signature='o') + } + else: + raise InvalidArgs('Unknown %s interface' % interface_name) + + @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='ssv') + def Set(self, interface_name, property_name, new_value): + if interface_name != 'org.freedesktop.Secret.Collection': + raise InvalidArgs('Unknown %s interface' % interface_name) + raise InvalidArgs('Not a writable property %s' % property_name) + def parse_options(args): global bus_name, ready_pipe diff --git a/library/tests/test-collection.c b/library/tests/test-collection.c index 1ac00d0..13e3c58 100644 --- a/library/tests/test-collection.c +++ b/library/tests/test-collection.c @@ -84,7 +84,7 @@ static void test_new_sync (Test *test, gconstpointer unused) { - const gchar *collection_path = "/org/freedesktop/secrets/collection/collection"; + const gchar *collection_path = "/org/freedesktop/secrets/collection/english"; GError *error = NULL; GSecretCollection *collection; @@ -97,11 +97,24 @@ test_new_sync (Test *test, egg_assert_not_object (collection); } +static void +test_new_sync_noexist (Test *test, + gconstpointer unused) +{ + const gchar *collection_path = "/org/freedesktop/secrets/collection/nonexistant"; + GError *error = NULL; + GSecretCollection *collection; + + collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error); + g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); + g_assert (collection == NULL); +} + static void test_new_async (Test *test, gconstpointer unused) { - const gchar *collection_path = "/org/freedesktop/secrets/collection/collection"; + const gchar *collection_path = "/org/freedesktop/secrets/collection/english"; GError *error = NULL; GSecretCollection *collection; GAsyncResult *result = NULL; @@ -121,13 +134,34 @@ test_new_async (Test *test, egg_assert_not_object (collection); } +static void +test_new_async_noexist (Test *test, + gconstpointer unused) +{ + const gchar *collection_path = "/org/freedesktop/secrets/collection/nonexistant"; + GError *error = NULL; + GSecretCollection *collection; + GAsyncResult *result = NULL; + + gsecret_collection_new (test->service, collection_path, NULL, on_async_result, &result); + g_assert (result == NULL); + + egg_test_wait (); + + collection = gsecret_collection_new_finish (result, &error); + g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); + g_assert (collection == NULL); + g_object_unref (result); +} + static void test_properties (Test *test, gconstpointer unused) { - const gchar *collection_path = "/org/freedesktop/secrets/collection/collection"; - GError *error = NULL; + const gchar *collection_path = "/org/freedesktop/secrets/collection/english"; GSecretCollection *collection; + GSecretService *service; + GError *error = NULL; guint64 created; guint64 modified; gboolean locked; @@ -149,6 +183,7 @@ test_properties (Test *test, "created", &created, "modified", &modified, "label", &label, + "service", &service, NULL); g_assert (locked == FALSE); @@ -158,6 +193,122 @@ test_properties (Test *test, g_assert_cmpstr (label, ==, "Collection One"); g_free (label); + g_assert (service == test->service); + g_object_unref (service); + + g_object_unref (collection); +} + +static void +check_items_equal (GList *items, + ...) +{ + GHashTable *paths; + gboolean have_item; + const gchar *path; + guint num_items; + va_list va; + GList *l; + + va_start (va, items); + paths = g_hash_table_new (g_str_hash, g_str_equal); + while ((path = va_arg (va, gchar *)) != NULL) + g_hash_table_insert (paths, (gpointer)path, (gpointer)path); + va_end (va); + + num_items = g_hash_table_size (paths); + g_assert_cmpuint (num_items, ==, g_list_length (items)); + + for (l = items; l != NULL; l = g_list_next (l)) { + path = g_dbus_proxy_get_object_path (l->data); + have_item = g_hash_table_remove (paths, path); + g_assert (have_item); + } + + g_hash_table_destroy (paths); +} + +static void +test_items (Test *test, + gconstpointer unused) +{ + const gchar *collection_path = "/org/freedesktop/secrets/collection/english"; + GSecretCollection *collection; + GError *error = NULL; + GList *items; + + collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error); + g_assert_no_error (error); + + items = gsecret_collection_get_items (collection); + check_items_equal (items, + "/org/freedesktop/secrets/collection/english/item_one", + "/org/freedesktop/secrets/collection/english/item_two", + "/org/freedesktop/secrets/collection/english/item_three", + NULL); + g_list_free_full (items, g_object_unref); + + g_object_get (collection, "items", &items, NULL); + check_items_equal (items, + "/org/freedesktop/secrets/collection/english/item_one", + "/org/freedesktop/secrets/collection/english/item_two", + "/org/freedesktop/secrets/collection/english/item_three", + NULL); + g_list_free_full (items, g_object_unref); + + g_object_unref (collection); +} + +static void +test_items_empty (Test *test, + gconstpointer unused) +{ + const gchar *collection_path = "/org/freedesktop/secrets/collection/empty"; + GSecretCollection *collection; + GError *error = NULL; + GList *items; + + collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error); + g_assert_no_error (error); + + items = gsecret_collection_get_items (collection); + check_items_equal (items, NULL); + g_list_free_full (items, g_object_unref); + + g_object_get (collection, "items", &items, NULL); + check_items_equal (items, NULL); + g_list_free_full (items, g_object_unref); + + g_object_unref (collection); +} + +static void +test_items_empty_async (Test *test, + gconstpointer unused) +{ + const gchar *collection_path = "/org/freedesktop/secrets/collection/empty"; + GSecretCollection *collection; + GAsyncResult *result = NULL; + GError *error = NULL; + GList *items; + + gsecret_collection_new (test->service, collection_path, NULL, on_async_result, &result); + g_assert (result == NULL); + + egg_test_wait (); + + collection = gsecret_collection_new_finish (result, &error); + g_assert_no_error (error); + g_object_unref (result); + + items = gsecret_collection_get_items (collection); + check_items_equal (items, NULL); + g_list_free_full (items, g_object_unref); + + g_object_get (collection, "items", &items, NULL); + check_items_equal (items, NULL); + g_list_free_full (items, g_object_unref); + g_object_unref (collection); } @@ -165,7 +316,7 @@ static void test_set_label_sync (Test *test, gconstpointer unused) { - const gchar *collection_path = "/org/freedesktop/secrets/collection/collection"; + const gchar *collection_path = "/org/freedesktop/secrets/collection/english"; GError *error = NULL; GSecretCollection *collection; gboolean ret; @@ -193,7 +344,7 @@ static void test_set_label_async (Test *test, gconstpointer unused) { - const gchar *collection_path = "/org/freedesktop/secrets/collection/collection"; + const gchar *collection_path = "/org/freedesktop/secrets/collection/english"; GAsyncResult *result = NULL; GError *error = NULL; GSecretCollection *collection; @@ -228,7 +379,7 @@ static void test_set_label_prop (Test *test, gconstpointer unused) { - const gchar *collection_path = "/org/freedesktop/secrets/collection/collection"; + const gchar *collection_path = "/org/freedesktop/secrets/collection/english"; GError *error = NULL; GSecretCollection *collection; guint sigs = 2; @@ -254,59 +405,58 @@ test_set_label_prop (Test *test, g_object_unref (collection); } -#if 0 static void test_delete_sync (Test *test, gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *collection_path = "/org/freedesktop/secrets/collection/english"; + GSecretCollection *collection; GError *error = NULL; - GSecretItem *item; gboolean ret; - item = gsecret_item_new_sync (test->service, item_path, NULL, &error); + collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error); g_assert_no_error (error); - ret = gsecret_item_delete_sync (item, NULL, &error); + ret = gsecret_collection_delete_sync (collection, NULL, &error); g_assert_no_error (error); g_assert (ret == TRUE); - g_object_unref (item); + g_object_unref (collection); - item = gsecret_item_new_sync (test->service, item_path, NULL, &error); + collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error); g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); - g_assert (item == NULL); + g_assert (collection == NULL); } static void test_delete_async (Test *test, gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *collection_path = "/org/freedesktop/secrets/collection/english"; + GSecretCollection *collection; GAsyncResult *result = NULL; GError *error = NULL; - GSecretItem *item; gboolean ret; - item = gsecret_item_new_sync (test->service, item_path, NULL, &error); + collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error); g_assert_no_error (error); - gsecret_item_delete (item, NULL, on_async_result, &result); + gsecret_collection_delete (collection, NULL, on_async_result, &result); g_assert (result == NULL); egg_test_wait (); - ret = gsecret_item_delete_finish (item, result, &error); + ret = gsecret_collection_delete_finish (collection, result, &error); g_assert_no_error (error); + g_object_unref (result); g_assert (ret == TRUE); - g_object_unref (item); + g_object_unref (collection); - item = gsecret_item_new_sync (test->service, item_path, NULL, &error); + collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error); g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); - g_assert (item == NULL); + g_assert (collection == NULL); } -#endif int main (int argc, char **argv) @@ -316,15 +466,18 @@ main (int argc, char **argv) g_type_init (); g_test_add ("/collection/new-sync", Test, "mock-service-normal.py", setup, test_new_sync, teardown); + g_test_add ("/collection/new-sync-noexist", Test, "mock-service-normal.py", setup, test_new_sync_noexist, teardown); g_test_add ("/collection/new-async", Test, "mock-service-normal.py", setup, test_new_async, teardown); + g_test_add ("/collection/new-async-noexist", Test, "mock-service-normal.py", setup, test_new_async_noexist, teardown); g_test_add ("/collection/properties", Test, "mock-service-normal.py", setup, test_properties, teardown); + g_test_add ("/collection/items", Test, "mock-service-normal.py", setup, test_items, teardown); + g_test_add ("/collection/items-empty", Test, "mock-service-normal.py", setup, test_items_empty, teardown); + g_test_add ("/collection/items-empty-async", Test, "mock-service-normal.py", setup, test_items_empty_async, teardown); g_test_add ("/collection/set-label-sync", Test, "mock-service-normal.py", setup, test_set_label_sync, teardown); g_test_add ("/collection/set-label-async", Test, "mock-service-normal.py", setup, test_set_label_async, teardown); g_test_add ("/collection/set-label-prop", Test, "mock-service-normal.py", setup, test_set_label_prop, teardown); -#if 0 - g_test_add ("/item/delete-sync", Test, "mock-service-normal.py", setup, test_delete_sync, teardown); - g_test_add ("/item/delete-async", Test, "mock-service-normal.py", setup, test_delete_async, teardown); -#endif + g_test_add ("/collection/delete-sync", Test, "mock-service-normal.py", setup, test_delete_sync, teardown); + g_test_add ("/collection/delete-async", Test, "mock-service-normal.py", setup, test_delete_async, teardown); return egg_tests_run_with_loop (); } diff --git a/library/tests/test-item.c b/library/tests/test-item.c index 3cf8565..49e664f 100644 --- a/library/tests/test-item.c +++ b/library/tests/test-item.c @@ -84,7 +84,7 @@ static void test_new_sync (Test *test, gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one"; GError *error = NULL; GSecretItem *item; @@ -97,10 +97,23 @@ test_new_sync (Test *test, } static void -test_new_async (Test *test, - gconstpointer unused) +test_new_sync_noexist (Test *test, + gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *item_path = "/org/freedesktop/secrets/collection/english/nonexistant"; + GError *error = NULL; + GSecretItem *item; + + item = gsecret_item_new_sync (test->service, item_path, NULL, &error); + g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); + g_assert (item == NULL); +} + +static void +test_new_async (Test *test, + gconstpointer unused) +{ + const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one"; GAsyncResult *result = NULL; GError *error = NULL; GSecretItem *item; @@ -119,13 +132,34 @@ test_new_async (Test *test, g_object_unref (item); } +static void +test_new_async_noexist (Test *test, + gconstpointer unused) +{ + const gchar *item_path = "/org/freedesktop/secrets/collection/english/nonexistant"; + GAsyncResult *result = NULL; + GError *error = NULL; + GSecretItem *item; + + gsecret_item_new (test->service, item_path, NULL, on_async_result, &result); + g_assert (result == NULL); + + egg_test_wait (); + + item = gsecret_item_new_finish (result, &error); + g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); + g_assert (item == NULL); + g_object_unref (result); +} + static void test_properties (Test *test, gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one"; GError *error = NULL; GHashTable *attributes; + GSecretService *service; GSecretItem *item; guint64 created; guint64 modified; @@ -146,7 +180,7 @@ test_properties (Test *test, attributes = gsecret_item_get_attributes (item); g_assert_cmpstr (g_hash_table_lookup (attributes, "string"), ==, "one"); g_assert_cmpstr (g_hash_table_lookup (attributes, "number"), ==, "1"); - g_assert_cmpstr (g_hash_table_lookup (attributes, "parity"), ==, "odd"); + g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false"); g_assert_cmpuint (g_hash_table_size (attributes), ==, 3); g_hash_table_unref (attributes); @@ -156,6 +190,7 @@ test_properties (Test *test, "modified", &modified, "label", &label, "attributes", &attributes, + "service", &service, NULL); g_assert (locked == FALSE); @@ -167,10 +202,13 @@ test_properties (Test *test, g_assert_cmpstr (g_hash_table_lookup (attributes, "string"), ==, "one"); g_assert_cmpstr (g_hash_table_lookup (attributes, "number"), ==, "1"); - g_assert_cmpstr (g_hash_table_lookup (attributes, "parity"), ==, "odd"); + g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false"); g_assert_cmpuint (g_hash_table_size (attributes), ==, 3); g_hash_table_unref (attributes); + g_assert (service == test->service); + g_object_unref (service); + g_object_unref (item); } @@ -178,7 +216,7 @@ static void test_set_label_sync (Test *test, gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one"; GError *error = NULL; GSecretItem *item; gboolean ret; @@ -206,7 +244,7 @@ static void test_set_label_async (Test *test, gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one"; GAsyncResult *result = NULL; GError *error = NULL; GSecretItem *item; @@ -241,7 +279,7 @@ static void test_set_label_prop (Test *test, gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one"; GError *error = NULL; GSecretItem *item; guint sigs = 2; @@ -271,7 +309,7 @@ static void test_set_attributes_sync (Test *test, gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one"; GError *error = NULL; GSecretItem *item; gboolean ret; @@ -283,7 +321,7 @@ test_set_attributes_sync (Test *test, attributes = gsecret_item_get_attributes (item); g_assert_cmpstr (g_hash_table_lookup (attributes, "string"), ==, "one"); g_assert_cmpstr (g_hash_table_lookup (attributes, "number"), ==, "1"); - g_assert_cmpstr (g_hash_table_lookup (attributes, "parity"), ==, "odd"); + g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false"); g_assert_cmpuint (g_hash_table_size (attributes), ==, 3); g_hash_table_unref (attributes); @@ -308,7 +346,7 @@ static void test_set_attributes_async (Test *test, gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one"; GHashTable *attributes; GError *error = NULL; GAsyncResult *result = NULL; @@ -321,7 +359,7 @@ test_set_attributes_async (Test *test, attributes = gsecret_item_get_attributes (item); g_assert_cmpstr (g_hash_table_lookup (attributes, "string"), ==, "one"); g_assert_cmpstr (g_hash_table_lookup (attributes, "number"), ==, "1"); - g_assert_cmpstr (g_hash_table_lookup (attributes, "parity"), ==, "odd"); + g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false"); g_assert_cmpuint (g_hash_table_size (attributes), ==, 3); g_hash_table_unref (attributes); @@ -351,7 +389,7 @@ static void test_set_attributes_prop (Test *test, gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one"; GError *error = NULL; GSecretItem *item; GHashTable *attributes; @@ -363,7 +401,7 @@ test_set_attributes_prop (Test *test, attributes = gsecret_item_get_attributes (item); g_assert_cmpstr (g_hash_table_lookup (attributes, "string"), ==, "one"); g_assert_cmpstr (g_hash_table_lookup (attributes, "number"), ==, "1"); - g_assert_cmpstr (g_hash_table_lookup (attributes, "parity"), ==, "odd"); + g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false"); g_assert_cmpuint (g_hash_table_size (attributes), ==, 3); g_hash_table_unref (attributes); @@ -391,7 +429,7 @@ static void test_get_secret_sync (Test *test, gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one"; GError *error = NULL; GSecretItem *item; GSecretValue *value; @@ -406,7 +444,7 @@ test_get_secret_sync (Test *test, g_assert (value != NULL); data = gsecret_value_get (value, &length); - egg_assert_cmpmem (data, length, ==, "uno", 3); + egg_assert_cmpmem (data, length, ==, "111", 3); gsecret_value_unref (value); @@ -417,7 +455,7 @@ static void test_get_secret_async (Test *test, gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one"; GAsyncResult *result = NULL; GError *error = NULL; GSecretItem *item; @@ -439,7 +477,7 @@ test_get_secret_async (Test *test, g_object_unref (result); data = gsecret_value_get (value, &length); - egg_assert_cmpmem (data, length, ==, "uno", 3); + egg_assert_cmpmem (data, length, ==, "111", 3); gsecret_value_unref (value); @@ -450,7 +488,7 @@ static void test_delete_sync (Test *test, gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one"; GError *error = NULL; GSecretItem *item; gboolean ret; @@ -473,7 +511,7 @@ static void test_delete_async (Test *test, gconstpointer unused) { - const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one"; + const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one"; GAsyncResult *result = NULL; GError *error = NULL; GSecretItem *item; @@ -506,7 +544,9 @@ main (int argc, char **argv) g_type_init (); g_test_add ("/item/new-sync", Test, "mock-service-normal.py", setup, test_new_sync, teardown); + g_test_add ("/item/new-sync-noexist", Test, "mock-service-normal.py", setup, test_new_sync_noexist, teardown); g_test_add ("/item/new-async", Test, "mock-service-normal.py", setup, test_new_async, teardown); + g_test_add ("/item/new-async-noexist", Test, "mock-service-normal.py", setup, test_new_async_noexist, teardown); g_test_add ("/item/properties", Test, "mock-service-normal.py", setup, test_properties, teardown); g_test_add ("/item/set-label-sync", Test, "mock-service-normal.py", setup, test_set_label_sync, teardown); g_test_add ("/item/set-label-async", Test, "mock-service-normal.py", setup, test_set_label_async, teardown); diff --git a/library/tests/test-service.c b/library/tests/test-service.c index 619d66a..854bfec 100644 --- a/library/tests/test-service.c +++ b/library/tests/test-service.c @@ -13,6 +13,8 @@ #include "config.h" +#include "gsecret-collection.h" +#include "gsecret-item.h" #include "gsecret-service.h" #include "gsecret-private.h" @@ -34,6 +36,15 @@ static const GSecretSchema DELETE_SCHEMA = { } }; +static const GSecretSchema STORE_SCHEMA = { + "org.mock.schema.Store", + { + { "number", GSECRET_ATTRIBUTE_INTEGER }, + { "string", GSECRET_ATTRIBUTE_STRING }, + { "even", GSECRET_ATTRIBUTE_BOOLEAN }, + } +}; + typedef struct { GSecretService *service; } Test; @@ -93,7 +104,7 @@ on_complete_get_result (GObject *source, } static void -test_instance (void) +test_get_sync (void) { GSecretService *service1; GSecretService *service2; @@ -126,6 +137,308 @@ test_instance (void) egg_assert_not_object (service3); } +static void +test_get_async (void) +{ + GSecretService *service1; + GSecretService *service2; + GSecretService *service3; + GAsyncResult *result = NULL; + GError *error = NULL; + + /* Both these sohuld point to the same thing */ + + gsecret_service_get (GSECRET_SERVICE_NONE, NULL, on_complete_get_result, &result); + g_assert (result == NULL); + egg_test_wait (); + service1 = gsecret_service_get_finish (result, &error); + g_assert_no_error (error); + g_clear_object (&result); + + gsecret_service_get (GSECRET_SERVICE_NONE, NULL, on_complete_get_result, &result); + g_assert (result == NULL); + egg_test_wait (); + service2 = gsecret_service_get_finish (result, &error); + g_assert_no_error (error); + g_clear_object (&result); + + g_assert (GSECRET_IS_SERVICE (service1)); + g_assert (service1 == service2); + + g_object_unref (service1); + g_assert (G_IS_OBJECT (service1)); + + g_object_unref (service2); + egg_assert_not_object (service2); + + /* Services were unreffed, so this should create a new one */ + gsecret_service_get (GSECRET_SERVICE_NONE, NULL, on_complete_get_result, &result); + g_assert (result == NULL); + egg_test_wait (); + service3 = gsecret_service_get_finish (result, &error); + g_assert_no_error (error); + g_clear_object (&result); + + g_object_unref (service3); + egg_assert_not_object (service3); +} + +static void +test_get_more_sync (Test *test, + gconstpointer data) +{ + GSecretService *service; + GSecretService *service2; + GError *error = NULL; + const gchar *path; + GList *collections; + + service = gsecret_service_get_sync (GSECRET_SERVICE_NONE, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpuint (gsecret_service_get_flags (service), ==, GSECRET_SERVICE_NONE); + + service2 = gsecret_service_get_sync (GSECRET_SERVICE_LOAD_COLLECTIONS, NULL, &error); + g_assert_no_error (error); + + g_assert (GSECRET_IS_SERVICE (service)); + g_assert (service == service2); + + g_assert_cmpuint (gsecret_service_get_flags (service), ==, GSECRET_SERVICE_LOAD_COLLECTIONS); + collections = gsecret_service_get_collections (service); + g_assert (collections != NULL); + g_list_free_full (collections, g_object_unref); + + g_object_unref (service2); + + service2 = gsecret_service_get_sync (GSECRET_SERVICE_OPEN_SESSION, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpuint (gsecret_service_get_flags (service), ==, GSECRET_SERVICE_OPEN_SESSION | GSECRET_SERVICE_LOAD_COLLECTIONS); + path = gsecret_service_get_session_path (service); + g_assert (path != NULL); + + g_object_unref (service2); + + g_object_unref (service); + egg_assert_not_object (service); +} + +static void +test_get_more_async (Test *test, + gconstpointer data) +{ + GAsyncResult *result = NULL; + GSecretService *service; + GError *error = NULL; + const gchar *path; + GList *collections; + + gsecret_service_get (GSECRET_SERVICE_LOAD_COLLECTIONS | GSECRET_SERVICE_OPEN_SESSION, NULL, on_complete_get_result, &result); + g_assert (result == NULL); + + egg_test_wait (); + + service = gsecret_service_get_finish (result, &error); + g_assert_no_error (error); + g_object_unref (result); + result = NULL; + + g_assert_cmpuint (gsecret_service_get_flags (service), ==, GSECRET_SERVICE_OPEN_SESSION | GSECRET_SERVICE_LOAD_COLLECTIONS); + path = gsecret_service_get_session_path (service); + g_assert (path != NULL); + + collections = gsecret_service_get_collections (service); + g_assert (collections != NULL); + g_list_free_full (collections, g_object_unref); + + g_object_unref (service); + egg_assert_not_object (service); + + /* Now get a session with just collections */ + + gsecret_service_get (GSECRET_SERVICE_LOAD_COLLECTIONS, NULL, on_complete_get_result, &result); + g_assert (result == NULL); + + egg_test_wait (); + + service = gsecret_service_get_finish (result, &error); + g_assert_no_error (error); + g_object_unref (result); + + g_assert_cmpuint (gsecret_service_get_flags (service), ==, GSECRET_SERVICE_LOAD_COLLECTIONS); + path = gsecret_service_get_session_path (service); + g_assert (path == NULL); + + collections = gsecret_service_get_collections (service); + g_assert (collections != NULL); + g_list_free_full (collections, g_object_unref); + + g_object_unref (service); + egg_assert_not_object (service); +} + +static void +test_new_sync (void) +{ + GSecretService *service1; + GSecretService *service2; + GError *error = NULL; + + /* Both these sohuld point to different things */ + + service1 = gsecret_service_new_sync (NULL, GSECRET_SERVICE_NONE, NULL, &error); + g_assert_no_error (error); + + service2 = gsecret_service_new_sync (NULL, GSECRET_SERVICE_NONE, NULL, &error); + g_assert_no_error (error); + + g_assert (GSECRET_IS_SERVICE (service1)); + g_assert (GSECRET_IS_SERVICE (service2)); + g_assert (service1 != service2); + + g_object_unref (service1); + egg_assert_not_object (service1); + + g_object_unref (service2); + egg_assert_not_object (service2); +} + +static void +test_new_async (void) +{ + GSecretService *service1; + GSecretService *service2; + GAsyncResult *result = NULL; + GError *error = NULL; + + /* Both these sohuld point to different things */ + + gsecret_service_new (NULL, GSECRET_SERVICE_NONE, NULL, on_complete_get_result, &result); + g_assert (result == NULL); + egg_test_wait (); + service1 = gsecret_service_new_finish (result, &error); + g_assert_no_error (error); + g_clear_object (&result); + + gsecret_service_new (NULL, GSECRET_SERVICE_NONE, NULL, on_complete_get_result, &result); + g_assert (result == NULL); + egg_test_wait (); + service2 = gsecret_service_new_finish (result, &error); + g_assert_no_error (error); + g_clear_object (&result); + + g_assert (GSECRET_IS_SERVICE (service1)); + g_assert (GSECRET_IS_SERVICE (service2)); + g_assert (service1 != service2); + + g_object_unref (service1); + egg_assert_not_object (service1); + + g_object_unref (service2); + egg_assert_not_object (service2); +} + +static void +test_new_more_sync (Test *test, + gconstpointer data) +{ + GSecretService *service; + GError *error = NULL; + const gchar *path; + GList *collections; + + service = gsecret_service_new_sync (NULL, GSECRET_SERVICE_NONE, NULL, &error); + g_assert_no_error (error); + g_assert (GSECRET_IS_SERVICE (service)); + + g_assert_cmpuint (gsecret_service_get_flags (service), ==, GSECRET_SERVICE_NONE); + g_assert (gsecret_service_get_collections (service) == NULL); + g_assert (gsecret_service_get_session_path (service) == NULL); + + g_object_unref (service); + egg_assert_not_object (service); + + service = gsecret_service_new_sync (NULL, GSECRET_SERVICE_LOAD_COLLECTIONS, NULL, &error); + g_assert_no_error (error); + g_assert (GSECRET_IS_SERVICE (service)); + + g_assert_cmpuint (gsecret_service_get_flags (service), ==, GSECRET_SERVICE_LOAD_COLLECTIONS); + collections = gsecret_service_get_collections (service); + g_assert (collections != NULL); + g_list_free_full (collections, g_object_unref); + g_assert (gsecret_service_get_session_path (service) == NULL); + + g_object_unref (service); + egg_assert_not_object (service); + + service = gsecret_service_new_sync (NULL, GSECRET_SERVICE_OPEN_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert (GSECRET_IS_SERVICE (service)); + + g_assert_cmpuint (gsecret_service_get_flags (service), ==, GSECRET_SERVICE_OPEN_SESSION); + g_assert (gsecret_service_get_collections (service) == NULL); + path = gsecret_service_get_session_path (service); + g_assert (path != NULL); + + g_object_unref (service); + egg_assert_not_object (service); +} + +static void +test_new_more_async (Test *test, + gconstpointer data) +{ + GAsyncResult *result = NULL; + GSecretService *service; + GError *error = NULL; + const gchar *path; + GList *collections; + + gsecret_service_new (NULL, GSECRET_SERVICE_LOAD_COLLECTIONS | GSECRET_SERVICE_OPEN_SESSION, NULL, on_complete_get_result, &result); + g_assert (result == NULL); + + egg_test_wait (); + + service = gsecret_service_new_finish (result, &error); + g_assert_no_error (error); + g_object_unref (result); + result = NULL; + + g_assert_cmpuint (gsecret_service_get_flags (service), ==, GSECRET_SERVICE_OPEN_SESSION | GSECRET_SERVICE_LOAD_COLLECTIONS); + path = gsecret_service_get_session_path (service); + g_assert (path != NULL); + + collections = gsecret_service_get_collections (service); + g_assert (collections != NULL); + g_list_free_full (collections, g_object_unref); + + g_object_unref (service); + egg_assert_not_object (service); + + /* Now get a session with just collections */ + + gsecret_service_new (NULL, GSECRET_SERVICE_LOAD_COLLECTIONS, NULL, on_complete_get_result, &result); + g_assert (result == NULL); + + egg_test_wait (); + + service = gsecret_service_new_finish (result, &error); + g_assert_no_error (error); + g_object_unref (result); + + g_assert_cmpuint (gsecret_service_get_flags (service), ==, GSECRET_SERVICE_LOAD_COLLECTIONS); + path = gsecret_service_get_session_path (service); + g_assert (path == NULL); + + collections = gsecret_service_get_collections (service); + g_assert (collections != NULL); + g_list_free_full (collections, g_object_unref); + + g_object_unref (service); + egg_assert_not_object (service); +} + static void test_connect_async (Test *test, gconstpointer used) @@ -181,8 +494,95 @@ test_connect_ensure_async (Test *test, } static void -test_search_paths (Test *test, +test_ensure_sync (Test *test, + gconstpointer used) +{ + GError *error = NULL; + GSecretService *service; + GSecretServiceFlags flags; + const gchar *path; + gboolean ret; + + /* Passing true, ensures session is established */ + service = gsecret_service_new_sync (NULL, GSECRET_SERVICE_NONE, NULL, &error); + g_assert_no_error (error); + g_assert (service != NULL); + + flags = gsecret_service_get_flags (service); + g_assert_cmpuint (flags, ==, GSECRET_SERVICE_NONE); + + ret = gsecret_service_ensure_collections_sync (service, NULL, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + g_object_get (service, "flags", &flags, NULL); + g_assert_cmpuint (flags, ==, GSECRET_SERVICE_LOAD_COLLECTIONS); + + path = gsecret_service_ensure_session_sync (service, NULL, &error); + g_assert_no_error (error); + g_assert (path != NULL); + + flags = gsecret_service_get_flags (service); + g_assert_cmpuint (flags, ==, GSECRET_SERVICE_OPEN_SESSION | GSECRET_SERVICE_LOAD_COLLECTIONS); + + g_object_unref (service); + egg_assert_not_object (service); +} + +static void +test_ensure_async (Test *test, gconstpointer used) +{ + GAsyncResult *result = NULL; + GSecretServiceFlags flags; + GSecretService *service; + GError *error = NULL; + const gchar *path; + gboolean ret; + + /* Passing true, ensures session is established */ + service = gsecret_service_new_sync (NULL, GSECRET_SERVICE_NONE, NULL, &error); + g_assert_no_error (error); + g_assert (service != NULL); + + flags = gsecret_service_get_flags (service); + g_assert_cmpuint (flags, ==, GSECRET_SERVICE_NONE); + + gsecret_service_ensure_collections (service, NULL, on_complete_get_result, &result); + g_assert (result == NULL); + + egg_test_wait (); + + ret = gsecret_service_ensure_collections_finish (service, result, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + g_object_unref (result); + result = NULL; + + g_object_get (service, "flags", &flags, NULL); + g_assert_cmpuint (flags, ==, GSECRET_SERVICE_LOAD_COLLECTIONS); + + gsecret_service_ensure_session (service, NULL, on_complete_get_result, &result); + g_assert (result == NULL); + + egg_test_wait (); + + path = gsecret_service_ensure_session_finish (service, result, &error); + g_assert_no_error (error); + g_assert (path != NULL); + g_object_unref (result); + result = NULL; + + flags = gsecret_service_get_flags (service); + g_assert_cmpuint (flags, ==, GSECRET_SERVICE_OPEN_SESSION | GSECRET_SERVICE_LOAD_COLLECTIONS); + + g_object_unref (service); + egg_assert_not_object (service); +} + +static void +test_search_paths_sync (Test *test, + gconstpointer used) { GHashTable *attributes; gboolean ret; @@ -199,10 +599,10 @@ test_search_paths (Test *test, g_assert (ret == TRUE); g_assert (locked); - g_assert_cmpstr (locked[0], ==, "/org/freedesktop/secrets/collection/second/item_one"); + g_assert_cmpstr (locked[0], ==, "/org/freedesktop/secrets/collection/spanish/item_one"); g_assert (unlocked); - g_assert_cmpstr (unlocked[0], ==, "/org/freedesktop/secrets/collection/collection/item_one"); + g_assert_cmpstr (unlocked[0], ==, "/org/freedesktop/secrets/collection/english/item_one"); g_strfreev (unlocked); g_strfreev (locked); @@ -236,10 +636,10 @@ test_search_paths_async (Test *test, g_assert (ret == TRUE); g_assert (locked); - g_assert_cmpstr (locked[0], ==, "/org/freedesktop/secrets/collection/second/item_one"); + g_assert_cmpstr (locked[0], ==, "/org/freedesktop/secrets/collection/spanish/item_one"); g_assert (unlocked); - g_assert_cmpstr (unlocked[0], ==, "/org/freedesktop/secrets/collection/collection/item_one"); + g_assert_cmpstr (unlocked[0], ==, "/org/freedesktop/secrets/collection/english/item_one"); g_strfreev (unlocked); g_strfreev (locked); @@ -266,7 +666,7 @@ test_search_paths_nulls (Test *test, g_assert_no_error (error); g_assert (ret == TRUE); g_assert (paths != NULL); - g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/collection/item_one"); + g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/english/item_one"); g_strfreev (paths); ret = gsecret_service_search_for_paths_sync (test->service, attributes, NULL, @@ -274,7 +674,7 @@ test_search_paths_nulls (Test *test, g_assert_no_error (error); g_assert (ret == TRUE); g_assert (paths != NULL); - g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/second/item_one"); + g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/spanish/item_one"); g_strfreev (paths); ret = gsecret_service_search_for_paths_sync (test->service, attributes, NULL, @@ -291,7 +691,7 @@ test_search_paths_nulls (Test *test, g_assert_no_error (error); g_assert (ret == TRUE); g_assert (paths != NULL); - g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/collection/item_one"); + g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/english/item_one"); g_strfreev (paths); g_clear_object (&result); @@ -304,7 +704,7 @@ test_search_paths_nulls (Test *test, g_assert_no_error (error); g_assert (ret == TRUE); g_assert (paths != NULL); - g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/second/item_one"); + g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/spanish/item_one"); g_strfreev (paths); g_clear_object (&result); @@ -322,8 +722,149 @@ test_search_paths_nulls (Test *test, } static void -test_secret_for_path (Test *test, - gconstpointer used) +test_search_sync (Test *test, + gconstpointer used) +{ + GHashTable *attributes; + gboolean ret; + GList *locked; + GList *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_sync (test->service, attributes, NULL, + &unlocked, &locked, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + g_assert (locked != NULL); + g_assert_cmpstr (g_dbus_proxy_get_object_path (locked->data), ==, "/org/freedesktop/secrets/collection/spanish/item_one"); + + g_assert (unlocked != NULL); + g_assert_cmpstr (g_dbus_proxy_get_object_path (unlocked->data), ==, "/org/freedesktop/secrets/collection/english/item_one"); + + g_list_free_full (unlocked, g_object_unref); + g_list_free_full (locked, g_object_unref); + + g_hash_table_unref (attributes); +} + +static void +test_search_async (Test *test, + gconstpointer used) +{ + GAsyncResult *result = NULL; + GHashTable *attributes; + gboolean ret; + GList *locked; + GList *unlocked; + GError *error = NULL; + + attributes = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (attributes, "number", "1"); + + gsecret_service_search (test->service, attributes, NULL, + on_complete_get_result, &result); + egg_test_wait (); + + g_assert (G_IS_ASYNC_RESULT (result)); + ret = gsecret_service_search_finish (test->service, result, + &unlocked, &locked, + &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + g_assert (locked != NULL); + g_assert_cmpstr (g_dbus_proxy_get_object_path (locked->data), ==, "/org/freedesktop/secrets/collection/spanish/item_one"); + + g_assert (unlocked != NULL); + g_assert_cmpstr (g_dbus_proxy_get_object_path (unlocked->data), ==, "/org/freedesktop/secrets/collection/english/item_one"); + + g_list_free_full (unlocked, g_object_unref); + g_list_free_full (locked, g_object_unref); + g_object_unref (result); + + g_hash_table_unref (attributes); +} + +static void +test_search_nulls (Test *test, + gconstpointer used) +{ + GAsyncResult *result = NULL; + GHashTable *attributes; + gboolean ret; + GList *items; + 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_sync (test->service, attributes, NULL, + &items, NULL, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + g_assert (items != NULL); + g_assert_cmpstr (g_dbus_proxy_get_object_path (items->data), ==, "/org/freedesktop/secrets/collection/english/item_one"); + g_list_free_full (items, g_object_unref); + + ret = gsecret_service_search_sync (test->service, attributes, NULL, + NULL, &items, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + g_assert (items != NULL); + g_assert_cmpstr (g_dbus_proxy_get_object_path (items->data), ==, "/org/freedesktop/secrets/collection/spanish/item_one"); + g_list_free_full (items, g_object_unref); + + ret = gsecret_service_search_sync (test->service, attributes, NULL, + NULL, NULL, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + gsecret_service_search (test->service, attributes, NULL, + on_complete_get_result, &result); + egg_test_wait (); + g_assert (G_IS_ASYNC_RESULT (result)); + ret = gsecret_service_search_finish (test->service, result, + &items, NULL, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + g_assert (items != NULL); + g_assert_cmpstr (g_dbus_proxy_get_object_path (items->data), ==, "/org/freedesktop/secrets/collection/english/item_one"); + g_list_free_full (items, g_object_unref); + g_clear_object (&result); + + gsecret_service_search (test->service, attributes, NULL, + on_complete_get_result, &result); + egg_test_wait (); + g_assert (G_IS_ASYNC_RESULT (result)); + ret = gsecret_service_search_finish (test->service, result, + NULL, &items, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + g_assert (items != NULL); + g_assert_cmpstr (g_dbus_proxy_get_object_path (items->data), ==, "/org/freedesktop/secrets/collection/spanish/item_one"); + g_list_free_full (items, g_object_unref); + g_clear_object (&result); + + gsecret_service_search (test->service, attributes, NULL, + on_complete_get_result, &result); + egg_test_wait (); + g_assert (G_IS_ASYNC_RESULT (result)); + ret = gsecret_service_search_finish (test->service, result, + NULL, NULL, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + g_clear_object (&result); + + g_hash_table_unref (attributes); +} + +static void +test_secret_for_path_sync (Test *test, + gconstpointer used) { GSecretValue *value; GError *error = NULL; @@ -331,17 +872,17 @@ test_secret_for_path (Test *test, const gchar *password; gsize length; - path = "/org/freedesktop/secrets/collection/collection/item_one"; + path = "/org/freedesktop/secrets/collection/english/item_one"; value = gsecret_service_get_secret_for_path_sync (test->service, path, NULL, &error); g_assert_no_error (error); g_assert (value != NULL); password = gsecret_value_get (value, &length); g_assert_cmpuint (length, ==, 3); - g_assert_cmpstr (password, ==, "uno"); + g_assert_cmpstr (password, ==, "111"); password = gsecret_value_get (value, NULL); - g_assert_cmpstr (password, ==, "uno"); + g_assert_cmpstr (password, ==, "111"); gsecret_value_unref (value); } @@ -357,7 +898,7 @@ test_secret_for_path_async (Test *test, GAsyncResult *result = NULL; gsize length; - path = "/org/freedesktop/secrets/collection/collection/item_one"; + path = "/org/freedesktop/secrets/collection/english/item_one"; gsecret_service_get_secret_for_path (test->service, path, NULL, on_complete_get_result, &result); g_assert (result == NULL); @@ -370,26 +911,26 @@ test_secret_for_path_async (Test *test, password = gsecret_value_get (value, &length); g_assert_cmpuint (length, ==, 3); - g_assert_cmpstr (password, ==, "uno"); + g_assert_cmpstr (password, ==, "111"); password = gsecret_value_get (value, NULL); - g_assert_cmpstr (password, ==, "uno"); + g_assert_cmpstr (password, ==, "111"); gsecret_value_unref (value); } static void -test_secrets_for_paths (Test *test, - gconstpointer used) +test_secrets_for_paths_sync (Test *test, + gconstpointer used) { - const gchar *path_item_one = "/org/freedesktop/secrets/collection/collection/item_one"; - const gchar *path_item_two = "/org/freedesktop/secrets/collection/collection/item_two"; + const gchar *path_item_one = "/org/freedesktop/secrets/collection/english/item_one"; + const gchar *path_item_two = "/org/freedesktop/secrets/collection/english/item_two"; const gchar *paths[] = { path_item_one, path_item_two, /* This one is locked, and not returned */ - "/org/freedesktop/secrets/collection/second/item_one", + "/org/freedesktop/secrets/collection/spanish/item_one", NULL }; @@ -409,13 +950,13 @@ test_secrets_for_paths (Test *test, g_assert (value != NULL); password = gsecret_value_get (value, &length); g_assert_cmpuint (length, ==, 3); - g_assert_cmpstr (password, ==, "uno"); + g_assert_cmpstr (password, ==, "111"); value = g_hash_table_lookup (values, path_item_two); g_assert (value != NULL); password = gsecret_value_get (value, &length); g_assert_cmpuint (length, ==, 3); - g_assert_cmpstr (password, ==, "dos"); + g_assert_cmpstr (password, ==, "222"); g_hash_table_unref (values); } @@ -424,14 +965,14 @@ static void test_secrets_for_paths_async (Test *test, gconstpointer used) { - const gchar *path_item_one = "/org/freedesktop/secrets/collection/collection/item_one"; - const gchar *path_item_two = "/org/freedesktop/secrets/collection/collection/item_two"; + const gchar *path_item_one = "/org/freedesktop/secrets/collection/english/item_one"; + const gchar *path_item_two = "/org/freedesktop/secrets/collection/english/item_two"; const gchar *paths[] = { path_item_one, path_item_two, /* This one is locked, and not returned */ - "/org/freedesktop/secrets/collection/second/item_one", + "/org/freedesktop/secrets/collection/spanish/item_one", NULL }; @@ -458,17 +999,121 @@ test_secrets_for_paths_async (Test *test, g_assert (value != NULL); password = gsecret_value_get (value, &length); g_assert_cmpuint (length, ==, 3); - g_assert_cmpstr (password, ==, "uno"); + g_assert_cmpstr (password, ==, "111"); value = g_hash_table_lookup (values, path_item_two); g_assert (value != NULL); password = gsecret_value_get (value, &length); g_assert_cmpuint (length, ==, 3); - g_assert_cmpstr (password, ==, "dos"); + g_assert_cmpstr (password, ==, "222"); g_hash_table_unref (values); } +static void +test_secrets_sync (Test *test, + gconstpointer used) +{ + const gchar *path_item_one = "/org/freedesktop/secrets/collection/english/item_one"; + const gchar *path_item_two = "/org/freedesktop/secrets/collection/english/item_two"; + const gchar *path_item_three = "/org/freedesktop/secrets/collection/spanish/item_one"; + + GSecretValue *value; + GHashTable *values; + GError *error = NULL; + const gchar *password; + GSecretItem *item_one, *item_two, *item_three; + GList *items = NULL; + gsize length; + + item_one = gsecret_item_new_sync (test->service, path_item_one, NULL, &error); + item_two = gsecret_item_new_sync (test->service, path_item_two, NULL, &error); + item_three = gsecret_item_new_sync (test->service, path_item_three, NULL, &error); + + items = g_list_append (items, item_one); + items = g_list_append (items, item_two); + items = g_list_append (items, item_three); + + values = gsecret_service_get_secrets_sync (test->service, items, NULL, &error); + g_list_free_full (items, g_object_unref); + g_assert_no_error (error); + + g_assert (values != NULL); + g_assert_cmpuint (g_hash_table_size (values), ==, 2); + + value = g_hash_table_lookup (values, item_one); + g_assert (value != NULL); + password = gsecret_value_get (value, &length); + g_assert_cmpuint (length, ==, 3); + g_assert_cmpstr (password, ==, "111"); + + value = g_hash_table_lookup (values, item_two); + g_assert (value != NULL); + password = gsecret_value_get (value, &length); + g_assert_cmpuint (length, ==, 3); + g_assert_cmpstr (password, ==, "222"); + + g_hash_table_unref (values); +} + +static void +test_secrets_async (Test *test, + gconstpointer used) +{ + const gchar *path_item_one = "/org/freedesktop/secrets/collection/english/item_one"; + const gchar *path_item_two = "/org/freedesktop/secrets/collection/english/item_two"; + const gchar *path_item_three = "/org/freedesktop/secrets/collection/spanish/item_one"; + + GSecretValue *value; + GHashTable *values; + GError *error = NULL; + const gchar *password; + GAsyncResult *result = NULL; + GSecretItem *item_one, *item_two, *item_three; + GList *items = NULL; + gsize length; + + item_one = gsecret_item_new_sync (test->service, path_item_one, NULL, &error); + item_two = gsecret_item_new_sync (test->service, path_item_two, NULL, &error); + item_three = gsecret_item_new_sync (test->service, path_item_three, NULL, &error); + + items = g_list_append (items, item_one); + items = g_list_append (items, item_two); + items = g_list_append (items, item_three); + + gsecret_service_get_secrets (test->service, items, NULL, + on_complete_get_result, &result); + g_assert (result == NULL); + g_list_free (items); + + egg_test_wait (); + + values = gsecret_service_get_secrets_finish (test->service, result, &error); + g_assert_no_error (error); + g_object_unref (result); + + g_assert (values != NULL); + g_assert_cmpuint (g_hash_table_size (values), ==, 2); + + value = g_hash_table_lookup (values, item_one); + g_assert (value != NULL); + password = gsecret_value_get (value, &length); + g_assert_cmpuint (length, ==, 3); + g_assert_cmpstr (password, ==, "111"); + + value = g_hash_table_lookup (values, item_two); + g_assert (value != NULL); + password = gsecret_value_get (value, &length); + g_assert_cmpuint (length, ==, 3); + g_assert_cmpstr (password, ==, "222"); + + g_hash_table_unref (values); + + g_object_unref (item_one); + g_object_unref (item_two); + g_object_unref (item_three); +} + static void test_delete_for_path_sync (Test *test, gconstpointer used) @@ -498,8 +1143,162 @@ test_delete_for_path_sync_prompt (Test *test, } static void -test_delete_password_sync (Test *test, - gconstpointer used) +test_lock_paths_sync (Test *test, + gconstpointer used) +{ + const gchar *collection_path = "/org/freedesktop/secrets/collection/lock_one"; + const gchar *paths[] = { + collection_path, + NULL, + }; + + GError *error = NULL; + gchar **locked = NULL; + gboolean ret; + + ret = gsecret_service_lock_paths_sync (test->service, paths, NULL, &locked, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + g_assert (locked != NULL); + g_assert_cmpstr (locked[0], ==, collection_path); + g_assert (locked[1] == NULL); + g_strfreev (locked); +} + +static void +test_lock_prompt_sync (Test *test, + gconstpointer used) +{ + const gchar *collection_path = "/org/freedesktop/secrets/collection/lock_prompt"; + const gchar *paths[] = { + collection_path, + NULL, + }; + + GError *error = NULL; + gchar **locked = NULL; + gboolean ret; + + ret = gsecret_service_lock_paths_sync (test->service, paths, NULL, &locked, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + g_assert (locked != NULL); + g_assert_cmpstr (locked[0], ==, collection_path); + g_assert (locked[1] == NULL); + g_strfreev (locked); +} + +static void +test_lock_sync (Test *test, + gconstpointer used) +{ + const gchar *collection_path = "/org/freedesktop/secrets/collection/lock_one"; + GSecretCollection *collection; + GError *error = NULL; + GList *locked; + GList *objects; + gboolean ret; + + collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error); + g_assert_no_error (error); + + objects = g_list_append (NULL, collection); + + ret = gsecret_service_lock_sync (test->service, objects, NULL, &locked, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + g_assert (locked != NULL); + g_assert (locked->data == collection); + g_assert (locked->next == NULL); + g_list_free_full (locked, g_object_unref); + + g_list_free (objects); + g_object_unref (collection); +} + +static void +test_unlock_paths_sync (Test *test, + gconstpointer used) +{ + const gchar *collection_path = "/org/freedesktop/secrets/collection/lock_one"; + const gchar *paths[] = { + collection_path, + NULL, + }; + + GError *error = NULL; + gchar **unlocked = NULL; + gboolean ret; + + ret = gsecret_service_unlock_paths_sync (test->service, paths, NULL, &unlocked, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + g_assert (unlocked != NULL); + g_assert_cmpstr (unlocked[0], ==, collection_path); + g_assert (unlocked[1] == NULL); + g_strfreev (unlocked); +} + +static void +test_unlock_prompt_sync (Test *test, + gconstpointer used) +{ + const gchar *collection_path = "/org/freedesktop/secrets/collection/lock_prompt"; + const gchar *paths[] = { + collection_path, + NULL, + }; + + GError *error = NULL; + gchar **unlocked = NULL; + gboolean ret; + + ret = gsecret_service_unlock_paths_sync (test->service, paths, NULL, &unlocked, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + g_assert (unlocked != NULL); + g_assert_cmpstr (unlocked[0], ==, collection_path); + g_assert (unlocked[1] == NULL); + g_strfreev (unlocked); +} + +static void +test_unlock_sync (Test *test, + gconstpointer used) +{ + const gchar *collection_path = "/org/freedesktop/secrets/collection/lock_one"; + GSecretCollection *collection; + GError *error = NULL; + GList *unlocked; + GList *objects; + gboolean ret; + + collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error); + g_assert_no_error (error); + + objects = g_list_append (NULL, collection); + + ret = gsecret_service_unlock_sync (test->service, objects, NULL, &unlocked, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + g_assert (unlocked != NULL); + g_assert (unlocked->data == collection); + g_assert (unlocked->next == NULL); + g_list_free_full (unlocked, g_object_unref); + + g_list_free (objects); + g_object_unref (collection); +} + +static void +test_remove_sync (Test *test, + gconstpointer used) { GError *error = NULL; gboolean ret; @@ -515,8 +1314,8 @@ test_delete_password_sync (Test *test, } static void -test_delete_password_async (Test *test, - gconstpointer used) +test_remove_async (Test *test, + gconstpointer used) { GError *error = NULL; GAsyncResult *result = NULL; @@ -541,15 +1340,15 @@ test_delete_password_async (Test *test, } static void -test_delete_password_locked (Test *test, - gconstpointer used) +test_remove_locked (Test *test, + gconstpointer used) { GError *error = NULL; gboolean ret; ret = gsecret_service_remove_sync (test->service, &DELETE_SCHEMA, NULL, &error, "even", FALSE, - "string", "three", + "string", "tres", "number", 3, NULL); @@ -558,8 +1357,8 @@ test_delete_password_locked (Test *test, } static void -test_delete_password_no_match (Test *test, - gconstpointer used) +test_remove_no_match (Test *test, + gconstpointer used) { GError *error = NULL; gboolean ret; @@ -574,6 +1373,100 @@ test_delete_password_no_match (Test *test, g_assert (ret == FALSE); } +static void +test_lookup_sync (Test *test, + gconstpointer used) +{ + GError *error = NULL; + GSecretValue *value; + gsize length; + + value = gsecret_service_lookup_sync (test->service, &STORE_SCHEMA, NULL, &error, + "even", FALSE, + "string", "one", + "number", 1, + NULL); + + g_assert_no_error (error); + + g_assert (value != NULL); + g_assert_cmpstr (gsecret_value_get (value, &length), ==, "111"); + g_assert_cmpuint (length, ==, 3); + + gsecret_value_unref (value); +} + +static void +test_lookup_async (Test *test, + gconstpointer used) +{ + GError *error = NULL; + GAsyncResult *result = NULL; + GSecretValue *value; + gsize length; + + gsecret_service_lookup (test->service, &STORE_SCHEMA, NULL, + on_complete_get_result, &result, + "even", FALSE, + "string", "one", + "number", 1, + NULL); + + g_assert (result == NULL); + + egg_test_wait (); + + value = gsecret_service_lookup_finish (test->service, result, &error); + g_assert_no_error (error); + + g_assert (value != NULL); + g_assert_cmpstr (gsecret_value_get (value, &length), ==, "111"); + g_assert_cmpuint (length, ==, 3); + + gsecret_value_unref (value); + g_object_unref (result); +} + +static void +test_lookup_locked (Test *test, + gconstpointer used) +{ + GError *error = NULL; + GSecretValue *value; + gsize length; + + value = gsecret_service_lookup_sync (test->service, &STORE_SCHEMA, NULL, &error, + "even", FALSE, + "string", "tres", + "number", 3, + NULL); + + g_assert_no_error (error); + + g_assert (value != NULL); + g_assert_cmpstr (gsecret_value_get (value, &length), ==, "3333"); + g_assert_cmpuint (length, ==, 4); + + gsecret_value_unref (value); +} + +static void +test_lookup_no_match (Test *test, + gconstpointer used) +{ + GError *error = NULL; + GSecretValue *value; + + /* Won't match anything */ + value = gsecret_service_lookup_sync (test->service, &STORE_SCHEMA, NULL, &error, + "even", TRUE, + "string", "one", + NULL); + + g_assert_no_error (error); + g_assert (value == NULL); +} + int main (int argc, char **argv) { @@ -581,27 +1474,56 @@ main (int argc, char **argv) g_set_prgname ("test-service"); g_type_init (); - g_test_add_func ("/service/instance", test_instance); + g_test_add_func ("/service/get-sync", test_get_sync); + g_test_add_func ("/service/get-async", test_get_async); + g_test_add ("/service/get-more-sync", Test, "mock-service-normal.py", setup_mock, test_get_more_sync, teardown_mock); + g_test_add ("/service/get-more-async", Test, "mock-service-normal.py", setup_mock, test_get_more_async, teardown_mock); + + g_test_add_func ("/service/new-sync", test_new_sync); + g_test_add_func ("/service/new-async", test_new_async); + g_test_add ("/service/new-more-sync", Test, "mock-service-normal.py", setup_mock, test_new_more_sync, teardown_mock); + g_test_add ("/service/new-more-async", Test, "mock-service-normal.py", setup_mock, test_new_more_async, teardown_mock); g_test_add ("/service/connect-sync", Test, "mock-service-normal.py", setup_mock, test_connect_async, teardown_mock); g_test_add ("/service/connect-ensure-sync", Test, "mock-service-normal.py", setup_mock, test_connect_ensure_async, teardown_mock); + g_test_add ("/service/ensure-sync", Test, "mock-service-normal.py", setup_mock, test_ensure_sync, teardown_mock); + g_test_add ("/service/ensure-async", Test, "mock-service-normal.py", setup_mock, test_ensure_async, teardown_mock); - g_test_add ("/service/search-for-paths", Test, "mock-service-normal.py", setup, test_search_paths, teardown); + g_test_add ("/service/search-for-paths", Test, "mock-service-normal.py", setup, test_search_paths_sync, teardown); g_test_add ("/service/search-for-paths-async", Test, "mock-service-normal.py", setup, test_search_paths_async, teardown); g_test_add ("/service/search-for-paths-nulls", Test, "mock-service-normal.py", setup, test_search_paths_nulls, teardown); + g_test_add ("/service/search-sync", Test, "mock-service-normal.py", setup, test_search_sync, teardown); + g_test_add ("/service/search-async", Test, "mock-service-normal.py", setup, test_search_async, teardown); + g_test_add ("/service/search-nulls", Test, "mock-service-normal.py", setup, test_search_nulls, teardown); - g_test_add ("/service/secret-for-path", Test, "mock-service-normal.py", setup, test_secret_for_path, teardown); - g_test_add ("/service/secret-for-path-plain", Test, "mock-service-only-plain.py", setup, test_secret_for_path, teardown); + g_test_add ("/service/secret-for-path-sync", Test, "mock-service-normal.py", setup, test_secret_for_path_sync, teardown); + g_test_add ("/service/secret-for-path-plain", Test, "mock-service-only-plain.py", setup, test_secret_for_path_sync, teardown); g_test_add ("/service/secret-for-path-async", Test, "mock-service-normal.py", setup, test_secret_for_path_async, teardown); - g_test_add ("/service/secrets-for-paths", Test, "mock-service-normal.py", setup, test_secrets_for_paths, teardown); + g_test_add ("/service/secrets-for-paths-sync", Test, "mock-service-normal.py", setup, test_secrets_for_paths_sync, teardown); g_test_add ("/service/secrets-for-paths-async", Test, "mock-service-normal.py", setup, test_secrets_for_paths_async, teardown); + g_test_add ("/service/secrets-sync", Test, "mock-service-normal.py", setup, test_secrets_sync, teardown); + g_test_add ("/service/secrets-async", Test, "mock-service-normal.py", setup, test_secrets_async, teardown); g_test_add ("/service/delete-for-path", Test, "mock-service-delete.py", setup, test_delete_for_path_sync, teardown); g_test_add ("/service/delete-for-path-with-prompt", Test, "mock-service-delete.py", setup, test_delete_for_path_sync_prompt, teardown); - g_test_add ("/service/delete-password-sync", Test, "mock-service-delete.py", setup, test_delete_password_sync, teardown); - g_test_add ("/service/delete-password-async", Test, "mock-service-delete.py", setup, test_delete_password_async, teardown); - g_test_add ("/service/delete-password-locked", Test, "mock-service-delete.py", setup, test_delete_password_locked, teardown); - g_test_add ("/service/delete-password-no-match", Test, "mock-service-delete.py", setup, test_delete_password_no_match, teardown); + + g_test_add ("/service/lock-paths-sync", Test, "mock-service-lock.py", setup, test_lock_paths_sync, teardown); + g_test_add ("/service/lock-prompt-sync", Test, "mock-service-lock.py", setup, test_lock_prompt_sync, teardown); + g_test_add ("/service/lock-sync", Test, "mock-service-lock.py", setup, test_lock_sync, teardown); + + g_test_add ("/service/unlock-paths-sync", Test, "mock-service-lock.py", setup, test_unlock_paths_sync, teardown); + g_test_add ("/service/unlock-prompt-sync", Test, "mock-service-lock.py", setup, test_unlock_prompt_sync, teardown); + g_test_add ("/service/unlock-sync", Test, "mock-service-lock.py", setup, test_unlock_sync, teardown); + + g_test_add ("/service/lookup-sync", Test, "mock-service-normal.py", setup, test_lookup_sync, teardown); + g_test_add ("/service/lookup-async", Test, "mock-service-normal.py", setup, test_lookup_async, teardown); + g_test_add ("/service/lookup-locked", Test, "mock-service-normal.py", setup, test_lookup_locked, teardown); + g_test_add ("/service/lookup-no-match", Test, "mock-service-normal.py", setup, test_lookup_no_match, teardown); + + g_test_add ("/service/remove-sync", Test, "mock-service-delete.py", setup, test_remove_sync, teardown); + g_test_add ("/service/remove-async", Test, "mock-service-delete.py", setup, test_remove_async, teardown); + g_test_add ("/service/remove-locked", Test, "mock-service-delete.py", setup, test_remove_locked, teardown); + g_test_add ("/service/remove-no-match", Test, "mock-service-delete.py", setup, test_remove_no_match, teardown); return egg_tests_run_with_loop (); }