From 79aab9d941738afb62b2403d243d999c126943b1 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Sat, 23 Jun 2012 14:09:50 +0200 Subject: Add secret_service_read_alias() and secret_service_set_alias() * Wrappers for Secret Service ReadAlias() and SetAlias() methods in various permutations. --- docs/reference/libsecret/libsecret-sections.txt | 12 + library/secret-methods.c | 533 ++++++++++++++++++++++++ library/secret-private.h | 3 + library/secret-service.c | 25 +- library/secret-service.h | 64 +++ library/tests/mock/service.py | 16 +- library/tests/test-methods.c | 127 ++++++ 7 files changed, 768 insertions(+), 12 deletions(-) diff --git a/docs/reference/libsecret/libsecret-sections.txt b/docs/reference/libsecret/libsecret-sections.txt index 746c29a..7f23f23 100644 --- a/docs/reference/libsecret/libsecret-sections.txt +++ b/docs/reference/libsecret/libsecret-sections.txt @@ -232,6 +232,18 @@ secret_service_create_item_path_sync secret_service_delete_path secret_service_delete_path_finish secret_service_delete_path_sync +secret_service_read_alias +secret_service_read_alias_finish +secret_service_read_alias_sync +secret_service_read_alias_path +secret_service_read_alias_path_finish +secret_service_read_alias_path_sync +secret_service_set_alias +secret_service_set_alias_finish +secret_service_set_alias_sync +secret_service_set_alias_path +secret_service_set_alias_path_finish +secret_service_set_alias_path_sync SECRET_IS_SERVICE SECRET_IS_SERVICE_CLASS diff --git a/library/secret-methods.c b/library/secret-methods.c index 2a9bf36..9b2ca98 100644 --- a/library/secret-methods.c +++ b/library/secret-methods.c @@ -3448,3 +3448,536 @@ secret_service_create_item_path_sync (SecretService *self, return path; } + +typedef struct { + GCancellable *cancellable; + SecretCollection *collection; +} ReadClosure; + +static void +read_closure_free (gpointer data) +{ + ReadClosure *read = data; + if (read->collection) + g_object_unref (read->collection); + if (read->cancellable) + g_object_unref (read->cancellable); + g_slice_free (ReadClosure, read); +} + +static void +on_read_alias_collection (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data); + ReadClosure *read = g_simple_async_result_get_op_res_gpointer (async); + GError *error = NULL; + + read->collection = secret_collection_new_finish (result, &error); + if (error != NULL) + g_simple_async_result_take_error (async, error); + + g_simple_async_result_complete (async); + g_object_unref (async); +} + +static void +on_read_alias_path (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data); + ReadClosure *read = g_simple_async_result_get_op_res_gpointer (async); + SecretService *self = SECRET_SERVICE (source); + GError *error = NULL; + gchar *collection_path; + + collection_path = secret_service_read_alias_path_finish (self, result, &error); + if (error == NULL) { + + /* No collection for this alias */ + if (collection_path == NULL) { + g_simple_async_result_complete (async); + + } else { + read->collection = _secret_service_find_collection_instance (self, + collection_path); + if (read->collection != NULL) { + g_simple_async_result_complete (async); + + /* No collection loaded, but valid path, load */ + } else { + secret_collection_new (self, collection_path, read->cancellable, + on_read_alias_collection, g_object_ref (async)); + } + } + + } else { + g_simple_async_result_take_error (async, error); + g_simple_async_result_complete (async); + } + + g_free (collection_path); + g_object_unref (async); +} + +/** + * secret_service_read_alias: + * @self: a secret service object + * @alias: the alias to lookup + * @cancellable: (allow-none): optional cancellation object + * @callback: called when the operation completes + * @user_data: data to pass to the callback + * + * Lookup which collection is assigned to this alias. Aliases help determine + * well known collections, such as 'default'. + * + * This method will return immediately and complete asynchronously. + */ +void +secret_service_read_alias (SecretService *self, + const gchar *alias, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *async; + ReadClosure *read; + + g_return_if_fail (SECRET_IS_SERVICE (self)); + g_return_if_fail (alias != NULL); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + async = g_simple_async_result_new (G_OBJECT (self), callback, user_data, + secret_service_read_alias); + read = g_slice_new0 (ReadClosure); + read->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + g_simple_async_result_set_op_res_gpointer (async, read, read_closure_free); + + secret_service_read_alias_path (self, alias, cancellable, + on_read_alias_path, g_object_ref (async)); + + g_object_unref (async); +} + +/** + * secret_service_read_alias_finish: + * @self: a secret service object + * @result: asynchronous result passed to callback + * @error: location to place error on failure + * + * Finish an asynchronous operation to lookup which collection is assigned + * to an alias. + * + * Returns: (transfer full): the collection, or %NULL if none assigned to the alias + */ +SecretCollection * +secret_service_read_alias_finish (SecretService *self, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *async; + ReadClosure *read; + + g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL); + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), + secret_service_read_alias), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + async = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (async, error)) + return NULL; + read = g_simple_async_result_get_op_res_gpointer (async); + if (read->collection) + g_object_ref (read->collection); + return read->collection; +} + +/** + * secret_service_read_alias_sync: + * @self: a secret service object + * @alias: the alias to lookup + * @cancellable: (allow-none): optional cancellation object + * @error: location to place error on failure + * + * Lookup which collection is assigned to this alias. Aliases help determine + * well known collections, such as 'default'. + * + * This method may block and should not be used in user interface threads. + * + * Returns: (transfer full): the collection, or %NULL if none assigned to the alias + */ +SecretCollection * +secret_service_read_alias_sync (SecretService *self, + const gchar *alias, + GCancellable *cancellable, + GError **error) +{ + SecretCollection *collection; + gchar *collection_path; + + g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL); + g_return_val_if_fail (alias != NULL, NULL); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + collection_path = secret_service_read_alias_path_sync (self, alias, + cancellable, error); + if (collection_path == NULL) + return NULL; + + /* No collection for this alias */ + if (collection_path == NULL) { + collection = NULL; + + } else { + collection = _secret_service_find_collection_instance (self, + collection_path); + + /* No collection loaded, but valid path, load */ + if (collection == NULL) { + collection = secret_collection_new_sync (self, collection_path, + cancellable, error); + } + } + + g_free (collection_path); + return collection; +} + +/** + * secret_service_read_alias_path: + * @self: a secret service object + * @alias: the alias to lookup + * @cancellable: (allow-none): optional cancellation object + * @callback: called when the operation completes + * @user_data: data to pass to the callback + * + * Lookup which collection is assigned to this alias. Aliases help determine + * well known collections, such as 'default'. This method looks up the + * dbus object path of the well known collection. + * + * This method will return immediately and complete asynchronously. + */ +void +secret_service_read_alias_path (SecretService *self, + const gchar *alias, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (SECRET_IS_SERVICE (self)); + g_return_if_fail (alias != NULL); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + g_dbus_proxy_call (G_DBUS_PROXY (self), "ReadAlias", + g_variant_new ("(s)", alias), + G_DBUS_CALL_FLAGS_NONE, -1, + cancellable, callback, user_data); +} + +/** + * secret_service_read_alias_path_finish: + * @self: a secret service object + * @result: asynchronous result passed to callback + * @error: location to place error on failure + * + * Finish an asynchronous operation to lookup which collection is assigned + * to an alias. This method returns the DBus object path of the collection + * + * Returns: (transfer full): the collection dbus object path, or %NULL if + * none assigned to the alias + */ +gchar * +secret_service_read_alias_path_finish (SecretService *self, + GAsyncResult *result, + GError **error) +{ + gchar *collection_path; + GVariant *retval; + + retval = g_dbus_proxy_call_finish (G_DBUS_PROXY (self), result, error); + if (retval == NULL) + return NULL; + + g_variant_get (retval, "(o)", &collection_path); + g_variant_unref (retval); + + if (g_str_equal (collection_path, "/")) { + g_free (collection_path); + collection_path = NULL; + } + + return collection_path; +} + +/** + * secret_service_read_alias_path_sync: + * @self: a secret service object + * @alias: the alias to lookup + * @cancellable: (allow-none): optional cancellation object + * @error: location to place error on failure + * + * Lookup which collection is assigned to this alias. Aliases help determine + * well known collections, such as 'default'. This method returns the dbus + * object path of the collection. + * + * This method may block and should not be used in user interface threads. + * + * Returns: (transfer full): the collection dbus object path, or %NULL if + * none assigned to the alias + */ +gchar * +secret_service_read_alias_path_sync (SecretService *self, + const gchar *alias, + GCancellable *cancellable, + GError **error) +{ + SecretSync *sync; + gchar *collection_path; + + g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL); + g_return_val_if_fail (alias != NULL, NULL); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + sync = _secret_sync_new (); + g_main_context_push_thread_default (sync->context); + + secret_service_read_alias_path (self, alias, cancellable, _secret_sync_on_result, sync); + + g_main_loop_run (sync->loop); + + collection_path = secret_service_read_alias_path_finish (self, sync->result, error); + + g_main_context_pop_thread_default (sync->context); + _secret_sync_free (sync); + + return collection_path; +} + +/** + * secret_service_set_alias: + * @self: a secret service object + * @alias: the alias to assign the collection to + * @collection: (allow-none): the collection to assign to the alias + * @cancellable: (allow-none): optional cancellation object + * @callback: called when the operation completes + * @user_data: data to pass to the callback + * + * Assign a collection to this alias. Aliases help determine + * well known collections, such as 'default'. + * + * This method will return immediately and complete asynchronously. + */ +void +secret_service_set_alias (SecretService *self, + const gchar *alias, + SecretCollection *collection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + const gchar *collection_path; + + g_return_if_fail (SECRET_IS_SERVICE (self)); + g_return_if_fail (alias != NULL); + g_return_if_fail (collection == NULL || SECRET_IS_COLLECTION (collection)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + if (collection) { + collection_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection)); + g_return_if_fail (collection != NULL); + } else { + collection_path = NULL; + } + + secret_service_set_alias_path (self, alias, collection_path, cancellable, + callback, user_data); +} + +/** + * secret_service_set_alias_finish: + * @self: a secret service object + * @result: asynchronous result passed to callback + * @error: location to place error on failure + * + * Finish an asynchronous operation to assign a collection to an alias. + * + * Returns: %TRUE if successful + */ +gboolean +secret_service_set_alias_finish (SecretService *self, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + return secret_service_set_alias_path_finish (self, result, error); +} + +/** + * secret_service_set_alias_sync: + * @self: a secret service object + * @alias: the alias to assign the collection to + * @collection: (allow-none): the collection to assign to the alias + * @cancellable: (allow-none): optional cancellation object + * @error: location to place error on failure + * + * Assign a collection to this alias. Aliases help determine + * well known collections, such as 'default'. + * + * This method may block and should not be used in user interface threads. + * + * Returns: %TRUE if successful + */ +gboolean +secret_service_set_alias_sync (SecretService *self, + const gchar *alias, + SecretCollection *collection, + GCancellable *cancellable, + GError **error) +{ + SecretSync *sync; + gboolean ret; + + g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE); + g_return_val_if_fail (alias != 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 = _secret_sync_new (); + g_main_context_push_thread_default (sync->context); + + secret_service_set_alias (self, alias, collection, cancellable, + _secret_sync_on_result, sync); + + g_main_loop_run (sync->loop); + + ret = secret_service_set_alias_finish (self, sync->result, error); + + g_main_context_pop_thread_default (sync->context); + _secret_sync_free (sync); + + return ret; +} + +/** + * secret_service_set_alias_path: + * @self: a secret service object + * @alias: the alias to assign the collection to + * @collection_path: (allow-none): the dbus object path of the collection to assign to the alias + * @cancellable: (allow-none): optional cancellation object + * @callback: called when the operation completes + * @user_data: data to pass to the callback + * + * Assign a collection to this alias. Aliases help determine + * well known collections, such as 'default'. This method takes the dbus object + * path of the collection to assign to the alias. + * + * This method will return immediately and complete asynchronously. + */ +void +secret_service_set_alias_path (SecretService *self, + const gchar *alias, + const gchar *collection_path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (SECRET_IS_SERVICE (self)); + g_return_if_fail (alias != NULL); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + if (collection_path == NULL) + collection_path = "/"; + else + g_return_if_fail (g_variant_is_object_path (collection_path)); + + g_dbus_proxy_call (G_DBUS_PROXY (self), "SetAlias", + g_variant_new ("(so)", alias, collection_path), + G_DBUS_CALL_FLAGS_NONE, -1, cancellable, + callback, user_data); +} + +/** + * secret_service_set_alias_path_finish: + * @self: a secret service object + * @result: asynchronous result passed to callback + * @error: location to place error on failure + * + * Finish an asynchronous operation to assign a collection to an alias. + * + * Returns: %TRUE if successful + */ +gboolean +secret_service_set_alias_path_finish (SecretService *self, + GAsyncResult *result, + GError **error) +{ + GVariant *retval; + + g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + retval = g_dbus_proxy_call_finish (G_DBUS_PROXY (self), result, error); + if (retval == NULL) + return FALSE; + + g_variant_unref (retval); + return TRUE; +} + +/** + * secret_service_set_alias_path_sync: + * @self: a secret service object + * @alias: the alias to assign the collection to + * @collection_path: (allow-none): the dbus object path of the collection to assign to the alias + * @cancellable: (allow-none): optional cancellation object + * @error: location to place error on failure + * + * Assign a collection to this alias. Aliases help determine + * well known collections, such as 'default'. This method takes the dbus object + * path of the collection to assign to the alias. + * + * This method may block and should not be used in user interface threads. + * + * Returns: %TRUE if successful + */ +gboolean +secret_service_set_alias_path_sync (SecretService *self, + const gchar *alias, + const gchar *collection_path, + GCancellable *cancellable, + GError **error) +{ + SecretSync *sync; + gboolean ret; + + g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE); + g_return_val_if_fail (alias != NULL, FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (collection_path == NULL) + collection_path = "/"; + else + g_return_val_if_fail (g_variant_is_object_path (collection_path), FALSE); + + sync = _secret_sync_new (); + g_main_context_push_thread_default (sync->context); + + secret_service_set_alias_path (self, alias, collection_path, + cancellable, _secret_sync_on_result, sync); + + g_main_loop_run (sync->loop); + + ret = secret_service_set_alias_path_finish (self, sync->result, error); + + g_main_context_pop_thread_default (sync->context); + _secret_sync_free (sync); + + return ret; +} diff --git a/library/secret-private.h b/library/secret-private.h index 3cb0dd1..c079758 100644 --- a/library/secret-private.h +++ b/library/secret-private.h @@ -139,6 +139,9 @@ void _secret_service_search_for_paths_variant (SecretService *se SecretItem * _secret_service_find_item_instance (SecretService *self, const gchar *item_path); +SecretCollection * _secret_service_find_collection_instance (SecretService *self, + const gchar *collection_path); + SecretItem * _secret_collection_find_item_instance (SecretCollection *self, const gchar *item_path); diff --git a/library/secret-service.c b/library/secret-service.c index 9753616..d449f50 100644 --- a/library/secret-service.c +++ b/library/secret-service.c @@ -1029,13 +1029,7 @@ _secret_service_find_item_instance (SecretService *self, collection_path = _secret_util_parent_path (item_path); - g_mutex_lock (&self->pv->mutex); - 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); + collection = _secret_service_find_collection_instance (self, collection_path); g_free (collection_path); @@ -1048,6 +1042,23 @@ _secret_service_find_item_instance (SecretService *self, return item; } +SecretCollection * +_secret_service_find_collection_instance (SecretService *self, + const gchar *collection_path) +{ + SecretCollection *collection = NULL; + + g_mutex_lock (&self->pv->mutex); + 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); + + return collection; +} + SecretSession * _secret_service_get_session (SecretService *self) { diff --git a/library/secret-service.h b/library/secret-service.h index 82f246e..25fc944 100644 --- a/library/secret-service.h +++ b/library/secret-service.h @@ -481,6 +481,70 @@ gchar * secret_service_create_item_path_sync (SecretService GCancellable *cancellable, GError **error); +void secret_service_read_alias (SecretService *self, + const gchar *alias, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +SecretCollection * secret_service_read_alias_finish (SecretService *self, + GAsyncResult *result, + GError **error); + +SecretCollection * secret_service_read_alias_sync (SecretService *self, + const gchar *alias, + GCancellable *cancellable, + GError **error); + +void secret_service_read_alias_path (SecretService *self, + const gchar *alias, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gchar * secret_service_read_alias_path_finish (SecretService *self, + GAsyncResult *result, + GError **error); + +gchar * secret_service_read_alias_path_sync (SecretService *self, + const gchar *alias, + GCancellable *cancellable, + GError **error); + +void secret_service_set_alias (SecretService *self, + const gchar *alias, + SecretCollection *collection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean secret_service_set_alias_finish (SecretService *self, + GAsyncResult *result, + GError **error); + +gboolean secret_service_set_alias_sync (SecretService *self, + const gchar *alias, + SecretCollection *collection, + GCancellable *cancellable, + GError **error); + +void secret_service_set_alias_path (SecretService *self, + const gchar *alias, + const gchar *collection_path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean secret_service_set_alias_path_finish (SecretService *self, + GAsyncResult *result, + GError **error); + +gboolean secret_service_set_alias_path_sync (SecretService *self, + const gchar *alias, + const gchar *collection_path, + GCancellable *cancellable, + GError **error); + G_END_DECLS #endif /* __SECRET_SERVICE_H___ */ diff --git a/library/tests/mock/service.py b/library/tests/mock/service.py index b36c2b1..6ba8ea3 100644 --- a/library/tests/mock/service.py +++ b/library/tests/mock/service.py @@ -551,8 +551,11 @@ class SecretService(dbus.service.Object): def set_alias(self, name, collection): self.remove_alias(name) - collection.add_alias(name) - self.aliases[name] = collection + if collection: + collection.add_alias(name) + self.aliases[name] = collection + elif name in self.aliases: + del self.aliases[name] def remove_alias(self, name): if name in self.aliases: @@ -656,9 +659,12 @@ class SecretService(dbus.service.Object): @dbus.service.method('org.freedesktop.Secret.Service') def SetAlias(self, name, collection): - if collection not in self.collections: - raise NoSuchObject("no such Collection") - self.set_alias(name, self.collections[collection]) + if collection == dbus.ObjectPath("/"): + self.set_alias(name, None) + else: + if collection not in self.collections: + raise NoSuchObject("no such Collection") + self.set_alias(name, self.collections[collection]) @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v') def Get(self, interface_name, property_name): diff --git a/library/tests/test-methods.c b/library/tests/test-methods.c index 377fb85..c699d4f 100644 --- a/library/tests/test-methods.c +++ b/library/tests/test-methods.c @@ -1351,6 +1351,127 @@ test_store_async (Test *test, g_strfreev (paths); } +static void +test_read_alias_sync (Test *test, + gconstpointer used) +{ + const gchar *collection_path; + SecretCollection *collection; + GError *error = NULL; + + collection = secret_service_read_alias_sync (test->service, "default", NULL, &error); + g_assert_no_error (error); + + collection_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection)); + g_assert_cmpstr (collection_path, ==, "/org/freedesktop/secrets/collection/english"); + g_object_unref (collection); + + collection = secret_service_read_alias_sync (test->service, "unknown", NULL, &error); + g_assert_no_error (error); + g_assert (collection == NULL); +} + +static void +test_read_alias_async (Test *test, + gconstpointer used) +{ + const gchar *collection_path; + SecretCollection *collection; + GAsyncResult *result = NULL; + GError *error = NULL; + + secret_service_read_alias (test->service, "default", NULL, + on_complete_get_result, &result); + g_assert (result == NULL); + egg_test_wait (); + + collection = secret_service_read_alias_finish (test->service, result, &error); + g_assert_no_error (error); + g_object_unref (result); + + collection_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection)); + g_assert_cmpstr (collection_path, ==, "/org/freedesktop/secrets/collection/english"); + g_object_unref (collection); + result = NULL; + + secret_service_read_alias (test->service, "unknown", NULL, + on_complete_get_result, &result); + g_assert (result == NULL); + egg_test_wait (); + + collection = secret_service_read_alias_finish (test->service, result, &error); + g_assert_no_error (error); + g_assert (collection == NULL); + g_object_unref (result); +} + +static void +test_set_alias_sync (Test *test, + gconstpointer used) +{ + SecretCollection *collection; + SecretCollection *blah; + GError *error = NULL; + gboolean ret; + + blah = secret_service_read_alias_sync (test->service, "blah", NULL, &error); + g_assert_no_error (error); + g_assert (blah == NULL); + + collection = secret_collection_new_sync (test->service, "/org/freedesktop/secrets/collection/english", NULL, &error); + g_assert_no_error (error); + g_assert (SECRET_IS_COLLECTION (collection)); + + ret = secret_service_set_alias_sync (test->service, "blah", collection, NULL, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + blah = secret_service_read_alias_sync (test->service, "blah", NULL, &error); + g_assert_no_error (error); + g_assert_cmpstr (g_dbus_proxy_get_object_path (G_DBUS_PROXY (blah)), ==, g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection))); + g_object_unref (blah); + + ret = secret_service_set_alias_sync (test->service, "blah", NULL, NULL, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + blah = secret_service_read_alias_sync (test->service, "blah", NULL, &error); + g_assert_no_error (error); + g_assert (blah == NULL); + + g_object_unref (collection); +} + +static void +test_set_alias_path (Test *test, + gconstpointer used) +{ + gchar *path; + GError *error = NULL; + gboolean ret; + + path = secret_service_read_alias_path_sync (test->service, "blah", NULL, &error); + g_assert_no_error (error); + g_assert (path == NULL); + + ret = secret_service_set_alias_path_sync (test->service, "blah", "/org/freedesktop/secrets/collection/english", NULL, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + path = secret_service_read_alias_path_sync (test->service, "blah", NULL, &error); + g_assert_no_error (error); + g_assert_cmpstr (path, ==, "/org/freedesktop/secrets/collection/english"); + g_free (path); + + ret = secret_service_set_alias_path_sync (test->service, "blah", NULL, NULL, &error); + g_assert_no_error (error); + g_assert (ret == TRUE); + + path = secret_service_read_alias_path_sync (test->service, "blah", NULL, &error); + g_assert_no_error (error); + g_assert (path == NULL); +} + int main (int argc, char **argv) { @@ -1406,5 +1527,11 @@ main (int argc, char **argv) g_test_add ("/service/store-async", Test, "mock-service-normal.py", setup, test_store_async, teardown); g_test_add ("/service/store-replace", Test, "mock-service-normal.py", setup, test_store_replace, teardown); + g_test_add ("/service/read-alias-sync", Test, "mock-service-normal.py", setup, test_read_alias_sync, teardown); + g_test_add ("/service/read-alias-async", Test, "mock-service-normal.py", setup, test_read_alias_async, teardown); + + g_test_add ("/service/set-alias-sync", Test, "mock-service-normal.py", setup, test_set_alias_sync, teardown); + g_test_add ("/service/set-alias-path", Test, "mock-service-normal.py", setup, test_set_alias_path, teardown); + return egg_tests_run_with_loop (); } -- cgit v1.2.1