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-enum-types.h"
21 #include "secret-item.h"
22 #include "secret-paths.h"
23 #include "secret-private.h"
24 #include "secret-service.h"
25 #include "secret-types.h"
26 #include "secret-value.h"
28 #include "egg/egg-secure-memory.h"
31 * SECTION:secret-service
32 * @title: SecretService
33 * @short_description: the Secret Service
35 * A #SecretService object represents the Secret Service implementation which
36 * runs as a D-Bus service.
38 * Normally a single #SecretService object can be shared between multiple
39 * callers. The secret_service_get() method is used to access this #SecretService
40 * object. If a new independent #SecretService object is required, use
41 * secret_service_open().
43 * In order to securely transfer secrets to the Sercret Service, an session
44 * is established. This session can be established while initializing a
45 * #SecretService object by passing the %SECRET_SERVICE_OPEN_SESSION flag
46 * to the secret_service_get() or secret_service_open() functions. In order to
47 * establish a session on an already existing #SecretService, use the
48 * secret_service_ensure_session() function.
50 * To search for items, use the secret_service_search() method.
52 * Multiple collections can exist in the Secret Service, each of which contains
53 * secret items. In order to instantiate #SecretCollection objects which
54 * represent those collections while initializing a #SecretService then pass
55 * the %SECRET_SERVICE_LOAD_COLLECTIONS flag to the secret_service_get() or
56 * secret_service_open() functions. In order to establish a session on an already
57 * existing #SecretService, use the secret_service_load_collections() function.
58 * To access the list of collections use secret_service_get_collections().
60 * Certain actions on the Secret Service require user prompting to complete,
61 * such as creating a collection, or unlocking a collection. When such a prompt
62 * is necessary, then a #SecretPrompt object is created by this library, and
63 * passed to the secret_service_prompt() method. In this way it is handled
66 * In order to customize prompt handling, override the <literal>prompt_async</literal>
67 * and <literal>prompt_finish</literal> virtual methods of the #SecretService class.
69 * These functions have an unstable API and may change across versions. Use
70 * <literal>libsecret-unstable</literal> package to access them.
78 * A proxy object representing the Secret Service.
83 * @parent_class: the parent class
84 * @collection_gtype: the #GType of the #SecretCollection objects instantiated
85 * by the #SecretService proxy
86 * @item_gtype: the #GType of the #SecretItem objects instantiated by the
87 * #SecretService proxy
88 * @prompt_async: called to perform asynchronous prompting when necessary
89 * @prompt_finish: called to complete an asynchronous prompt operation
90 * @prompt_sync: called to perform synchronous prompting when necessary
91 * @get_collection_gtype: called to get the GObject type for collections
92 * instantiated by the #SecretService proxy
93 * @get_item_gtype: called to get the GObject type for collections
94 * instantiated by the #SecretService proxy
96 * The class for #SecretService.
100 * SecretServiceFlags:
101 * @SECRET_SERVICE_NONE: no flags for initializing the #SecretService
102 * @SECRET_SERVICE_OPEN_SESSION: establish a session for transfer of secrets
103 * while initializing the #SecretService
104 * @SECRET_SERVICE_LOAD_COLLECTIONS: load collections while initializing the
107 * Flags which determine which parts of the #SecretService proxy are initialized
108 * during a secret_service_get() or secret_service_open() operation.
111 EGG_SECURE_DEFINE_GLIB_GLOBALS ();
113 GQuark _secret_error_quark = 0;
121 struct _SecretServicePrivate {
122 /* No change between construct and finalize */
123 GCancellable *cancellable;
124 SecretServiceFlags init_flags;
126 /* Locked by mutex */
129 GHashTable *collections;
132 G_LOCK_DEFINE (service_instance);
133 static gpointer service_instance = NULL;
134 static guint service_watch = 0;
136 static GInitableIface *secret_service_initable_parent_iface = NULL;
138 static GAsyncInitableIface *secret_service_async_initable_parent_iface = NULL;
140 static void secret_service_initable_iface (GInitableIface *iface);
142 static void secret_service_async_initable_iface (GAsyncInitableIface *iface);
144 G_DEFINE_TYPE_WITH_CODE (SecretService, secret_service, G_TYPE_DBUS_PROXY,
145 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, secret_service_initable_iface);
146 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, secret_service_async_initable_iface);
149 static SecretService *
150 service_get_instance (void)
152 SecretService *instance = NULL;
154 G_LOCK (service_instance);
155 if (service_instance != NULL)
156 instance = g_object_ref (service_instance);
157 G_UNLOCK (service_instance);
163 service_uncache_instance (SecretService *which)
165 SecretService *instance = NULL;
167 gboolean matched = FALSE;
169 G_LOCK (service_instance);
170 if (which == NULL || service_instance == which) {
171 instance = service_instance;
172 service_instance = NULL;
173 watch = service_watch;
177 G_UNLOCK (service_instance);
179 if (instance != NULL)
180 g_object_unref (instance);
182 g_bus_unwatch_name (watch);
188 on_service_instance_vanished (GDBusConnection *connection,
192 if (!service_uncache_instance (user_data)) {
193 g_warning ("Global default SecretService instance out of sync "
194 "with the watch for its DBus name");
199 service_cache_instance (SecretService *instance)
204 g_object_ref (instance);
205 proxy = G_DBUS_PROXY (instance);
206 watch = g_bus_watch_name_on_connection (g_dbus_proxy_get_connection (proxy),
207 g_dbus_proxy_get_name (proxy),
208 G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
209 NULL, on_service_instance_vanished,
212 G_LOCK (service_instance);
213 if (service_instance == NULL) {
214 service_instance = instance;
216 service_watch = watch;
219 G_UNLOCK (service_instance);
221 if (instance != NULL)
222 g_object_unref (instance);
224 g_bus_unwatch_name (watch);
228 secret_service_init (SecretService *self)
230 self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SECRET_TYPE_SERVICE,
231 SecretServicePrivate);
233 g_mutex_init (&self->pv->mutex);
234 self->pv->cancellable = g_cancellable_new ();
238 secret_service_get_property (GObject *obj,
243 SecretService *self = SECRET_SERVICE (obj);
247 g_value_set_flags (value, secret_service_get_flags (self));
249 case PROP_COLLECTIONS:
250 g_value_take_boxed (value, secret_service_get_collections (self));
253 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
259 secret_service_set_property (GObject *obj,
264 SecretService *self = SECRET_SERVICE (obj);
268 self->pv->init_flags = g_value_get_flags (value);
271 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
277 secret_service_dispose (GObject *obj)
279 SecretService *self = SECRET_SERVICE (obj);
281 g_cancellable_cancel (self->pv->cancellable);
283 G_OBJECT_CLASS (secret_service_parent_class)->dispose (obj);
287 secret_service_finalize (GObject *obj)
289 SecretService *self = SECRET_SERVICE (obj);
291 _secret_session_free (self->pv->session);
292 if (self->pv->collections)
293 g_hash_table_destroy (self->pv->collections);
294 g_clear_object (&self->pv->cancellable);
295 g_mutex_clear (&self->pv->mutex);
297 G_OBJECT_CLASS (secret_service_parent_class)->finalize (obj);
301 secret_service_real_prompt_sync (SecretService *self,
302 SecretPrompt *prompt,
303 GCancellable *cancellable,
304 const GVariantType *return_type,
307 return secret_prompt_perform_sync (prompt, 0, cancellable, return_type, error);
311 on_real_prompt_completed (GObject *source,
312 GAsyncResult *result,
315 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
316 GError *error = NULL;
319 retval = secret_prompt_perform_finish (SECRET_PROMPT (source), result, &error);
321 g_simple_async_result_set_op_res_gpointer (res, retval, (GDestroyNotify)g_variant_unref);
323 g_simple_async_result_take_error (res, error);
324 g_simple_async_result_complete (res);
325 g_object_unref (res);
329 secret_service_real_prompt_async (SecretService *self,
330 SecretPrompt *prompt,
331 const GVariantType *return_type,
332 GCancellable *cancellable,
333 GAsyncReadyCallback callback,
336 GSimpleAsyncResult *res;
338 res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
339 secret_service_real_prompt_async);
341 secret_prompt_perform (prompt, 0, return_type, cancellable,
342 on_real_prompt_completed,
345 g_object_unref (res);
349 secret_service_real_prompt_finish (SecretService *self,
350 GAsyncResult *result,
353 GSimpleAsyncResult *res;
356 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
357 secret_service_real_prompt_async), NULL);
359 res = G_SIMPLE_ASYNC_RESULT (result);
360 if (_secret_util_propagate_error (res, error))
363 retval = g_simple_async_result_get_op_res_gpointer (res);
367 return g_variant_ref (retval);
371 handle_property_changed (SecretService *self,
372 const gchar *property_name,
377 g_variant_ref_sink (value);
379 if (g_str_equal (property_name, "Collections")) {
381 g_mutex_lock (&self->pv->mutex);
382 perform = self->pv->collections != NULL;
383 g_mutex_unlock (&self->pv->mutex);
386 secret_service_load_collections (self, self->pv->cancellable, NULL, NULL);
389 g_variant_unref (value);
393 secret_service_properties_changed (GDBusProxy *proxy,
394 GVariant *changed_properties,
395 const gchar* const *invalidated_properties)
397 SecretService *self = SECRET_SERVICE (proxy);
398 gchar *property_name;
402 g_object_freeze_notify (G_OBJECT (self));
404 g_variant_iter_init (&iter, changed_properties);
405 while (g_variant_iter_loop (&iter, "{sv}", &property_name, &value))
406 handle_property_changed (self, property_name, value);
408 g_object_thaw_notify (G_OBJECT (self));
412 secret_service_signal (GDBusProxy *proxy,
413 const gchar *sender_name,
414 const gchar *signal_name,
415 GVariant *parameters)
417 SecretService *self = SECRET_SERVICE (proxy);
418 SecretCollection *collection;
419 const gchar *collection_path;
420 GVariantBuilder builder;
421 gboolean found = FALSE;
428 * Remember that these signals come from a time before PropertiesChanged.
429 * We support them because they're in the spec, and ksecretservice uses them.
432 paths = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Collections");
434 /* A new collection was added, add it to the Collections property */
435 if (g_str_equal (signal_name, SECRET_SIGNAL_COLLECTION_CREATED)) {
436 g_variant_get (parameters, "(@o)", &value);
437 g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
438 g_variant_iter_init (&iter, paths);
439 while ((path = g_variant_iter_next_value (&iter)) != NULL) {
440 if (g_variant_equal (path, value)) {
444 g_variant_builder_add_value (&builder, path);
445 g_variant_unref (path);
448 g_variant_builder_add_value (&builder, value);
449 handle_property_changed (self, "Collections", g_variant_builder_end (&builder));
451 g_variant_builder_clear (&builder);
452 g_variant_unref (value);
454 /* A collection was deleted, remove it from the Collections property */
455 } else if (g_str_equal (signal_name, SECRET_SIGNAL_COLLECTION_DELETED)) {
456 g_variant_get (parameters, "(@o)", &value);
457 g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
458 g_variant_iter_init (&iter, paths);
459 while ((path = g_variant_iter_next_value (&iter)) != NULL) {
460 if (g_variant_equal (path, value))
463 g_variant_builder_add_value (&builder, path);
464 g_variant_unref (path);
467 handle_property_changed (self, "Collections", g_variant_builder_end (&builder));
468 g_variant_unref (value);
470 /* The collection changed, update it */
471 } else if (g_str_equal (signal_name, SECRET_SIGNAL_COLLECTION_CHANGED)) {
472 g_variant_get (parameters, "(&o)", &collection_path);
474 g_mutex_lock (&self->pv->mutex);
476 if (self->pv->collections)
477 collection = g_hash_table_lookup (self->pv->collections, collection_path);
481 g_object_ref (collection);
483 g_mutex_unlock (&self->pv->mutex);
486 secret_collection_refresh (collection);
487 g_object_unref (collection);
491 g_variant_unref (paths);
495 secret_service_real_get_collection_gtype (SecretService *self)
497 SecretServiceClass *klass;
499 klass = SECRET_SERVICE_GET_CLASS (self);
500 return klass->collection_gtype;
504 secret_service_real_get_item_gtype (SecretService *self)
506 SecretServiceClass *klass;
508 klass = SECRET_SERVICE_GET_CLASS (self);
509 return klass->item_gtype;
513 secret_service_class_init (SecretServiceClass *klass)
515 GObjectClass *object_class = G_OBJECT_CLASS (klass);
516 GDBusProxyClass *proxy_class = G_DBUS_PROXY_CLASS (klass);
518 object_class->get_property = secret_service_get_property;
519 object_class->set_property = secret_service_set_property;
520 object_class->dispose = secret_service_dispose;
521 object_class->finalize = secret_service_finalize;
523 proxy_class->g_properties_changed = secret_service_properties_changed;
524 proxy_class->g_signal = secret_service_signal;
526 klass->prompt_sync = secret_service_real_prompt_sync;
527 klass->prompt_async = secret_service_real_prompt_async;
528 klass->prompt_finish = secret_service_real_prompt_finish;
530 klass->item_gtype = SECRET_TYPE_ITEM;
531 klass->collection_gtype = SECRET_TYPE_COLLECTION;
532 klass->get_item_gtype = secret_service_real_get_item_gtype;
533 klass->get_collection_gtype = secret_service_real_get_collection_gtype;
536 * SecretService:flags:
538 * A set of flags describing which parts of the secret service have
541 g_object_class_install_property (object_class, PROP_FLAGS,
542 g_param_spec_flags ("flags", "Flags", "Service flags",
543 secret_service_flags_get_type (), SECRET_SERVICE_NONE,
544 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
547 * SecretService:collections:
549 * A list of #SecretCollection objects representing the collections in
550 * the Secret Service. This list may be %NULL if the collections have
553 * To load the collections, specify the %SECRET_SERVICE_LOAD_COLLECTIONS
554 * initialization flag when calling the secret_service_get() or
555 * secret_service_open() functions. Or call the secret_service_load_collections()
558 g_object_class_install_property (object_class, PROP_COLLECTIONS,
559 g_param_spec_boxed ("collections", "Collections", "Secret Service Collections",
560 _secret_list_get_type (), G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
562 g_type_class_add_private (klass, sizeof (SecretServicePrivate));
564 /* Initialize this error domain, registers dbus errors */
565 _secret_error_quark = secret_error_get_quark ();
569 GCancellable *cancellable;
570 SecretServiceFlags flags;
574 init_closure_free (gpointer data)
576 InitClosure *closure = data;
577 g_clear_object (&closure->cancellable);
578 g_slice_free (InitClosure, closure);
582 service_ensure_for_flags_sync (SecretService *self,
583 SecretServiceFlags flags,
584 GCancellable *cancellable,
587 if (flags & SECRET_SERVICE_OPEN_SESSION)
588 if (!secret_service_ensure_session_sync (self, cancellable, error))
591 if (flags & SECRET_SERVICE_LOAD_COLLECTIONS)
592 if (!secret_service_load_collections_sync (self, cancellable, error))
599 on_load_collections (GObject *source,
600 GAsyncResult *result,
603 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
604 SecretService *self = SECRET_SERVICE (source);
605 GError *error = NULL;
607 if (!secret_service_load_collections_finish (self, result, &error))
608 g_simple_async_result_take_error (res, error);
610 g_simple_async_result_complete (res);
611 g_object_unref (res);
615 on_ensure_session (GObject *source,
616 GAsyncResult *result,
619 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
620 InitClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
621 SecretService *self = SECRET_SERVICE (source);
622 GError *error = NULL;
624 if (!secret_service_ensure_session_finish (self, result, &error)) {
625 g_simple_async_result_take_error (res, error);
626 g_simple_async_result_complete (res);
628 } else if (closure->flags & SECRET_SERVICE_LOAD_COLLECTIONS) {
629 secret_service_load_collections (self, closure->cancellable,
630 on_load_collections, g_object_ref (res));
633 g_simple_async_result_complete_in_idle (res);
636 g_object_unref (res);
640 service_ensure_for_flags_async (SecretService *self,
641 SecretServiceFlags flags,
642 GSimpleAsyncResult *res)
644 InitClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
646 closure->flags = flags;
648 if (closure->flags & SECRET_SERVICE_OPEN_SESSION)
649 secret_service_ensure_session (self, closure->cancellable,
650 on_ensure_session, g_object_ref (res));
652 else if (closure->flags & SECRET_SERVICE_LOAD_COLLECTIONS)
653 secret_service_load_collections (self, closure->cancellable,
654 on_load_collections, g_object_ref (res));
657 g_simple_async_result_complete_in_idle (res);
661 secret_service_initable_init (GInitable *initable,
662 GCancellable *cancellable,
667 if (!secret_service_initable_parent_iface->init (initable, cancellable, error))
670 self = SECRET_SERVICE (initable);
671 return service_ensure_for_flags_sync (self, self->pv->init_flags, cancellable, error);
675 secret_service_initable_iface (GInitableIface *iface)
677 secret_service_initable_parent_iface = g_type_interface_peek_parent (iface);
679 iface->init = secret_service_initable_init;
683 on_init_base (GObject *source,
684 GAsyncResult *result,
687 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
688 SecretService *self = SECRET_SERVICE (source);
689 GError *error = NULL;
691 if (!secret_service_async_initable_parent_iface->init_finish (G_ASYNC_INITABLE (self),
693 g_simple_async_result_take_error (res, error);
694 g_simple_async_result_complete (res);
696 service_ensure_for_flags_async (self, self->pv->init_flags, res);
699 g_object_unref (res);
703 secret_service_async_initable_init_async (GAsyncInitable *initable,
705 GCancellable *cancellable,
706 GAsyncReadyCallback callback,
709 GSimpleAsyncResult *res;
710 InitClosure *closure;
712 res = g_simple_async_result_new (G_OBJECT (initable), callback, user_data,
713 secret_service_async_initable_init_async);
714 closure = g_slice_new0 (InitClosure);
715 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
716 g_simple_async_result_set_op_res_gpointer (res, closure, init_closure_free);
718 secret_service_async_initable_parent_iface->init_async (initable, io_priority,
723 g_object_unref (res);
727 secret_service_async_initable_init_finish (GAsyncInitable *initable,
728 GAsyncResult *result,
731 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (initable),
732 secret_service_async_initable_init_async), FALSE);
734 if (_secret_util_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
741 secret_service_async_initable_iface (GAsyncInitableIface *iface)
743 secret_service_async_initable_parent_iface = g_type_interface_peek_parent (iface);
745 iface->init_async = secret_service_async_initable_init_async;
746 iface->init_finish = secret_service_async_initable_init_finish;
750 get_default_bus_name (void)
752 const gchar *bus_name;
754 bus_name = g_getenv ("SECRET_SERVICE_BUS_NAME");
755 if (bus_name == NULL)
756 bus_name = SECRET_SERVICE_BUS_NAME;
762 * secret_service_get:
763 * @flags: flags for which service functionality to ensure is initialized
764 * @cancellable: optional cancellation object
765 * @callback: called when the operation completes
766 * @user_data: data to be passed to the callback
768 * Get a #SecretService proxy for the Secret Service. If such a proxy object
769 * already exists, then the same proxy is returned.
771 * If @flags contains any flags of which parts of the secret service to
772 * ensure are initialized, then those will be initialized before completing.
774 * This method will return immediately and complete asynchronously.
777 secret_service_get (SecretServiceFlags flags,
778 GCancellable *cancellable,
779 GAsyncReadyCallback callback,
782 SecretService *service = NULL;
783 GSimpleAsyncResult *res;
784 InitClosure *closure;
786 service = service_get_instance ();
788 /* Create a whole new service */
789 if (service == NULL) {
790 g_async_initable_new_async (SECRET_TYPE_SERVICE, G_PRIORITY_DEFAULT,
791 cancellable, callback, user_data,
792 "g-flags", G_DBUS_PROXY_FLAGS_NONE,
793 "g-interface-info", _secret_gen_service_interface_info (),
794 "g-name", get_default_bus_name (),
795 "g-bus-type", G_BUS_TYPE_SESSION,
796 "g-object-path", SECRET_SERVICE_PATH,
797 "g-interface-name", SECRET_SERVICE_INTERFACE,
801 /* Just have to ensure that the service matches flags */
803 res = g_simple_async_result_new (G_OBJECT (service), callback,
804 user_data, secret_service_get);
805 closure = g_slice_new0 (InitClosure);
806 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
807 closure->flags = flags;
808 g_simple_async_result_set_op_res_gpointer (res, closure, init_closure_free);
810 service_ensure_for_flags_async (service, flags, res);
812 g_object_unref (service);
813 g_object_unref (res);
818 * secret_service_get_finish:
819 * @result: the asynchronous result passed to the callback
820 * @error: location to place an error on failure
822 * Complete an asynchronous operation to get a #SecretService proxy for the
825 * Returns: (transfer full): a new reference to a #SecretService proxy, which
826 * should be released with g_object_unref().
829 secret_service_get_finish (GAsyncResult *result,
832 GObject *service = NULL;
833 GObject *source_object;
835 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
836 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
838 source_object = g_async_result_get_source_object (result);
840 /* Just ensuring that the service matches flags */
841 if (g_simple_async_result_is_valid (result, source_object, secret_service_get)) {
842 if (!_secret_util_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
843 service = g_object_ref (source_object);
845 /* Creating a whole new service */
847 service = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), result, error);
849 service_cache_instance (SECRET_SERVICE (service));
853 g_object_unref (source_object);
858 return SECRET_SERVICE (service);
862 * secret_service_get_sync:
863 * @flags: flags for which service functionality to ensure is initialized
864 * @cancellable: optional cancellation object
865 * @error: location to place an error on failure
867 * Get a #SecretService proxy for the Secret Service. If such a proxy object
868 * already exists, then the same proxy is returned.
870 * If @flags contains any flags of which parts of the secret service to
871 * ensure are initialized, then those will be initialized before returning.
873 * This method may block indefinitely and should not be used in user interface
876 * Returns: (transfer full): a new reference to a #SecretService proxy, which
877 * should be released with g_object_unref().
880 secret_service_get_sync (SecretServiceFlags flags,
881 GCancellable *cancellable,
884 SecretService *service = NULL;
886 service = service_get_instance ();
888 if (service == NULL) {
889 service = g_initable_new (SECRET_TYPE_SERVICE, cancellable, error,
890 "g-flags", G_DBUS_PROXY_FLAGS_NONE,
891 "g-interface-info", _secret_gen_service_interface_info (),
892 "g-name", get_default_bus_name (),
893 "g-bus-type", G_BUS_TYPE_SESSION,
894 "g-object-path", SECRET_SERVICE_PATH,
895 "g-interface-name", SECRET_SERVICE_INTERFACE,
900 service_cache_instance (service);
903 if (!service_ensure_for_flags_sync (service, flags, cancellable, error)) {
904 g_object_unref (service);
913 * secret_service_disconnect:
915 * Disconnect the default #SecretService proxy returned by secret_service_get()
916 * and secret_service_get_sync().
918 * It is not necessary to call this function, but you may choose to do so at
919 * program exit. It is useful for testing that memory is not leaked.
921 * This function is safe to call at any time. But if other objects in this
922 * library are still referenced, then this will not result in all memory
926 secret_service_disconnect (void)
928 service_uncache_instance (NULL);
932 * secret_service_open:
933 * @service_gtype: the GType of the new secret service
934 * @service_bus_name: (allow-none): the D-Bus service name of the secret service
935 * @flags: flags for which service functionality to ensure is initialized
936 * @cancellable: optional cancellation object
937 * @callback: called when the operation completes
938 * @user_data: data to be passed to the callback
940 * Create a new #SecretService proxy for the Secret Service.
942 * This function is rarely used, see secret_service_get() instead.
944 * The @service_gtype argument should be set to %SECRET_TYPE_SERVICE or a the type
945 * of a derived class.
947 * If @flags contains any flags of which parts of the secret service to
948 * ensure are initialized, then those will be initialized before returning.
950 * If @service_bus_name is %NULL then the default is used.
952 * This method will return immediately and complete asynchronously.
955 secret_service_open (GType service_gtype,
956 const gchar *service_bus_name,
957 SecretServiceFlags flags,
958 GCancellable *cancellable,
959 GAsyncReadyCallback callback,
962 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
963 g_return_if_fail (g_type_is_a (service_gtype, SECRET_TYPE_SERVICE));
965 if (service_bus_name == NULL)
966 service_bus_name = get_default_bus_name ();
968 g_async_initable_new_async (service_gtype, G_PRIORITY_DEFAULT,
969 cancellable, callback, user_data,
970 "g-flags", G_DBUS_PROXY_FLAGS_NONE,
971 "g-interface-info", _secret_gen_service_interface_info (),
972 "g-name", service_bus_name,
973 "g-bus-type", G_BUS_TYPE_SESSION,
974 "g-object-path", SECRET_SERVICE_PATH,
975 "g-interface-name", SECRET_SERVICE_INTERFACE,
981 * secret_service_open_finish:
982 * @result: the asynchronous result passed to the callback
983 * @error: location to place an error on failure
985 * Complete an asynchronous operation to create a new #SecretService proxy for
986 * the Secret Service.
988 * Returns: (transfer full): a new reference to a #SecretService proxy, which
989 * should be released with g_object_unref().
992 secret_service_open_finish (GAsyncResult *result,
995 GObject *source_object;
998 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
999 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1001 source_object = g_async_result_get_source_object (result);
1002 object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
1004 g_object_unref (source_object);
1009 return SECRET_SERVICE (object);
1013 * secret_service_open_sync:
1014 * @service_gtype: the GType of the new secret service
1015 * @service_bus_name: (allow-none): the D-Bus service name of the secret service
1016 * @flags: flags for which service functionality to ensure is initialized
1017 * @cancellable: optional cancellation object
1018 * @error: location to place an error on failure
1020 * Create a new #SecretService proxy for the Secret Service.
1022 * This function is rarely used, see secret_service_get_sync() instead.
1024 * The @service_gtype argument should be set to %SECRET_TYPE_SERVICE or a the
1025 * type of a derived class.
1027 * If @flags contains any flags of which parts of the secret service to
1028 * ensure are initialized, then those will be initialized before returning.
1030 * If @service_bus_name is %NULL then the default is used.
1032 * This method may block indefinitely and should not be used in user interface
1035 * Returns: (transfer full): a new reference to a #SecretService proxy, which
1036 * should be released with g_object_unref().
1039 secret_service_open_sync (GType service_gtype,
1040 const gchar *service_bus_name,
1041 SecretServiceFlags flags,
1042 GCancellable *cancellable,
1045 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
1046 g_return_val_if_fail (g_type_is_a (service_gtype, SECRET_TYPE_SERVICE), NULL);
1048 if (service_bus_name == NULL)
1049 service_bus_name = get_default_bus_name ();
1051 return g_initable_new (service_gtype, cancellable, error,
1052 "g-flags", G_DBUS_PROXY_FLAGS_NONE,
1053 "g-interface-info", _secret_gen_service_interface_info (),
1054 "g-name", service_bus_name,
1055 "g-bus-type", G_BUS_TYPE_SESSION,
1056 "g-object-path", SECRET_SERVICE_PATH,
1057 "g-interface-name", SECRET_SERVICE_INTERFACE,
1063 * secret_service_get_flags:
1064 * @self: the secret service proxy
1066 * Get the flags representing what features of the #SecretService proxy
1067 * have been initialized.
1069 * Use secret_service_ensure_session() or secret_service_load_collections()
1070 * to initialize further features and change the flags.
1072 * Returns: the flags for features initialized
1075 secret_service_get_flags (SecretService *self)
1077 SecretServiceFlags flags = 0;
1079 g_return_val_if_fail (SECRET_IS_SERVICE (self), SECRET_SERVICE_NONE);
1081 g_mutex_lock (&self->pv->mutex);
1083 if (self->pv->session)
1084 flags |= SECRET_SERVICE_OPEN_SESSION;
1085 if (self->pv->collections)
1086 flags |= SECRET_SERVICE_LOAD_COLLECTIONS;
1088 g_mutex_unlock (&self->pv->mutex);
1094 * secret_service_get_collections:
1095 * @self: the secret service proxy
1097 * Get a list of #SecretCollection objects representing all the collections
1098 * in the secret service.
1100 * If the %SECRET_SERVICE_LOAD_COLLECTIONS flag was not specified when
1101 * initializing #SecretService proxy object, then this method will return
1102 * %NULL. Use secret_service_load_collections() to load the collections.
1104 * Returns: (transfer full) (element-type SecretUnstable.Collection) (allow-none): a
1105 * list of the collections in the secret service
1108 secret_service_get_collections (SecretService *self)
1110 GList *l, *collections;
1112 g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
1114 g_mutex_lock (&self->pv->mutex);
1116 if (self->pv->collections == NULL) {
1120 collections = g_hash_table_get_values (self->pv->collections);
1121 for (l = collections; l != NULL; l = g_list_next (l))
1122 g_object_ref (l->data);
1125 g_mutex_unlock (&self->pv->mutex);
1131 _secret_service_find_item_instance (SecretService *self,
1132 const gchar *item_path)
1134 SecretCollection *collection = NULL;
1135 gchar *collection_path;
1138 collection_path = _secret_util_parent_path (item_path);
1140 collection = _secret_service_find_collection_instance (self, collection_path);
1142 g_free (collection_path);
1144 if (collection == NULL)
1147 item = _secret_collection_find_item_instance (collection, item_path);
1148 g_object_unref (collection);
1154 _secret_service_find_collection_instance (SecretService *self,
1155 const gchar *collection_path)
1157 SecretCollection *collection = NULL;
1159 g_mutex_lock (&self->pv->mutex);
1160 if (self->pv->collections) {
1161 collection = g_hash_table_lookup (self->pv->collections, collection_path);
1162 if (collection != NULL)
1163 g_object_ref (collection);
1165 g_mutex_unlock (&self->pv->mutex);
1171 _secret_service_get_session (SecretService *self)
1173 SecretSession *session;
1175 g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
1177 g_mutex_lock (&self->pv->mutex);
1178 session = self->pv->session;
1179 g_mutex_unlock (&self->pv->mutex);
1185 _secret_service_take_session (SecretService *self,
1186 SecretSession *session)
1188 g_return_if_fail (SECRET_IS_SERVICE (self));
1189 g_return_if_fail (session != NULL);
1191 g_mutex_lock (&self->pv->mutex);
1192 if (self->pv->session == NULL)
1193 self->pv->session = session;
1195 _secret_session_free (session);
1196 g_mutex_unlock (&self->pv->mutex);
1200 * secret_service_get_session_algorithms:
1201 * @self: the secret service proxy
1203 * Get the set of algorithms being used to transfer secrets between this
1204 * secret service proxy and the Secret Service itself.
1206 * This will be %NULL if no session has been established. Use
1207 * secret_service_ensure_session() to establish a session.
1209 * Returns: (allow-none): a string representing the algorithms for transferring
1213 secret_service_get_session_algorithms (SecretService *self)
1215 SecretSession *session;
1216 const gchar *algorithms;
1218 g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
1220 g_mutex_lock (&self->pv->mutex);
1221 session = self->pv->session;
1222 algorithms = session ? _secret_session_get_algorithms (session) : NULL;
1223 g_mutex_unlock (&self->pv->mutex);
1225 /* Session never changes once established, so can return const */
1230 * secret_service_get_session_dbus_path:
1231 * @self: the secret service proxy
1233 * Get the D-Bus object path of the session object being used to transfer
1234 * secrets between this secret service proxy and the Secret Service itself.
1236 * This will be %NULL if no session has been established. Use
1237 * secret_service_ensure_session() to establish a session.
1239 * Returns: (allow-none): a string representing the D-Bus object path of the
1243 secret_service_get_session_dbus_path (SecretService *self)
1245 SecretSession *session;
1248 g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
1250 g_mutex_lock (&self->pv->mutex);
1251 session = self->pv->session;
1252 path = session ? _secret_session_get_path (session) : NULL;
1253 g_mutex_unlock (&self->pv->mutex);
1255 /* Session never changes once established, so can return const */
1260 * secret_service_ensure_session:
1261 * @self: the secret service
1262 * @cancellable: optional cancellation object
1263 * @callback: called when the operation completes
1264 * @user_data: data to be passed to the callback
1266 * Ensure that the #SecretService proxy has established a session with the
1267 * Secret Service. This session is used to transfer secrets.
1269 * It is not normally necessary to call this method, as the session is
1270 * established as necessary. You can also pass the %SECRET_SERVICE_OPEN_SESSION
1271 * to secret_service_get() in order to ensure that a session has been established
1272 * by the time you get the #SecretService proxy.
1274 * This method will return immediately and complete asynchronously.
1277 secret_service_ensure_session (SecretService *self,
1278 GCancellable *cancellable,
1279 GAsyncReadyCallback callback,
1282 GSimpleAsyncResult *res;
1283 SecretSession *session;
1285 g_return_if_fail (SECRET_IS_SERVICE (self));
1286 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1288 g_mutex_lock (&self->pv->mutex);
1289 session = self->pv->session;
1290 g_mutex_unlock (&self->pv->mutex);
1292 if (session == NULL) {
1293 _secret_session_open (self, cancellable, callback, user_data);
1296 res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
1297 secret_service_ensure_session);
1298 g_simple_async_result_complete_in_idle (res);
1299 g_object_unref (res);
1304 * secret_service_ensure_session_finish:
1305 * @self: the secret service
1306 * @result: the asynchronous result passed to the callback
1307 * @error: location to place an error on failure
1309 * Finish an asynchronous operation to ensure that the #SecretService proxy
1310 * has established a session with the Secret Service.
1312 * Returns: whether a session is established or not
1315 secret_service_ensure_session_finish (SecretService *self,
1316 GAsyncResult *result,
1319 g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
1320 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1322 if (!g_simple_async_result_is_valid (result, G_OBJECT (self),
1323 secret_service_ensure_session)) {
1324 if (!_secret_session_open_finish (result, error))
1328 g_return_val_if_fail (self->pv->session != NULL, FALSE);
1333 * secret_service_ensure_session_sync:
1334 * @self: the secret service
1335 * @cancellable: optional cancellation object
1336 * @error: location to place an error on failure
1338 * Ensure that the #SecretService proxy has established a session with the
1339 * Secret Service. This session is used to transfer secrets.
1341 * It is not normally necessary to call this method, as the session is
1342 * established as necessary. You can also pass the %SECRET_SERVICE_OPEN_SESSION
1343 * to secret_service_get_sync() in order to ensure that a session has been
1344 * established by the time you get the #SecretService proxy.
1346 * This method may block indefinitely and should not be used in user interface
1349 * Returns: whether a session is established or not
1352 secret_service_ensure_session_sync (SecretService *self,
1353 GCancellable *cancellable,
1359 g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
1360 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1361 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1363 sync = _secret_sync_new ();
1364 g_main_context_push_thread_default (sync->context);
1366 secret_service_ensure_session (self, cancellable,
1367 _secret_sync_on_result, sync);
1369 g_main_loop_run (sync->loop);
1371 ret = secret_service_ensure_session_finish (self, sync->result, error);
1373 g_main_context_pop_thread_default (sync->context);
1374 _secret_sync_free (sync);
1379 static SecretCollection *
1380 service_lookup_collection (SecretService *self,
1383 SecretCollection *collection = NULL;
1385 g_mutex_lock (&self->pv->mutex);
1387 if (self->pv->collections) {
1388 collection = g_hash_table_lookup (self->pv->collections, path);
1389 if (collection != NULL)
1390 g_object_ref (collection);
1393 g_mutex_unlock (&self->pv->mutex);
1399 service_update_collections (SecretService *self,
1400 GHashTable *collections)
1402 GHashTable *previous;
1404 g_hash_table_ref (collections);
1406 g_mutex_lock (&self->pv->mutex);
1408 previous = self->pv->collections;
1409 self->pv->collections = collections;
1411 g_mutex_unlock (&self->pv->mutex);
1413 if (previous != NULL)
1414 g_hash_table_unref (previous);
1416 g_object_notify (G_OBJECT (self), "collections");
1420 GCancellable *cancellable;
1421 GHashTable *collections;
1422 gint collections_loading;
1426 collections_table_new (void)
1428 return g_hash_table_new_full (g_str_hash, g_str_equal,
1429 g_free, g_object_unref);
1433 ensure_closure_free (gpointer data)
1435 EnsureClosure *closure = data;
1436 g_clear_object (&closure->cancellable);
1437 g_hash_table_unref (closure->collections);
1438 g_slice_free (EnsureClosure, closure);
1442 on_ensure_collection (GObject *source,
1443 GAsyncResult *result,
1446 GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
1447 SecretService *self = SECRET_SERVICE (g_async_result_get_source_object (user_data));
1448 EnsureClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
1449 SecretCollection *collection;
1451 GError *error = NULL;
1453 closure->collections_loading--;
1455 collection = secret_collection_new_for_dbus_path_finish (result, &error);
1458 g_simple_async_result_take_error (res, error);
1460 if (collection != NULL) {
1461 path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection));
1462 g_hash_table_insert (closure->collections, g_strdup (path), collection);
1465 if (closure->collections_loading == 0) {
1466 service_update_collections (self, closure->collections);
1467 g_simple_async_result_complete (res);
1470 g_object_unref (self);
1471 g_object_unref (res);
1475 * secret_service_load_collections:
1476 * @self: the secret service
1477 * @cancellable: optional cancellation object
1478 * @callback: called when the operation completes
1479 * @user_data: data to be passed to the callback
1481 * Ensure that the #SecretService proxy has loaded all the collections present
1482 * in the Secret Service. This affects the result of
1483 * secret_service_get_collections().
1485 * You can also pass the %SECRET_SERVICE_LOAD_COLLECTIONS to
1486 * secret_service_get_sync() in order to ensure that the collections have been
1487 * loaded by the time you get the #SecretService proxy.
1489 * This method will return immediately and complete asynchronously.
1492 secret_service_load_collections (SecretService *self,
1493 GCancellable *cancellable,
1494 GAsyncReadyCallback callback,
1497 EnsureClosure *closure;
1498 SecretCollection *collection;
1499 GSimpleAsyncResult *res;
1504 g_return_if_fail (SECRET_IS_SERVICE (self));
1505 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1507 paths = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Collections");
1508 g_return_if_fail (paths != NULL);
1510 res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
1511 secret_service_load_collections);
1512 closure = g_slice_new0 (EnsureClosure);
1513 closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1514 closure->collections = collections_table_new ();
1515 g_simple_async_result_set_op_res_gpointer (res, closure, ensure_closure_free);
1517 g_variant_iter_init (&iter, paths);
1518 while (g_variant_iter_loop (&iter, "&o", &path)) {
1519 collection = service_lookup_collection (self, path);
1521 /* No such collection yet create a new one */
1522 if (collection == NULL) {
1523 secret_collection_new_for_dbus_path (self, path, SECRET_COLLECTION_LOAD_ITEMS,
1524 cancellable, on_ensure_collection, g_object_ref (res));
1525 closure->collections_loading++;
1527 g_hash_table_insert (closure->collections, g_strdup (path), collection);
1531 if (closure->collections_loading == 0) {
1532 service_update_collections (self, closure->collections);
1533 g_simple_async_result_complete_in_idle (res);
1536 g_variant_unref (paths);
1537 g_object_unref (res);
1541 * secret_service_load_collections_finish:
1542 * @self: the secret service
1543 * @result: the asynchronous result passed to the callback
1544 * @error: location to place an error on failure
1546 * Complete an asynchronous operation to ensure that the #SecretService proxy
1547 * has loaded all the collections present in the Secret Service.
1549 * Returns: whether the load was successful or not
1552 secret_service_load_collections_finish (SecretService *self,
1553 GAsyncResult *result,
1556 g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
1557 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1558 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
1559 secret_service_load_collections), FALSE);
1561 if (_secret_util_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
1568 * secret_service_load_collections_sync:
1569 * @self: the secret service
1570 * @cancellable: optional cancellation object
1571 * @error: location to place an error on failure
1573 * Ensure that the #SecretService proxy has loaded all the collections present
1574 * in the Secret Service. This affects the result of
1575 * secret_service_get_collections().
1577 * You can also pass the %SECRET_SERVICE_LOAD_COLLECTIONS to
1578 * secret_service_get_sync() in order to ensure that the collections have been
1579 * loaded by the time you get the #SecretService proxy.
1581 * This method may block indefinitely and should not be used in user interface
1584 * Returns: whether the load was successful or not
1587 secret_service_load_collections_sync (SecretService *self,
1588 GCancellable *cancellable,
1591 SecretCollection *collection;
1592 GHashTable *collections;
1596 gboolean ret = TRUE;
1598 g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
1599 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1600 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1602 paths = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Collections");
1603 g_return_val_if_fail (paths != NULL, FALSE);
1605 collections = collections_table_new ();
1607 g_variant_iter_init (&iter, paths);
1608 while (g_variant_iter_next (&iter, "&o", &path)) {
1609 collection = service_lookup_collection (self, path);
1611 /* No such collection yet create a new one */
1612 if (collection == NULL) {
1613 collection = secret_collection_new_for_dbus_path_sync (self, path,
1614 SECRET_COLLECTION_LOAD_ITEMS,
1615 cancellable, error);
1616 if (collection == NULL) {
1622 g_hash_table_insert (collections, g_strdup (path), collection);
1626 service_update_collections (self, collections);
1628 g_hash_table_unref (collections);
1629 g_variant_unref (paths);
1634 * secret_service_prompt_sync:
1635 * @self: the secret service
1636 * @prompt: the prompt
1637 * @cancellable: optional cancellation object
1638 * @return_type: the variant type of the prompt result
1639 * @error: location to place an error on failure
1641 * Perform prompting for a #SecretPrompt.
1643 * Runs a prompt and performs the prompting. Returns a variant result if the
1644 * prompt was completed and not dismissed. The type of result depends on the
1645 * action the prompt is completing, and is defined in the Secret Service DBus
1646 * API specification.
1648 * This function is called by other parts of this library to handle prompts
1649 * for the various actions that can require prompting.
1651 * Override the #SecretServiceClass <literal>prompt_sync</literal> virtual method
1652 * to change the behavior of the propmting. The default behavior is to simply
1653 * run secret_prompt_perform_sync() on the prompt.
1655 * Returns: (transfer full): %NULL if the prompt was dismissed or an error occurred,
1656 * a variant result if the prompt was successful
1659 secret_service_prompt_sync (SecretService *self,
1660 SecretPrompt *prompt,
1661 GCancellable *cancellable,
1662 const GVariantType *return_type,
1665 SecretServiceClass *klass;
1667 g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
1668 g_return_val_if_fail (SECRET_IS_PROMPT (prompt), NULL);
1669 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
1670 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1672 klass = SECRET_SERVICE_GET_CLASS (self);
1673 g_return_val_if_fail (klass->prompt_sync != NULL, NULL);
1675 return (klass->prompt_sync) (self, prompt, cancellable, return_type, error);
1679 * secret_service_prompt:
1680 * @self: the secret service
1681 * @prompt: the prompt
1682 * @return_type: (allow-none): the variant type of the prompt result
1683 * @cancellable: optional cancellation object
1684 * @callback: called when the operation completes
1685 * @user_data: data to be passed to the callback
1687 * Perform prompting for a #SecretPrompt.
1689 * This function is called by other parts of this library to handle prompts
1690 * for the various actions that can require prompting.
1692 * Override the #SecretServiceClass <literal>prompt_async</literal> virtual method
1693 * to change the behavior of the propmting. The default behavior is to simply
1694 * run secret_prompt_perform() on the prompt.
1697 secret_service_prompt (SecretService *self,
1698 SecretPrompt *prompt,
1699 const GVariantType *return_type,
1700 GCancellable *cancellable,
1701 GAsyncReadyCallback callback,
1704 SecretServiceClass *klass;
1706 g_return_if_fail (SECRET_IS_SERVICE (self));
1707 g_return_if_fail (SECRET_IS_PROMPT (prompt));
1708 g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1710 klass = SECRET_SERVICE_GET_CLASS (self);
1711 g_return_if_fail (klass->prompt_async != NULL);
1713 (klass->prompt_async) (self, prompt, return_type, cancellable, callback, user_data);
1717 * secret_service_prompt_finish:
1718 * @self: the secret service
1719 * @result: the asynchronous result passed to the callback
1720 * @error: location to place an error on failure
1722 * Complete asynchronous operation to perform prompting for a #SecretPrompt.
1724 * Returns a variant result if the prompt was completed and not dismissed. The
1725 * type of result depends on the action the prompt is completing, and is defined
1726 * in the Secret Service DBus API specification.
1728 * Returns: (transfer full): %NULL if the prompt was dismissed or an error occurred,
1729 * a variant result if the prompt was successful
1732 secret_service_prompt_finish (SecretService *self,
1733 GAsyncResult *result,
1736 SecretServiceClass *klass;
1738 g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL);
1739 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
1740 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1742 klass = SECRET_SERVICE_GET_CLASS (self);
1743 g_return_val_if_fail (klass->prompt_finish != NULL, NULL);
1745 return (klass->prompt_finish) (self, result, error);
1749 * secret_service_get_collection_gtype:
1750 * @self: the secret service
1752 * Get the GObject type for collections instantiated by this service.
1753 * This will always be either #SecretCollection or derived from it.
1755 * Returns: the gobject type for collections
1758 secret_service_get_collection_gtype (SecretService *self)
1760 SecretServiceClass *klass;
1763 g_return_val_if_fail (SECRET_IS_SERVICE (self), 0);
1765 klass = SECRET_SERVICE_GET_CLASS (self);
1766 g_return_val_if_fail (klass->get_collection_gtype != NULL,
1767 SECRET_TYPE_COLLECTION);
1769 type = (klass->get_collection_gtype) (self);
1770 g_return_val_if_fail (g_type_is_a (type, SECRET_TYPE_COLLECTION),
1771 SECRET_TYPE_COLLECTION);
1777 * secret_service_get_item_gtype:
1778 * @self: the collection
1780 * Get the GObject type for items instantiated by this collection.
1781 * This will always be either #SecretItem or derived from it.
1783 * Returns: the gobject type for items
1786 secret_service_get_item_gtype (SecretService *self)
1788 SecretServiceClass *klass;
1791 g_return_val_if_fail (SECRET_IS_SERVICE (self), 0);
1793 klass = SECRET_SERVICE_GET_CLASS (self);
1794 g_return_val_if_fail (klass->get_item_gtype != NULL,
1797 type = (klass->get_item_gtype) (self);
1798 g_return_val_if_fail (g_type_is_a (type, SECRET_TYPE_ITEM),