[libsecret] Add secret_service_read_alias() and secret_service_set_alias()



commit 79aab9d941738afb62b2403d243d999c126943b1
Author: Stef Walter <stefw gnome org>
Date:   Sat Jun 23 14:09:50 2012 +0200

    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
 <SUBSECTION Standard>
 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 ();
 }



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