diff --git a/docs/reference/libsecret/libsecret-sections.txt b/docs/reference/libsecret/libsecret-sections.txt index 264a8b2..02d6c23 100644 --- a/docs/reference/libsecret/libsecret-sections.txt +++ b/docs/reference/libsecret/libsecret-sections.txt @@ -4,6 +4,9 @@ SecretCollection SecretCollectionClass SecretCollectionFlags +secret_collection_for_alias +secret_collection_for_alias_finish +secret_collection_for_alias_sync secret_collection_load_items secret_collection_load_items_finish secret_collection_load_items_sync @@ -213,9 +216,6 @@ 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 diff --git a/library/secret-collection.c b/library/secret-collection.c index a9db480..0da35ba 100644 --- a/library/secret-collection.c +++ b/library/secret-collection.c @@ -68,7 +68,7 @@ * SECRET_COLLECTION_DEFAULT: * * An alias to the default collection. This can be passed to secret_password_store() - * secret_service_read_alias(). + * secret_collection_for_alias(). */ /** @@ -76,7 +76,7 @@ * * An alias to the session collection, which will be cleared when the user ends * the session. This can be passed to secret_password_store(), - * secret_service_read_alias() or similar functions. + * secret_collection_for_alias() or similar functions. */ enum { @@ -1969,3 +1969,240 @@ secret_collection_get_modified (SecretCollection *self) return modified; } + + +typedef struct { + GCancellable *cancellable; + gchar *alias; + SecretCollection *collection; +} ReadClosure; + +static void +read_closure_free (gpointer data) +{ + ReadClosure *read = data; + g_free (read->alias); + if (read->collection) + g_object_unref (read->collection); + if (read->cancellable) + g_object_unref (read->cancellable); + g_slice_free (ReadClosure, read); +} + +static void +on_read_alias_collection (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data); + ReadClosure *read = g_simple_async_result_get_op_res_gpointer (async); + GError *error = NULL; + + read->collection = secret_collection_new_for_dbus_path_finish (result, &error); + if (error != NULL) + g_simple_async_result_take_error (async, error); + + g_simple_async_result_complete (async); + g_object_unref (async); +} + +static void +on_read_alias_path (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data); + ReadClosure *read = g_simple_async_result_get_op_res_gpointer (async); + SecretService *self = SECRET_SERVICE (source); + GError *error = NULL; + gchar *collection_path; + + collection_path = secret_service_read_alias_dbus_path_finish (self, result, &error); + if (error == NULL) { + + /* No collection for this alias */ + if (collection_path == NULL) { + g_simple_async_result_complete (async); + + } else { + read->collection = _secret_service_find_collection_instance (self, + collection_path); + if (read->collection != NULL) { + g_simple_async_result_complete (async); + + /* No collection loaded, but valid path, load */ + } else { + secret_collection_new_for_dbus_path (self, collection_path, + SECRET_COLLECTION_NONE, + read->cancellable, + on_read_alias_collection, + g_object_ref (async)); + } + } + + } else { + g_simple_async_result_take_error (async, error); + g_simple_async_result_complete (async); + } + + g_free (collection_path); + g_object_unref (async); +} + +static void +on_read_alias_service (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data); + ReadClosure *read = g_simple_async_result_get_op_res_gpointer (async); + SecretService *service; + GError *error = NULL; + + service = secret_service_get_finish (result, &error); + if (error == NULL) { + secret_service_read_alias_dbus_path (service, read->alias, read->cancellable, + on_read_alias_path, g_object_ref (async)); + g_object_unref (service); + + } else { + g_simple_async_result_take_error (async, error); + g_simple_async_result_complete (async); + } + + g_object_unref (async); +} + +/** + * secret_collection_for_alias: + * @service: (allow-none): 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'. + * + * If @service is NULL, then secret_service_get() will be called to get + * the default #SecretService proxy. + * + * This method will return immediately and complete asynchronously. + */ +void +secret_collection_for_alias (SecretService *service, + const gchar *alias, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *async; + ReadClosure *read; + + g_return_if_fail (service == NULL || SECRET_IS_SERVICE (service)); + g_return_if_fail (alias != NULL); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + async = g_simple_async_result_new (NULL, callback, user_data, + secret_collection_for_alias); + read = g_slice_new0 (ReadClosure); + read->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + read->alias = g_strdup (alias); + g_simple_async_result_set_op_res_gpointer (async, read, read_closure_free); + + if (service == NULL) { + secret_service_get (SECRET_SERVICE_NONE, cancellable, + on_read_alias_service, g_object_ref (async)); + } else { + secret_service_read_alias_dbus_path (service, read->alias, read->cancellable, + on_read_alias_path, g_object_ref (async)); + } + + g_object_unref (async); +} + +/** + * secret_collection_for_alias_finish: + * @result: asynchronous result passed to callback + * @error: location to place error on failure + * + * Finish an asynchronous operation to lookup which collection is assigned + * to an alias. + * + * Returns: (transfer full): the collection, or %NULL if none assigned to the alias + */ +SecretCollection * +secret_collection_for_alias_finish (GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *async; + ReadClosure *read; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, + secret_collection_for_alias), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + async = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (async, error)) + return NULL; + read = g_simple_async_result_get_op_res_gpointer (async); + if (read->collection) + g_object_ref (read->collection); + return read->collection; +} + +/** + * secret_collection_for_alias_sync: + * @service: (allow-none): 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'. + * + * If @service is NULL, then secret_service_get_sync() will be called to get + * the default #SecretService proxy. + * + * This method may block and should not be used in user interface threads. + * + * Returns: (transfer full): the collection, or %NULL if none assigned to the alias + */ +SecretCollection * +secret_collection_for_alias_sync (SecretService *service, + const gchar *alias, + GCancellable *cancellable, + GError **error) +{ + SecretCollection *collection; + gchar *collection_path; + + g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), NULL); + g_return_val_if_fail (alias != NULL, NULL); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + collection_path = secret_service_read_alias_dbus_path_sync (service, alias, + cancellable, error); + if (collection_path == NULL) + return NULL; + + /* No collection for this alias */ + if (collection_path == NULL) { + collection = NULL; + + } else { + collection = _secret_service_find_collection_instance (service, + collection_path); + + /* No collection loaded, but valid path, load */ + if (collection == NULL) { + collection = secret_collection_new_for_dbus_path_sync (service, collection_path, + SECRET_COLLECTION_LOAD_ITEMS, + cancellable, error); + } + } + + g_free (collection_path); + return collection; +} diff --git a/library/secret-collection.h b/library/secret-collection.h index 2b58f39..3296d09 100644 --- a/library/secret-collection.h +++ b/library/secret-collection.h @@ -57,6 +57,20 @@ struct _SecretCollectionClass { GType secret_collection_get_type (void) G_GNUC_CONST; +void secret_collection_for_alias (SecretService *service, + const gchar *alias, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +SecretCollection * secret_collection_for_alias_finish (GAsyncResult *result, + GError **error); + +SecretCollection * secret_collection_for_alias_sync (SecretService *service, + const gchar *alias, + GCancellable *cancellable, + GError **error); + void secret_collection_load_items (SecretCollection *self, GCancellable *cancellable, GAsyncReadyCallback callback, diff --git a/library/secret-methods.c b/library/secret-methods.c index 3393408..a45f04c 100644 --- a/library/secret-methods.c +++ b/library/secret-methods.c @@ -1736,245 +1736,6 @@ secret_service_remove_sync (SecretService *service, return result; } -typedef struct { - GCancellable *cancellable; - gchar *alias; - SecretCollection *collection; -} ReadClosure; - -static void -read_closure_free (gpointer data) -{ - ReadClosure *read = data; - g_free (read->alias); - if (read->collection) - g_object_unref (read->collection); - if (read->cancellable) - g_object_unref (read->cancellable); - g_slice_free (ReadClosure, read); -} - -static void -on_read_alias_collection (GObject *source, - GAsyncResult *result, - gpointer user_data) -{ - GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data); - ReadClosure *read = g_simple_async_result_get_op_res_gpointer (async); - GError *error = NULL; - - read->collection = secret_collection_new_for_dbus_path_finish (result, &error); - if (error != NULL) - g_simple_async_result_take_error (async, error); - - g_simple_async_result_complete (async); - g_object_unref (async); -} - -static void -on_read_alias_path (GObject *source, - GAsyncResult *result, - gpointer user_data) -{ - GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data); - ReadClosure *read = g_simple_async_result_get_op_res_gpointer (async); - SecretService *self = SECRET_SERVICE (source); - GError *error = NULL; - gchar *collection_path; - - collection_path = secret_service_read_alias_dbus_path_finish (self, result, &error); - if (error == NULL) { - - /* No collection for this alias */ - if (collection_path == NULL) { - g_simple_async_result_complete (async); - - } else { - read->collection = _secret_service_find_collection_instance (self, - collection_path); - if (read->collection != NULL) { - g_simple_async_result_complete (async); - - /* No collection loaded, but valid path, load */ - } else { - secret_collection_new_for_dbus_path (self, collection_path, - SECRET_COLLECTION_NONE, - read->cancellable, - on_read_alias_collection, - g_object_ref (async)); - } - } - - } else { - g_simple_async_result_take_error (async, error); - g_simple_async_result_complete (async); - } - - g_free (collection_path); - g_object_unref (async); -} - -static void -on_read_alias_service (GObject *source, - GAsyncResult *result, - gpointer user_data) -{ - GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data); - ReadClosure *read = g_simple_async_result_get_op_res_gpointer (async); - SecretService *service; - GError *error = NULL; - - service = secret_service_get_finish (result, &error); - if (error == NULL) { - secret_service_read_alias_dbus_path (service, read->alias, read->cancellable, - on_read_alias_path, g_object_ref (async)); - g_object_unref (service); - - } else { - g_simple_async_result_take_error (async, error); - g_simple_async_result_complete (async); - } - - g_object_unref (async); -} - -/** - * secret_service_read_alias: - * @service: (allow-none): 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'. - * - * If @service is NULL, then secret_service_get() will be called to get - * the default #SecretService proxy. - * - * This method will return immediately and complete asynchronously. - */ -void -secret_service_read_alias (SecretService *service, - const gchar *alias, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *async; - ReadClosure *read; - - g_return_if_fail (service == NULL || SECRET_IS_SERVICE (service)); - g_return_if_fail (alias != NULL); - g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); - - async = g_simple_async_result_new (G_OBJECT (service), callback, user_data, - secret_service_read_alias); - read = g_slice_new0 (ReadClosure); - read->cancellable = cancellable ? g_object_ref (cancellable) : NULL; - read->alias = g_strdup (alias); - g_simple_async_result_set_op_res_gpointer (async, read, read_closure_free); - - if (service == NULL) { - secret_service_get (SECRET_SERVICE_NONE, cancellable, - on_read_alias_service, g_object_ref (async)); - } else { - secret_service_read_alias_dbus_path (service, read->alias, read->cancellable, - on_read_alias_path, g_object_ref (async)); - } - - g_object_unref (async); -} - -/** - * secret_service_read_alias_finish: - * @service: (allow-none): a secret service object - * @result: asynchronous result passed to callback - * @error: location to place error on failure - * - * Finish an asynchronous operation to lookup which collection is assigned - * to an alias. - * - * Returns: (transfer full): the collection, or %NULL if none assigned to the alias - */ -SecretCollection * -secret_service_read_alias_finish (SecretService *service, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *async; - ReadClosure *read; - - g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), NULL); - g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (service), - secret_service_read_alias), NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - async = G_SIMPLE_ASYNC_RESULT (result); - if (g_simple_async_result_propagate_error (async, error)) - return NULL; - read = g_simple_async_result_get_op_res_gpointer (async); - if (read->collection) - g_object_ref (read->collection); - return read->collection; -} - -/** - * secret_service_read_alias_sync: - * @service: (allow-none): 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'. - * - * If @service is NULL, then secret_service_get_sync() will be called to get - * the default #SecretService proxy. - * - * This method may block and should not be used in user interface threads. - * - * Returns: (transfer full): the collection, or %NULL if none assigned to the alias - */ -SecretCollection * -secret_service_read_alias_sync (SecretService *service, - const gchar *alias, - GCancellable *cancellable, - GError **error) -{ - SecretCollection *collection; - gchar *collection_path; - - g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), NULL); - g_return_val_if_fail (alias != NULL, NULL); - g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - collection_path = secret_service_read_alias_dbus_path_sync (service, alias, - cancellable, error); - if (collection_path == NULL) - return NULL; - - /* No collection for this alias */ - if (collection_path == NULL) { - collection = NULL; - - } else { - collection = _secret_service_find_collection_instance (service, - collection_path); - - /* No collection loaded, but valid path, load */ - if (collection == NULL) { - collection = secret_collection_new_for_dbus_path_sync (service, collection_path, - SECRET_COLLECTION_LOAD_ITEMS, - cancellable, error); - } - } - - g_free (collection_path); - return collection; -} - typedef struct { GCancellable *cancellable; gchar *alias; diff --git a/library/secret-service.h b/library/secret-service.h index 79ae773..69d3ce0 100644 --- a/library/secret-service.h +++ b/library/secret-service.h @@ -270,21 +270,6 @@ gboolean secret_service_remove_sync (SecretService GCancellable *cancellable, GError **error); -void secret_service_read_alias (SecretService *service, - const gchar *alias, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -SecretCollection * secret_service_read_alias_finish (SecretService *service, - GAsyncResult *result, - GError **error); - -SecretCollection * secret_service_read_alias_sync (SecretService *service, - const gchar *alias, - GCancellable *cancellable, - GError **error); - void secret_service_set_alias (SecretService *service, const gchar *alias, SecretCollection *collection, diff --git a/library/tests/test-collection.c b/library/tests/test-collection.c index 039c14b..0b205c6 100644 --- a/library/tests/test-collection.c +++ b/library/tests/test-collection.c @@ -171,6 +171,61 @@ test_new_async_noexist (Test *test, } +static void +test_for_alias_sync (Test *test, + gconstpointer used) +{ + const gchar *collection_path; + SecretCollection *collection; + GError *error = NULL; + + collection = secret_collection_for_alias_sync (test->service, "default", NULL, &error); + g_assert_no_error (error); + + collection_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection)); + g_assert_cmpstr (collection_path, ==, "/org/freedesktop/secrets/collection/english"); + g_object_unref (collection); + + collection = secret_collection_for_alias_sync (test->service, "unknown", NULL, &error); + g_assert_no_error (error); + g_assert (collection == NULL); +} + +static void +test_for_alias_async (Test *test, + gconstpointer used) +{ + const gchar *collection_path; + SecretCollection *collection; + GAsyncResult *result = NULL; + GError *error = NULL; + + secret_collection_for_alias (test->service, "default", NULL, + on_async_result, &result); + g_assert (result == NULL); + egg_test_wait (); + + collection = secret_collection_for_alias_finish (result, &error); + g_assert_no_error (error); + g_object_unref (result); + + collection_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection)); + g_assert_cmpstr (collection_path, ==, "/org/freedesktop/secrets/collection/english"); + g_object_unref (collection); + result = NULL; + + secret_collection_for_alias (test->service, "unknown", NULL, + on_async_result, &result); + g_assert (result == NULL); + egg_test_wait (); + + collection = secret_collection_for_alias_finish (result, &error); + g_assert_no_error (error); + g_assert (collection == NULL); + g_object_unref (result); +} + + static void test_create_sync (Test *test, gconstpointer unused) @@ -875,6 +930,8 @@ main (int argc, char **argv) g_test_add ("/collection/new-async", Test, "mock-service-normal.py", setup, test_new_async, teardown); g_test_add ("/collection/new-sync-noexist", Test, "mock-service-normal.py", setup, test_new_sync_noexist, teardown); g_test_add ("/collection/new-async-noexist", Test, "mock-service-normal.py", setup, test_new_async_noexist, teardown); + g_test_add ("/collection/for-alias-sync", Test, "mock-service-normal.py", setup, test_for_alias_sync, teardown); + g_test_add ("/collection/for-alias-async", Test, "mock-service-normal.py", setup, test_for_alias_async, teardown); g_test_add ("/collection/create-sync", Test, "mock-service-normal.py", setup, test_create_sync, teardown); g_test_add ("/collection/create-async", Test, "mock-service-normal.py", setup, test_create_async, teardown); g_test_add ("/collection/properties", Test, "mock-service-normal.py", setup, test_properties, teardown); diff --git a/library/tests/test-methods.c b/library/tests/test-methods.c index 8b77dbc..2398185 100644 --- a/library/tests/test-methods.c +++ b/library/tests/test-methods.c @@ -864,70 +864,16 @@ test_store_async (Test *test, g_strfreev (paths); } -static void -test_read_alias_sync (Test *test, - gconstpointer used) -{ - const gchar *collection_path; - SecretCollection *collection; - GError *error = NULL; - - collection = secret_service_read_alias_sync (test->service, "default", NULL, &error); - g_assert_no_error (error); - - collection_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection)); - g_assert_cmpstr (collection_path, ==, "/org/freedesktop/secrets/collection/english"); - g_object_unref (collection); - - collection = secret_service_read_alias_sync (test->service, "unknown", NULL, &error); - g_assert_no_error (error); - g_assert (collection == NULL); -} - -static void -test_read_alias_async (Test *test, - gconstpointer used) -{ - const gchar *collection_path; - SecretCollection *collection; - GAsyncResult *result = NULL; - GError *error = NULL; - - secret_service_read_alias (test->service, "default", NULL, - on_complete_get_result, &result); - g_assert (result == NULL); - egg_test_wait (); - - collection = secret_service_read_alias_finish (test->service, result, &error); - g_assert_no_error (error); - g_object_unref (result); - - collection_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection)); - g_assert_cmpstr (collection_path, ==, "/org/freedesktop/secrets/collection/english"); - g_object_unref (collection); - result = NULL; - - secret_service_read_alias (test->service, "unknown", NULL, - on_complete_get_result, &result); - g_assert (result == NULL); - egg_test_wait (); - - collection = secret_service_read_alias_finish (test->service, result, &error); - g_assert_no_error (error); - g_assert (collection == NULL); - g_object_unref (result); -} - static void test_set_alias_sync (Test *test, gconstpointer used) { SecretCollection *collection; - SecretCollection *blah; + gchar *blah; GError *error = NULL; gboolean ret; - blah = secret_service_read_alias_sync (test->service, "blah", NULL, &error); + blah = secret_service_read_alias_dbus_path_sync (test->service, "blah", NULL, &error); g_assert_no_error (error); g_assert (blah == NULL); @@ -941,16 +887,16 @@ test_set_alias_sync (Test *test, g_assert_no_error (error); g_assert (ret == TRUE); - blah = secret_service_read_alias_sync (test->service, "blah", NULL, &error); + blah = secret_service_read_alias_dbus_path_sync (test->service, "blah", NULL, &error); g_assert_no_error (error); - g_assert_cmpstr (g_dbus_proxy_get_object_path (G_DBUS_PROXY (blah)), ==, g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection))); - g_object_unref (blah); + g_assert_cmpstr (blah, ==, g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection))); + g_free (blah); ret = secret_service_set_alias_sync (test->service, "blah", NULL, NULL, &error); g_assert_no_error (error); g_assert (ret == TRUE); - blah = secret_service_read_alias_sync (test->service, "blah", NULL, &error); + blah = secret_service_read_alias_dbus_path_sync (test->service, "blah", NULL, &error); g_assert_no_error (error); g_assert (blah == NULL); @@ -993,9 +939,6 @@ main (int argc, char **argv) g_test_add ("/service/store-async", Test, "mock-service-normal.py", setup, test_store_async, teardown); g_test_add ("/service/store-replace", Test, "mock-service-normal.py", setup, test_store_replace, teardown); - g_test_add ("/service/read-alias-sync", Test, "mock-service-normal.py", setup, test_read_alias_sync, teardown); - g_test_add ("/service/read-alias-async", Test, "mock-service-normal.py", setup, test_read_alias_async, teardown); - g_test_add ("/service/set-alias-sync", Test, "mock-service-normal.py", setup, test_set_alias_sync, teardown); return egg_tests_run_with_loop ();