diff --git a/docs/reference/libsecret/libsecret-docs.sgml b/docs/reference/libsecret/libsecret-docs.sgml
index 3ec04c1..c7b168a 100644
--- a/docs/reference/libsecret/libsecret-docs.sgml
+++ b/docs/reference/libsecret/libsecret-docs.sgml
@@ -30,6 +30,7 @@
+
diff --git a/docs/reference/libsecret/libsecret-sections.txt b/docs/reference/libsecret/libsecret-sections.txt
index 1168fea..1a53da5 100644
--- a/docs/reference/libsecret/libsecret-sections.txt
+++ b/docs/reference/libsecret/libsecret-sections.txt
@@ -186,30 +186,15 @@ secret_service_ensure_collections_sync
secret_service_search
secret_service_search_finish
secret_service_search_sync
-secret_service_search_for_paths
-secret_service_search_for_paths_finish
-secret_service_search_for_paths_sync
secret_service_get_secrets
secret_service_get_secrets_finish
secret_service_get_secrets_sync
-secret_service_get_secrets_for_paths
-secret_service_get_secrets_for_paths_finish
-secret_service_get_secrets_for_paths_sync
-secret_service_get_secret_for_path
-secret_service_get_secret_for_path_finish
-secret_service_get_secret_for_path_sync
secret_service_lock
secret_service_lock_finish
secret_service_lock_sync
-secret_service_lock_paths
-secret_service_lock_paths_finish
-secret_service_lock_paths_sync
secret_service_unlock
secret_service_unlock_finish
secret_service_unlock_sync
-secret_service_unlock_paths
-secret_service_unlock_paths_finish
-secret_service_unlock_paths_sync
secret_service_store
secret_service_store_finish
secret_service_store_sync
@@ -222,6 +207,43 @@ secret_service_remove_sync
secret_service_prompt
secret_service_prompt_finish
secret_service_prompt_sync
+secret_service_read_alias
+secret_service_read_alias_finish
+secret_service_read_alias_sync
+secret_service_set_alias
+secret_service_set_alias_finish
+secret_service_set_alias_sync
+
+SECRET_IS_SERVICE
+SECRET_IS_SERVICE_CLASS
+SECRET_SERVICE
+SECRET_SERVICE_CLASS
+SECRET_SERVICE_GET_CLASS
+SECRET_TYPE_SERVICE
+SECRET_TYPE_SERVICE_FLAGS
+SecretServicePrivate
+secret_service_flags_get_type
+secret_service_get_type
+
+
+
+secret-paths
+secret/secret-unstable.h
+secret_service_search_for_paths
+secret_service_search_for_paths_finish
+secret_service_search_for_paths_sync
+secret_service_get_secrets_for_paths
+secret_service_get_secrets_for_paths_finish
+secret_service_get_secrets_for_paths_sync
+secret_service_get_secret_for_path
+secret_service_get_secret_for_path_finish
+secret_service_get_secret_for_path_sync
+secret_service_lock_paths
+secret_service_lock_paths_finish
+secret_service_lock_paths_sync
+secret_service_unlock_paths
+secret_service_unlock_paths_finish
+secret_service_unlock_paths_sync
secret_service_prompt_path
secret_service_prompt_path_finish
secret_service_prompt_path_sync
@@ -234,29 +256,12 @@ 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
-SECRET_SERVICE
-SECRET_SERVICE_CLASS
-SECRET_SERVICE_GET_CLASS
-SECRET_TYPE_SERVICE
-SECRET_TYPE_SERVICE_FLAGS
-SecretServicePrivate
-secret_service_flags_get_type
-secret_service_get_type
diff --git a/library/Makefile.am b/library/Makefile.am
index 752dd01..c45c10f 100644
--- a/library/Makefile.am
+++ b/library/Makefile.am
@@ -26,6 +26,7 @@ HEADER_FILES = \
secret-collection.h \
secret-item.h \
secret-password.h \
+ secret-paths.h \
secret-prompt.h \
secret-schema.h \
secret-schemas.h \
@@ -51,6 +52,7 @@ PUBLIC_FILES = \
secret-item.h secret-item.c \
secret-methods.c \
secret-password.h secret-password.c \
+ secret-paths.h secret-paths.c \
secret-prompt.h secret-prompt.c \
secret-schema.h secret-schema.c \
secret-schemas.h secret-schemas.c \
diff --git a/library/secret-collection.c b/library/secret-collection.c
index 56992b5..95e8b22 100644
--- a/library/secret-collection.c
+++ b/library/secret-collection.c
@@ -17,6 +17,7 @@
#include "secret-collection.h"
#include "secret-dbus-generated.h"
#include "secret-item.h"
+#include "secret-paths.h"
#include "secret-private.h"
#include "secret-service.h"
#include "secret-types.h"
diff --git a/library/secret-item.c b/library/secret-item.c
index ce53955..81f5a2e 100644
--- a/library/secret-item.c
+++ b/library/secret-item.c
@@ -18,6 +18,7 @@
#include "secret-dbus-generated.h"
#include "secret-enum-types.h"
#include "secret-item.h"
+#include "secret-paths.h"
#include "secret-private.h"
#include "secret-service.h"
#include "secret-types.h"
diff --git a/library/secret-methods.c b/library/secret-methods.c
index 6842384..91405c4 100644
--- a/library/secret-methods.c
+++ b/library/secret-methods.c
@@ -18,213 +18,12 @@
#include "secret-collection.h"
#include "secret-dbus-generated.h"
#include "secret-item.h"
+#include "secret-paths.h"
#include "secret-private.h"
#include "secret-service.h"
#include "secret-types.h"
#include "secret-value.h"
-static void
-on_search_items_complete (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- GError *error = NULL;
- GVariant *response;
-
- response = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);
- if (error != NULL)
- g_simple_async_result_take_error (res, error);
- else
- g_simple_async_result_set_op_res_gpointer (res, response,
- (GDestroyNotify)g_variant_unref);
-
- g_simple_async_result_complete (res);
- g_object_unref (res);
-}
-
-/**
- * secret_service_search_for_paths:
- * @self: the secret service
- * @attributes: (element-type utf8 utf8): search for items matching these attributes
- * @cancellable: optional cancellation object
- * @callback: called when the operation completes
- * @user_data: data to pass to the callback
- *
- * Search for items matching the @attributes, and return their D-Bus object paths.
- * All collections are searched. The @attributes should be a table of string keys
- * and string values.
- *
- * This function returns immediately and completes asynchronously.
- *
- * When your callback is called use secret_service_search_for_paths_finish()
- * to get the results of this function. Only the D-Bus object paths of the
- * items will be returned. If you would like #SecretItem objects to be returned
- * instead, then use the secret_service_search() function.
- */
-void
-secret_service_search_for_paths (SecretService *self,
- GHashTable *attributes,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_return_if_fail (SECRET_IS_SERVICE (self));
- g_return_if_fail (attributes != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- _secret_service_search_for_paths_variant (self, _secret_attributes_to_variant (attributes, NULL),
- cancellable, callback, user_data);
-}
-
-void
-_secret_service_search_for_paths_variant (SecretService *self,
- GVariant *attributes,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *res;
-
- g_return_if_fail (SECRET_IS_SERVICE (self));
- g_return_if_fail (attributes != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
- secret_service_search_for_paths);
-
- g_dbus_proxy_call (G_DBUS_PROXY (self), "SearchItems",
- g_variant_new ("(@a{ss})", attributes),
- G_DBUS_CALL_FLAGS_NONE, -1, cancellable,
- on_search_items_complete, g_object_ref (res));
-
- g_object_unref (res);
-}
-
-/**
- * secret_service_search_for_paths_finish:
- * @self: the secret service
- * @result: asynchronous result passed to callback
- * @unlocked: (out) (transfer full) (array zero-terminated=1) (allow-none):
- * location to place an array of D-Bus object paths for matching
- * items which were locked.
- * @locked: (out) (transfer full) (array zero-terminated=1) (allow-none):
- * location to place an array of D-Bus object paths for matching
- * items which were locked.
- * @error: location to place error on failure
- *
- * Complete asynchronous operation to search for items, and return their
- * D-Bus object paths.
- *
- * Matching items that are locked or unlocked, have their D-Bus paths placed
- * in the @locked or @unlocked arrays respectively.
- *
- * D-Bus object paths of the items will be returned in the @unlocked or
- * @locked arrays. If you would to have #SecretItem objects to be returned
- * instead, then us the secret_service_search() and
- * secret_service_search_finish() functions.
- *
- * Returns: whether the search was successful or not
- */
-gboolean
-secret_service_search_for_paths_finish (SecretService *self,
- GAsyncResult *result,
- gchar ***unlocked,
- gchar ***locked,
- GError **error)
-{
- GVariant *response;
- GSimpleAsyncResult *res;
- gchar **dummy = NULL;
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
- secret_service_search_for_paths), FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- res = G_SIMPLE_ASYNC_RESULT (result);
- if (g_simple_async_result_propagate_error (res, error))
- return FALSE;
-
- if (unlocked || locked) {
- if (!unlocked)
- unlocked = &dummy;
- else if (!locked)
- locked = &dummy;
- response = g_simple_async_result_get_op_res_gpointer (res);
- g_variant_get (response, "(^ao^ao)", unlocked, locked);
- }
-
- g_strfreev (dummy);
- return TRUE;
-}
-
-/**
- * secret_service_search_for_paths_sync:
- * @self: the secret service
- * @attributes: (element-type utf8 utf8): search for items matching these attributes
- * @cancellable: optional cancellation object
- * @unlocked: (out) (transfer full) (array zero-terminated=1) (allow-none):
- * location to place an array of D-Bus object paths for matching
- * items which were locked.
- * @locked: (out) (transfer full) (array zero-terminated=1) (allow-none):
- * location to place an array of D-Bus object paths for matching
- * items which were locked.
- * @error: location to place error on failure
- *
- * Search for items matching the @attributes, and return their D-Bus object
- * paths. All collections are searched. The @attributes should be a table of
- * string keys and string values.
- *
- * This function may block indefinetely. Use the asynchronous version
- * in user interface threads.
- *
- * Matching items that are locked or unlocked, have their D-Bus paths placed
- * in the @locked or @unlocked arrays respectively.
- *
- * D-Bus object paths of the items will be returned in the @unlocked or
- * @locked arrays. If you would to have #SecretItem objects to be returned
- * instead, then use the secret_service_search_sync() function.
- *
- * Returns: whether the search was successful or not
- */
-gboolean
-secret_service_search_for_paths_sync (SecretService *self,
- GHashTable *attributes,
- GCancellable *cancellable,
- gchar ***unlocked,
- gchar ***locked,
- GError **error)
-{
- gchar **dummy = NULL;
- GVariant *response;
-
- g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
- g_return_val_if_fail (attributes != NULL, FALSE);
- g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- response = g_dbus_proxy_call_sync (G_DBUS_PROXY (self), "SearchItems",
- g_variant_new ("(@a{ss})",
- _secret_attributes_to_variant (attributes, NULL)),
- G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error);
-
- if (response != NULL) {
- if (unlocked || locked) {
- if (!unlocked)
- unlocked = &dummy;
- else if (!locked)
- locked = &dummy;
- g_variant_get (response, "(^ao^ao)", unlocked, locked);
- }
-
- g_variant_unref (response);
- }
-
- g_strfreev (dummy);
-
- return response != NULL;
-}
-
typedef struct {
GCancellable *cancellable;
GHashTable *items;
@@ -584,54 +383,10 @@ on_get_secrets_session (GObject *source,
g_object_unref (res);
}
-/**
- * secret_service_get_secret_for_path:
- * @self: the secret service
- * @item_path: the D-Bus path to item to retrieve secret for
- * @cancellable: optional cancellation object
- * @callback: called when the operation completes
- * @user_data: data to pass to the callback
- *
- * Get the secret value for an secret item stored in the service.
- *
- * The item is represented by its D-Bus object path. If you already have a
- * #SecretItem proxy object, use use secret_item_get_secret() to more simply
- * get its secret value.
- *
- * This function returns immediately and completes asynchronously.
- */
-void
-secret_service_get_secret_for_path (SecretService *self,
- const gchar *item_path,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *res;
- GetClosure *closure;
- g_return_if_fail (SECRET_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,
- secret_service_get_secret_for_path);
-
- closure = g_slice_new0 (GetClosure);
- closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- closure->in = g_variant_ref_sink (g_variant_new_objv (&item_path, 1));
- g_simple_async_result_set_op_res_gpointer (res, closure, get_closure_free);
-
- secret_service_ensure_session (self, cancellable,
- on_get_secrets_session,
- g_object_ref (res));
-
- g_object_unref (res);
-}
-
-static SecretValue *
-service_decode_get_secrets_first (SecretService *self,
- GVariant *out)
+SecretValue *
+_secret_service_decode_get_secrets_first (SecretService *self,
+ GVariant *out)
{
SecretSession *session;
SecretValue *value = NULL;
@@ -650,9 +405,9 @@ service_decode_get_secrets_first (SecretService *self,
return value;
}
-static GHashTable *
-service_decode_get_secrets_all (SecretService *self,
- GVariant *out)
+GHashTable *
+_secret_service_decode_get_secrets_all (SecretService *self,
+ GVariant *out)
{
SecretSession *session;
GVariantIter *iter;
@@ -674,223 +429,6 @@ service_decode_get_secrets_all (SecretService *self,
return values;
}
-/**
- * secret_service_get_secret_for_path_finish:
- * @self: the secret service
- * @result: asynchronous result passed to callback
- * @error: location to place an error on failure
- *
- * Complete asynchronous operation to get the secret value for an
- * secret item stored in the service.
- *
- * Will return %NULL if the item is locked.
- *
- * Returns: (transfer full) (allow-none): the newly allocated secret value
- * for the item, which should be released with secret_value_unref()
- */
-SecretValue *
-secret_service_get_secret_for_path_finish (SecretService *self,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *res;
- GetClosure *closure;
-
- 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_get_secret_for_path), NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
- res = G_SIMPLE_ASYNC_RESULT (result);
- if (g_simple_async_result_propagate_error (res, error))
- return NULL;
-
- closure = g_simple_async_result_get_op_res_gpointer (res);
- return service_decode_get_secrets_first (self, closure->out);
-}
-
-/**
- * secret_service_get_secret_for_path_sync:
- * @self: the secret service
- * @item_path: the D-Bus path to item to retrieve secret for
- * @cancellable: optional cancellation object
- * @error: location to place an error on failure
- *
- * Get the secret value for an secret item stored in the service.
- *
- * The item is represented by its D-Bus object path. If you already have a
- * #SecretItem proxy object, use use secret_item_get_secret_sync() to more simply
- * get its secret value.
- *
- * This method may block indefinitely and should not be used in user interface
- * threads.
- *
- * Will return %NULL if the item is locked.
- *
- * Returns: (transfer full) (allow-none): the newly allocated secret value
- * for the item, which should be released with secret_value_unref()
- */
-SecretValue *
-secret_service_get_secret_for_path_sync (SecretService *self,
- const gchar *item_path,
- GCancellable *cancellable,
- GError **error)
-{
- SecretSync *sync;
- SecretValue *value;
-
- g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
- g_return_val_if_fail (item_path != 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_get_secret_for_path (self, item_path, cancellable,
- _secret_sync_on_result, sync);
-
- g_main_loop_run (sync->loop);
-
- value = secret_service_get_secret_for_path_finish (self, sync->result, error);
-
- g_main_context_pop_thread_default (sync->context);
- _secret_sync_free (sync);
-
- return value;
-}
-
-/**
- * secret_service_get_secrets_for_paths:
- * @self: the secret service
- * @item_paths: the D-Bus paths to items to retrieve secrets for
- * @cancellable: optional cancellation object
- * @callback: called when the operation completes
- * @user_data: data to pass to the callback
- *
- * Get the secret values for an secret items stored in the service.
- *
- * The items are represented by their D-Bus object paths. If you already have
- * #SecretItem proxy objects, use use secret_service_get_secrets() to more simply
- * get their secret values.
- *
- * This function returns immediately and completes asynchronously.
- */
-void
-secret_service_get_secrets_for_paths (SecretService *self,
- const gchar **item_paths,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *res;
- GetClosure *closure;
-
- g_return_if_fail (SECRET_IS_SERVICE (self));
- g_return_if_fail (item_paths != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
- secret_service_get_secret_for_path);
-
- closure = g_slice_new0 (GetClosure);
- closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- closure->in = g_variant_ref_sink (g_variant_new_objv (item_paths, -1));
- g_simple_async_result_set_op_res_gpointer (res, closure, get_closure_free);
-
- secret_service_ensure_session (self, cancellable,
- on_get_secrets_session,
- g_object_ref (res));
-
- g_object_unref (res);
-}
-
-/**
- * secret_service_get_secrets_for_paths_finish:
- * @self: the secret service
- * @result: asynchronous result passed to callback
- * @error: location to place an error on failure
- *
- * Complete asynchronous operation to get the secret values for an
- * secret items stored in the service.
- *
- * Items that are locked will not be included the results.
- *
- * Returns: (transfer full): a newly allocated hash table of item_path keys to
- * #SecretValue values.
- */
-GHashTable *
-secret_service_get_secrets_for_paths_finish (SecretService *self,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *res;
- GetClosure *closure;
-
- 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_get_secret_for_path), NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
- res = G_SIMPLE_ASYNC_RESULT (result);
- if (g_simple_async_result_propagate_error (res, error))
- return NULL;
-
- closure = g_simple_async_result_get_op_res_gpointer (res);
- return service_decode_get_secrets_all (self, closure->out);
-}
-
-/**
- * secret_service_get_secrets_for_paths_sync:
- * @self: the secret service
- * @item_paths: the D-Bus paths to items to retrieve secrets for
- * @cancellable: optional cancellation object
- * @error: location to place an error on failure
- *
- * Get the secret values for an secret items stored in the service.
- *
- * The items are represented by their D-Bus object paths. If you already have
- * #SecretItem proxy objects, use use secret_service_get_secrets_sync() to more
- * simply get their secret values.
- *
- * This method may block indefinitely and should not be used in user interface
- * threads.
- *
- * Items that are locked will not be included the results.
- *
- * Returns: (transfer full): a newly allocated hash table of item_path keys to
- * #SecretValue values.
- */
-GHashTable *
-secret_service_get_secrets_for_paths_sync (SecretService *self,
- const gchar **item_paths,
- GCancellable *cancellable,
- GError **error)
-{
- SecretSync *sync;
- GHashTable *secrets;
-
- g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
- g_return_val_if_fail (item_paths != 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_get_secrets_for_paths (self, item_paths, cancellable,
- _secret_sync_on_result, sync);
-
- g_main_loop_run (sync->loop);
-
- secrets = secret_service_get_secrets_for_paths_finish (self, sync->result, error);
-
- g_main_context_pop_thread_default (sync->context);
- _secret_sync_free (sync);
-
- return secrets;
-}
-
/**
* secret_service_get_secrets:
* @self: the secret service
@@ -988,7 +526,7 @@ secret_service_get_secrets_finish (SecretService *self,
return NULL;
closure = g_simple_async_result_get_op_res_gpointer (res);
- with_paths = service_decode_get_secrets_all (self, closure->out);
+ with_paths = _secret_service_decode_get_secrets_all (self, closure->out);
g_return_val_if_fail (with_paths != NULL, NULL);
with_items = g_hash_table_new_full (g_direct_hash, g_direct_equal,
@@ -1381,262 +919,6 @@ secret_service_lock_sync (SecretService *self,
return count;
}
-/**
- * secret_service_lock_paths_sync:
- * @self: the secret service
- * @paths: the D-Bus object paths of the items or collections to lock
- * @cancellable: optional cancellation object
- * @locked: (out) (array zero-terminated=1) (transfer full) (allow-none):
- * location to place array of D-Bus paths of items or collections
- * that were locked
- * @error: location to place an error on failure
- *
- * Lock items or collections in the secret service.
- *
- * The items or collections are represented by their D-Bus object paths. If you
- * already have #SecretItem and #SecretCollection proxy objects, use use
- * secret_service_lock_sync() instead.
- *
- * The secret service may not be able to lock items individually, and may
- * lock an entire collection instead.
- *
- * This method may block indefinitely and should not be used in user
- * interface threads. The secret service may prompt the user.
- * secret_service_prompt() will be used to handle any prompts that show up.
- *
- * Returns: the number of items or collections that were locked
- */
-gint
-secret_service_lock_paths_sync (SecretService *self,
- const gchar **paths,
- GCancellable *cancellable,
- gchar ***locked,
- GError **error)
-{
- SecretSync *sync;
- gint count;
-
- g_return_val_if_fail (SECRET_IS_SERVICE (self), -1);
- g_return_val_if_fail (paths != NULL, -1);
- g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1);
- g_return_val_if_fail (error == NULL || *error == NULL, -1);
-
- sync = _secret_sync_new ();
- g_main_context_push_thread_default (sync->context);
-
- secret_service_lock_paths (self, paths, cancellable,
- _secret_sync_on_result, sync);
-
- g_main_loop_run (sync->loop);
-
- count = secret_service_lock_paths_finish (self, sync->result,
- locked, error);
-
- g_main_context_pop_thread_default (sync->context);
- _secret_sync_free (sync);
-
- return count;
-}
-
-/**
- * secret_service_lock_paths:
- * @self: the secret service
- * @paths: the D-Bus paths for items or collections to lock
- * @cancellable: optional cancellation object
- * @callback: called when the operation completes
- * @user_data: data to pass to the callback
- *
- * Lock items or collections in the secret service.
- *
- * The items or collections are represented by their D-Bus object paths. If you
- * already have #SecretItem and #SecretCollection proxy objects, use use
- * secret_service_lock() instead.
- *
- * The secret service may not be able to lock items individually, and may
- * lock an entire collection instead.
- *
- * This method returns immediately and completes asynchronously. The secret
- * service may prompt the user. secret_service_prompt() will be used to handle
- * any prompts that show up.
- */
-void
-secret_service_lock_paths (SecretService *self,
- const gchar **paths,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *res;
-
- g_return_if_fail (SECRET_IS_SERVICE (self));
- g_return_if_fail (paths != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- res = service_xlock_paths_async (self, "Lock", paths, cancellable,
- callback, user_data);
-
- g_object_unref (res);
-}
-
-/**
- * secret_service_lock_paths_finish:
- * @self: the secret service
- * @result: asynchronous result passed to the callback
- * @locked: (out) (array zero-terminated=1) (transfer full) (allow-none):
- * location to place array of D-Bus paths of items or collections
- * that were locked
- * @error: location to place an error on failure
- *
- * Complete asynchronous operation to lock items or collections in the secret
- * service.
- *
- * The secret service may not be able to lock items individually, and may
- * lock an entire collection instead.
- *
- * Returns: the number of items or collections that were locked
- */
-gint
-secret_service_lock_paths_finish (SecretService *self,
- GAsyncResult *result,
- gchar ***locked,
- GError **error)
-{
- g_return_val_if_fail (SECRET_IS_SERVICE (self), -1);
- g_return_val_if_fail (locked != NULL, -1);
- g_return_val_if_fail (error == NULL || *error == NULL, -1);
-
- return service_xlock_paths_finish (self, result, locked, error);
-}
-
-/**
- * secret_service_unlock_paths_sync:
- * @self: the secret service
- * @paths: the D-Bus object paths of the items or collections to unlock
- * @cancellable: optional cancellation object
- * @unlocked: (out) (array zero-terminated=1) (transfer full) (allow-none):
- * location to place array of D-Bus paths of items or collections
- * that were unlocked
- * @error: location to place an error on failure
- *
- * Unlock items or collections in the secret service.
- *
- * The items or collections are represented by their D-Bus object paths. If you
- * already have #SecretItem and #SecretCollection proxy objects, use use
- * secret_service_unlock_sync() instead.
- *
- * The secret service may not be able to unlock items individually, and may
- * unlock an entire collection instead.
- *
- * This method may block indefinitely and should not be used in user
- * interface threads. The secret service may prompt the user.
- * secret_service_prompt() will be used to handle any prompts that show up.
- *
- * Returns: the number of items or collections that were unlocked
- */
-gint
-secret_service_unlock_paths_sync (SecretService *self,
- const gchar **paths,
- GCancellable *cancellable,
- gchar ***unlocked,
- GError **error)
-{
- SecretSync *sync;
- gint count;
-
- g_return_val_if_fail (SECRET_IS_SERVICE (self), -1);
- g_return_val_if_fail (paths != NULL, -1);
- g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1);
- g_return_val_if_fail (unlocked != NULL, -1);
- g_return_val_if_fail (error == NULL || *error == NULL, -1);
-
- sync = _secret_sync_new ();
- g_main_context_push_thread_default (sync->context);
-
- secret_service_unlock_paths (self, paths, cancellable,
- _secret_sync_on_result, sync);
-
- g_main_loop_run (sync->loop);
-
- count = secret_service_unlock_paths_finish (self, sync->result,
- unlocked, error);
-
- g_main_context_pop_thread_default (sync->context);
- _secret_sync_free (sync);
-
- return count;
-}
-
-/**
- * secret_service_unlock_paths:
- * @self: the secret service
- * @paths: the D-Bus paths for items or collections to unlock
- * @cancellable: optional cancellation object
- * @callback: called when the operation completes
- * @user_data: data to pass to the callback
- *
- * Unlock items or collections in the secret service.
- *
- * The items or collections are represented by their D-Bus object paths. If you
- * already have #SecretItem and #SecretCollection proxy objects, use use
- * secret_service_unlock() instead.
- *
- * The secret service may not be able to unlock items individually, and may
- * unlock an entire collection instead.
- *
- * This method returns immediately and completes asynchronously. The secret
- * service may prompt the user. secret_service_prompt() will be used to handle
- * any prompts that show up.
- */
-void
-secret_service_unlock_paths (SecretService *self,
- const gchar **paths,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *res;
-
- g_return_if_fail (SECRET_IS_SERVICE (self));
- g_return_if_fail (paths != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- res = service_xlock_paths_async (self, "Unlock",
- paths, cancellable,
- callback, user_data);
-
- g_object_unref (res);
-}
-
-/**
- * secret_service_unlock_paths_finish:
- * @self: the secret service
- * @result: asynchronous result passed to the callback
- * @unlocked: (out) (array zero-terminated=1) (transfer full) (allow-none):
- * location to place array of D-Bus paths of items or collections
- * that were unlocked
- * @error: location to place an error on failure
- *
- * Complete asynchronous operation to unlock items or collections in the secret
- * service.
- *
- * The secret service may not be able to unlock items individually, and may
- * unlock an entire collection instead.
- *
- * Returns: the number of items or collections that were unlocked
- */
-gint
-secret_service_unlock_paths_finish (SecretService *self,
- GAsyncResult *result,
- gchar ***unlocked,
- GError **error)
-{
- g_return_val_if_fail (SECRET_IS_SERVICE (self), -1);
- g_return_val_if_fail (error == NULL || *error == NULL, -1);
-
- return service_xlock_paths_finish (self, result,
- unlocked, error);
-}
-
/**
* secret_service_unlock:
* @self: the secret service
@@ -2179,208 +1461,6 @@ delete_closure_free (gpointer data)
g_slice_free (DeleteClosure, closure);
}
-static void
-on_delete_prompted (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
- GError *error = NULL;
- GVariant *retval;
-
- retval = secret_service_prompt_finish (SECRET_SERVICE (source), result,
- NULL, &error);
-
- if (error == NULL)
- closure->deleted = TRUE;
- else
- g_simple_async_result_take_error (res, error);
- if (retval != NULL)
- g_variant_unref (retval);
- g_simple_async_result_complete (res);
- g_object_unref (res);
-}
-
-static void
-on_delete_complete (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
- SecretService *self = SECRET_SERVICE (g_async_result_get_source_object (user_data));
- const gchar *prompt_path;
- GError *error = NULL;
- GVariant *retval;
-
- retval = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
- if (error == NULL) {
- g_variant_get (retval, "(&o)", &prompt_path);
-
- if (_secret_util_empty_path (prompt_path)) {
- closure->deleted = TRUE;
- g_simple_async_result_complete (res);
-
- } else {
- closure->prompt = _secret_prompt_instance (self, prompt_path);
-
- secret_service_prompt (self, closure->prompt,
- closure->cancellable,
- on_delete_prompted,
- g_object_ref (res));
- }
-
- g_variant_unref (retval);
-
- } else {
- g_simple_async_result_take_error (res, error);
- g_simple_async_result_complete (res);
- }
-
- g_object_unref (self);
- g_object_unref (res);
-}
-
-void
-_secret_service_delete_path (SecretService *self,
- const gchar *object_path,
- gboolean is_an_item,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *res;
- DeleteClosure *closure;
-
- g_return_if_fail (SECRET_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,
- _secret_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 ? SECRET_ITEM_INTERFACE : SECRET_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);
-}
-
-/**
- * secret_service_delete_path:
- * @self: the secret service
- * @item_path: the D-Bus path of item to delete
- * @cancellable: optional cancellation object
- * @callback: called when the operation completes
- * @user_data: data to be passed to the callback
- *
- * Delete a secret item from the secret service.
- *
- * The item is represented by its D-Bus object path. If you already have a
- * #SecretItem proxy objects, use use secret_item_delete() instead.
- *
- * This method will return immediately and complete asynchronously.
- */
-void
-secret_service_delete_path (SecretService *self,
- const gchar *item_path,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_return_if_fail (SECRET_IS_SERVICE (self));
- g_return_if_fail (item_path != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- _secret_service_delete_path (self, item_path, TRUE, cancellable, callback, user_data);
-}
-
-/**
- * secret_service_delete_path_finish:
- * @self: the secret service
- * @result: the asynchronous result passed to the callback
- * @error: location to place an error on failure
- *
- * Complete an asynchronous operation to delete a secret item from the secret
- * service.
- *
- * Returns: whether the deletion was successful or not
- */
-gboolean
-secret_service_delete_path_finish (SecretService *self,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *res;
- DeleteClosure *closure;
-
- g_return_val_if_fail (SECRET_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),
- _secret_service_delete_path), FALSE);
-
- res = G_SIMPLE_ASYNC_RESULT (result);
- if (g_simple_async_result_propagate_error (res, error))
- return FALSE;
-
- closure = g_simple_async_result_get_op_res_gpointer (res);
- return closure->deleted;
-}
-
-/**
- * secret_service_delete_path_sync:
- * @self: the secret service
- * @item_path: the D-Bus path of item to delete
- * @cancellable: optional cancellation object
- * @error: location to place an error on failure
- *
- * Delete a secret item from the secret service.
- *
- * The item is represented by its D-Bus object path. If you already have a
- * #SecretItem proxy objects, use use secret_item_delete_sync() instead.
- *
- * This method may block indefinitely and should not be used in user interface
- * threads.
- *
- * Returns: whether the deletion was successful or not
- */
-gboolean
-secret_service_delete_path_sync (SecretService *self,
- const gchar *item_path,
- GCancellable *cancellable,
- GError **error)
-{
- SecretSync *sync;
- gboolean result;
-
- g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
- g_return_val_if_fail (item_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 = _secret_sync_new ();
- g_main_context_push_thread_default (sync->context);
-
- secret_service_delete_path (self, item_path, cancellable,
- _secret_sync_on_result, sync);
-
- g_main_loop_run (sync->loop);
-
- result = secret_service_delete_path_finish (self, sync->result, error);
-
- g_main_context_pop_thread_default (sync->context);
- _secret_sync_free (sync);
-
- return result;
-}
-
static void
on_delete_password_complete (GObject *source,
GAsyncResult *result,
@@ -2586,564 +1666,6 @@ secret_service_remove_sync (SecretService *self,
return result;
}
-typedef struct {
- GCancellable *cancellable;
- SecretPrompt *prompt;
- gchar *collection_path;
-} CollectionClosure;
-
-static void
-collection_closure_free (gpointer data)
-{
- CollectionClosure *closure = data;
- g_clear_object (&closure->cancellable);
- g_clear_object (&closure->prompt);
- g_slice_free (CollectionClosure, closure);
-}
-
-static void
-on_create_collection_prompt (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- CollectionClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
- GError *error = NULL;
- GVariant *value;
-
- value = secret_service_prompt_finish (SECRET_SERVICE (source), result,
- G_VARIANT_TYPE ("o"), &error);
- if (error != NULL)
- g_simple_async_result_take_error (res, error);
- if (value != NULL) {
- closure->collection_path = g_variant_dup_string (value, NULL);
- g_variant_unref (value);
- }
-
- g_simple_async_result_complete (res);
- g_object_unref (res);
-}
-
-static void
-on_create_collection_called (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- CollectionClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
- SecretService *self = SECRET_SERVICE (g_async_result_get_source_object (user_data));
- const gchar *prompt_path = NULL;
- const gchar *collection_path = NULL;
- GError *error = NULL;
- GVariant *retval;
-
- retval = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
- if (error == NULL) {
- g_variant_get (retval, "(&o&o)", &collection_path, &prompt_path);
- if (!_secret_util_empty_path (prompt_path)) {
- closure->prompt = _secret_prompt_instance (self, prompt_path);
- secret_service_prompt (self, closure->prompt,
- closure->cancellable, on_create_collection_prompt,
- g_object_ref (res));
-
- } else {
- closure->collection_path = g_strdup (collection_path);
- g_simple_async_result_complete (res);
- }
-
- g_variant_unref (retval);
-
- } else {
- g_simple_async_result_take_error (res, error);
- g_simple_async_result_complete (res);
- }
-
- g_object_unref (self);
- g_object_unref (res);
-}
-
-/**
- * secret_service_create_collection_path:
- * @self: a secret service object
- * @properties: (element-type utf8 GLib.Variant): hash table of properties for
- * the new collection
- * @alias: (allow-none): an alias to check for before creating the new
- * collection, or to assign to the new collection
- * @cancellable: optional cancellation object
- * @callback: called when the operation completes
- * @user_data: data to be passed to the callback
- *
- * Create a new collection in the secret service, and return its path.
- *
- * Using this method requires that you setup a correct hash table of D-Bus
- * properties for the new collection. You may prefer to use
- * secret_collection_create() which does handles this for you.
- *
- * An @alias is a well-known tag for a collection, such as 'default' (ie: the
- * default collection to store items in). This allows other applications to
- * easily identify and share a collection. If a collection with the @alias
- * already exists, then instead of creating a new collection, the existing
- * collection will be returned. If no collection with this alias exists, then a
- * new collection will be created and this alias will be assigned to it.
- *
- * @properties is a set of properties for the new collection. The keys in the
- * hash table should be interface.property strings like
- * org.freedesktop.Secret.Collection.Label. The values
- * in the hash table should be #GVariant values of the properties.
- *
- * If you wish to have a
- *
- * This method will return immediately and complete asynchronously. The secret
- * service may prompt the user. secret_service_prompt() will be used to handle
- * any prompts that are required.
- */
-void
-secret_service_create_collection_path (SecretService *self,
- GHashTable *properties,
- const gchar *alias,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *res;
- CollectionClosure *closure;
- GVariant *params;
- GVariant *props;
- GDBusProxy *proxy;
-
- g_return_if_fail (SECRET_IS_SERVICE (self));
- g_return_if_fail (properties != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- if (alias == NULL)
- alias = "";
-
- res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
- secret_service_create_collection_path);
- closure = g_slice_new0 (CollectionClosure);
- closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- g_simple_async_result_set_op_res_gpointer (res, closure, collection_closure_free);
-
- props = _secret_util_variant_for_properties (properties);
- params = g_variant_new ("(@a{sv}s)", props, alias);
- proxy = G_DBUS_PROXY (self);
-
- g_dbus_connection_call (g_dbus_proxy_get_connection (proxy),
- g_dbus_proxy_get_name (proxy),
- g_dbus_proxy_get_object_path (proxy),
- SECRET_SERVICE_INTERFACE,
- "CreateCollection", params, G_VARIANT_TYPE ("(oo)"),
- G_DBUS_CALL_FLAGS_NONE, -1,
- closure->cancellable,
- on_create_collection_called,
- g_object_ref (res));
-
- g_object_unref (res);
-
-}
-
-/**
- * secret_service_create_collection_path_finish:
- * @self: a secret service object
- * @result: the asynchronous result passed to the callback
- * @error: location to place an error on failure
- *
- * Finish asynchronous operation to create a new collection in the secret
- * service.
- *
- * Returns: (transfer full): a new string containing the D-Bus object path
- * of the collection
- */
-gchar *
-secret_service_create_collection_path_finish (SecretService *self,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *res;
- CollectionClosure *closure;
- gchar *path;
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
- secret_service_create_collection_path), NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
- res = G_SIMPLE_ASYNC_RESULT (result);
-
- if (g_simple_async_result_propagate_error (res, error))
- return NULL;
-
- closure = g_simple_async_result_get_op_res_gpointer (res);
- path = closure->collection_path;
- closure->collection_path = NULL;
- return path;
-}
-
-/**
- * secret_service_create_collection_path_sync:
- * @self: a secret service object
- * @properties: (element-type utf8 GLib.Variant): hash table of D-Bus properties
- * for the new collection
- * @alias: (allow-none): an alias to check for before creating the new
- * collection, or to assign to the new collection
- * @cancellable: optional cancellation object
- * @error: location to place an error on failure
- *
- * Create a new collection in the secret service and return its path.
- *
- * Using this method requires that you setup a correct hash table of D-Bus
- * properties for the new collection. You may prefer to use
- * secret_collection_create() which does handles this for you.
- *
- * An @alias is a well-known tag for a collection, such as 'default' (ie: the
- * default collection to store items in). This allows other applications to
- * easily identify and share a collection. If a collection with the @alias
- * already exists, then instead of creating a new collection, the existing
- * collection will be returned. If no collection with this alias exists, then
- * a new collection will be created and this alias will be assigned to it.
- *
- * @properties is a set of properties for the new collection. The keys in the
- * hash table should be interface.property strings like
- * org.freedesktop.Secret.Collection.Label. The values
- * in the hash table should be #GVariant values of the properties.
- *
- * This method may block indefinitely and should not be used in user interface
- * threads. The secret service may prompt the user. secret_service_prompt()
- * will be used to handle any prompts that are required.
- *
- * Returns: (transfer full): a new string containing the D-Bus object path
- * of the collection
- */
-gchar *
-secret_service_create_collection_path_sync (SecretService *self,
- GHashTable *properties,
- const gchar *alias,
- GCancellable *cancellable,
- GError **error)
-{
- SecretSync *sync;
- gchar *path;
-
- g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
- g_return_val_if_fail (properties != 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_create_collection_path (self, properties, alias, cancellable,
- _secret_sync_on_result, sync);
-
- g_main_loop_run (sync->loop);
-
- path = secret_service_create_collection_path_finish (self, sync->result, error);
-
- g_main_context_pop_thread_default (sync->context);
- _secret_sync_free (sync);
-
- return path;
-}
-
-typedef struct {
- GCancellable *cancellable;
- GVariant *properties;
- SecretValue *value;
- gboolean replace;
- gchar *collection_path;
- SecretPrompt *prompt;
- gchar *item_path;
-} ItemClosure;
-
-static void
-item_closure_free (gpointer data)
-{
- ItemClosure *closure = data;
- g_variant_unref (closure->properties);
- secret_value_unref (closure->value);
- g_clear_object (&closure->cancellable);
- g_free (closure->collection_path);
- g_clear_object (&closure->prompt);
- g_slice_free (ItemClosure, closure);
-}
-
-static void
-on_create_item_prompt (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- ItemClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
- GError *error = NULL;
- GVariant *value;
-
- value = secret_service_prompt_finish (SECRET_SERVICE (source), result,
- G_VARIANT_TYPE ("o"), &error);
- if (error != NULL)
- g_simple_async_result_take_error (res, error);
- if (value != NULL) {
- closure->item_path = g_variant_dup_string (value, NULL);
- g_variant_unref (value);
- }
-
- g_simple_async_result_complete (res);
- g_object_unref (res);
-}
-
-static void
-on_create_item_called (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- ItemClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
- SecretService *self = SECRET_SERVICE (g_async_result_get_source_object (user_data));
- const gchar *prompt_path = NULL;
- const gchar *item_path = NULL;
- GError *error = NULL;
- GVariant *retval;
-
- retval = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
- if (error == NULL) {
- g_variant_get (retval, "(&o&o)", &item_path, &prompt_path);
- if (!_secret_util_empty_path (prompt_path)) {
- closure->prompt = _secret_prompt_instance (self, prompt_path);
- secret_service_prompt (self, closure->prompt,
- closure->cancellable, on_create_item_prompt,
- g_object_ref (res));
-
- } else {
- closure->item_path = g_strdup (item_path);
- g_simple_async_result_complete (res);
- }
-
- g_variant_unref (retval);
-
- } else {
- g_simple_async_result_take_error (res, error);
- g_simple_async_result_complete (res);
- }
-
- g_object_unref (self);
- g_object_unref (res);
-}
-
-static void
-on_create_item_session (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- ItemClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
- SecretService *self = SECRET_SERVICE (source);
- SecretSession *session;
- GVariant *params;
- GError *error = NULL;
- GDBusProxy *proxy;
-
- secret_service_ensure_session_finish (self, result, &error);
- if (error == NULL) {
- session = _secret_service_get_session (self);
- params = g_variant_new ("(@a{sv}@(oayays)b)",
- closure->properties,
- _secret_session_encode_secret (session, closure->value),
- closure->replace);
-
- proxy = G_DBUS_PROXY (self);
- g_dbus_connection_call (g_dbus_proxy_get_connection (proxy),
- g_dbus_proxy_get_name (proxy),
- closure->collection_path,
- SECRET_COLLECTION_INTERFACE,
- "CreateItem", params, G_VARIANT_TYPE ("(oo)"),
- G_DBUS_CALL_FLAGS_NONE, -1,
- closure->cancellable,
- on_create_item_called,
- g_object_ref (res));
- } else {
- g_simple_async_result_take_error (res, error);
- g_simple_async_result_complete (res);
- }
-
- g_object_unref (res);
-}
-
-/**
- * secret_service_create_item_path:
- * @self: a secret service object
- * @collection_path: (allow-none): the D-Bus object path of the collection in which to create item
- * @properties: (element-type utf8 GLib.Variant): hash table of D-Bus properties
- * for the new collection
- * @value: the secret value to store in the item
- * @replace: whether to replace an item with the matching attributes
- * @cancellable: optional cancellation object
- * @callback: called when the operation completes
- * @user_data: data to be passed to the callback
- *
- * Create a new item in a secret service collection and return its D-Bus
- * object path.
- *
- * It is often easier to use secret_password_store() or secret_item_create()
- * rather than using this function. Using this method requires that you setup
- * a correct hash table of D-Bus @properties for the new collection.
- *
- * If @replace is set to %TRUE, and an item already in the collection matches
- * the attributes (specified in @properties) then the item will be updated
- * instead of creating a new item.
- *
- * @properties is a set of properties for the new collection. The keys in the
- * hash table should be interface.property strings like
- * org.freedesktop.Secret.Item.Label. The values
- * in the hash table should be #GVariant values of the properties.
- *
- * If @collection_path is %NULL, then the default collection will be
- * used. Use #SECRET_COLLECTION_SESSION to store the password in the session
- * collection, which doesn't get stored across login sessions.
- *
- * This method will return immediately and complete asynchronously. The secret
- * service may prompt the user. secret_service_prompt() will be used to handle
- * any prompts that are required.
- */
-void
-secret_service_create_item_path (SecretService *self,
- const gchar *collection_path,
- GHashTable *properties,
- SecretValue *value,
- gboolean replace,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *res;
- ItemClosure *closure;
-
- g_return_if_fail (SECRET_IS_SERVICE (self));
- g_return_if_fail (properties != NULL);
- g_return_if_fail (value != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- if (collection_path == NULL)
- collection_path = SECRET_COLLECTION_DEFAULT;
-
- res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
- secret_service_create_item_path);
- closure = g_slice_new0 (ItemClosure);
- closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- closure->properties = _secret_util_variant_for_properties (properties);
- g_variant_ref_sink (closure->properties);
- closure->replace = replace;
- closure->value = secret_value_ref (value);
- closure->collection_path = g_strdup (collection_path);
- g_simple_async_result_set_op_res_gpointer (res, closure, item_closure_free);
-
- secret_service_ensure_session (self, cancellable,
- on_create_item_session,
- g_object_ref (res));
-
- g_object_unref (res);
-}
-
-/**
- * secret_service_create_item_path_finish:
- * @self: a secret service object
- * @result: the asynchronous result passed to the callback
- * @error: location to place an error on failure
- *
- * Finish asynchronous operation to create a new item in the secret
- * service.
- *
- * Returns: (transfer full): a new string containing the D-Bus object path
- * of the item
- */
-gchar *
-secret_service_create_item_path_finish (SecretService *self,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *res;
- ItemClosure *closure;
- gchar *path;
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
- secret_service_create_item_path), NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
- res = G_SIMPLE_ASYNC_RESULT (result);
-
- if (g_simple_async_result_propagate_error (res, error))
- return NULL;
-
- closure = g_simple_async_result_get_op_res_gpointer (res);
- path = closure->item_path;
- closure->item_path = NULL;
- return path;
-}
-
-/**
- * secret_service_create_item_path_sync:
- * @self: a secret service object
- * @collection_path: (allow-none): the D-Bus path of the collection in which to create item
- * @properties: (element-type utf8 GLib.Variant): hash table of D-Bus properties
- * for the new collection
- * @value: the secret value to store in the item
- * @replace: whether to replace an item with the matching attributes
- * @cancellable: optional cancellation object
- * @error: location to place an error on failure
- *
- * Create a new item in a secret service collection and return its D-Bus
- * object path.
- *
- * It is often easier to use secret_password_store_sync() or secret_item_create_sync()
- * rather than using this function. Using this method requires that you setup
- * a correct hash table of D-Bus @properties for the new collection.
- *
- * If @replace is set to %TRUE, and an item already in the collection matches
- * the attributes (specified in @properties) then the item will be updated
- * instead of creating a new item.
- *
- * @properties is a set of properties for the new collection. The keys in the
- * hash table should be interface.property strings like
- * org.freedesktop.Secret.Item.Label. The values
- * in the hash table should be #GVariant values of the properties.
- *
- * This method may block indefinitely and should not be used in user interface
- * threads. The secret service may prompt the user. secret_service_prompt()
- * will be used to handle any prompts that are required.
- *
- * Returns: (transfer full): a new string containing the D-Bus object path
- * of the item
- */
-gchar *
-secret_service_create_item_path_sync (SecretService *self,
- const gchar *collection_path,
- GHashTable *properties,
- SecretValue *value,
- gboolean replace,
- GCancellable *cancellable,
- GError **error)
-{
- SecretSync *sync;
- gchar *path;
-
- g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
- g_return_val_if_fail (properties != 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_create_item_path (self, collection_path, properties, value, replace,
- cancellable, _secret_sync_on_result, sync);
-
- g_main_loop_run (sync->loop);
-
- path = secret_service_create_item_path_finish (self, sync->result, error);
-
- g_main_context_pop_thread_default (sync->context);
- _secret_sync_free (sync);
-
- return path;
-}
-
typedef struct {
GCancellable *cancellable;
SecretCollection *collection;
@@ -3341,117 +1863,6 @@ secret_service_read_alias_sync (SecretService *self,
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
@@ -3558,121 +1969,3 @@ secret_service_set_alias_sync (SecretService *self,
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-paths.c b/library/secret-paths.c
new file mode 100644
index 0000000..6919d87
--- /dev/null
+++ b/library/secret-paths.c
@@ -0,0 +1,2054 @@
+/* libsecret - GLib wrapper for Secret Service
+ *
+ * Copyright 2011 Collabora Ltd.
+ * Copyright 2012 Red Hat Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the licence or (at
+ * your option) any later version.
+ *
+ * See the included COPYING file for more information.
+ *
+ * Author: Stef Walter
+ */
+
+#include "config.h"
+
+#include "secret-dbus-generated.h"
+#include "secret-paths.h"
+#include "secret-private.h"
+#include "secret-service.h"
+#include "secret-types.h"
+#include "secret-value.h"
+
+
+/**
+ * SECTION:secret-paths
+ * @title: DBus Path Related Functions
+ * @short_description: Secret Service functions which operate on DBus object paths
+ *
+ * These are low level functions which operate on DBus object paths of
+ * collections or items, instead of the #SecretCollection or #SecretItem
+ * objects themselves.
+ *
+ * You can use these functions if you wish to manage access to the secret
+ * service using the DBus API directly, and only wish to use a few calls
+ * in libsecret.
+ *
+ * Stability: Unstable
+ */
+
+static void
+on_search_items_complete (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ GError *error = NULL;
+ GVariant *response;
+
+ response = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);
+ if (error != NULL)
+ g_simple_async_result_take_error (res, error);
+ else
+ g_simple_async_result_set_op_res_gpointer (res, response,
+ (GDestroyNotify)g_variant_unref);
+
+ g_simple_async_result_complete (res);
+ g_object_unref (res);
+}
+
+/**
+ * secret_service_search_for_paths:
+ * @self: the secret service
+ * @attributes: (element-type utf8 utf8): search for items matching these attributes
+ * @cancellable: optional cancellation object
+ * @callback: called when the operation completes
+ * @user_data: data to pass to the callback
+ *
+ * Search for items matching the @attributes, and return their D-Bus object paths.
+ * All collections are searched. The @attributes should be a table of string keys
+ * and string values.
+ *
+ * This function returns immediately and completes asynchronously.
+ *
+ * When your callback is called use secret_service_search_for_paths_finish()
+ * to get the results of this function. Only the D-Bus object paths of the
+ * items will be returned. If you would like #SecretItem objects to be returned
+ * instead, then use the secret_service_search() function.
+ */
+void
+secret_service_search_for_paths (SecretService *self,
+ GHashTable *attributes,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (SECRET_IS_SERVICE (self));
+ g_return_if_fail (attributes != NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ _secret_service_search_for_paths_variant (self, _secret_attributes_to_variant (attributes, NULL),
+ cancellable, callback, user_data);
+}
+
+void
+_secret_service_search_for_paths_variant (SecretService *self,
+ GVariant *attributes,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+
+ g_return_if_fail (SECRET_IS_SERVICE (self));
+ g_return_if_fail (attributes != NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ secret_service_search_for_paths);
+
+ g_dbus_proxy_call (G_DBUS_PROXY (self), "SearchItems",
+ g_variant_new ("(@a{ss})", attributes),
+ G_DBUS_CALL_FLAGS_NONE, -1, cancellable,
+ on_search_items_complete, g_object_ref (res));
+
+ g_object_unref (res);
+}
+
+/**
+ * secret_service_search_for_paths_finish:
+ * @self: the secret service
+ * @result: asynchronous result passed to callback
+ * @unlocked: (out) (transfer full) (array zero-terminated=1) (allow-none):
+ * location to place an array of D-Bus object paths for matching
+ * items which were locked.
+ * @locked: (out) (transfer full) (array zero-terminated=1) (allow-none):
+ * location to place an array of D-Bus object paths for matching
+ * items which were locked.
+ * @error: location to place error on failure
+ *
+ * Complete asynchronous operation to search for items, and return their
+ * D-Bus object paths.
+ *
+ * Matching items that are locked or unlocked, have their D-Bus paths placed
+ * in the @locked or @unlocked arrays respectively.
+ *
+ * D-Bus object paths of the items will be returned in the @unlocked or
+ * @locked arrays. If you would to have #SecretItem objects to be returned
+ * instead, then us the secret_service_search() and
+ * secret_service_search_finish() functions.
+ *
+ * Returns: whether the search was successful or not
+ */
+gboolean
+secret_service_search_for_paths_finish (SecretService *self,
+ GAsyncResult *result,
+ gchar ***unlocked,
+ gchar ***locked,
+ GError **error)
+{
+ GVariant *response;
+ GSimpleAsyncResult *res;
+ gchar **dummy = NULL;
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+ secret_service_search_for_paths), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ res = G_SIMPLE_ASYNC_RESULT (result);
+ if (g_simple_async_result_propagate_error (res, error))
+ return FALSE;
+
+ if (unlocked || locked) {
+ if (!unlocked)
+ unlocked = &dummy;
+ else if (!locked)
+ locked = &dummy;
+ response = g_simple_async_result_get_op_res_gpointer (res);
+ g_variant_get (response, "(^ao^ao)", unlocked, locked);
+ }
+
+ g_strfreev (dummy);
+ return TRUE;
+}
+
+/**
+ * secret_service_search_for_paths_sync:
+ * @self: the secret service
+ * @attributes: (element-type utf8 utf8): search for items matching these attributes
+ * @cancellable: optional cancellation object
+ * @unlocked: (out) (transfer full) (array zero-terminated=1) (allow-none):
+ * location to place an array of D-Bus object paths for matching
+ * items which were locked.
+ * @locked: (out) (transfer full) (array zero-terminated=1) (allow-none):
+ * location to place an array of D-Bus object paths for matching
+ * items which were locked.
+ * @error: location to place error on failure
+ *
+ * Search for items matching the @attributes, and return their D-Bus object
+ * paths. All collections are searched. The @attributes should be a table of
+ * string keys and string values.
+ *
+ * This function may block indefinetely. Use the asynchronous version
+ * in user interface threads.
+ *
+ * Matching items that are locked or unlocked, have their D-Bus paths placed
+ * in the @locked or @unlocked arrays respectively.
+ *
+ * D-Bus object paths of the items will be returned in the @unlocked or
+ * @locked arrays. If you would to have #SecretItem objects to be returned
+ * instead, then use the secret_service_search_sync() function.
+ *
+ * Returns: whether the search was successful or not
+ */
+gboolean
+secret_service_search_for_paths_sync (SecretService *self,
+ GHashTable *attributes,
+ GCancellable *cancellable,
+ gchar ***unlocked,
+ gchar ***locked,
+ GError **error)
+{
+ gchar **dummy = NULL;
+ GVariant *response;
+
+ g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
+ g_return_val_if_fail (attributes != NULL, FALSE);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ response = g_dbus_proxy_call_sync (G_DBUS_PROXY (self), "SearchItems",
+ g_variant_new ("(@a{ss})",
+ _secret_attributes_to_variant (attributes, NULL)),
+ G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error);
+
+ if (response != NULL) {
+ if (unlocked || locked) {
+ if (!unlocked)
+ unlocked = &dummy;
+ else if (!locked)
+ locked = &dummy;
+ g_variant_get (response, "(^ao^ao)", unlocked, locked);
+ }
+
+ g_variant_unref (response);
+ }
+
+ g_strfreev (dummy);
+
+ return response != NULL;
+}
+
+typedef struct {
+ GCancellable *cancellable;
+ GVariant *in;
+ GVariant *out;
+ GHashTable *items;
+} GetClosure;
+
+static void
+get_closure_free (gpointer data)
+{
+ GetClosure *closure = data;
+ if (closure->in)
+ g_variant_unref (closure->in);
+ if (closure->out)
+ g_variant_unref (closure->out);
+ g_clear_object (&closure->cancellable);
+ g_slice_free (GetClosure, closure);
+}
+
+static void
+on_get_secrets_complete (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ GetClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ GError *error = NULL;
+
+ closure->out = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);
+ if (error != NULL)
+ g_simple_async_result_take_error (res, error);
+ g_simple_async_result_complete (res);
+
+ g_object_unref (res);
+}
+
+static void
+on_get_secrets_session (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ GetClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ GError *error = NULL;
+ const gchar *session;
+
+ session = secret_service_ensure_session_finish (SECRET_SERVICE (source),
+ result, &error);
+ if (error != NULL) {
+ g_simple_async_result_take_error (res, error);
+ g_simple_async_result_complete (res);
+ } else {
+ g_dbus_proxy_call (G_DBUS_PROXY (source), "GetSecrets",
+ g_variant_new ("(@aoo)", closure->in, session),
+ G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
+ closure->cancellable, on_get_secrets_complete,
+ g_object_ref (res));
+ }
+
+ g_object_unref (res);
+}
+
+/**
+ * secret_service_get_secret_for_path:
+ * @self: the secret service
+ * @item_path: the D-Bus path to item to retrieve secret for
+ * @cancellable: optional cancellation object
+ * @callback: called when the operation completes
+ * @user_data: data to pass to the callback
+ *
+ * Get the secret value for an secret item stored in the service.
+ *
+ * The item is represented by its D-Bus object path. If you already have a
+ * #SecretItem proxy object, use use secret_item_get_secret() to more simply
+ * get its secret value.
+ *
+ * This function returns immediately and completes asynchronously.
+ */
+void
+secret_service_get_secret_for_path (SecretService *self,
+ const gchar *item_path,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ GetClosure *closure;
+
+ g_return_if_fail (SECRET_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,
+ secret_service_get_secret_for_path);
+
+ closure = g_slice_new0 (GetClosure);
+ closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
+ closure->in = g_variant_ref_sink (g_variant_new_objv (&item_path, 1));
+ g_simple_async_result_set_op_res_gpointer (res, closure, get_closure_free);
+
+ secret_service_ensure_session (self, cancellable,
+ on_get_secrets_session,
+ g_object_ref (res));
+
+ g_object_unref (res);
+}
+
+/**
+ * secret_service_get_secret_for_path_finish:
+ * @self: the secret service
+ * @result: asynchronous result passed to callback
+ * @error: location to place an error on failure
+ *
+ * Complete asynchronous operation to get the secret value for an
+ * secret item stored in the service.
+ *
+ * Will return %NULL if the item is locked.
+ *
+ * Returns: (transfer full) (allow-none): the newly allocated secret value
+ * for the item, which should be released with secret_value_unref()
+ */
+SecretValue *
+secret_service_get_secret_for_path_finish (SecretService *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *res;
+ GetClosure *closure;
+
+ 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_get_secret_for_path), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ res = G_SIMPLE_ASYNC_RESULT (result);
+ if (g_simple_async_result_propagate_error (res, error))
+ return NULL;
+
+ closure = g_simple_async_result_get_op_res_gpointer (res);
+ return _secret_service_decode_get_secrets_first (self, closure->out);
+}
+
+/**
+ * secret_service_get_secret_for_path_sync:
+ * @self: the secret service
+ * @item_path: the D-Bus path to item to retrieve secret for
+ * @cancellable: optional cancellation object
+ * @error: location to place an error on failure
+ *
+ * Get the secret value for an secret item stored in the service.
+ *
+ * The item is represented by its D-Bus object path. If you already have a
+ * #SecretItem proxy object, use use secret_item_get_secret_sync() to more simply
+ * get its secret value.
+ *
+ * This method may block indefinitely and should not be used in user interface
+ * threads.
+ *
+ * Will return %NULL if the item is locked.
+ *
+ * Returns: (transfer full) (allow-none): the newly allocated secret value
+ * for the item, which should be released with secret_value_unref()
+ */
+SecretValue *
+secret_service_get_secret_for_path_sync (SecretService *self,
+ const gchar *item_path,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SecretSync *sync;
+ SecretValue *value;
+
+ g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
+ g_return_val_if_fail (item_path != 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_get_secret_for_path (self, item_path, cancellable,
+ _secret_sync_on_result, sync);
+
+ g_main_loop_run (sync->loop);
+
+ value = secret_service_get_secret_for_path_finish (self, sync->result, error);
+
+ g_main_context_pop_thread_default (sync->context);
+ _secret_sync_free (sync);
+
+ return value;
+}
+
+/**
+ * secret_service_get_secrets_for_paths:
+ * @self: the secret service
+ * @item_paths: the D-Bus paths to items to retrieve secrets for
+ * @cancellable: optional cancellation object
+ * @callback: called when the operation completes
+ * @user_data: data to pass to the callback
+ *
+ * Get the secret values for an secret items stored in the service.
+ *
+ * The items are represented by their D-Bus object paths. If you already have
+ * #SecretItem proxy objects, use use secret_service_get_secrets() to more simply
+ * get their secret values.
+ *
+ * This function returns immediately and completes asynchronously.
+ */
+void
+secret_service_get_secrets_for_paths (SecretService *self,
+ const gchar **item_paths,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ GetClosure *closure;
+
+ g_return_if_fail (SECRET_IS_SERVICE (self));
+ g_return_if_fail (item_paths != NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ secret_service_get_secret_for_path);
+
+ closure = g_slice_new0 (GetClosure);
+ closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
+ closure->in = g_variant_ref_sink (g_variant_new_objv (item_paths, -1));
+ g_simple_async_result_set_op_res_gpointer (res, closure, get_closure_free);
+
+ secret_service_ensure_session (self, cancellable,
+ on_get_secrets_session,
+ g_object_ref (res));
+
+ g_object_unref (res);
+}
+
+/**
+ * secret_service_get_secrets_for_paths_finish:
+ * @self: the secret service
+ * @result: asynchronous result passed to callback
+ * @error: location to place an error on failure
+ *
+ * Complete asynchronous operation to get the secret values for an
+ * secret items stored in the service.
+ *
+ * Items that are locked will not be included the results.
+ *
+ * Returns: (transfer full): a newly allocated hash table of item_path keys to
+ * #SecretValue values.
+ */
+GHashTable *
+secret_service_get_secrets_for_paths_finish (SecretService *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *res;
+ GetClosure *closure;
+
+ 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_get_secret_for_path), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ res = G_SIMPLE_ASYNC_RESULT (result);
+ if (g_simple_async_result_propagate_error (res, error))
+ return NULL;
+
+ closure = g_simple_async_result_get_op_res_gpointer (res);
+ return _secret_service_decode_get_secrets_all (self, closure->out);
+}
+
+/**
+ * secret_service_get_secrets_for_paths_sync:
+ * @self: the secret service
+ * @item_paths: the D-Bus paths to items to retrieve secrets for
+ * @cancellable: optional cancellation object
+ * @error: location to place an error on failure
+ *
+ * Get the secret values for an secret items stored in the service.
+ *
+ * The items are represented by their D-Bus object paths. If you already have
+ * #SecretItem proxy objects, use use secret_service_get_secrets_sync() to more
+ * simply get their secret values.
+ *
+ * This method may block indefinitely and should not be used in user interface
+ * threads.
+ *
+ * Items that are locked will not be included the results.
+ *
+ * Returns: (transfer full): a newly allocated hash table of item_path keys to
+ * #SecretValue values.
+ */
+GHashTable *
+secret_service_get_secrets_for_paths_sync (SecretService *self,
+ const gchar **item_paths,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SecretSync *sync;
+ GHashTable *secrets;
+
+ g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
+ g_return_val_if_fail (item_paths != 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_get_secrets_for_paths (self, item_paths, cancellable,
+ _secret_sync_on_result, sync);
+
+ g_main_loop_run (sync->loop);
+
+ secrets = secret_service_get_secrets_for_paths_finish (self, sync->result, error);
+
+ g_main_context_pop_thread_default (sync->context);
+ _secret_sync_free (sync);
+
+ return secrets;
+}
+
+
+typedef struct {
+ GCancellable *cancellable;
+ SecretPrompt *prompt;
+ GHashTable *objects;
+ GPtrArray *xlocked;
+} XlockClosure;
+
+static void
+xlock_closure_free (gpointer data)
+{
+ XlockClosure *closure = data;
+ g_clear_object (&closure->cancellable);
+ g_clear_object (&closure->prompt);
+ if (closure->xlocked)
+ g_ptr_array_unref (closure->xlocked);
+ if (closure->objects)
+ g_hash_table_unref (closure->objects);
+ g_slice_free (XlockClosure, closure);
+}
+
+static void
+on_xlock_prompted (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ XlockClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ SecretService *self = SECRET_SERVICE (source);
+ GError *error = NULL;
+ GVariantIter iter;
+ GVariant *retval;
+ gchar *path;
+
+ retval = secret_service_prompt_finish (self, result, G_VARIANT_TYPE ("ao"), &error);
+ if (error != NULL)
+ g_simple_async_result_take_error (res, error);
+
+ if (retval != NULL) {
+ g_variant_iter_init (&iter, retval);
+ while (g_variant_iter_loop (&iter, "o", &path))
+ g_ptr_array_add (closure->xlocked, g_strdup (path));
+ g_variant_unref (retval);
+ }
+
+ g_simple_async_result_complete (res);
+ g_object_unref (res);
+}
+
+static void
+on_xlock_called (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ XlockClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ SecretService *self = SECRET_SERVICE (g_async_result_get_source_object (user_data));
+ const gchar *prompt = NULL;
+ gchar **xlocked = NULL;
+ GError *error = NULL;
+ GVariant *retval;
+ guint i;
+
+ retval = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);
+ if (error != NULL) {
+ g_simple_async_result_take_error (res, error);
+ g_simple_async_result_complete (res);
+
+ } else {
+ g_variant_get (retval, "(^ao&o)", &xlocked, &prompt);
+
+ if (_secret_util_empty_path (prompt)) {
+ for (i = 0; xlocked[i]; i++)
+ g_ptr_array_add (closure->xlocked, g_strdup (xlocked[i]));
+ g_simple_async_result_complete (res);
+
+ } else {
+ closure->prompt = _secret_prompt_instance (self, prompt);
+ secret_service_prompt (self, closure->prompt, closure->cancellable,
+ on_xlock_prompted, g_object_ref (res));
+ }
+
+ g_strfreev (xlocked);
+ g_variant_unref (retval);
+ }
+
+ g_object_unref (self);
+ g_object_unref (res);
+}
+
+static GSimpleAsyncResult *
+service_xlock_paths_async (SecretService *self,
+ const gchar *method,
+ const gchar **paths,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ XlockClosure *closure;
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ service_xlock_paths_async);
+ 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,
+ g_variant_new ("(@ao)", g_variant_new_objv (paths, -1)),
+ G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
+ cancellable, on_xlock_called, g_object_ref (res));
+
+ return res;
+}
+
+static gint
+service_xlock_paths_finish (SecretService *self,
+ GAsyncResult *result,
+ gchar ***xlocked,
+ GError **error)
+{
+ GSimpleAsyncResult *res;
+ XlockClosure *closure;
+ gint count;
+
+ res = G_SIMPLE_ASYNC_RESULT (result);
+ if (g_simple_async_result_propagate_error (res, error))
+ return -1;
+
+ closure = g_simple_async_result_get_op_res_gpointer (res);
+ count = closure->xlocked->len;
+
+ if (xlocked != NULL) {
+ g_ptr_array_add (closure->xlocked, NULL);
+ *xlocked = (gchar **)g_ptr_array_free (closure->xlocked, FALSE);
+ closure->xlocked = NULL;
+ }
+
+ return count;
+}
+
+/**
+ * secret_service_lock_paths_sync:
+ * @self: the secret service
+ * @paths: the D-Bus object paths of the items or collections to lock
+ * @cancellable: optional cancellation object
+ * @locked: (out) (array zero-terminated=1) (transfer full) (allow-none):
+ * location to place array of D-Bus paths of items or collections
+ * that were locked
+ * @error: location to place an error on failure
+ *
+ * Lock items or collections in the secret service.
+ *
+ * The items or collections are represented by their D-Bus object paths. If you
+ * already have #SecretItem and #SecretCollection proxy objects, use use
+ * secret_service_lock_sync() instead.
+ *
+ * The secret service may not be able to lock items individually, and may
+ * lock an entire collection instead.
+ *
+ * This method may block indefinitely and should not be used in user
+ * interface threads. The secret service may prompt the user.
+ * secret_service_prompt() will be used to handle any prompts that show up.
+ *
+ * Returns: the number of items or collections that were locked
+ */
+gint
+secret_service_lock_paths_sync (SecretService *self,
+ const gchar **paths,
+ GCancellable *cancellable,
+ gchar ***locked,
+ GError **error)
+{
+ SecretSync *sync;
+ gint count;
+
+ g_return_val_if_fail (SECRET_IS_SERVICE (self), -1);
+ g_return_val_if_fail (paths != NULL, -1);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1);
+ g_return_val_if_fail (error == NULL || *error == NULL, -1);
+
+ sync = _secret_sync_new ();
+ g_main_context_push_thread_default (sync->context);
+
+ secret_service_lock_paths (self, paths, cancellable,
+ _secret_sync_on_result, sync);
+
+ g_main_loop_run (sync->loop);
+
+ count = secret_service_lock_paths_finish (self, sync->result,
+ locked, error);
+
+ g_main_context_pop_thread_default (sync->context);
+ _secret_sync_free (sync);
+
+ return count;
+}
+
+/**
+ * secret_service_lock_paths:
+ * @self: the secret service
+ * @paths: the D-Bus paths for items or collections to lock
+ * @cancellable: optional cancellation object
+ * @callback: called when the operation completes
+ * @user_data: data to pass to the callback
+ *
+ * Lock items or collections in the secret service.
+ *
+ * The items or collections are represented by their D-Bus object paths. If you
+ * already have #SecretItem and #SecretCollection proxy objects, use use
+ * secret_service_lock() instead.
+ *
+ * The secret service may not be able to lock items individually, and may
+ * lock an entire collection instead.
+ *
+ * This method returns immediately and completes asynchronously. The secret
+ * service may prompt the user. secret_service_prompt() will be used to handle
+ * any prompts that show up.
+ */
+void
+secret_service_lock_paths (SecretService *self,
+ const gchar **paths,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+
+ g_return_if_fail (SECRET_IS_SERVICE (self));
+ g_return_if_fail (paths != NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ res = service_xlock_paths_async (self, "Lock", paths, cancellable,
+ callback, user_data);
+
+ g_object_unref (res);
+}
+
+/**
+ * secret_service_lock_paths_finish:
+ * @self: the secret service
+ * @result: asynchronous result passed to the callback
+ * @locked: (out) (array zero-terminated=1) (transfer full) (allow-none):
+ * location to place array of D-Bus paths of items or collections
+ * that were locked
+ * @error: location to place an error on failure
+ *
+ * Complete asynchronous operation to lock items or collections in the secret
+ * service.
+ *
+ * The secret service may not be able to lock items individually, and may
+ * lock an entire collection instead.
+ *
+ * Returns: the number of items or collections that were locked
+ */
+gint
+secret_service_lock_paths_finish (SecretService *self,
+ GAsyncResult *result,
+ gchar ***locked,
+ GError **error)
+{
+ g_return_val_if_fail (SECRET_IS_SERVICE (self), -1);
+ g_return_val_if_fail (locked != NULL, -1);
+ g_return_val_if_fail (error == NULL || *error == NULL, -1);
+
+ return service_xlock_paths_finish (self, result, locked, error);
+}
+
+/**
+ * secret_service_unlock_paths_sync:
+ * @self: the secret service
+ * @paths: the D-Bus object paths of the items or collections to unlock
+ * @cancellable: optional cancellation object
+ * @unlocked: (out) (array zero-terminated=1) (transfer full) (allow-none):
+ * location to place array of D-Bus paths of items or collections
+ * that were unlocked
+ * @error: location to place an error on failure
+ *
+ * Unlock items or collections in the secret service.
+ *
+ * The items or collections are represented by their D-Bus object paths. If you
+ * already have #SecretItem and #SecretCollection proxy objects, use use
+ * secret_service_unlock_sync() instead.
+ *
+ * The secret service may not be able to unlock items individually, and may
+ * unlock an entire collection instead.
+ *
+ * This method may block indefinitely and should not be used in user
+ * interface threads. The secret service may prompt the user.
+ * secret_service_prompt() will be used to handle any prompts that show up.
+ *
+ * Returns: the number of items or collections that were unlocked
+ */
+gint
+secret_service_unlock_paths_sync (SecretService *self,
+ const gchar **paths,
+ GCancellable *cancellable,
+ gchar ***unlocked,
+ GError **error)
+{
+ SecretSync *sync;
+ gint count;
+
+ g_return_val_if_fail (SECRET_IS_SERVICE (self), -1);
+ g_return_val_if_fail (paths != NULL, -1);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1);
+ g_return_val_if_fail (unlocked != NULL, -1);
+ g_return_val_if_fail (error == NULL || *error == NULL, -1);
+
+ sync = _secret_sync_new ();
+ g_main_context_push_thread_default (sync->context);
+
+ secret_service_unlock_paths (self, paths, cancellable,
+ _secret_sync_on_result, sync);
+
+ g_main_loop_run (sync->loop);
+
+ count = secret_service_unlock_paths_finish (self, sync->result,
+ unlocked, error);
+
+ g_main_context_pop_thread_default (sync->context);
+ _secret_sync_free (sync);
+
+ return count;
+}
+
+/**
+ * secret_service_unlock_paths:
+ * @self: the secret service
+ * @paths: the D-Bus paths for items or collections to unlock
+ * @cancellable: optional cancellation object
+ * @callback: called when the operation completes
+ * @user_data: data to pass to the callback
+ *
+ * Unlock items or collections in the secret service.
+ *
+ * The items or collections are represented by their D-Bus object paths. If you
+ * already have #SecretItem and #SecretCollection proxy objects, use use
+ * secret_service_unlock() instead.
+ *
+ * The secret service may not be able to unlock items individually, and may
+ * unlock an entire collection instead.
+ *
+ * This method returns immediately and completes asynchronously. The secret
+ * service may prompt the user. secret_service_prompt() will be used to handle
+ * any prompts that show up.
+ */
+void
+secret_service_unlock_paths (SecretService *self,
+ const gchar **paths,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+
+ g_return_if_fail (SECRET_IS_SERVICE (self));
+ g_return_if_fail (paths != NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ res = service_xlock_paths_async (self, "Unlock",
+ paths, cancellable,
+ callback, user_data);
+
+ g_object_unref (res);
+}
+
+/**
+ * secret_service_unlock_paths_finish:
+ * @self: the secret service
+ * @result: asynchronous result passed to the callback
+ * @unlocked: (out) (array zero-terminated=1) (transfer full) (allow-none):
+ * location to place array of D-Bus paths of items or collections
+ * that were unlocked
+ * @error: location to place an error on failure
+ *
+ * Complete asynchronous operation to unlock items or collections in the secret
+ * service.
+ *
+ * The secret service may not be able to unlock items individually, and may
+ * unlock an entire collection instead.
+ *
+ * Returns: the number of items or collections that were unlocked
+ */
+gint
+secret_service_unlock_paths_finish (SecretService *self,
+ GAsyncResult *result,
+ gchar ***unlocked,
+ GError **error)
+{
+ g_return_val_if_fail (SECRET_IS_SERVICE (self), -1);
+ g_return_val_if_fail (error == NULL || *error == NULL, -1);
+
+ return service_xlock_paths_finish (self, result,
+ unlocked, error);
+}
+
+typedef struct {
+ GCancellable *cancellable;
+ SecretPrompt *prompt;
+ gboolean deleted;
+} DeleteClosure;
+
+static void
+delete_closure_free (gpointer data)
+{
+ DeleteClosure *closure = data;
+ g_clear_object (&closure->prompt);
+ g_clear_object (&closure->cancellable);
+ g_slice_free (DeleteClosure, closure);
+}
+
+static void
+on_delete_prompted (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ GError *error = NULL;
+ GVariant *retval;
+
+ retval = secret_service_prompt_finish (SECRET_SERVICE (source), result,
+ NULL, &error);
+
+ if (error == NULL)
+ closure->deleted = TRUE;
+ else
+ g_simple_async_result_take_error (res, error);
+ if (retval != NULL)
+ g_variant_unref (retval);
+ g_simple_async_result_complete (res);
+ g_object_unref (res);
+}
+
+static void
+on_delete_complete (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ SecretService *self = SECRET_SERVICE (g_async_result_get_source_object (user_data));
+ const gchar *prompt_path;
+ GError *error = NULL;
+ GVariant *retval;
+
+ retval = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
+ if (error == NULL) {
+ g_variant_get (retval, "(&o)", &prompt_path);
+
+ if (_secret_util_empty_path (prompt_path)) {
+ closure->deleted = TRUE;
+ g_simple_async_result_complete (res);
+
+ } else {
+ closure->prompt = _secret_prompt_instance (self, prompt_path);
+
+ secret_service_prompt (self, closure->prompt,
+ closure->cancellable,
+ on_delete_prompted,
+ g_object_ref (res));
+ }
+
+ g_variant_unref (retval);
+
+ } else {
+ g_simple_async_result_take_error (res, error);
+ g_simple_async_result_complete (res);
+ }
+
+ g_object_unref (self);
+ g_object_unref (res);
+}
+
+void
+_secret_service_delete_path (SecretService *self,
+ const gchar *object_path,
+ gboolean is_an_item,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ DeleteClosure *closure;
+
+ g_return_if_fail (SECRET_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,
+ _secret_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 ? SECRET_ITEM_INTERFACE : SECRET_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);
+}
+
+/**
+ * secret_service_delete_path:
+ * @self: the secret service
+ * @item_path: the D-Bus path of item to delete
+ * @cancellable: optional cancellation object
+ * @callback: called when the operation completes
+ * @user_data: data to be passed to the callback
+ *
+ * Delete a secret item from the secret service.
+ *
+ * The item is represented by its D-Bus object path. If you already have a
+ * #SecretItem proxy objects, use use secret_item_delete() instead.
+ *
+ * This method will return immediately and complete asynchronously.
+ */
+void
+secret_service_delete_path (SecretService *self,
+ const gchar *item_path,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (SECRET_IS_SERVICE (self));
+ g_return_if_fail (item_path != NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ _secret_service_delete_path (self, item_path, TRUE, cancellable, callback, user_data);
+}
+
+/**
+ * secret_service_delete_path_finish:
+ * @self: the secret service
+ * @result: the asynchronous result passed to the callback
+ * @error: location to place an error on failure
+ *
+ * Complete an asynchronous operation to delete a secret item from the secret
+ * service.
+ *
+ * Returns: whether the deletion was successful or not
+ */
+gboolean
+secret_service_delete_path_finish (SecretService *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *res;
+ DeleteClosure *closure;
+
+ g_return_val_if_fail (SECRET_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),
+ _secret_service_delete_path), FALSE);
+
+ res = G_SIMPLE_ASYNC_RESULT (result);
+ if (g_simple_async_result_propagate_error (res, error))
+ return FALSE;
+
+ closure = g_simple_async_result_get_op_res_gpointer (res);
+ return closure->deleted;
+}
+
+/**
+ * secret_service_delete_path_sync:
+ * @self: the secret service
+ * @item_path: the D-Bus path of item to delete
+ * @cancellable: optional cancellation object
+ * @error: location to place an error on failure
+ *
+ * Delete a secret item from the secret service.
+ *
+ * The item is represented by its D-Bus object path. If you already have a
+ * #SecretItem proxy objects, use use secret_item_delete_sync() instead.
+ *
+ * This method may block indefinitely and should not be used in user interface
+ * threads.
+ *
+ * Returns: whether the deletion was successful or not
+ */
+gboolean
+secret_service_delete_path_sync (SecretService *self,
+ const gchar *item_path,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SecretSync *sync;
+ gboolean result;
+
+ g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
+ g_return_val_if_fail (item_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 = _secret_sync_new ();
+ g_main_context_push_thread_default (sync->context);
+
+ secret_service_delete_path (self, item_path, cancellable,
+ _secret_sync_on_result, sync);
+
+ g_main_loop_run (sync->loop);
+
+ result = secret_service_delete_path_finish (self, sync->result, error);
+
+ g_main_context_pop_thread_default (sync->context);
+ _secret_sync_free (sync);
+
+ return result;
+}
+
+typedef struct {
+ GCancellable *cancellable;
+ SecretPrompt *prompt;
+ gchar *collection_path;
+} CollectionClosure;
+
+static void
+collection_closure_free (gpointer data)
+{
+ CollectionClosure *closure = data;
+ g_clear_object (&closure->cancellable);
+ g_clear_object (&closure->prompt);
+ g_slice_free (CollectionClosure, closure);
+}
+
+static void
+on_create_collection_prompt (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ CollectionClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ GError *error = NULL;
+ GVariant *value;
+
+ value = secret_service_prompt_finish (SECRET_SERVICE (source), result,
+ G_VARIANT_TYPE ("o"), &error);
+ if (error != NULL)
+ g_simple_async_result_take_error (res, error);
+ if (value != NULL) {
+ closure->collection_path = g_variant_dup_string (value, NULL);
+ g_variant_unref (value);
+ }
+
+ g_simple_async_result_complete (res);
+ g_object_unref (res);
+}
+
+static void
+on_create_collection_called (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ CollectionClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ SecretService *self = SECRET_SERVICE (g_async_result_get_source_object (user_data));
+ const gchar *prompt_path = NULL;
+ const gchar *collection_path = NULL;
+ GError *error = NULL;
+ GVariant *retval;
+
+ retval = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
+ if (error == NULL) {
+ g_variant_get (retval, "(&o&o)", &collection_path, &prompt_path);
+ if (!_secret_util_empty_path (prompt_path)) {
+ closure->prompt = _secret_prompt_instance (self, prompt_path);
+ secret_service_prompt (self, closure->prompt,
+ closure->cancellable, on_create_collection_prompt,
+ g_object_ref (res));
+
+ } else {
+ closure->collection_path = g_strdup (collection_path);
+ g_simple_async_result_complete (res);
+ }
+
+ g_variant_unref (retval);
+
+ } else {
+ g_simple_async_result_take_error (res, error);
+ g_simple_async_result_complete (res);
+ }
+
+ g_object_unref (self);
+ g_object_unref (res);
+}
+
+/**
+ * secret_service_create_collection_path:
+ * @self: a secret service object
+ * @properties: (element-type utf8 GLib.Variant): hash table of properties for
+ * the new collection
+ * @alias: (allow-none): an alias to check for before creating the new
+ * collection, or to assign to the new collection
+ * @cancellable: optional cancellation object
+ * @callback: called when the operation completes
+ * @user_data: data to be passed to the callback
+ *
+ * Create a new collection in the secret service, and return its path.
+ *
+ * Using this method requires that you setup a correct hash table of D-Bus
+ * properties for the new collection. You may prefer to use
+ * secret_collection_create() which does handles this for you.
+ *
+ * An @alias is a well-known tag for a collection, such as 'default' (ie: the
+ * default collection to store items in). This allows other applications to
+ * easily identify and share a collection. If a collection with the @alias
+ * already exists, then instead of creating a new collection, the existing
+ * collection will be returned. If no collection with this alias exists, then a
+ * new collection will be created and this alias will be assigned to it.
+ *
+ * @properties is a set of properties for the new collection. The keys in the
+ * hash table should be interface.property strings like
+ * org.freedesktop.Secret.Collection.Label. The values
+ * in the hash table should be #GVariant values of the properties.
+ *
+ * If you wish to have a
+ *
+ * This method will return immediately and complete asynchronously. The secret
+ * service may prompt the user. secret_service_prompt() will be used to handle
+ * any prompts that are required.
+ */
+void
+secret_service_create_collection_path (SecretService *self,
+ GHashTable *properties,
+ const gchar *alias,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ CollectionClosure *closure;
+ GVariant *params;
+ GVariant *props;
+ GDBusProxy *proxy;
+
+ g_return_if_fail (SECRET_IS_SERVICE (self));
+ g_return_if_fail (properties != NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ if (alias == NULL)
+ alias = "";
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ secret_service_create_collection_path);
+ closure = g_slice_new0 (CollectionClosure);
+ closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
+ g_simple_async_result_set_op_res_gpointer (res, closure, collection_closure_free);
+
+ props = _secret_util_variant_for_properties (properties);
+ params = g_variant_new ("(@a{sv}s)", props, alias);
+ proxy = G_DBUS_PROXY (self);
+
+ g_dbus_connection_call (g_dbus_proxy_get_connection (proxy),
+ g_dbus_proxy_get_name (proxy),
+ g_dbus_proxy_get_object_path (proxy),
+ SECRET_SERVICE_INTERFACE,
+ "CreateCollection", params, G_VARIANT_TYPE ("(oo)"),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ closure->cancellable,
+ on_create_collection_called,
+ g_object_ref (res));
+
+ g_object_unref (res);
+
+}
+
+/**
+ * secret_service_create_collection_path_finish:
+ * @self: a secret service object
+ * @result: the asynchronous result passed to the callback
+ * @error: location to place an error on failure
+ *
+ * Finish asynchronous operation to create a new collection in the secret
+ * service.
+ *
+ * Returns: (transfer full): a new string containing the D-Bus object path
+ * of the collection
+ */
+gchar *
+secret_service_create_collection_path_finish (SecretService *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *res;
+ CollectionClosure *closure;
+ gchar *path;
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+ secret_service_create_collection_path), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ res = G_SIMPLE_ASYNC_RESULT (result);
+
+ if (g_simple_async_result_propagate_error (res, error))
+ return NULL;
+
+ closure = g_simple_async_result_get_op_res_gpointer (res);
+ path = closure->collection_path;
+ closure->collection_path = NULL;
+ return path;
+}
+
+/**
+ * secret_service_create_collection_path_sync:
+ * @self: a secret service object
+ * @properties: (element-type utf8 GLib.Variant): hash table of D-Bus properties
+ * for the new collection
+ * @alias: (allow-none): an alias to check for before creating the new
+ * collection, or to assign to the new collection
+ * @cancellable: optional cancellation object
+ * @error: location to place an error on failure
+ *
+ * Create a new collection in the secret service and return its path.
+ *
+ * Using this method requires that you setup a correct hash table of D-Bus
+ * properties for the new collection. You may prefer to use
+ * secret_collection_create() which does handles this for you.
+ *
+ * An @alias is a well-known tag for a collection, such as 'default' (ie: the
+ * default collection to store items in). This allows other applications to
+ * easily identify and share a collection. If a collection with the @alias
+ * already exists, then instead of creating a new collection, the existing
+ * collection will be returned. If no collection with this alias exists, then
+ * a new collection will be created and this alias will be assigned to it.
+ *
+ * @properties is a set of properties for the new collection. The keys in the
+ * hash table should be interface.property strings like
+ * org.freedesktop.Secret.Collection.Label. The values
+ * in the hash table should be #GVariant values of the properties.
+ *
+ * This method may block indefinitely and should not be used in user interface
+ * threads. The secret service may prompt the user. secret_service_prompt()
+ * will be used to handle any prompts that are required.
+ *
+ * Returns: (transfer full): a new string containing the D-Bus object path
+ * of the collection
+ */
+gchar *
+secret_service_create_collection_path_sync (SecretService *self,
+ GHashTable *properties,
+ const gchar *alias,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SecretSync *sync;
+ gchar *path;
+
+ g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
+ g_return_val_if_fail (properties != 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_create_collection_path (self, properties, alias, cancellable,
+ _secret_sync_on_result, sync);
+
+ g_main_loop_run (sync->loop);
+
+ path = secret_service_create_collection_path_finish (self, sync->result, error);
+
+ g_main_context_pop_thread_default (sync->context);
+ _secret_sync_free (sync);
+
+ return path;
+}
+
+typedef struct {
+ GCancellable *cancellable;
+ GVariant *properties;
+ SecretValue *value;
+ gboolean replace;
+ gchar *collection_path;
+ SecretPrompt *prompt;
+ gchar *item_path;
+} ItemClosure;
+
+static void
+item_closure_free (gpointer data)
+{
+ ItemClosure *closure = data;
+ g_variant_unref (closure->properties);
+ secret_value_unref (closure->value);
+ g_clear_object (&closure->cancellable);
+ g_free (closure->collection_path);
+ g_clear_object (&closure->prompt);
+ g_slice_free (ItemClosure, closure);
+}
+
+static void
+on_create_item_prompt (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ ItemClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ GError *error = NULL;
+ GVariant *value;
+
+ value = secret_service_prompt_finish (SECRET_SERVICE (source), result,
+ G_VARIANT_TYPE ("o"), &error);
+ if (error != NULL)
+ g_simple_async_result_take_error (res, error);
+ if (value != NULL) {
+ closure->item_path = g_variant_dup_string (value, NULL);
+ g_variant_unref (value);
+ }
+
+ g_simple_async_result_complete (res);
+ g_object_unref (res);
+}
+
+static void
+on_create_item_called (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ ItemClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ SecretService *self = SECRET_SERVICE (g_async_result_get_source_object (user_data));
+ const gchar *prompt_path = NULL;
+ const gchar *item_path = NULL;
+ GError *error = NULL;
+ GVariant *retval;
+
+ retval = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
+ if (error == NULL) {
+ g_variant_get (retval, "(&o&o)", &item_path, &prompt_path);
+ if (!_secret_util_empty_path (prompt_path)) {
+ closure->prompt = _secret_prompt_instance (self, prompt_path);
+ secret_service_prompt (self, closure->prompt,
+ closure->cancellable, on_create_item_prompt,
+ g_object_ref (res));
+
+ } else {
+ closure->item_path = g_strdup (item_path);
+ g_simple_async_result_complete (res);
+ }
+
+ g_variant_unref (retval);
+
+ } else {
+ g_simple_async_result_take_error (res, error);
+ g_simple_async_result_complete (res);
+ }
+
+ g_object_unref (self);
+ g_object_unref (res);
+}
+
+static void
+on_create_item_session (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ ItemClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ SecretService *self = SECRET_SERVICE (source);
+ SecretSession *session;
+ GVariant *params;
+ GError *error = NULL;
+ GDBusProxy *proxy;
+
+ secret_service_ensure_session_finish (self, result, &error);
+ if (error == NULL) {
+ session = _secret_service_get_session (self);
+ params = g_variant_new ("(@a{sv}@(oayays)b)",
+ closure->properties,
+ _secret_session_encode_secret (session, closure->value),
+ closure->replace);
+
+ proxy = G_DBUS_PROXY (self);
+ g_dbus_connection_call (g_dbus_proxy_get_connection (proxy),
+ g_dbus_proxy_get_name (proxy),
+ closure->collection_path,
+ SECRET_COLLECTION_INTERFACE,
+ "CreateItem", params, G_VARIANT_TYPE ("(oo)"),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ closure->cancellable,
+ on_create_item_called,
+ g_object_ref (res));
+ } else {
+ g_simple_async_result_take_error (res, error);
+ g_simple_async_result_complete (res);
+ }
+
+ g_object_unref (res);
+}
+
+/**
+ * secret_service_create_item_path:
+ * @self: a secret service object
+ * @collection_path: (allow-none): the D-Bus object path of the collection in which to create item
+ * @properties: (element-type utf8 GLib.Variant): hash table of D-Bus properties
+ * for the new collection
+ * @value: the secret value to store in the item
+ * @replace: whether to replace an item with the matching attributes
+ * @cancellable: optional cancellation object
+ * @callback: called when the operation completes
+ * @user_data: data to be passed to the callback
+ *
+ * Create a new item in a secret service collection and return its D-Bus
+ * object path.
+ *
+ * It is often easier to use secret_password_store() or secret_item_create()
+ * rather than using this function. Using this method requires that you setup
+ * a correct hash table of D-Bus @properties for the new collection.
+ *
+ * If @replace is set to %TRUE, and an item already in the collection matches
+ * the attributes (specified in @properties) then the item will be updated
+ * instead of creating a new item.
+ *
+ * @properties is a set of properties for the new collection. The keys in the
+ * hash table should be interface.property strings like
+ * org.freedesktop.Secret.Item.Label. The values
+ * in the hash table should be #GVariant values of the properties.
+ *
+ * If @collection_path is %NULL, then the default collection will be
+ * used. Use #SECRET_COLLECTION_SESSION to store the password in the session
+ * collection, which doesn't get stored across login sessions.
+ *
+ * This method will return immediately and complete asynchronously. The secret
+ * service may prompt the user. secret_service_prompt() will be used to handle
+ * any prompts that are required.
+ */
+void
+secret_service_create_item_path (SecretService *self,
+ const gchar *collection_path,
+ GHashTable *properties,
+ SecretValue *value,
+ gboolean replace,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ ItemClosure *closure;
+
+ g_return_if_fail (SECRET_IS_SERVICE (self));
+ g_return_if_fail (properties != NULL);
+ g_return_if_fail (value != NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ if (collection_path == NULL)
+ collection_path = SECRET_COLLECTION_DEFAULT;
+
+ res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ secret_service_create_item_path);
+ closure = g_slice_new0 (ItemClosure);
+ closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
+ closure->properties = _secret_util_variant_for_properties (properties);
+ g_variant_ref_sink (closure->properties);
+ closure->replace = replace;
+ closure->value = secret_value_ref (value);
+ closure->collection_path = g_strdup (collection_path);
+ g_simple_async_result_set_op_res_gpointer (res, closure, item_closure_free);
+
+ secret_service_ensure_session (self, cancellable,
+ on_create_item_session,
+ g_object_ref (res));
+
+ g_object_unref (res);
+}
+
+/**
+ * secret_service_create_item_path_finish:
+ * @self: a secret service object
+ * @result: the asynchronous result passed to the callback
+ * @error: location to place an error on failure
+ *
+ * Finish asynchronous operation to create a new item in the secret
+ * service.
+ *
+ * Returns: (transfer full): a new string containing the D-Bus object path
+ * of the item
+ */
+gchar *
+secret_service_create_item_path_finish (SecretService *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *res;
+ ItemClosure *closure;
+ gchar *path;
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+ secret_service_create_item_path), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ res = G_SIMPLE_ASYNC_RESULT (result);
+
+ if (g_simple_async_result_propagate_error (res, error))
+ return NULL;
+
+ closure = g_simple_async_result_get_op_res_gpointer (res);
+ path = closure->item_path;
+ closure->item_path = NULL;
+ return path;
+}
+
+/**
+ * secret_service_create_item_path_sync:
+ * @self: a secret service object
+ * @collection_path: (allow-none): the D-Bus path of the collection in which to create item
+ * @properties: (element-type utf8 GLib.Variant): hash table of D-Bus properties
+ * for the new collection
+ * @value: the secret value to store in the item
+ * @replace: whether to replace an item with the matching attributes
+ * @cancellable: optional cancellation object
+ * @error: location to place an error on failure
+ *
+ * Create a new item in a secret service collection and return its D-Bus
+ * object path.
+ *
+ * It is often easier to use secret_password_store_sync() or secret_item_create_sync()
+ * rather than using this function. Using this method requires that you setup
+ * a correct hash table of D-Bus @properties for the new collection.
+ *
+ * If @replace is set to %TRUE, and an item already in the collection matches
+ * the attributes (specified in @properties) then the item will be updated
+ * instead of creating a new item.
+ *
+ * @properties is a set of properties for the new collection. The keys in the
+ * hash table should be interface.property strings like
+ * org.freedesktop.Secret.Item.Label. The values
+ * in the hash table should be #GVariant values of the properties.
+ *
+ * This method may block indefinitely and should not be used in user interface
+ * threads. The secret service may prompt the user. secret_service_prompt()
+ * will be used to handle any prompts that are required.
+ *
+ * Returns: (transfer full): a new string containing the D-Bus object path
+ * of the item
+ */
+gchar *
+secret_service_create_item_path_sync (SecretService *self,
+ const gchar *collection_path,
+ GHashTable *properties,
+ SecretValue *value,
+ gboolean replace,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SecretSync *sync;
+ gchar *path;
+
+ g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
+ g_return_val_if_fail (properties != 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_create_item_path (self, collection_path, properties, value, replace,
+ cancellable, _secret_sync_on_result, sync);
+
+ g_main_loop_run (sync->loop);
+
+ path = secret_service_create_item_path_finish (self, sync->result, error);
+
+ g_main_context_pop_thread_default (sync->context);
+ _secret_sync_free (sync);
+
+ return path;
+}
+
+/**
+ * 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_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;
+}
+
+GVariant *
+secret_service_prompt_path_sync (SecretService *self,
+ const gchar *prompt_path,
+ GCancellable *cancellable,
+ const GVariantType *return_type,
+ GError **error)
+{
+ SecretPrompt *prompt;
+ GVariant *retval;
+
+ g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
+ g_return_val_if_fail (prompt_path != NULL, NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ prompt = _secret_prompt_instance (self, prompt_path);
+ retval = secret_service_prompt_sync (self, prompt, cancellable, return_type, error);
+ g_object_unref (prompt);
+
+ return retval;
+}
+
+/**
+ * secret_service_prompt_path:
+ * @self: the secret service
+ * @prompt_path: the D-Bus object path of the prompt
+ * @cancellable: optional cancellation object
+ * @callback: called when the operation completes
+ * @user_data: data to be passed to the callback
+ *
+ * Perform prompting for a #SecretPrompt.
+ *
+ * This function is called by other parts of this library to handle prompts
+ * for the various actions that can require prompting.
+ *
+ * Override the #SecretServiceClass prompt_async virtual method
+ * to change the behavior of the propmting. The default behavior is to simply
+ * run secret_prompt_perform() on the prompt.
+ */
+void
+secret_service_prompt_path (SecretService *self,
+ const gchar *prompt_path,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SecretPrompt *prompt;
+
+ g_return_if_fail (SECRET_IS_SERVICE (self));
+ g_return_if_fail (prompt_path != NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ prompt = _secret_prompt_instance (self, prompt_path);
+ secret_service_prompt (self, prompt, cancellable, callback, user_data);
+ g_object_unref (prompt);
+}
+
+/**
+ * secret_service_prompt_path_finish:
+ * @self: the secret service
+ * @result: the asynchronous result passed to the callback
+ * @return_type: the variant type of the prompt result
+ * @error: location to place an error on failure
+ *
+ * Complete asynchronous operation to perform prompting for a #SecretPrompt.
+ *
+ * Returns a variant result if the prompt was completed and not dismissed. The
+ * type of result depends on the action the prompt is completing, and is defined
+ * in the Secret Service DBus API specification.
+ *
+ * Returns: (transfer full): %NULL if the prompt was dismissed or an error occurred,
+ * a variant result if the prompt was successful
+ */
+GVariant *
+secret_service_prompt_path_finish (SecretService *self,
+ GAsyncResult *result,
+ const GVariantType *return_type,
+ GError **error)
+{
+ g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ return secret_service_prompt_finish (self, result, return_type, error);
+}
diff --git a/library/secret-paths.h b/library/secret-paths.h
new file mode 100644
index 0000000..a26a5e7
--- /dev/null
+++ b/library/secret-paths.h
@@ -0,0 +1,219 @@
+/* libsecret - GLib wrapper for Secret Service
+ *
+ * Copyright 2011 Collabora Ltd.
+ * Copyright 2012 Red Hat Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the licence or (at
+ * your option) any later version.
+ *
+ * See the included COPYING file for more information.
+ *
+ * Author: Stef Walter
+ */
+
+#if !defined (__SECRET_INSIDE_HEADER__) && !defined (SECRET_COMPILATION)
+#error "Only or can be included directly."
+#endif
+
+#ifndef __SECRET_PATHS_H__
+#define __SECRET_PATHS_H__
+
+#include
+
+#include "secret-prompt.h"
+#include "secret-schema.h"
+#include "secret-types.h"
+#include "secret-value.h"
+
+G_BEGIN_DECLS
+
+void secret_service_search_for_paths (SecretService *self,
+ GHashTable *attributes,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean secret_service_search_for_paths_finish (SecretService *self,
+ GAsyncResult *result,
+ gchar ***unlocked,
+ gchar ***locked,
+ GError **error);
+
+gboolean secret_service_search_for_paths_sync (SecretService *self,
+ GHashTable *attributes,
+ GCancellable *cancellable,
+ gchar ***unlocked,
+ gchar ***locked,
+ GError **error);
+
+void secret_service_get_secret_for_path (SecretService *self,
+ const gchar *item_path,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+SecretValue * secret_service_get_secret_for_path_finish (SecretService *self,
+ GAsyncResult *result,
+ GError **error);
+
+SecretValue * secret_service_get_secret_for_path_sync (SecretService *self,
+ const gchar *item_path,
+ GCancellable *cancellable,
+ GError **error);
+
+void secret_service_get_secrets_for_paths (SecretService *self,
+ const gchar **item_paths,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GHashTable * secret_service_get_secrets_for_paths_finish (SecretService *self,
+ GAsyncResult *result,
+ GError **error);
+
+GHashTable * secret_service_get_secrets_for_paths_sync (SecretService *self,
+ const gchar **item_paths,
+ GCancellable *cancellable,
+ GError **error);
+
+gint secret_service_lock_paths_sync (SecretService *self,
+ const gchar **paths,
+ GCancellable *cancellable,
+ gchar ***locked,
+ GError **error);
+
+void secret_service_lock_paths (SecretService *self,
+ const gchar **paths,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gint secret_service_lock_paths_finish (SecretService *self,
+ GAsyncResult *result,
+ gchar ***locked,
+ GError **error);
+
+gint secret_service_unlock_paths_sync (SecretService *self,
+ const gchar **paths,
+ GCancellable *cancellable,
+ gchar ***unlocked,
+ GError **error);
+
+void secret_service_unlock_paths (SecretService *self,
+ const gchar **paths,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gint secret_service_unlock_paths_finish (SecretService *self,
+ GAsyncResult *result,
+ gchar ***unlocked,
+ GError **error);
+
+GVariant * secret_service_prompt_path_sync (SecretService *self,
+ const gchar *prompt_path,
+ GCancellable *cancellable,
+ const GVariantType *return_type,
+ GError **error);
+
+void secret_service_prompt_path (SecretService *self,
+ const gchar *prompt_path,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GVariant * secret_service_prompt_path_finish (SecretService *self,
+ GAsyncResult *result,
+ const GVariantType *return_type,
+ GError **error);
+
+void secret_service_delete_path (SecretService *self,
+ const gchar *item_path,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean secret_service_delete_path_finish (SecretService *self,
+ GAsyncResult *result,
+ GError **error);
+
+gboolean secret_service_delete_path_sync (SecretService *self,
+ const gchar *item_path,
+ GCancellable *cancellable,
+ GError **error);
+
+void secret_service_create_collection_path (SecretService *self,
+ GHashTable *properties,
+ const gchar *alias,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gchar * secret_service_create_collection_path_finish (SecretService *self,
+ GAsyncResult *result,
+ GError **error);
+
+gchar * secret_service_create_collection_path_sync (SecretService *self,
+ GHashTable *properties,
+ const gchar *alias,
+ GCancellable *cancellable,
+ GError **error);
+
+void secret_service_create_item_path (SecretService *self,
+ const gchar *collection_path,
+ GHashTable *properties,
+ SecretValue *value,
+ gboolean replace,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gchar * secret_service_create_item_path_finish (SecretService *self,
+ GAsyncResult *result,
+ GError **error);
+
+gchar * secret_service_create_item_path_sync (SecretService *self,
+ const gchar *collection_path,
+ GHashTable *properties,
+ SecretValue *value,
+ gboolean replace,
+ 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_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/secret-private.h b/library/secret-private.h
index e6a86d7..b4ecebd 100644
--- a/library/secret-private.h
+++ b/library/secret-private.h
@@ -139,6 +139,12 @@ SecretItem * _secret_service_find_item_instance (SecretService *se
SecretCollection * _secret_service_find_collection_instance (SecretService *self,
const gchar *collection_path);
+SecretValue * _secret_service_decode_get_secrets_first (SecretService *self,
+ GVariant *out);
+
+GHashTable * _secret_service_decode_get_secrets_all (SecretService *self,
+ GVariant *out);
+
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 0b9e923..9a6eb16 100644
--- a/library/secret-service.c
+++ b/library/secret-service.c
@@ -19,6 +19,7 @@
#include "secret-dbus-generated.h"
#include "secret-enum-types.h"
#include "secret-item.h"
+#include "secret-paths.h"
#include "secret-private.h"
#include "secret-service.h"
#include "secret-types.h"
@@ -1648,89 +1649,3 @@ secret_service_prompt_finish (SecretService *self,
return (klass->prompt_finish) (self, result, return_type, error);
}
-
-GVariant *
-secret_service_prompt_path_sync (SecretService *self,
- const gchar *prompt_path,
- GCancellable *cancellable,
- const GVariantType *return_type,
- GError **error)
-{
- SecretPrompt *prompt;
- GVariant *retval;
-
- g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
- g_return_val_if_fail (prompt_path != NULL, NULL);
- g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
- prompt = _secret_prompt_instance (self, prompt_path);
- retval = secret_service_prompt_sync (self, prompt, cancellable, return_type, error);
- g_object_unref (prompt);
-
- return retval;
-}
-
-/**
- * secret_service_prompt_path:
- * @self: the secret service
- * @prompt_path: the D-Bus object path of the prompt
- * @cancellable: optional cancellation object
- * @callback: called when the operation completes
- * @user_data: data to be passed to the callback
- *
- * Perform prompting for a #SecretPrompt.
- *
- * This function is called by other parts of this library to handle prompts
- * for the various actions that can require prompting.
- *
- * Override the #SecretServiceClass prompt_async virtual method
- * to change the behavior of the propmting. The default behavior is to simply
- * run secret_prompt_perform() on the prompt.
- */
-void
-secret_service_prompt_path (SecretService *self,
- const gchar *prompt_path,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- SecretPrompt *prompt;
-
- g_return_if_fail (SECRET_IS_SERVICE (self));
- g_return_if_fail (prompt_path != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- prompt = _secret_prompt_instance (self, prompt_path);
- secret_service_prompt (self, prompt, cancellable, callback, user_data);
- g_object_unref (prompt);
-}
-
-/**
- * secret_service_prompt_path_finish:
- * @self: the secret service
- * @result: the asynchronous result passed to the callback
- * @return_type: the variant type of the prompt result
- * @error: location to place an error on failure
- *
- * Complete asynchronous operation to perform prompting for a #SecretPrompt.
- *
- * Returns a variant result if the prompt was completed and not dismissed. The
- * type of result depends on the action the prompt is completing, and is defined
- * in the Secret Service DBus API specification.
- *
- * Returns: (transfer full): %NULL if the prompt was dismissed or an error occurred,
- * a variant result if the prompt was successful
- */
-GVariant *
-secret_service_prompt_path_finish (SecretService *self,
- GAsyncResult *result,
- const GVariantType *return_type,
- GError **error)
-{
- g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
- return secret_service_prompt_finish (self, result, return_type, error);
-}
diff --git a/library/secret-service.h b/library/secret-service.h
index 8bb4e7a..a29bd47 100644
--- a/library/secret-service.h
+++ b/library/secret-service.h
@@ -162,55 +162,6 @@ gboolean secret_service_search_sync (SecretService
GList **locked,
GError **error);
-void secret_service_search_for_paths (SecretService *self,
- GHashTable *attributes,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean secret_service_search_for_paths_finish (SecretService *self,
- GAsyncResult *result,
- gchar ***unlocked,
- gchar ***locked,
- GError **error);
-
-gboolean secret_service_search_for_paths_sync (SecretService *self,
- GHashTable *attributes,
- GCancellable *cancellable,
- gchar ***unlocked,
- gchar ***locked,
- GError **error);
-
-void secret_service_get_secret_for_path (SecretService *self,
- const gchar *item_path,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-SecretValue * secret_service_get_secret_for_path_finish (SecretService *self,
- GAsyncResult *result,
- GError **error);
-
-SecretValue * secret_service_get_secret_for_path_sync (SecretService *self,
- const gchar *item_path,
- GCancellable *cancellable,
- GError **error);
-
-void secret_service_get_secrets_for_paths (SecretService *self,
- const gchar **item_paths,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-GHashTable * secret_service_get_secrets_for_paths_finish (SecretService *self,
- GAsyncResult *result,
- GError **error);
-
-GHashTable * secret_service_get_secrets_for_paths_sync (SecretService *self,
- const gchar **item_paths,
- GCancellable *cancellable,
- GError **error);
-
void secret_service_get_secrets (SecretService *self,
GList *items,
GCancellable *cancellable,
@@ -243,23 +194,6 @@ gint secret_service_lock_sync (SecretService
GList **locked,
GError **error);
-gint secret_service_lock_paths_sync (SecretService *self,
- const gchar **paths,
- GCancellable *cancellable,
- gchar ***locked,
- GError **error);
-
-void secret_service_lock_paths (SecretService *self,
- const gchar **paths,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gint secret_service_lock_paths_finish (SecretService *self,
- GAsyncResult *result,
- gchar ***locked,
- GError **error);
-
void secret_service_unlock (SecretService *self,
GList *objects,
GCancellable *cancellable,
@@ -277,23 +211,6 @@ gint secret_service_unlock_sync (SecretService
GList **unlocked,
GError **error);
-gint secret_service_unlock_paths_sync (SecretService *self,
- const gchar **paths,
- GCancellable *cancellable,
- gchar ***unlocked,
- GError **error);
-
-void secret_service_unlock_paths (SecretService *self,
- const gchar **paths,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gint secret_service_unlock_paths_finish (SecretService *self,
- GAsyncResult *result,
- gchar ***unlocked,
- GError **error);
-
GVariant * secret_service_prompt_sync (SecretService *self,
SecretPrompt *prompt,
GCancellable *cancellable,
@@ -311,23 +228,6 @@ GVariant * secret_service_prompt_finish (SecretService
const GVariantType *return_type,
GError **error);
-GVariant * secret_service_prompt_path_sync (SecretService *self,
- const gchar *prompt_path,
- GCancellable *cancellable,
- const GVariantType *return_type,
- GError **error);
-
-void secret_service_prompt_path (SecretService *self,
- const gchar *prompt_path,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-GVariant * secret_service_prompt_path_finish (SecretService *self,
- GAsyncResult *result,
- const GVariantType *return_type,
- GError **error);
-
void secret_service_store (SecretService *self,
const SecretSchema *schema,
GHashTable *attributes,
@@ -368,21 +268,6 @@ SecretValue * secret_service_lookup_sync (SecretService
GCancellable *cancellable,
GError **error);
-void secret_service_delete_path (SecretService *self,
- const gchar *item_path,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean secret_service_delete_path_finish (SecretService *self,
- GAsyncResult *result,
- GError **error);
-
-gboolean secret_service_delete_path_sync (SecretService *self,
- const gchar *item_path,
- GCancellable *cancellable,
- GError **error);
-
void secret_service_remove (SecretService *self,
const SecretSchema *schema,
GHashTable *attributes,
@@ -400,44 +285,6 @@ gboolean secret_service_remove_sync (SecretService
GCancellable *cancellable,
GError **error);
-void secret_service_create_collection_path (SecretService *self,
- GHashTable *properties,
- const gchar *alias,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gchar * secret_service_create_collection_path_finish (SecretService *self,
- GAsyncResult *result,
- GError **error);
-
-gchar * secret_service_create_collection_path_sync (SecretService *self,
- GHashTable *properties,
- const gchar *alias,
- GCancellable *cancellable,
- GError **error);
-
-void secret_service_create_item_path (SecretService *self,
- const gchar *collection_path,
- GHashTable *properties,
- SecretValue *value,
- gboolean replace,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gchar * secret_service_create_item_path_finish (SecretService *self,
- GAsyncResult *result,
- GError **error);
-
-gchar * secret_service_create_item_path_sync (SecretService *self,
- const gchar *collection_path,
- GHashTable *properties,
- SecretValue *value,
- gboolean replace,
- GCancellable *cancellable,
- GError **error);
-
void secret_service_read_alias (SecretService *self,
const gchar *alias,
GCancellable *cancellable,
@@ -453,21 +300,6 @@ SecretCollection * secret_service_read_alias_sync (SecretService
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,
@@ -485,23 +317,6 @@ gboolean secret_service_set_alias_sync (SecretService
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/secret-unstable.h b/library/secret-unstable.h
index 2d1a629..0a781bd 100644
--- a/library/secret-unstable.h
+++ b/library/secret-unstable.h
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/library/tests/Makefile.am b/library/tests/Makefile.am
index 77c0d28..fe0e86e 100644
--- a/library/tests/Makefile.am
+++ b/library/tests/Makefile.am
@@ -36,6 +36,7 @@ C_TESTS = \
test-prompt \
test-service \
test-session \
+ test-paths \
test-methods \
test-password \
test-item \
diff --git a/library/tests/test-methods.c b/library/tests/test-methods.c
index f0f6665..09de317 100644
--- a/library/tests/test-methods.c
+++ b/library/tests/test-methods.c
@@ -16,8 +16,9 @@
#include "secret-attributes.h"
#include "secret-collection.h"
#include "secret-item.h"
-#include "secret-service.h"
+#include "secret-paths.h"
#include "secret-private.h"
+#include "secret-service.h"
#include "mock-service.h"
@@ -115,147 +116,6 @@ on_complete_get_result (GObject *source,
egg_test_wait_stop ();
}
-static void
-test_search_paths_sync (Test *test,
- gconstpointer used)
-{
- GHashTable *attributes;
- gboolean ret;
- gchar **locked;
- gchar **unlocked;
- GError *error = NULL;
-
- attributes = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (attributes, "number", "1");
-
- ret = secret_service_search_for_paths_sync (test->service, attributes, NULL,
- &unlocked, &locked, &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
-
- g_assert (locked);
- g_assert_cmpstr (locked[0], ==, "/org/freedesktop/secrets/collection/spanish/10");
-
- g_assert (unlocked);
- g_assert_cmpstr (unlocked[0], ==, "/org/freedesktop/secrets/collection/english/1");
-
- g_strfreev (unlocked);
- g_strfreev (locked);
-
- g_hash_table_unref (attributes);
-}
-
-static void
-test_search_paths_async (Test *test,
- gconstpointer used)
-{
- GAsyncResult *result = NULL;
- GHashTable *attributes;
- gboolean ret;
- gchar **locked;
- gchar **unlocked;
- GError *error = NULL;
-
- attributes = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (attributes, "number", "1");
-
- secret_service_search_for_paths (test->service, attributes, NULL,
- on_complete_get_result, &result);
- egg_test_wait ();
-
- g_assert (G_IS_ASYNC_RESULT (result));
- ret = secret_service_search_for_paths_finish (test->service, result,
- &unlocked, &locked,
- &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
-
- g_assert (locked);
- g_assert_cmpstr (locked[0], ==, "/org/freedesktop/secrets/collection/spanish/10");
-
- g_assert (unlocked);
- g_assert_cmpstr (unlocked[0], ==, "/org/freedesktop/secrets/collection/english/1");
-
- g_strfreev (unlocked);
- g_strfreev (locked);
- g_object_unref (result);
-
- g_hash_table_unref (attributes);
-}
-
-static void
-test_search_paths_nulls (Test *test,
- gconstpointer used)
-{
- GAsyncResult *result = NULL;
- GHashTable *attributes;
- gboolean ret;
- gchar **paths;
- GError *error = NULL;
-
- attributes = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (attributes, "number", "1");
-
- ret = secret_service_search_for_paths_sync (test->service, attributes, NULL,
- &paths, NULL, &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
- g_assert (paths != NULL);
- g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/english/1");
- g_strfreev (paths);
-
- ret = secret_service_search_for_paths_sync (test->service, attributes, NULL,
- NULL, &paths, &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
- g_assert (paths != NULL);
- g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/spanish/10");
- g_strfreev (paths);
-
- ret = secret_service_search_for_paths_sync (test->service, attributes, NULL,
- NULL, NULL, &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
-
- secret_service_search_for_paths (test->service, attributes, NULL,
- on_complete_get_result, &result);
- egg_test_wait ();
- g_assert (G_IS_ASYNC_RESULT (result));
- ret = secret_service_search_for_paths_finish (test->service, result,
- &paths, NULL, &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
- g_assert (paths != NULL);
- g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/english/1");
- g_strfreev (paths);
- g_clear_object (&result);
-
- secret_service_search_for_paths (test->service, attributes, NULL,
- on_complete_get_result, &result);
- egg_test_wait ();
- g_assert (G_IS_ASYNC_RESULT (result));
- ret = secret_service_search_for_paths_finish (test->service, result,
- NULL, &paths, &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
- g_assert (paths != NULL);
- g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/spanish/10");
- g_strfreev (paths);
- g_clear_object (&result);
-
- secret_service_search_for_paths (test->service, attributes, NULL,
- on_complete_get_result, &result);
- egg_test_wait ();
- g_assert (G_IS_ASYNC_RESULT (result));
- ret = secret_service_search_for_paths_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_search_sync (Test *test,
gconstpointer used)
@@ -397,154 +257,6 @@ test_search_nulls (Test *test,
g_hash_table_unref (attributes);
}
-static void
-test_secret_for_path_sync (Test *test,
- gconstpointer used)
-{
- SecretValue *value;
- GError *error = NULL;
- const gchar *path;
- const gchar *password;
- gsize length;
-
- path = "/org/freedesktop/secrets/collection/english/1";
- value = secret_service_get_secret_for_path_sync (test->service, path, NULL, &error);
- g_assert_no_error (error);
- g_assert (value != NULL);
-
- password = secret_value_get (value, &length);
- g_assert_cmpuint (length, ==, 3);
- g_assert_cmpstr (password, ==, "111");
-
- password = secret_value_get (value, NULL);
- g_assert_cmpstr (password, ==, "111");
-
- secret_value_unref (value);
-}
-
-static void
-test_secret_for_path_async (Test *test,
- gconstpointer used)
-{
- SecretValue *value;
- GError *error = NULL;
- const gchar *path;
- const gchar *password;
- GAsyncResult *result = NULL;
- gsize length;
-
- path = "/org/freedesktop/secrets/collection/english/1";
- secret_service_get_secret_for_path (test->service, path, NULL,
- on_complete_get_result, &result);
- g_assert (result == NULL);
- egg_test_wait ();
-
- value = secret_service_get_secret_for_path_finish (test->service, result, &error);
- g_assert_no_error (error);
- g_assert (value != NULL);
- g_object_unref (result);
-
- password = secret_value_get (value, &length);
- g_assert_cmpuint (length, ==, 3);
- g_assert_cmpstr (password, ==, "111");
-
- password = secret_value_get (value, NULL);
- g_assert_cmpstr (password, ==, "111");
-
- secret_value_unref (value);
-}
-
-static void
-test_secrets_for_paths_sync (Test *test,
- gconstpointer used)
-{
- const gchar *path_item_one = "/org/freedesktop/secrets/collection/english/1";
- const gchar *path_item_two = "/org/freedesktop/secrets/collection/english/2";
- const gchar *paths[] = {
- path_item_one,
- path_item_two,
-
- /* This one is locked, and not returned */
- "/org/freedesktop/secrets/collection/spanish/10",
- NULL
- };
-
- SecretValue *value;
- GHashTable *values;
- GError *error = NULL;
- const gchar *password;
- gsize length;
-
- values = secret_service_get_secrets_for_paths_sync (test->service, paths, NULL, &error);
- g_assert_no_error (error);
-
- g_assert (values != NULL);
- g_assert_cmpuint (g_hash_table_size (values), ==, 2);
-
- value = g_hash_table_lookup (values, path_item_one);
- g_assert (value != NULL);
- password = secret_value_get (value, &length);
- g_assert_cmpuint (length, ==, 3);
- g_assert_cmpstr (password, ==, "111");
-
- value = g_hash_table_lookup (values, path_item_two);
- g_assert (value != NULL);
- password = secret_value_get (value, &length);
- g_assert_cmpuint (length, ==, 3);
- g_assert_cmpstr (password, ==, "222");
-
- g_hash_table_unref (values);
-}
-
-static void
-test_secrets_for_paths_async (Test *test,
- gconstpointer used)
-{
- const gchar *path_item_one = "/org/freedesktop/secrets/collection/english/1";
- const gchar *path_item_two = "/org/freedesktop/secrets/collection/english/2";
- const gchar *paths[] = {
- path_item_one,
- path_item_two,
-
- /* This one is locked, and not returned */
- "/org/freedesktop/secrets/collection/spanish/10",
- NULL
- };
-
- SecretValue *value;
- GHashTable *values;
- GError *error = NULL;
- const gchar *password;
- GAsyncResult *result = NULL;
- gsize length;
-
- secret_service_get_secrets_for_paths (test->service, paths, NULL,
- on_complete_get_result, &result);
- g_assert (result == NULL);
- egg_test_wait ();
-
- values = secret_service_get_secrets_for_paths_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, path_item_one);
- g_assert (value != NULL);
- password = secret_value_get (value, &length);
- g_assert_cmpuint (length, ==, 3);
- g_assert_cmpstr (password, ==, "111");
-
- value = g_hash_table_lookup (values, path_item_two);
- g_assert (value != NULL);
- password = secret_value_get (value, &length);
- g_assert_cmpuint (length, ==, 3);
- g_assert_cmpstr (password, ==, "222");
-
- g_hash_table_unref (values);
-}
-
static void
test_secrets_sync (Test *test,
gconstpointer used)
@@ -655,82 +367,6 @@ test_secrets_async (Test *test,
g_object_unref (item_three);
}
-static void
-test_delete_for_path_sync (Test *test,
- gconstpointer used)
-
-{
- const gchar *path_item_one = "/org/freedesktop/secrets/collection/todelete/item";
- GError *error = NULL;
- gboolean ret;
-
- ret = secret_service_delete_path_sync (test->service, path_item_one, NULL, &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
-}
-
-static void
-test_delete_for_path_sync_prompt (Test *test,
- gconstpointer used)
-
-{
- const gchar *path_item_one = "/org/freedesktop/secrets/collection/todelete/confirm";
- GError *error = NULL;
- gboolean ret;
-
- ret = secret_service_delete_path_sync (test->service, path_item_one, NULL, &error);
- g_assert_no_error (error);
- g_assert (ret == TRUE);
-}
-
-static void
-test_lock_paths_sync (Test *test,
- gconstpointer used)
-{
- const gchar *collection_path = "/org/freedesktop/secrets/collection/lockone";
- const gchar *paths[] = {
- collection_path,
- NULL,
- };
-
- GError *error = NULL;
- gchar **locked = NULL;
- gboolean ret;
-
- ret = secret_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/lockprompt";
- const gchar *paths[] = {
- collection_path,
- NULL,
- };
-
- GError *error = NULL;
- gchar **locked = NULL;
- gboolean ret;
-
- ret = secret_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)
@@ -760,54 +396,6 @@ test_lock_sync (Test *test,
g_object_unref (collection);
}
-static void
-test_unlock_paths_sync (Test *test,
- gconstpointer used)
-{
- const gchar *collection_path = "/org/freedesktop/secrets/collection/lockone";
- const gchar *paths[] = {
- collection_path,
- NULL,
- };
-
- GError *error = NULL;
- gchar **unlocked = NULL;
- gboolean ret;
-
- ret = secret_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/lockprompt";
- const gchar *paths[] = {
- collection_path,
- NULL,
- };
-
- GError *error = NULL;
- gchar **unlocked = NULL;
- gboolean ret;
-
- ret = secret_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)
@@ -837,152 +425,6 @@ test_unlock_sync (Test *test,
g_object_unref (collection);
}
-static void
-test_collection_sync (Test *test,
- gconstpointer used)
-{
- GHashTable *properties;
- GError *error = NULL;
- gchar *path;
-
- properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
- (GDestroyNotify)g_variant_unref);
- g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Label",
- g_variant_ref_sink (g_variant_new_string ("Wheeee")));
-
- path = secret_service_create_collection_path_sync (test->service, properties,
- NULL, NULL, &error);
-
- g_hash_table_unref (properties);
-
- g_assert_no_error (error);
- g_assert (path != NULL);
- g_assert (g_str_has_prefix (path, "/org/freedesktop/secrets/collection/"));
-
- g_free (path);
-}
-
-static void
-test_collection_async (Test *test,
- gconstpointer used)
-{
- GAsyncResult *result = NULL;
- GHashTable *properties;
- GError *error = NULL;
- gchar *path;
-
- properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
- (GDestroyNotify)g_variant_unref);
- g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Label",
- g_variant_ref_sink (g_variant_new_string ("Wheeee")));
-
- secret_service_create_collection_path (test->service, properties,
- NULL, NULL, on_complete_get_result, &result);
-
- g_hash_table_unref (properties);
- g_assert (result == NULL);
-
- egg_test_wait ();
-
- path = secret_service_create_collection_path_finish (test->service, result, &error);
- g_object_unref (result);
-
- g_assert_no_error (error);
- g_assert (path != NULL);
- g_assert (g_str_has_prefix (path, "/org/freedesktop/secrets/collection/"));
-
- g_free (path);
-}
-
-static void
-test_item_sync (Test *test,
- gconstpointer used)
-{
- const gchar *collection_path = "/org/freedesktop/secrets/collection/english";
- GHashTable *properties;
- GHashTable *attributes;
- SecretValue *value;
- GError *error = NULL;
- gchar *path;
-
- attributes = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (attributes, "even", "true");
- g_hash_table_insert (attributes, "string", "ten");
- g_hash_table_insert (attributes, "number", "10");
-
- properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
- (GDestroyNotify)g_variant_unref);
- g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Label",
- g_variant_ref_sink (g_variant_new_string ("Wheeee")));
- g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Attributes",
- g_variant_ref_sink (_secret_attributes_to_variant (attributes, "org.gnome.Test")));
-
- g_hash_table_unref (attributes);
-
- value = secret_value_new ("andmoreandmore", -1, "text/plain");
-
- path = secret_service_create_item_path_sync (test->service, collection_path,
- properties, value, FALSE,
- NULL, &error);
-
- secret_value_unref (value);
- g_hash_table_unref (properties);
-
- g_assert_no_error (error);
- g_assert (path != NULL);
- g_assert (g_str_has_prefix (path, collection_path));
-
- g_free (path);
-}
-
-static void
-test_item_async (Test *test,
- gconstpointer used)
-{
- const gchar *collection_path = "/org/freedesktop/secrets/collection/english";
- GHashTable *properties;
- GHashTable *attributes;
- SecretValue *value;
- GError *error = NULL;
- GAsyncResult *result = NULL;
- gchar *path;
-
- attributes = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (attributes, "even", "true");
- g_hash_table_insert (attributes, "string", "ten");
- g_hash_table_insert (attributes, "number", "10");
-
- properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
- (GDestroyNotify)g_variant_unref);
- g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Label",
- g_variant_ref_sink (g_variant_new_string ("Wheeee")));
- g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Attributes",
- g_variant_ref_sink (_secret_attributes_to_variant (attributes, NULL)));
-
- g_hash_table_unref (attributes);
-
- value = secret_value_new ("andmoreandmore", -1, "text/plain");
-
- secret_service_create_item_path (test->service, collection_path,
- properties, value, FALSE,
- NULL, on_complete_get_result, &result);
-
- g_assert (result == NULL);
- secret_value_unref (value);
- g_hash_table_unref (properties);
-
- egg_test_wait ();
-
- path = secret_service_create_item_path_finish (test->service, result, &error);
- g_object_unref (result);
-
- g_assert_no_error (error);
- g_assert (path != NULL);
- g_assert (g_str_has_prefix (path, collection_path));
-
- g_free (path);
-}
-
static void
test_remove_sync (Test *test,
gconstpointer used)
@@ -1485,36 +927,6 @@ test_set_alias_sync (Test *test,
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)
{
@@ -1522,38 +934,17 @@ main (int argc, char **argv)
g_set_prgname ("test-service");
g_type_init ();
- 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-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-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/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/create-collection-sync", Test, "mock-service-normal.py", setup, test_collection_sync, teardown);
- g_test_add ("/service/create-collection-async", Test, "mock-service-normal.py", setup, test_collection_async, teardown);
-
- g_test_add ("/service/create-item-sync", Test, "mock-service-normal.py", setup, test_item_sync, teardown);
- g_test_add ("/service/create-item-async", Test, "mock-service-normal.py", setup, test_item_async, 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);
@@ -1574,7 +965,6 @@ main (int argc, char **argv)
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 ();
}
diff --git a/library/tests/test-paths.c b/library/tests/test-paths.c
new file mode 100644
index 0000000..ba349eb
--- /dev/null
+++ b/library/tests/test-paths.c
@@ -0,0 +1,743 @@
+/* libsecret - GLib wrapper for Secret Service
+ *
+ * Copyright 2011 Collabora Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the licence or (at
+ * your option) any later version.
+ *
+ * See the included COPYING file for more information.
+ */
+
+
+#include "config.h"
+
+#include "secret-attributes.h"
+#include "secret-collection.h"
+#include "secret-item.h"
+#include "secret-paths.h"
+#include "secret-private.h"
+#include "secret-service.h"
+
+#include "mock-service.h"
+
+#include "egg/egg-testing.h"
+
+#include
+
+#include
+#include
+
+static const SecretSchema MOCK_SCHEMA = {
+ "org.mock.Schema",
+ SECRET_SCHEMA_NONE,
+ {
+ { "number", SECRET_SCHEMA_ATTRIBUTE_INTEGER },
+ { "string", SECRET_SCHEMA_ATTRIBUTE_STRING },
+ { "even", SECRET_SCHEMA_ATTRIBUTE_BOOLEAN },
+ }
+};
+
+static const SecretSchema PRIME_SCHEMA = {
+ "org.mock.Prime",
+ SECRET_SCHEMA_NONE,
+ {
+ { "number", SECRET_SCHEMA_ATTRIBUTE_INTEGER },
+ { "string", SECRET_SCHEMA_ATTRIBUTE_STRING },
+ { "prime", SECRET_SCHEMA_ATTRIBUTE_BOOLEAN },
+ }
+};
+
+static const SecretSchema NO_NAME_SCHEMA = {
+ "unused.Schema.Name",
+ SECRET_SCHEMA_DONT_MATCH_NAME,
+ {
+ { "number", SECRET_SCHEMA_ATTRIBUTE_INTEGER },
+ { "string", SECRET_SCHEMA_ATTRIBUTE_STRING },
+ }
+};
+
+typedef struct {
+ SecretService *service;
+} Test;
+
+static void
+setup_mock (Test *test,
+ gconstpointer data)
+{
+ GError *error = NULL;
+ const gchar *mock_script = data;
+
+ mock_service_start (mock_script, &error);
+ g_assert_no_error (error);
+}
+
+static void
+setup (Test *test,
+ gconstpointer data)
+{
+ GError *error = NULL;
+
+ setup_mock (test, data);
+
+ test->service = secret_service_get_sync (SECRET_SERVICE_NONE, NULL, &error);
+ g_assert_no_error (error);
+}
+
+static void
+teardown_mock (Test *test,
+ gconstpointer unused)
+{
+ mock_service_stop ();
+}
+
+static void
+teardown (Test *test,
+ gconstpointer unused)
+{
+ egg_test_wait_idle ();
+
+ g_object_unref (test->service);
+ egg_assert_not_object (test->service);
+
+ teardown_mock (test, unused);
+}
+
+static void
+on_complete_get_result (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GAsyncResult **ret = user_data;
+ g_assert (ret != NULL);
+ g_assert (*ret == NULL);
+ *ret = g_object_ref (result);
+ egg_test_wait_stop ();
+}
+
+static void
+test_search_paths_sync (Test *test,
+ gconstpointer used)
+{
+ GHashTable *attributes;
+ gboolean ret;
+ gchar **locked;
+ gchar **unlocked;
+ GError *error = NULL;
+
+ attributes = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (attributes, "number", "1");
+
+ ret = secret_service_search_for_paths_sync (test->service, attributes, NULL,
+ &unlocked, &locked, &error);
+ g_assert_no_error (error);
+ g_assert (ret == TRUE);
+
+ g_assert (locked);
+ g_assert_cmpstr (locked[0], ==, "/org/freedesktop/secrets/collection/spanish/10");
+
+ g_assert (unlocked);
+ g_assert_cmpstr (unlocked[0], ==, "/org/freedesktop/secrets/collection/english/1");
+
+ g_strfreev (unlocked);
+ g_strfreev (locked);
+
+ g_hash_table_unref (attributes);
+}
+
+static void
+test_search_paths_async (Test *test,
+ gconstpointer used)
+{
+ GAsyncResult *result = NULL;
+ GHashTable *attributes;
+ gboolean ret;
+ gchar **locked;
+ gchar **unlocked;
+ GError *error = NULL;
+
+ attributes = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (attributes, "number", "1");
+
+ secret_service_search_for_paths (test->service, attributes, NULL,
+ on_complete_get_result, &result);
+ egg_test_wait ();
+
+ g_assert (G_IS_ASYNC_RESULT (result));
+ ret = secret_service_search_for_paths_finish (test->service, result,
+ &unlocked, &locked,
+ &error);
+ g_assert_no_error (error);
+ g_assert (ret == TRUE);
+
+ g_assert (locked);
+ g_assert_cmpstr (locked[0], ==, "/org/freedesktop/secrets/collection/spanish/10");
+
+ g_assert (unlocked);
+ g_assert_cmpstr (unlocked[0], ==, "/org/freedesktop/secrets/collection/english/1");
+
+ g_strfreev (unlocked);
+ g_strfreev (locked);
+ g_object_unref (result);
+
+ g_hash_table_unref (attributes);
+}
+
+static void
+test_search_paths_nulls (Test *test,
+ gconstpointer used)
+{
+ GAsyncResult *result = NULL;
+ GHashTable *attributes;
+ gboolean ret;
+ gchar **paths;
+ GError *error = NULL;
+
+ attributes = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (attributes, "number", "1");
+
+ ret = secret_service_search_for_paths_sync (test->service, attributes, NULL,
+ &paths, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret == TRUE);
+ g_assert (paths != NULL);
+ g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/english/1");
+ g_strfreev (paths);
+
+ ret = secret_service_search_for_paths_sync (test->service, attributes, NULL,
+ NULL, &paths, &error);
+ g_assert_no_error (error);
+ g_assert (ret == TRUE);
+ g_assert (paths != NULL);
+ g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/spanish/10");
+ g_strfreev (paths);
+
+ ret = secret_service_search_for_paths_sync (test->service, attributes, NULL,
+ NULL, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret == TRUE);
+
+ secret_service_search_for_paths (test->service, attributes, NULL,
+ on_complete_get_result, &result);
+ egg_test_wait ();
+ g_assert (G_IS_ASYNC_RESULT (result));
+ ret = secret_service_search_for_paths_finish (test->service, result,
+ &paths, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret == TRUE);
+ g_assert (paths != NULL);
+ g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/english/1");
+ g_strfreev (paths);
+ g_clear_object (&result);
+
+ secret_service_search_for_paths (test->service, attributes, NULL,
+ on_complete_get_result, &result);
+ egg_test_wait ();
+ g_assert (G_IS_ASYNC_RESULT (result));
+ ret = secret_service_search_for_paths_finish (test->service, result,
+ NULL, &paths, &error);
+ g_assert_no_error (error);
+ g_assert (ret == TRUE);
+ g_assert (paths != NULL);
+ g_assert_cmpstr (paths[0], ==, "/org/freedesktop/secrets/collection/spanish/10");
+ g_strfreev (paths);
+ g_clear_object (&result);
+
+ secret_service_search_for_paths (test->service, attributes, NULL,
+ on_complete_get_result, &result);
+ egg_test_wait ();
+ g_assert (G_IS_ASYNC_RESULT (result));
+ ret = secret_service_search_for_paths_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)
+{
+ SecretValue *value;
+ GError *error = NULL;
+ const gchar *path;
+ const gchar *password;
+ gsize length;
+
+ path = "/org/freedesktop/secrets/collection/english/1";
+ value = secret_service_get_secret_for_path_sync (test->service, path, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (value != NULL);
+
+ password = secret_value_get (value, &length);
+ g_assert_cmpuint (length, ==, 3);
+ g_assert_cmpstr (password, ==, "111");
+
+ password = secret_value_get (value, NULL);
+ g_assert_cmpstr (password, ==, "111");
+
+ secret_value_unref (value);
+}
+
+static void
+test_secret_for_path_async (Test *test,
+ gconstpointer used)
+{
+ SecretValue *value;
+ GError *error = NULL;
+ const gchar *path;
+ const gchar *password;
+ GAsyncResult *result = NULL;
+ gsize length;
+
+ path = "/org/freedesktop/secrets/collection/english/1";
+ secret_service_get_secret_for_path (test->service, path, NULL,
+ on_complete_get_result, &result);
+ g_assert (result == NULL);
+ egg_test_wait ();
+
+ value = secret_service_get_secret_for_path_finish (test->service, result, &error);
+ g_assert_no_error (error);
+ g_assert (value != NULL);
+ g_object_unref (result);
+
+ password = secret_value_get (value, &length);
+ g_assert_cmpuint (length, ==, 3);
+ g_assert_cmpstr (password, ==, "111");
+
+ password = secret_value_get (value, NULL);
+ g_assert_cmpstr (password, ==, "111");
+
+ secret_value_unref (value);
+}
+
+static void
+test_secrets_for_paths_sync (Test *test,
+ gconstpointer used)
+{
+ const gchar *path_item_one = "/org/freedesktop/secrets/collection/english/1";
+ const gchar *path_item_two = "/org/freedesktop/secrets/collection/english/2";
+ const gchar *paths[] = {
+ path_item_one,
+ path_item_two,
+
+ /* This one is locked, and not returned */
+ "/org/freedesktop/secrets/collection/spanish/10",
+ NULL
+ };
+
+ SecretValue *value;
+ GHashTable *values;
+ GError *error = NULL;
+ const gchar *password;
+ gsize length;
+
+ values = secret_service_get_secrets_for_paths_sync (test->service, paths, NULL, &error);
+ g_assert_no_error (error);
+
+ g_assert (values != NULL);
+ g_assert_cmpuint (g_hash_table_size (values), ==, 2);
+
+ value = g_hash_table_lookup (values, path_item_one);
+ g_assert (value != NULL);
+ password = secret_value_get (value, &length);
+ g_assert_cmpuint (length, ==, 3);
+ g_assert_cmpstr (password, ==, "111");
+
+ value = g_hash_table_lookup (values, path_item_two);
+ g_assert (value != NULL);
+ password = secret_value_get (value, &length);
+ g_assert_cmpuint (length, ==, 3);
+ g_assert_cmpstr (password, ==, "222");
+
+ g_hash_table_unref (values);
+}
+
+static void
+test_secrets_for_paths_async (Test *test,
+ gconstpointer used)
+{
+ const gchar *path_item_one = "/org/freedesktop/secrets/collection/english/1";
+ const gchar *path_item_two = "/org/freedesktop/secrets/collection/english/2";
+ const gchar *paths[] = {
+ path_item_one,
+ path_item_two,
+
+ /* This one is locked, and not returned */
+ "/org/freedesktop/secrets/collection/spanish/10",
+ NULL
+ };
+
+ SecretValue *value;
+ GHashTable *values;
+ GError *error = NULL;
+ const gchar *password;
+ GAsyncResult *result = NULL;
+ gsize length;
+
+ secret_service_get_secrets_for_paths (test->service, paths, NULL,
+ on_complete_get_result, &result);
+ g_assert (result == NULL);
+ egg_test_wait ();
+
+ values = secret_service_get_secrets_for_paths_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, path_item_one);
+ g_assert (value != NULL);
+ password = secret_value_get (value, &length);
+ g_assert_cmpuint (length, ==, 3);
+ g_assert_cmpstr (password, ==, "111");
+
+ value = g_hash_table_lookup (values, path_item_two);
+ g_assert (value != NULL);
+ password = secret_value_get (value, &length);
+ g_assert_cmpuint (length, ==, 3);
+ g_assert_cmpstr (password, ==, "222");
+
+ g_hash_table_unref (values);
+}
+
+static void
+test_delete_for_path_sync (Test *test,
+ gconstpointer used)
+
+{
+ const gchar *path_item_one = "/org/freedesktop/secrets/collection/todelete/item";
+ GError *error = NULL;
+ gboolean ret;
+
+ ret = secret_service_delete_path_sync (test->service, path_item_one, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret == TRUE);
+}
+
+static void
+test_delete_for_path_sync_prompt (Test *test,
+ gconstpointer used)
+
+{
+ const gchar *path_item_one = "/org/freedesktop/secrets/collection/todelete/confirm";
+ GError *error = NULL;
+ gboolean ret;
+
+ ret = secret_service_delete_path_sync (test->service, path_item_one, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret == TRUE);
+}
+
+static void
+test_lock_paths_sync (Test *test,
+ gconstpointer used)
+{
+ const gchar *collection_path = "/org/freedesktop/secrets/collection/lockone";
+ const gchar *paths[] = {
+ collection_path,
+ NULL,
+ };
+
+ GError *error = NULL;
+ gchar **locked = NULL;
+ gboolean ret;
+
+ ret = secret_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/lockprompt";
+ const gchar *paths[] = {
+ collection_path,
+ NULL,
+ };
+
+ GError *error = NULL;
+ gchar **locked = NULL;
+ gboolean ret;
+
+ ret = secret_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_unlock_paths_sync (Test *test,
+ gconstpointer used)
+{
+ const gchar *collection_path = "/org/freedesktop/secrets/collection/lockone";
+ const gchar *paths[] = {
+ collection_path,
+ NULL,
+ };
+
+ GError *error = NULL;
+ gchar **unlocked = NULL;
+ gboolean ret;
+
+ ret = secret_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/lockprompt";
+ const gchar *paths[] = {
+ collection_path,
+ NULL,
+ };
+
+ GError *error = NULL;
+ gchar **unlocked = NULL;
+ gboolean ret;
+
+ ret = secret_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_collection_sync (Test *test,
+ gconstpointer used)
+{
+ GHashTable *properties;
+ GError *error = NULL;
+ gchar *path;
+
+ properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify)g_variant_unref);
+ g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Label",
+ g_variant_ref_sink (g_variant_new_string ("Wheeee")));
+
+ path = secret_service_create_collection_path_sync (test->service, properties,
+ NULL, NULL, &error);
+
+ g_hash_table_unref (properties);
+
+ g_assert_no_error (error);
+ g_assert (path != NULL);
+ g_assert (g_str_has_prefix (path, "/org/freedesktop/secrets/collection/"));
+
+ g_free (path);
+}
+
+static void
+test_collection_async (Test *test,
+ gconstpointer used)
+{
+ GAsyncResult *result = NULL;
+ GHashTable *properties;
+ GError *error = NULL;
+ gchar *path;
+
+ properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify)g_variant_unref);
+ g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Label",
+ g_variant_ref_sink (g_variant_new_string ("Wheeee")));
+
+ secret_service_create_collection_path (test->service, properties,
+ NULL, NULL, on_complete_get_result, &result);
+
+ g_hash_table_unref (properties);
+ g_assert (result == NULL);
+
+ egg_test_wait ();
+
+ path = secret_service_create_collection_path_finish (test->service, result, &error);
+ g_object_unref (result);
+
+ g_assert_no_error (error);
+ g_assert (path != NULL);
+ g_assert (g_str_has_prefix (path, "/org/freedesktop/secrets/collection/"));
+
+ g_free (path);
+}
+
+static void
+test_item_sync (Test *test,
+ gconstpointer used)
+{
+ const gchar *collection_path = "/org/freedesktop/secrets/collection/english";
+ GHashTable *properties;
+ GHashTable *attributes;
+ SecretValue *value;
+ GError *error = NULL;
+ gchar *path;
+
+ attributes = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (attributes, "even", "true");
+ g_hash_table_insert (attributes, "string", "ten");
+ g_hash_table_insert (attributes, "number", "10");
+
+ properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify)g_variant_unref);
+ g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Label",
+ g_variant_ref_sink (g_variant_new_string ("Wheeee")));
+ g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Attributes",
+ g_variant_ref_sink (_secret_attributes_to_variant (attributes, "org.gnome.Test")));
+
+ g_hash_table_unref (attributes);
+
+ value = secret_value_new ("andmoreandmore", -1, "text/plain");
+
+ path = secret_service_create_item_path_sync (test->service, collection_path,
+ properties, value, FALSE,
+ NULL, &error);
+
+ secret_value_unref (value);
+ g_hash_table_unref (properties);
+
+ g_assert_no_error (error);
+ g_assert (path != NULL);
+ g_assert (g_str_has_prefix (path, collection_path));
+
+ g_free (path);
+}
+
+static void
+test_item_async (Test *test,
+ gconstpointer used)
+{
+ const gchar *collection_path = "/org/freedesktop/secrets/collection/english";
+ GHashTable *properties;
+ GHashTable *attributes;
+ SecretValue *value;
+ GError *error = NULL;
+ GAsyncResult *result = NULL;
+ gchar *path;
+
+ attributes = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (attributes, "even", "true");
+ g_hash_table_insert (attributes, "string", "ten");
+ g_hash_table_insert (attributes, "number", "10");
+
+ properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify)g_variant_unref);
+ g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Label",
+ g_variant_ref_sink (g_variant_new_string ("Wheeee")));
+ g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Attributes",
+ g_variant_ref_sink (_secret_attributes_to_variant (attributes, NULL)));
+
+ g_hash_table_unref (attributes);
+
+ value = secret_value_new ("andmoreandmore", -1, "text/plain");
+
+ secret_service_create_item_path (test->service, collection_path,
+ properties, value, FALSE,
+ NULL, on_complete_get_result, &result);
+
+ g_assert (result == NULL);
+ secret_value_unref (value);
+ g_hash_table_unref (properties);
+
+ egg_test_wait ();
+
+ path = secret_service_create_item_path_finish (test->service, result, &error);
+ g_object_unref (result);
+
+ g_assert_no_error (error);
+ g_assert (path != NULL);
+ g_assert (g_str_has_prefix (path, collection_path));
+
+ g_free (path);
+}
+
+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)
+{
+ g_test_init (&argc, &argv, NULL);
+ g_set_prgname ("test-service");
+ g_type_init ();
+
+ 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/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-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/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/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/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/create-collection-sync", Test, "mock-service-normal.py", setup, test_collection_sync, teardown);
+ g_test_add ("/service/create-collection-async", Test, "mock-service-normal.py", setup, test_collection_async, teardown);
+
+ g_test_add ("/service/create-item-sync", Test, "mock-service-normal.py", setup, test_item_sync, teardown);
+ g_test_add ("/service/create-item-async", Test, "mock-service-normal.py", setup, test_item_async, 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 ();
+}