summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2012-06-23 14:09:50 +0200
committerStef Walter <stefw@gnome.org>2012-06-23 14:47:13 +0200
commit79aab9d941738afb62b2403d243d999c126943b1 (patch)
tree191fd5ba0888f14cc99912a9d8c6d2b0511bb819
parent279ea1cc10064261779e02656772d8546ce194df (diff)
downloadlibsecret-79aab9d941738afb62b2403d243d999c126943b1.tar.gz
Add secret_service_read_alias() and secret_service_set_alias()
* Wrappers for Secret Service ReadAlias() and SetAlias() methods in various permutations.
-rw-r--r--docs/reference/libsecret/libsecret-sections.txt12
-rw-r--r--library/secret-methods.c533
-rw-r--r--library/secret-private.h3
-rw-r--r--library/secret-service.c25
-rw-r--r--library/secret-service.h64
-rw-r--r--library/tests/mock/service.py16
-rw-r--r--library/tests/test-methods.c127
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 ();
}