1 /* libsecret - GLib wrapper for Secret Service
3 * Copyright 2011 Collabora Ltd.
4 * Copyright 2012 Red Hat Inc.
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 2.1 of the licence or (at
9 * your option) any later version.
11 * See the included COPYING file for more information.
13 * Author: Stef Walter <stefw@gnome.org>
18 #include "secret-collection.h"
19 #include "secret-dbus-generated.h"
20 #include "secret-item.h"
21 #include "secret-paths.h"
22 #include "secret-private.h"
23 #include "secret-service.h"
24 #include "secret-types.h"
25 #include "secret-value.h"
29 * @SECRET_SEARCH_NONE: no flags
30 * @SECRET_SEARCH_ALL: all the items matching the search will be returned, instead of just the first one
31 * @SECRET_SEARCH_UNLOCK: unlock locked items while searching
32 * @SECRET_SEARCH_LOAD_SECRETS: while searching load secrets for items that are not locked
34 * Various flags to be used with secret_service_search() and secret_service_search_sync().
38 SecretService *service;
39 GCancellable *cancellable;
44 SecretSearchFlags flags;
49 search_closure_free (gpointer data)
51 SearchClosure *closure = data;
52 g_object_unref (closure->service);
53 g_clear_object (&closure->cancellable);
54 g_hash_table_unref (closure->items);
55 g_variant_unref (closure->attributes);
56 g_strfreev (closure->unlocked);
57 g_strfreev (closure->locked);
58 g_slice_free (SearchClosure, closure);
62 search_closure_take_item (SearchClosure *closure,
65 const gchar *path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (item));
66 g_hash_table_insert (closure->items, (gpointer)path, item);
70 search_closure_build_items (SearchClosure *closure,
73 GList *results = NULL;
77 for (i = 0; paths[i]; i++) {
78 item = g_hash_table_lookup (closure->items, paths[i]);
80 results = g_list_prepend (results, g_object_ref (item));
83 return g_list_reverse (results);
87 on_search_secrets (GObject *source,
91 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
93 /* Note that we ignore any unlock failure */
94 secret_item_load_secrets_finish (result, NULL);
96 g_simple_async_result_complete (async);
97 g_object_unref (async);
101 on_search_unlocked (GObject *source,
102 GAsyncResult *result,
105 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
106 SearchClosure *search = g_simple_async_result_get_op_res_gpointer (async);
109 /* Note that we ignore any unlock failure */
110 secret_service_unlock_finish (search->service, result, NULL, NULL);
112 /* If loading secrets ... locked items automatically ignored */
113 if (search->flags & SECRET_SEARCH_LOAD_SECRETS) {
114 items = g_hash_table_get_values (search->items);
115 secret_item_load_secrets (items, search->cancellable,
116 on_search_secrets, g_object_ref (async));
119 /* No additional options, just complete */
121 g_simple_async_result_complete (async);
124 g_object_unref (async);
128 secret_search_unlock_load_or_complete (GSimpleAsyncResult *async,
129 SearchClosure *search)
133 /* If unlocking then unlock all the locked items */
134 if (search->flags & SECRET_SEARCH_UNLOCK) {
135 items = search_closure_build_items (search, search->locked);
136 secret_service_unlock (search->service, items, search->cancellable,
137 on_search_unlocked, g_object_ref (async));
138 g_list_free_full (items, g_object_unref);
140 /* If loading secrets ... locked items automatically ignored */
141 } else if (search->flags & SECRET_SEARCH_LOAD_SECRETS) {
142 items = g_hash_table_get_values (search->items);
143 secret_item_load_secrets (items, search->cancellable,
144 on_search_secrets, g_object_ref (async));
147 /* No additional options, just complete */
149 g_simple_async_result_complete (async);
154 on_search_loaded (GObject *source,
155 GAsyncResult *result,
158 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
159 SearchClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
160 GError *error = NULL;
165 item = secret_item_new_for_dbus_path_finish (result, &error);
167 g_simple_async_result_take_error (res, error);
170 search_closure_take_item (closure, item);
172 /* We're done loading, lets go to the next step */
173 if (closure->loading == 0)
174 secret_search_unlock_load_or_complete (res, closure);
176 g_object_unref (res);
180 search_load_item_async (SecretService *self,
181 GSimpleAsyncResult *res,
182 SearchClosure *closure,
187 item = _secret_service_find_item_instance (self, path);
189 secret_item_new_for_dbus_path (self, path, SECRET_ITEM_NONE, closure->cancellable,
190 on_search_loaded, g_object_ref (res));
193 search_closure_take_item (closure, item);
198 on_search_paths (GObject *source,
199 GAsyncResult *result,
202 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
203 SearchClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
204 SecretService *self = closure->service;
205 GError *error = NULL;
210 secret_service_search_for_dbus_paths_finish (self, result, &closure->unlocked,
211 &closure->locked, &error);
214 if (closure->flags & SECRET_SEARCH_ALL)
218 for (i = 0; count < want && closure->unlocked[i] != NULL; i++, count++)
219 search_load_item_async (self, res, closure, closure->unlocked[i]);
220 for (i = 0; count < want && closure->locked[i] != NULL; i++, count++)
221 search_load_item_async (self, res, closure, closure->locked[i]);
223 /* No items loading, complete operation now */
224 if (closure->loading == 0)
225 secret_search_unlock_load_or_complete (res, closure);
228 g_simple_async_result_take_error (res, error);
229 g_simple_async_result_complete (res);
232 g_object_unref (res);
236 on_search_service (GObject *source,
237 GAsyncResult *result,
240 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
241 SearchClosure *search = g_simple_async_result_get_op_res_gpointer (async);
242 GError *error = NULL;
244 search->service = secret_service_get_finish (result, &error);
246 _secret_service_search_for_paths_variant (search->service, search->attributes,
247 search->cancellable, on_search_paths,
248 g_object_ref (async));
251 g_simple_async_result_take_error (async, error);
252 g_simple_async_result_complete (async);
255 g_object_unref (async);
259 * secret_service_search:
260 * @service: (allow-none): the secret service
261 * @schema: (allow-none): the schema for the attributes
262 * @attributes: (element-type utf8 utf8): search for items matching these attributes
263 * @flags: search option flags
264 * @cancellable: optional cancellation object
265 * @callback: called when the operation completes
266 * @user_data: data to pass to the callback
268 * Search for items matching the @attributes. All collections are searched.
269 * The @attributes should be a table of string keys and string values.
271 * If @service is NULL, then secret_service_get() will be called to get
272 * the default #SecretService proxy.
274 * If %SECRET_SEARCH_ALL is set in @flags, then all the items matching the
275 * search will be returned. Otherwise only the first item will be returned.
276 * This is almost always the unlocked item that was most recently stored.
278 * If %SECRET_SEARCH_UNLOCK is set in @flags, then items will be unlocked
279 * if necessary. In either case, locked and unlocked items will match the
280 * search and be returned. If the unlock fails, the search does not fail.
282 * If %SECRET_SEARCH_LOAD_SECRETS is set in @flags, then the items will have
283 * their secret values loaded and available via secret_item_get_secret().
285 * This function returns immediately and completes asynchronously.
288 secret_service_search (SecretService *service,
289 const SecretSchema *schema,
290 GHashTable *attributes,
291 SecretSearchFlags flags,
292 GCancellable *cancellable,
293 GAsyncReadyCallback callback,
296 GSimpleAsyncResult *res;
297 SearchClosure *closure;
298 const gchar *schema_name = NULL;
300 g_return_if_fail (service == NULL || SECRET_IS_SERVICE (service));
301 g_return_if_fail (attributes != NULL);
302 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
304 /* Warnings raised already */
305 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
308 if (schema != NULL && !(schema->flags & SECRET_SCHEMA_DONT_MATCH_NAME))
309 schema_name = schema->name;
311 res = g_simple_async_result_new (G_OBJECT (service), callback, user_data,
312 secret_service_search);
313 closure = g_slice_new0 (SearchClosure);
314 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
315 closure->items = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
316 closure->flags = flags;
317 closure->attributes = _secret_attributes_to_variant (attributes, schema_name);
318 g_variant_ref_sink (closure->attributes);
319 g_simple_async_result_set_op_res_gpointer (res, closure, search_closure_free);
322 closure->service = g_object_ref (service);
323 _secret_service_search_for_paths_variant (closure->service, closure->attributes,
324 closure->cancellable, on_search_paths,
328 secret_service_get (SECRET_SERVICE_NONE, cancellable,
329 on_search_service, g_object_ref (res));
332 g_object_unref (res);
336 * secret_service_search_finish:
337 * @service: (allow-none): the secret service
338 * @result: asynchronous result passed to callback
339 * @error: location to place error on failure
341 * Complete asynchronous operation to search for items.
343 * Returns: (transfer full) (element-type Secret.Item):
344 * a list of items that matched the search
347 secret_service_search_finish (SecretService *service,
348 GAsyncResult *result,
351 GSimpleAsyncResult *res;
352 SearchClosure *closure;
355 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), FALSE);
356 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
357 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (service),
358 secret_service_search), FALSE);
360 res = G_SIMPLE_ASYNC_RESULT (result);
362 if (g_simple_async_result_propagate_error (res, error))
365 closure = g_simple_async_result_get_op_res_gpointer (res);
366 if (closure->unlocked)
367 items = search_closure_build_items (closure, closure->unlocked);
369 items = g_list_concat (items, search_closure_build_items (closure, closure->locked));
374 service_load_items_sync (SecretService *service,
375 GCancellable *cancellable,
385 for (i = 0; *have < want && paths[i] != NULL; i++) {
386 item = _secret_service_find_item_instance (service, paths[i]);
388 item = secret_item_new_for_dbus_path_sync (service, paths[i], SECRET_ITEM_NONE,
394 *items = g_list_prepend (*items, item);
403 * secret_service_search_sync:
404 * @service: (allow-none): the secret service
405 * @schema: (allow-none): the schema for the attributes
406 * @attributes: (element-type utf8 utf8): search for items matching these attributes
407 * @flags: search option flags
408 * @cancellable: optional cancellation object
409 * @error: location to place error on failure
411 * Search for items matching the @attributes. All collections are searched.
412 * The @attributes should be a table of string keys and string values.
414 * If @service is NULL, then secret_service_get_sync() will be called to get
415 * the default #SecretService proxy.
417 * If %SECRET_SEARCH_ALL is set in @flags, then all the items matching the
418 * search will be returned. Otherwise only the first item will be returned.
419 * This is almost always the unlocked item that was most recently stored.
421 * If %SECRET_SEARCH_UNLOCK is set in @flags, then items will be unlocked
422 * if necessary. In either case, locked and unlocked items will match the
423 * search and be returned. If the unlock fails, the search does not fail.
425 * If %SECRET_SEARCH_LOAD_SECRETS is set in @flags, then the items' secret
426 * values will be loaded for any unlocked items. Loaded item secret values
427 * are available via secret_item_get_secret(). If the load of a secret values
430 * This function may block indefinetely. Use the asynchronous version
431 * in user interface threads.
433 * Returns: (transfer full) (element-type Secret.Item):
434 * a list of items that matched the search
437 secret_service_search_sync (SecretService *service,
438 const SecretSchema *schema,
439 GHashTable *attributes,
440 SecretSearchFlags flags,
441 GCancellable *cancellable,
444 gchar **unlocked_paths = NULL;
445 gchar **locked_paths = NULL;
447 GList *locked = NULL;
448 GList *unlocked = NULL;
453 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), NULL);
454 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
455 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
457 /* Warnings raised already */
458 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
461 if (service == NULL) {
462 service = secret_service_get_sync (SECRET_SERVICE_NONE, cancellable, error);
466 g_object_ref (service);
469 if (!secret_service_search_for_dbus_paths_sync (service, schema, attributes, cancellable,
470 &unlocked_paths, &locked_paths, error)) {
471 g_object_unref (service);
478 if (flags & SECRET_SEARCH_ALL)
482 /* Remember, we're adding to the list backwards */
484 if (unlocked_paths) {
485 ret = service_load_items_sync (service, cancellable, unlocked_paths,
486 &unlocked, want, &have, error);
489 if (ret && locked_paths) {
490 ret = service_load_items_sync (service, cancellable, locked_paths,
491 &locked, want, &have, error);
494 g_strfreev (unlocked_paths);
495 g_strfreev (locked_paths);
498 g_list_free_full (unlocked, g_object_unref);
499 g_list_free_full (locked, g_object_unref);
500 g_object_unref (service);
504 /* The lists are backwards at this point ... */
505 items = g_list_concat (items, g_list_copy (locked));
506 items = g_list_concat (items, g_list_copy (unlocked));
507 items = g_list_reverse (items);
509 if (flags & SECRET_SEARCH_UNLOCK)
510 secret_service_unlock_sync (service, locked, cancellable, NULL, NULL);
512 if (flags & SECRET_SEARCH_LOAD_SECRETS)
513 secret_item_load_secrets_sync (items, NULL, NULL);
515 g_list_free (locked);
516 g_list_free (unlocked);
517 g_object_unref (service);
522 _secret_service_decode_get_secrets_first (SecretService *self,
525 SecretSession *session;
526 SecretValue *value = NULL;
531 g_variant_get (out, "(a{o(oayays)})", &iter);
532 while (g_variant_iter_next (iter, "{&o@(oayays)}", &path, &variant)) {
533 session = _secret_service_get_session (self);
534 value = _secret_session_decode_secret (session, variant);
535 g_variant_unref (variant);
538 g_variant_iter_free (iter);
543 _secret_service_decode_get_secrets_all (SecretService *self,
546 SecretSession *session;
553 session = _secret_service_get_session (self);
554 values = g_hash_table_new_full (g_str_hash, g_str_equal,
555 g_free, secret_value_unref);
556 g_variant_get (out, "(a{o(oayays)})", &iter);
557 while (g_variant_iter_loop (iter, "{o@(oayays)}", &path, &variant)) {
558 value = _secret_session_decode_secret (session, variant);
560 g_hash_table_insert (values, g_strdup (path), value);
562 g_variant_iter_free (iter);
567 GCancellable *cancellable;
576 xlock_closure_free (gpointer data)
578 XlockClosure *closure = data;
579 if (closure->cancellable)
580 g_object_unref (closure->cancellable);
581 g_ptr_array_free (closure->paths, TRUE);
582 g_strfreev (closure->xlocked);
583 g_hash_table_unref (closure->objects);
584 g_slice_free (XlockClosure, closure);
588 on_xlock_paths (GObject *source,
589 GAsyncResult *result,
592 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
593 XlockClosure *xlock = g_simple_async_result_get_op_res_gpointer (async);
596 GError *error = NULL;
599 xlock->count = _secret_service_xlock_paths_finish (SECRET_SERVICE (source), result,
600 &xlock->xlocked, &error);
604 * After a lock or unlock we want the Locked property to immediately
605 * reflect the new state, and not have to wait for a PropertiesChanged
606 * signal to be processed later.
609 lockval = g_variant_ref_sink (g_variant_new_boolean (xlock->locking));
610 for (i = 0; xlock->xlocked[i] != NULL; i++) {
611 object = g_hash_table_lookup (xlock->objects, xlock->xlocked[i]);
613 g_dbus_proxy_set_cached_property (object, "Locked", lockval);
615 g_variant_unref (lockval);
618 g_simple_async_result_take_error (async, error);
621 g_simple_async_result_complete (async);
622 g_object_unref (async);
626 on_xlock_service (GObject *source,
627 GAsyncResult *result,
630 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
631 XlockClosure *xlock = g_simple_async_result_get_op_res_gpointer (async);
632 GError *error = NULL;
633 SecretService *service;
635 service = secret_service_get_finish (result, &error);
637 _secret_service_xlock_paths_async (service, xlock->locking ? "Lock" : "Unlock",
638 (const gchar **)xlock->paths->pdata,
639 xlock->cancellable, on_xlock_paths,
640 g_object_ref (async));
641 g_object_unref (service);
644 g_simple_async_result_take_error (async, error);
645 g_simple_async_result_complete (async);
648 g_object_unref (async);
652 service_xlock_async (SecretService *service,
655 GCancellable *cancellable,
656 GAsyncReadyCallback callback,
659 GSimpleAsyncResult *async;
664 async = g_simple_async_result_new (G_OBJECT (service), callback, user_data,
665 service_xlock_async);
666 xlock = g_slice_new0 (XlockClosure);
667 xlock->objects = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
668 xlock->locking = locking;
669 xlock->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
670 xlock->paths = g_ptr_array_new ();
672 for (l = objects; l != NULL; l = g_list_next (l)) {
673 path = g_dbus_proxy_get_object_path (l->data);
674 g_ptr_array_add (xlock->paths, (gpointer)path);
675 g_hash_table_insert (xlock->objects, g_strdup (path), g_object_ref (l->data));
677 g_ptr_array_add (xlock->paths, NULL);
679 g_simple_async_result_set_op_res_gpointer (async, xlock, xlock_closure_free);
681 if (service == NULL) {
682 secret_service_get (SECRET_SERVICE_NONE, cancellable,
683 on_xlock_service, g_object_ref (async));
685 _secret_service_xlock_paths_async (service, xlock->locking ? "Lock" : "Unlock",
686 (const gchar **)xlock->paths->pdata,
687 xlock->cancellable, on_xlock_paths,
688 g_object_ref (async));
691 g_object_unref (async);
695 service_xlock_finish (SecretService *service,
696 GAsyncResult *result,
700 GSimpleAsyncResult *async;
705 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (service),
706 service_xlock_async), -1);
708 async = G_SIMPLE_ASYNC_RESULT (result);
709 if (g_simple_async_result_propagate_error (async, error))
712 xlock = g_simple_async_result_get_op_res_gpointer (async);
715 for (i = 0; xlock->xlocked[i] != NULL; i++) {
716 object = g_hash_table_lookup (xlock->objects, xlock->xlocked[i]);
718 *xlocked = g_list_prepend (*xlocked, g_object_ref (object));
726 * secret_service_lock:
727 * @service: (allow-none): the secret service
728 * @objects: (element-type GLib.DBusProxy): the items or collections to lock
729 * @cancellable: optional cancellation object
730 * @callback: called when the operation completes
731 * @user_data: data to pass to the callback
733 * Lock items or collections in the secret service.
735 * The secret service may not be able to lock items individually, and may
736 * lock an entire collection instead.
738 * If @service is NULL, then secret_service_get() will be called to get
739 * the default #SecretService proxy.
741 * This method returns immediately and completes asynchronously. The secret
742 * service may prompt the user. secret_service_prompt() will be used to handle
743 * any prompts that show up.
746 secret_service_lock (SecretService *service,
748 GCancellable *cancellable,
749 GAsyncReadyCallback callback,
752 g_return_if_fail (service == NULL || SECRET_IS_SERVICE (service));
753 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
755 service_xlock_async (service, TRUE, objects, cancellable, callback, user_data);
759 * secret_service_lock_finish:
760 * @service: (allow-none): the secret service
761 * @result: asynchronous result passed to the callback
762 * @locked: (out) (element-type GLib.DBusProxy) (transfer full) (allow-none):
763 * location to place list of items or collections that were locked
764 * @error: location to place an error on failure
766 * Complete asynchronous operation to lock items or collections in the secret
769 * The secret service may not be able to lock items individually, and may
770 * lock an entire collection instead.
772 * Returns: the number of items or collections that were locked
775 secret_service_lock_finish (SecretService *service,
776 GAsyncResult *result,
780 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), -1);
781 g_return_val_if_fail (error == NULL || *error == NULL, -1);
783 return service_xlock_finish (service, result, locked, error);
787 * secret_service_lock_sync:
788 * @service: (allow-none): the secret service
789 * @objects: (element-type GLib.DBusProxy): the items or collections to lock
790 * @cancellable: optional cancellation object
791 * @locked: (out) (element-type GLib.DBusProxy) (transfer full) (allow-none):
792 * location to place list of items or collections that were locked
793 * @error: location to place an error on failure
795 * Lock items or collections in the secret service.
797 * The secret service may not be able to lock items individually, and may
798 * lock an entire collection instead.
800 * If @service is NULL, then secret_service_get_sync() will be called to get
801 * the default #SecretService proxy.
803 * This method may block indefinitely and should not be used in user
804 * interface threads. The secret service may prompt the user.
805 * secret_service_prompt() will be used to handle any prompts that show up.
807 * Returns: the number of items or collections that were locked
810 secret_service_lock_sync (SecretService *service,
812 GCancellable *cancellable,
819 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), -1);
820 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1);
821 g_return_val_if_fail (error == NULL || *error == NULL, -1);
823 sync = _secret_sync_new ();
824 g_main_context_push_thread_default (sync->context);
826 secret_service_lock (service, objects, cancellable,
827 _secret_sync_on_result, sync);
829 g_main_loop_run (sync->loop);
831 count = secret_service_lock_finish (service, sync->result, locked, error);
833 g_main_context_pop_thread_default (sync->context);
834 _secret_sync_free (sync);
840 * secret_service_unlock:
841 * @service: (allow-none): the secret service
842 * @objects: (element-type GLib.DBusProxy): the items or collections to unlock
843 * @cancellable: optional cancellation object
844 * @callback: called when the operation completes
845 * @user_data: data to pass to the callback
847 * Unlock items or collections in the secret service.
849 * The secret service may not be able to unlock items individually, and may
850 * unlock an entire collection instead.
852 * If @service is NULL, then secret_service_get() will be called to get
853 * the default #SecretService proxy.
855 * This method may block indefinitely and should not be used in user
856 * interface threads. The secret service may prompt the user.
857 * secret_service_prompt() will be used to handle any prompts that show up.
860 secret_service_unlock (SecretService *service,
862 GCancellable *cancellable,
863 GAsyncReadyCallback callback,
866 g_return_if_fail (service == NULL || SECRET_IS_SERVICE (service));
867 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
869 service_xlock_async (service, FALSE, objects, cancellable, callback, user_data);
873 * secret_service_unlock_finish:
874 * @service: (allow-none): the secret service
875 * @result: asynchronous result passed to the callback
876 * @unlocked: (out) (element-type GLib.DBusProxy) (transfer full) (allow-none):
877 * location to place list of items or collections that were unlocked
878 * @error: location to place an error on failure
880 * Complete asynchronous operation to unlock items or collections in the secret
883 * The secret service may not be able to unlock items individually, and may
884 * unlock an entire collection instead.
886 * Returns: the number of items or collections that were unlocked
889 secret_service_unlock_finish (SecretService *service,
890 GAsyncResult *result,
894 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), -1);
895 g_return_val_if_fail (error == NULL || *error == NULL, -1);
897 return service_xlock_finish (service, result, unlocked, error);
901 * secret_service_unlock_sync:
902 * @service: (allow-none): the secret service
903 * @objects: (element-type GLib.DBusProxy): the items or collections to unlock
904 * @cancellable: optional cancellation object
905 * @unlocked: (out) (element-type GLib.DBusProxy) (transfer full) (allow-none):
906 * location to place list of items or collections that were unlocked
907 * @error: location to place an error on failure
909 * Unlock items or collections in the secret service.
911 * The secret service may not be able to unlock items individually, and may
912 * unlock an entire collection instead.
914 * If @service is NULL, then secret_service_get_sync() will be called to get
915 * the default #SecretService proxy.
917 * This method may block indefinitely and should not be used in user
918 * interface threads. The secret service may prompt the user.
919 * secret_service_prompt() will be used to handle any prompts that show up.
921 * Returns: the number of items or collections that were unlocked
924 secret_service_unlock_sync (SecretService *service,
926 GCancellable *cancellable,
933 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), -1);
934 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), -1);
935 g_return_val_if_fail (error == NULL || *error == NULL, -1);
937 sync = _secret_sync_new ();
938 g_main_context_push_thread_default (sync->context);
940 secret_service_unlock (service, objects, cancellable,
941 _secret_sync_on_result, sync);
943 g_main_loop_run (sync->loop);
945 count = secret_service_unlock_finish (service, sync->result, unlocked, error);
947 g_main_context_pop_thread_default (sync->context);
948 _secret_sync_free (sync);
954 GCancellable *cancellable;
955 gchar *collection_path;
957 GHashTable *properties;
961 store_closure_free (gpointer data)
963 StoreClosure *store = data;
964 if (store->cancellable)
965 g_object_unref (store->cancellable);
966 g_free (store->collection_path);
967 secret_value_unref (store->value);
968 g_hash_table_unref (store->properties);
969 g_slice_free (StoreClosure, store);
973 on_store_create (GObject *source,
974 GAsyncResult *result,
977 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
978 GError *error = NULL;
981 path = secret_service_create_item_dbus_path_finish (SECRET_SERVICE (source), result, &error);
983 g_simple_async_result_take_error (async, error);
986 g_simple_async_result_complete (async);
987 g_object_unref (async);
991 on_store_service (GObject *source,
992 GAsyncResult *result,
995 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
996 StoreClosure *store = g_simple_async_result_get_op_res_gpointer (async);
997 SecretService *service;
998 GError *error = NULL;
1000 service = secret_service_get_finish (result, &error);
1001 if (error == NULL) {
1002 secret_service_create_item_dbus_path (service, store->collection_path,
1003 store->properties, store->value,
1004 SECRET_ITEM_CREATE_REPLACE, store->cancellable,
1005 on_store_create, g_object_ref (async));
1006 g_object_unref (service);
1009 g_simple_async_result_take_error (async, error);
1010 g_simple_async_result_complete (async);
1013 g_object_unref (async);
1017 * secret_service_store:
1018 * @service: (allow-none): the secret service
1019 * @schema: (allow-none): the schema to use to check attributes
1020 * @attributes: (element-type utf8 utf8): the attribute keys and values
1021 * @collection: (allow-none): a collection alias, or D-Bus object path of the collection where to store the secret
1022 * @label: label for the secret
1023 * @value: the secret value
1024 * @cancellable: optional cancellation object
1025 * @callback: called when the operation completes
1026 * @user_data: data to be passed to the callback
1028 * Store a secret value in the secret service.
1030 * The @attributes should be a set of key and value string pairs.
1032 * If the attributes match a secret item already stored in the collection, then
1033 * the item will be updated with these new values.
1035 * If @service is NULL, then secret_service_get() will be called to get
1036 * the default #SecretService proxy.
1038 * If @collection is not specified, then the default collection will be
1039 * used. Use #SECRET_COLLECTION_SESSION to store the password in the session
1040 * collection, which doesn't get stored across login sessions.
1042 * This method will return immediately and complete asynchronously.
1045 secret_service_store (SecretService *service,
1046 const SecretSchema *schema,
1047 GHashTable *attributes,
1048 const gchar *collection,
1051 GCancellable *cancellable,
1052 GAsyncReadyCallback callback,
1055 GSimpleAsyncResult *async;
1056 StoreClosure *store;
1057 const gchar *schema_name;
1060 g_return_if_fail (service == NULL || SECRET_IS_SERVICE (service));
1061 g_return_if_fail (attributes != NULL);
1062 g_return_if_fail (label != NULL);
1063 g_return_if_fail (value != NULL);
1064 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1066 /* Warnings raised already */
1067 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, FALSE))
1070 async = g_simple_async_result_new (G_OBJECT (service), callback, user_data,
1071 secret_service_store);
1072 store = g_slice_new0 (StoreClosure);
1073 store->collection_path = _secret_util_collection_to_path (collection);
1074 store->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1075 store->value = secret_value_ref (value);
1076 store->properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
1077 (GDestroyNotify)g_variant_unref);
1079 propval = g_variant_new_string (label);
1080 g_hash_table_insert (store->properties,
1081 SECRET_ITEM_INTERFACE ".Label",
1082 g_variant_ref_sink (propval));
1084 /* Always store the schema name in the attributes */
1085 schema_name = (schema == NULL) ? NULL : schema->name;
1086 propval = _secret_attributes_to_variant (attributes, schema_name);
1087 g_hash_table_insert (store->properties,
1088 SECRET_ITEM_INTERFACE ".Attributes",
1089 g_variant_ref_sink (propval));
1091 g_simple_async_result_set_op_res_gpointer (async, store, store_closure_free);
1093 if (service == NULL) {
1094 secret_service_get (SECRET_SERVICE_OPEN_SESSION, cancellable,
1095 on_store_service, g_object_ref (async));
1098 secret_service_create_item_dbus_path (service, store->collection_path,
1099 store->properties, store->value,
1100 SECRET_ITEM_CREATE_REPLACE, store->cancellable,
1101 on_store_create, g_object_ref (async));
1104 g_object_unref (async);
1108 * secret_service_store_finish:
1109 * @service: (allow-none): the secret service
1110 * @result: the asynchronous result passed to the callback
1111 * @error: location to place an error on failure
1113 * Finish asynchronous operation to store a secret value in the secret service.
1115 * Returns: whether the storage was successful or not
1118 secret_service_store_finish (SecretService *service,
1119 GAsyncResult *result,
1122 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), FALSE);
1123 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (service),
1124 secret_service_store), FALSE);
1125 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1127 if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
1134 * secret_service_store_sync:
1135 * @service: (allow-none): the secret service
1136 * @schema: (allow-none): the schema for the attributes
1137 * @attributes: (element-type utf8 utf8): the attribute keys and values
1138 * @collection: (allow-none): a collection alias, or D-Bus object path of the collection where to store the secret
1139 * @label: label for the secret
1140 * @value: the secret value
1141 * @cancellable: optional cancellation object
1142 * @error: location to place an error on failure
1144 * Store a secret value in the secret service.
1146 * The @attributes should be a set of key and value string pairs.
1148 * If the attributes match a secret item already stored in the collection, then
1149 * the item will be updated with these new values.
1151 * If @collection is %NULL, then the default collection will be
1152 * used. Use #SECRET_COLLECTION_SESSION to store the password in the session
1153 * collection, which doesn't get stored across login sessions.
1155 * If @service is NULL, then secret_service_get_sync() will be called to get
1156 * the default #SecretService proxy.
1158 * This method may block indefinitely and should not be used in user interface
1161 * Returns: whether the storage was successful or not
1164 secret_service_store_sync (SecretService *service,
1165 const SecretSchema *schema,
1166 GHashTable *attributes,
1167 const gchar *collection,
1170 GCancellable *cancellable,
1176 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), FALSE);
1177 g_return_val_if_fail (attributes != NULL, FALSE);
1178 g_return_val_if_fail (label != NULL, FALSE);
1179 g_return_val_if_fail (value != NULL, FALSE);
1180 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1181 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1183 /* Warnings raised already */
1184 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, FALSE))
1187 sync = _secret_sync_new ();
1188 g_main_context_push_thread_default (sync->context);
1190 secret_service_store (service, schema, attributes, collection,
1191 label, value, cancellable, _secret_sync_on_result, sync);
1193 g_main_loop_run (sync->loop);
1195 ret = secret_service_store_finish (service, sync->result, error);
1197 g_main_context_pop_thread_default (sync->context);
1198 _secret_sync_free (sync);
1204 GVariant *attributes;
1206 GCancellable *cancellable;
1210 lookup_closure_free (gpointer data)
1212 LookupClosure *closure = data;
1213 g_variant_unref (closure->attributes);
1215 secret_value_unref (closure->value);
1216 g_clear_object (&closure->cancellable);
1217 g_slice_free (LookupClosure, closure);
1221 on_lookup_get_secret (GObject *source,
1222 GAsyncResult *result,
1225 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
1226 LookupClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
1227 SecretService *self = SECRET_SERVICE (source);
1228 GError *error = NULL;
1230 closure->value = secret_service_get_secret_for_dbus_path_finish (self, result, &error);
1232 g_simple_async_result_take_error (res, error);
1234 g_simple_async_result_complete (res);
1235 g_object_unref (res);
1239 on_lookup_unlocked (GObject *source,
1240 GAsyncResult *result,
1243 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
1244 LookupClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
1245 SecretService *self = SECRET_SERVICE (source);
1246 GError *error = NULL;
1247 gchar **unlocked = NULL;
1249 secret_service_unlock_dbus_paths_finish (SECRET_SERVICE (source),
1250 result, &unlocked, &error);
1251 if (error != NULL) {
1252 g_simple_async_result_take_error (res, error);
1253 g_simple_async_result_complete (res);
1255 } else if (unlocked && unlocked[0]) {
1256 secret_service_get_secret_for_dbus_path (self, unlocked[0],
1257 closure->cancellable,
1258 on_lookup_get_secret,
1259 g_object_ref (res));
1262 g_simple_async_result_complete (res);
1265 g_strfreev (unlocked);
1266 g_object_unref (res);
1270 on_lookup_searched (GObject *source,
1271 GAsyncResult *result,
1274 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
1275 LookupClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
1276 SecretService *self = SECRET_SERVICE (source);
1277 GError *error = NULL;
1278 gchar **unlocked = NULL;
1279 gchar **locked = NULL;
1281 secret_service_search_for_dbus_paths_finish (self, result, &unlocked, &locked, &error);
1282 if (error != NULL) {
1283 g_simple_async_result_take_error (res, error);
1284 g_simple_async_result_complete (res);
1286 } else if (unlocked && unlocked[0]) {
1287 secret_service_get_secret_for_dbus_path (self, unlocked[0],
1288 closure->cancellable,
1289 on_lookup_get_secret,
1290 g_object_ref (res));
1292 } else if (locked && locked[0]) {
1293 const gchar *paths[] = { locked[0], NULL };
1294 secret_service_unlock_dbus_paths (self, paths,
1295 closure->cancellable,
1297 g_object_ref (res));
1300 g_simple_async_result_complete (res);
1303 g_strfreev (unlocked);
1304 g_strfreev (locked);
1305 g_object_unref (res);
1309 on_lookup_service (GObject *source,
1310 GAsyncResult *result,
1313 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
1314 LookupClosure *lookup = g_simple_async_result_get_op_res_gpointer (async);
1315 SecretService *service;
1316 GError *error = NULL;
1318 service = secret_service_get_finish (result, &error);
1319 if (error == NULL) {
1320 _secret_service_search_for_paths_variant (service, lookup->attributes,
1321 lookup->cancellable,
1322 on_lookup_searched, g_object_ref (async));
1323 g_object_unref (service);
1326 g_simple_async_result_take_error (async, error);
1327 g_simple_async_result_complete (async);
1330 g_object_unref (async);
1334 * secret_service_lookup:
1335 * @service: (allow-none): the secret service
1336 * @schema: (allow-none): the schema for the attributes
1337 * @attributes: (element-type utf8 utf8): the attribute keys and values
1338 * @cancellable: optional cancellation object
1339 * @callback: called when the operation completes
1340 * @user_data: data to be passed to the callback
1342 * Lookup a secret value in the secret service.
1344 * The @attributes should be a set of key and value string pairs.
1346 * If @service is NULL, then secret_service_get() will be called to get
1347 * the default #SecretService proxy.
1349 * This method will return immediately and complete asynchronously.
1352 secret_service_lookup (SecretService *service,
1353 const SecretSchema *schema,
1354 GHashTable *attributes,
1355 GCancellable *cancellable,
1356 GAsyncReadyCallback callback,
1359 const gchar *schema_name = NULL;
1360 GSimpleAsyncResult *res;
1361 LookupClosure *closure;
1363 g_return_if_fail (service == NULL || SECRET_IS_SERVICE (service));
1364 g_return_if_fail (attributes != NULL);
1365 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1367 /* Warnings raised already */
1368 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
1371 if (schema != NULL && !(schema->flags & SECRET_SCHEMA_DONT_MATCH_NAME))
1372 schema_name = schema->name;
1374 res = g_simple_async_result_new (G_OBJECT (service), callback, user_data,
1375 secret_service_lookup);
1376 closure = g_slice_new0 (LookupClosure);
1377 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1378 closure->attributes = _secret_attributes_to_variant (attributes, schema_name);
1379 g_variant_ref_sink (closure->attributes);
1380 g_simple_async_result_set_op_res_gpointer (res, closure, lookup_closure_free);
1382 if (service == NULL) {
1383 secret_service_get (SECRET_SERVICE_OPEN_SESSION, cancellable,
1384 on_lookup_service, g_object_ref (res));
1386 _secret_service_search_for_paths_variant (service, closure->attributes,
1387 closure->cancellable,
1388 on_lookup_searched, g_object_ref (res));
1391 g_object_unref (res);
1395 * secret_service_lookup_finish:
1396 * @service: (allow-none): the secret service
1397 * @result: the asynchronous result passed to the callback
1398 * @error: location to place an error on failure
1400 * Finish asynchronous operation to lookup a secret value in the secret service.
1402 * If no secret is found then %NULL is returned.
1404 * Returns: (transfer full): a newly allocated #SecretValue, which should be
1405 * released with secret_value_unref(), or %NULL if no secret found
1408 secret_service_lookup_finish (SecretService *service,
1409 GAsyncResult *result,
1412 GSimpleAsyncResult *res;
1413 LookupClosure *closure;
1416 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), NULL);
1417 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1418 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (service),
1419 secret_service_lookup), NULL);
1421 res = G_SIMPLE_ASYNC_RESULT (result);
1422 if (g_simple_async_result_propagate_error (res, error))
1425 closure = g_simple_async_result_get_op_res_gpointer (res);
1426 value = closure->value;
1427 closure->value = NULL;
1432 * secret_service_lookup_sync:
1433 * @service: (allow-none): the secret service
1434 * @schema: (allow-none): the schema for the attributes
1435 * @attributes: (element-type utf8 utf8): the attribute keys and values
1436 * @cancellable: optional cancellation object
1437 * @error: location to place an error on failure
1439 * Lookup a secret value in the secret service.
1441 * The @attributes should be a set of key and value string pairs.
1443 * If @service is NULL, then secret_service_get_sync() will be called to get
1444 * the default #SecretService proxy.
1446 * This method may block indefinitely and should not be used in user interface
1449 * Returns: (transfer full): a newly allocated #SecretValue, which should be
1450 * released with secret_value_unref(), or %NULL if no secret found
1453 secret_service_lookup_sync (SecretService *service,
1454 const SecretSchema *schema,
1455 GHashTable *attributes,
1456 GCancellable *cancellable,
1462 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), NULL);
1463 g_return_val_if_fail (attributes != NULL, NULL);
1464 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
1466 /* Warnings raised already */
1467 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
1470 sync = _secret_sync_new ();
1471 g_main_context_push_thread_default (sync->context);
1473 secret_service_lookup (service, schema, attributes, cancellable,
1474 _secret_sync_on_result, sync);
1476 g_main_loop_run (sync->loop);
1478 value = secret_service_lookup_finish (service, sync->result, error);
1480 g_main_context_pop_thread_default (sync->context);
1481 _secret_sync_free (sync);
1487 GCancellable *cancellable;
1488 SecretService *service;
1489 GVariant *attributes;
1495 delete_closure_free (gpointer data)
1497 DeleteClosure *closure = data;
1498 if (closure->service)
1499 g_object_unref (closure->service);
1500 g_variant_unref (closure->attributes);
1501 g_clear_object (&closure->cancellable);
1502 g_slice_free (DeleteClosure, closure);
1506 on_delete_password_complete (GObject *source,
1507 GAsyncResult *result,
1510 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
1511 DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
1512 GError *error = NULL;
1515 closure->deleting--;
1517 deleted = _secret_service_delete_path_finish (SECRET_SERVICE (source), result, &error);
1519 g_simple_async_result_take_error (res, error);
1523 if (closure->deleting <= 0)
1524 g_simple_async_result_complete (res);
1526 g_object_unref (res);
1530 on_delete_searched (GObject *source,
1531 GAsyncResult *result,
1534 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
1535 DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
1536 GError *error = NULL;
1537 gchar **unlocked = NULL;
1540 secret_service_search_for_dbus_paths_finish (SECRET_SERVICE (source), result, &unlocked, NULL, &error);
1541 if (error == NULL) {
1542 for (i = 0; unlocked[i] != NULL; i++) {
1543 _secret_service_delete_path (closure->service, unlocked[i], TRUE,
1544 closure->cancellable,
1545 on_delete_password_complete,
1546 g_object_ref (res));
1547 closure->deleting++;
1550 if (closure->deleting == 0)
1551 g_simple_async_result_complete (res);
1553 g_simple_async_result_take_error (res, error);
1554 g_simple_async_result_complete (res);
1557 g_strfreev (unlocked);
1558 g_object_unref (res);
1562 on_delete_service (GObject *source,
1563 GAsyncResult *result,
1566 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
1567 DeleteClosure *closure = g_simple_async_result_get_op_res_gpointer (async);
1568 GError *error = NULL;
1570 closure->service = secret_service_get_finish (result, &error);
1571 if (error == NULL) {
1572 _secret_service_search_for_paths_variant (closure->service, closure->attributes,
1573 closure->cancellable,
1574 on_delete_searched, g_object_ref (async));
1577 g_simple_async_result_take_error (async, error);
1578 g_simple_async_result_complete (async);
1581 g_object_unref (async);
1585 * secret_service_remove:
1586 * @service: (allow-none): the secret service
1587 * @schema: (allow-none): the schema for the attributes
1588 * @attributes: (element-type utf8 utf8): the attribute keys and values
1589 * @cancellable: optional cancellation object
1590 * @callback: called when the operation completes
1591 * @user_data: data to be passed to the callback
1593 * Remove a secret value from the secret service.
1595 * The @attributes should be a set of key and value string pairs.
1597 * If multiple items match the attributes, then only one will be deleted.
1599 * If @service is NULL, then secret_service_get() will be called to get
1600 * the default #SecretService proxy.
1602 * This method will return immediately and complete asynchronously.
1605 secret_service_remove (SecretService *service,
1606 const SecretSchema *schema,
1607 GHashTable *attributes,
1608 GCancellable *cancellable,
1609 GAsyncReadyCallback callback,
1612 const gchar *schema_name = NULL;
1613 GSimpleAsyncResult *res;
1614 DeleteClosure *closure;
1616 g_return_if_fail (service == NULL || SECRET_SERVICE (service));
1617 g_return_if_fail (attributes != NULL);
1618 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1620 /* Warnings raised already */
1621 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
1624 if (schema != NULL && !(schema->flags & SECRET_SCHEMA_DONT_MATCH_NAME))
1625 schema_name = schema->name;
1627 res = g_simple_async_result_new (G_OBJECT (service), callback, user_data,
1628 secret_service_remove);
1629 closure = g_slice_new0 (DeleteClosure);
1630 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1631 closure->attributes = _secret_attributes_to_variant (attributes, schema_name);
1632 g_variant_ref_sink (closure->attributes);
1633 g_simple_async_result_set_op_res_gpointer (res, closure, delete_closure_free);
1635 /* A double check to make sure we don't delete everything, should have been checked earlier */
1636 g_assert (g_variant_n_children (closure->attributes) > 0);
1638 if (service == NULL) {
1639 secret_service_get (SECRET_SERVICE_NONE, cancellable,
1640 on_delete_service, g_object_ref (res));
1642 closure->service = g_object_ref (service);
1643 _secret_service_search_for_paths_variant (closure->service, closure->attributes,
1644 closure->cancellable,
1645 on_delete_searched, g_object_ref (res));
1648 g_object_unref (res);
1652 * secret_service_remove_finish:
1653 * @service: (allow-none): the secret service
1654 * @result: the asynchronous result passed to the callback
1655 * @error: location to place an error on failure
1657 * Finish asynchronous operation to remove a secret value from the secret
1660 * Returns: whether the removal was successful or not
1663 secret_service_remove_finish (SecretService *service,
1664 GAsyncResult *result,
1667 GSimpleAsyncResult *res;
1668 DeleteClosure *closure;
1670 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), FALSE);
1671 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1672 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (service),
1673 secret_service_remove), FALSE);
1675 res = G_SIMPLE_ASYNC_RESULT (result);
1676 if (g_simple_async_result_propagate_error (res, error))
1679 closure = g_simple_async_result_get_op_res_gpointer (res);
1680 return closure->deleted > 0;
1684 * secret_service_remove_sync:
1685 * @service: (allow-none): the secret service
1686 * @schema: (allow-none): the schema for the attributes
1687 * @attributes: (element-type utf8 utf8): the attribute keys and values
1688 * @cancellable: optional cancellation object
1689 * @error: location to place an error on failure
1691 * Remove a secret value from the secret service.
1693 * The @attributes should be a set of key and value string pairs.
1695 * If multiple items match the attributes, then only one will be deleted.
1697 * If @service is NULL, then secret_service_get_sync() will be called to get
1698 * the default #SecretService proxy.
1700 * This method may block indefinitely and should not be used in user interface
1703 * Returns: whether the removal was successful or not
1706 secret_service_remove_sync (SecretService *service,
1707 const SecretSchema *schema,
1708 GHashTable *attributes,
1709 GCancellable *cancellable,
1715 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), FALSE);
1716 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1717 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1719 /* Warnings raised already */
1720 if (schema != NULL && !_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
1723 sync = _secret_sync_new ();
1724 g_main_context_push_thread_default (sync->context);
1726 secret_service_remove (service, schema, attributes, cancellable,
1727 _secret_sync_on_result, sync);
1729 g_main_loop_run (sync->loop);
1731 result = secret_service_remove_finish (service, sync->result, error);
1733 g_main_context_pop_thread_default (sync->context);
1734 _secret_sync_free (sync);
1740 GCancellable *cancellable;
1742 gchar *collection_path;
1746 set_closure_free (gpointer data)
1748 SetClosure *set = data;
1749 if (set->cancellable)
1750 g_object_unref (set->cancellable);
1751 g_free (set->alias);
1752 g_free (set->collection_path);
1753 g_slice_free (SetClosure, set);
1757 on_set_alias_done (GObject *source,
1758 GAsyncResult *result,
1761 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
1762 GError *error = NULL;
1764 secret_service_set_alias_to_dbus_path_finish (SECRET_SERVICE (source), result, &error);
1766 g_simple_async_result_take_error (async, error);
1768 g_simple_async_result_complete (async);
1769 g_object_unref (async);
1773 on_set_alias_service (GObject *source,
1774 GAsyncResult *result,
1777 GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
1778 SetClosure *set = g_simple_async_result_get_op_res_gpointer (async);
1779 SecretService *service;
1780 GError *error = NULL;
1782 service = secret_service_get_finish (result, &error);
1783 if (error == NULL) {
1784 secret_service_set_alias_to_dbus_path (service, set->alias,
1785 set->collection_path,
1788 g_object_ref (async));
1789 g_object_unref (service);
1792 g_simple_async_result_take_error (async, error);
1793 g_simple_async_result_complete (async);
1796 g_object_unref (async);
1800 * secret_service_set_alias:
1801 * @service: (allow-none): a secret service object
1802 * @alias: the alias to assign the collection to
1803 * @collection: (allow-none): the collection to assign to the alias
1804 * @cancellable: (allow-none): optional cancellation object
1805 * @callback: called when the operation completes
1806 * @user_data: data to pass to the callback
1808 * Assign a collection to this alias. Aliases help determine
1809 * well known collections, such as 'default'.
1811 * If @service is NULL, then secret_service_get() will be called to get
1812 * the default #SecretService proxy.
1814 * This method will return immediately and complete asynchronously.
1817 secret_service_set_alias (SecretService *service,
1819 SecretCollection *collection,
1820 GCancellable *cancellable,
1821 GAsyncReadyCallback callback,
1824 GSimpleAsyncResult *async;
1828 g_return_if_fail (service == NULL || SECRET_IS_SERVICE (service));
1829 g_return_if_fail (alias != NULL);
1830 g_return_if_fail (collection == NULL || SECRET_IS_COLLECTION (collection));
1831 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1833 async = g_simple_async_result_new (G_OBJECT (service), callback, user_data,
1834 secret_service_set_alias);
1835 set = g_slice_new0 (SetClosure);
1836 set->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1837 set->alias = g_strdup (alias);
1840 path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection));
1841 g_return_if_fail (path != NULL);
1846 set->collection_path = g_strdup (path);
1847 g_simple_async_result_set_op_res_gpointer (async, set, set_closure_free);
1849 if (service == NULL) {
1850 secret_service_get (SECRET_SERVICE_NONE, cancellable,
1851 on_set_alias_service, g_object_ref (async));
1853 secret_service_set_alias_to_dbus_path (service, set->alias,
1854 set->collection_path,
1857 g_object_ref (async));
1860 g_object_unref (async);
1864 * secret_service_set_alias_finish:
1865 * @service: (allow-none): a secret service object
1866 * @result: asynchronous result passed to callback
1867 * @error: location to place error on failure
1869 * Finish an asynchronous operation to assign a collection to an alias.
1871 * Returns: %TRUE if successful
1874 secret_service_set_alias_finish (SecretService *service,
1875 GAsyncResult *result,
1878 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), FALSE);
1879 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (service),
1880 secret_service_set_alias), FALSE);
1881 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1883 if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
1890 * secret_service_set_alias_sync:
1891 * @service: (allow-none): a secret service object
1892 * @alias: the alias to assign the collection to
1893 * @collection: (allow-none): the collection to assign to the alias
1894 * @cancellable: (allow-none): optional cancellation object
1895 * @error: location to place error on failure
1897 * Assign a collection to this alias. Aliases help determine
1898 * well known collections, such as 'default'.
1900 * If @service is NULL, then secret_service_get_sync() will be called to get
1901 * the default #SecretService proxy.
1903 * This method may block and should not be used in user interface threads.
1905 * Returns: %TRUE if successful
1908 secret_service_set_alias_sync (SecretService *service,
1910 SecretCollection *collection,
1911 GCancellable *cancellable,
1917 g_return_val_if_fail (service == NULL || SECRET_IS_SERVICE (service), FALSE);
1918 g_return_val_if_fail (alias != NULL, FALSE);
1919 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1920 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1922 sync = _secret_sync_new ();
1923 g_main_context_push_thread_default (sync->context);
1925 secret_service_set_alias (service, alias, collection, cancellable,
1926 _secret_sync_on_result, sync);
1928 g_main_loop_run (sync->loop);
1930 ret = secret_service_set_alias_finish (service, sync->result, error);
1932 g_main_context_pop_thread_default (sync->context);
1933 _secret_sync_free (sync);