diff options
author | Milan Crha <mcrha@redhat.com> | 2015-02-02 14:44:05 +0100 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2015-02-02 14:44:05 +0100 |
commit | 884fb8d872787d9c9e8132d4cfca47f275d9da3e (patch) | |
tree | 13875694627f5539660d776a520cff230632acfd /libebackend/e-source-registry-server.c | |
parent | a83cc09fc20edb2401f1e08d9d7b9f2eca408641 (diff) | |
download | evolution-data-server-884fb8d872787d9c9e8132d4cfca47f275d9da3e.tar.gz |
Move authentication of backends back to the client
Since this change the client is responsible to provide credentials
to use to authenticate backends (through ESource-s, to be more precise),
unless the credentials are already saved.
Diffstat (limited to 'libebackend/e-source-registry-server.c')
-rw-r--r-- | libebackend/e-source-registry-server.c | 756 |
1 files changed, 41 insertions, 715 deletions
diff --git a/libebackend/e-source-registry-server.c b/libebackend/e-source-registry-server.c index 5ff0efef5..741920bbb 100644 --- a/libebackend/e-source-registry-server.c +++ b/libebackend/e-source-registry-server.c @@ -23,9 +23,8 @@ * The #ESourceRegistryServer is the heart of the registry D-Bus service. * Acting as a global singleton store for all #EServerSideSource instances, * its responsibilities include loading data source content from key files, - * exporting data sources to clients over D-Bus, handling authentication - * and content change requests from clients, and saving content changes - * back to key files. + * exporting data sources to clients over D-Bus, handling content change + * requests from clients, and saving content changes back to key files. * * It also hosts any number of built-in or 3rd party data source collection * backends, which coordinate with #ESourceRegistryServer to automatically @@ -42,9 +41,8 @@ #include <e-dbus-source.h> #include <e-dbus-source-manager.h> -#include <libebackend/e-authentication-mediator.h> -#include <libebackend/e-authentication-session.h> -#include <libebackend/e-server-side-source.h> +#include "e-server-side-source.h" +#include "e-server-side-source-credentials-provider.h" #define E_SOURCE_REGISTRY_SERVER_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ @@ -54,8 +52,6 @@ * sources with a [Collection] extension. */ #define BACKEND_DATA_KEY "__e_collection_backend__" -typedef struct _AuthRequest AuthRequest; - struct _ESourceRegistryServerPrivate { GMainContext *main_context; @@ -69,30 +65,7 @@ struct _ESourceRegistryServerPrivate { GMutex sources_lock; GMutex orphans_lock; - /* In pseudo-Python notation: - * - * running_auths = { UID : AuthRequest } - * waiting_auths = { UID : [ AuthRequest, ... ] } - * - * We process all authenticators for a given source UID at once. - * The thought being after the first authenticator for a given UID - * completes (the first being most likely to trigger a user prompt), - * then any other authenticators for that same UID should complete - * quickly, hopefully without having to reprompt. That is unless - * the user decides not to cache the secret at all, in which case - * he gets what he asked for: lots of annoying prompts. - */ - GMutex auth_lock; - GHashTable *running_auths; - GHashTable *waiting_auths; -}; - -struct _AuthRequest { - volatile gint ref_count; - EAuthenticationSession *session; - GSimpleAsyncResult *simple; - ESource *source; /* may be NULL */ - GCancellable *cancellable; + ESourceCredentialsProvider *credentials_provider; }; enum { @@ -104,11 +77,6 @@ enum { LAST_SIGNAL }; -/* Forward Declarations */ -static void source_registry_server_maybe_start_auth_session - (ESourceRegistryServer *server, - const gchar *uid); - static guint signals[LAST_SIGNAL]; G_DEFINE_TYPE ( @@ -116,65 +84,6 @@ G_DEFINE_TYPE ( e_source_registry_server, E_TYPE_DATA_FACTORY) -static AuthRequest * -auth_request_new (EAuthenticationSession *session, - GSimpleAsyncResult *simple, - GCancellable *cancellable) -{ - ESourceRegistryServer *server; - AuthRequest *request; - const gchar *uid; - - server = e_authentication_session_get_server (session); - uid = e_authentication_session_get_source_uid (session); - - request = g_slice_new0 (AuthRequest); - request->ref_count = 1; - request->session = g_object_ref (session); - request->simple = g_object_ref (simple); - - /* This will return NULL if the authenticating data source - * has not yet been submitted to the D-Bus registry server. */ - request->source = e_source_registry_server_ref_source (server, uid); - - if (G_IS_CANCELLABLE (cancellable)) - request->cancellable = g_object_ref (cancellable); - - return request; -} - -static AuthRequest * -auth_request_ref (AuthRequest *request) -{ - g_return_val_if_fail (request != NULL, NULL); - g_return_val_if_fail (request->ref_count > 0, NULL); - - g_atomic_int_inc (&request->ref_count); - - return request; -} - -static void -auth_request_unref (AuthRequest *request) -{ - g_return_if_fail (request != NULL); - g_return_if_fail (request->ref_count > 0); - - if (g_atomic_int_dec_and_test (&request->ref_count)) { - - g_object_unref (request->session); - g_object_unref (request->simple); - - if (request->source != NULL) - g_object_unref (request->source); - - if (request->cancellable != NULL) - g_object_unref (request->cancellable); - - g_slice_free (AuthRequest, request); - } -} - /* GDestroyNotify callback for 'sources' values */ static void unref_data_source (ESource *source) @@ -184,17 +93,6 @@ unref_data_source (ESource *source) g_object_unref (source); } -/* GDestroyNotify callback for 'waiting_auths' values */ -static void -free_auth_queue (GQueue *queue) -{ - /* XXX g_queue_clear_full() would be nice here. */ - while (!g_queue_is_empty (queue)) - g_object_unref (g_queue_pop_head (queue)); - - g_queue_free (queue); -} - static void source_registry_server_sources_insert (ESourceRegistryServer *server, ESource *source) @@ -367,384 +265,6 @@ source_registry_server_orphans_steal (ESourceRegistryServer *server, return array; } -static void -source_request_server_auth_request_cancel_all (ESourceRegistryServer *server) -{ - GHashTableIter iter; - gpointer value; - - g_mutex_lock (&server->priv->auth_lock); - - g_hash_table_iter_init (&iter, server->priv->waiting_auths); - - while (g_hash_table_iter_next (&iter, NULL, &value)) { - GQueue *queue = value; - GList *list, *link; - - list = g_queue_peek_head_link (queue); - - for (link = list; link != NULL; link = g_list_next (link)) { - AuthRequest *request = link->data; - g_cancellable_cancel (request->cancellable); - } - } - - g_hash_table_iter_init (&iter, server->priv->running_auths); - - while (g_hash_table_iter_next (&iter, NULL, &value)) { - AuthRequest *request = value; - g_cancellable_cancel (request->cancellable); - } - - g_mutex_unlock (&server->priv->auth_lock); -} - -static void -source_registry_server_auth_request_push (ESourceRegistryServer *server, - const gchar *uid, - AuthRequest *request) -{ - GQueue *queue; - - g_return_if_fail (uid != NULL); - - g_mutex_lock (&server->priv->auth_lock); - - queue = g_hash_table_lookup (server->priv->waiting_auths, uid); - - if (queue == NULL) { - queue = g_queue_new (); - g_hash_table_insert ( - server->priv->waiting_auths, - g_strdup (uid), queue); - } - - g_queue_push_tail (queue, auth_request_ref (request)); - - g_mutex_unlock (&server->priv->auth_lock); -} - -static AuthRequest * -source_registry_server_auth_request_next (ESourceRegistryServer *server, - const gchar *uid) -{ - AuthRequest *request = NULL; - - g_return_val_if_fail (uid != NULL, NULL); - - g_mutex_lock (&server->priv->auth_lock); - - /* If we're already busy processing an authentication request - * for this UID, the next request will have to wait in line. */ - if (!g_hash_table_contains (server->priv->running_auths, uid)) { - GQueue *queue; - - queue = g_hash_table_lookup ( - server->priv->waiting_auths, uid); - - if (queue != NULL) - request = g_queue_pop_head (queue); - - if (request != NULL) - g_hash_table_insert ( - server->priv->running_auths, - g_strdup (uid), - auth_request_ref (request)); - } - - g_mutex_unlock (&server->priv->auth_lock); - - return request; -} - -static void -source_registry_server_auth_request_done (ESourceRegistryServer *server, - const gchar *uid) -{ - g_return_if_fail (uid != NULL); - - g_mutex_lock (&server->priv->auth_lock); - - g_hash_table_remove (server->priv->running_auths, uid); - - g_mutex_unlock (&server->priv->auth_lock); -} - -static void -source_registry_server_auth_session_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - ESourceRegistryServer *server; - EAuthenticationSession *session; - EAuthenticationSessionResult auth_result; - AuthRequest *request; - const gchar *uid; - GError *error = NULL; - - session = E_AUTHENTICATION_SESSION (source_object); - request = (AuthRequest *) user_data; - - auth_result = e_authentication_session_execute_finish ( - session, result, &error); - - if (error != NULL) { - ESourceAuthenticator *authenticator; - - g_warn_if_fail (auth_result == E_AUTHENTICATION_SESSION_ERROR); - g_simple_async_result_take_error (request->simple, error); - - /* If the authenticator is an EAuthenticationMediator, - * have it emit a "server-error" signal to the client. */ - authenticator = - e_authentication_session_get_authenticator (session); - if (E_IS_AUTHENTICATION_MEDIATOR (authenticator)) - e_authentication_mediator_server_error ( - E_AUTHENTICATION_MEDIATOR (authenticator), - error); - } - - /* Authentication dismissals require additional handling. */ - if (auth_result == E_AUTHENTICATION_SESSION_DISMISSED) { - ESourceAuthenticator *authenticator; - - /* If the authenticator is an EAuthenticationMediator, - * have it emit a "dismissed" signal to the client. */ - authenticator = - e_authentication_session_get_authenticator (session); - if (E_IS_AUTHENTICATION_MEDIATOR (authenticator)) - e_authentication_mediator_dismiss ( - E_AUTHENTICATION_MEDIATOR (authenticator)); - - /* Prevent further user interruptions. */ - if (request->source != NULL) - e_server_side_source_set_allow_auth_prompt ( - E_SERVER_SIDE_SOURCE (request->source), FALSE); - - /* e_source_registry_server_authenticate_finish() should - * return an error since authentication did not complete. */ - g_simple_async_result_set_error ( - request->simple, - G_IO_ERROR, G_IO_ERROR_CANCELLED, - _("The user declined to authenticate")); - } - - g_simple_async_result_complete_in_idle (request->simple); - - server = e_authentication_session_get_server (session); - uid = e_authentication_session_get_source_uid (session); - - source_registry_server_auth_request_done (server, uid); - source_registry_server_maybe_start_auth_session (server, uid); - - auth_request_unref (request); -} - -static gboolean -source_registry_server_start_auth_session_idle_cb (gpointer user_data) -{ - AuthRequest *request = user_data; - - /* Execute the new active auth session. This signals it to - * respond with a cached secret in the keyring if it can, or - * else show an authentication prompt and wait for input. */ - e_authentication_session_execute ( - request->session, - G_PRIORITY_DEFAULT, - request->cancellable, - source_registry_server_auth_session_cb, - auth_request_ref (request)); - - return FALSE; -} - -static void -source_registry_server_maybe_start_auth_session (ESourceRegistryServer *server, - const gchar *uid) -{ - AuthRequest *request; - - /* We own the returned reference, unless we get NULL. */ - request = source_registry_server_auth_request_next (server, uid); - - if (request != NULL) { - GSource *idle_source; - - /* Process the next AuthRequest from an idle callback - * on our own GMainContext, since the current thread- - * default GMainContext may only be temporary. */ - idle_source = g_idle_source_new (); - g_source_set_callback ( - idle_source, - source_registry_server_start_auth_session_idle_cb, - auth_request_ref (request), - (GDestroyNotify) auth_request_unref); - g_source_attach (idle_source, server->priv->main_context); - g_source_unref (idle_source); - - auth_request_unref (request); - } -} - -static void -source_registry_server_authenticate_done_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - GError *error = NULL; - - e_source_registry_server_authenticate_finish ( - E_SOURCE_REGISTRY_SERVER (source_object), result, &error); - - /* Ignore cancellations. */ - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_error_free (error); - - } else if (error != NULL) { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_error_free (error); - } -} - -static void -source_registry_server_wait_for_client_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - EAuthenticationMediator *mediator; - EAuthenticationSession *session; - GError *error = NULL; - - mediator = E_AUTHENTICATION_MEDIATOR (source_object); - session = E_AUTHENTICATION_SESSION (user_data); - - e_authentication_mediator_wait_for_client_finish ( - mediator, result, &error); - - if (error == NULL) { - ESourceRegistryServer *server; - - server = e_authentication_session_get_server (session); - - /* Client is ready and waiting to test passwords, so - * execute the authentication session as soon as all - * other authentication sessions for this same data - * source are finished. - * - * XXX Note this asynchronous operation is not cancellable - * but it does time out on its own after a few minutes. */ - e_source_registry_server_authenticate ( - server, session, NULL, - source_registry_server_authenticate_done_cb, NULL); - - } else { - /* Most likely the client went dark and the operation - * timed out. Emit a dismissed signal anyway just in - * case the client is still alive and listening. */ - e_authentication_mediator_dismiss (mediator); - g_warning ("%s: %s", G_STRFUNC, error->message); - g_error_free (error); - } - - g_object_unref (session); -} - -static gboolean -source_registry_server_allow_auth_prompt_all_cb (EDBusSourceManager *dbus_interface, - GDBusMethodInvocation *invocation, - ESourceRegistryServer *server) -{ - GList *list, *link; - - list = e_source_registry_server_list_sources (server, NULL); - - for (link = list; link != NULL; link = g_list_next (link)) - e_server_side_source_set_allow_auth_prompt ( - E_SERVER_SIDE_SOURCE (link->data), TRUE); - - g_list_free_full (list, (GDestroyNotify) g_object_unref); - - e_dbus_source_manager_complete_allow_auth_prompt_all ( - dbus_interface, invocation); - - return TRUE; -} - -static gboolean -source_registry_server_authenticate_cb (EDBusSourceManager *dbus_interface, - GDBusMethodInvocation *invocation, - const gchar *source_uid, - const gchar *prompt_title, - const gchar *prompt_message, - const gchar *prompt_description, - ESourceRegistryServer *server) -{ - GDBusConnection *connection; - EAuthenticationSession *session; - ESourceAuthenticator *authenticator; - const gchar *sender; - gchar *auth_object_path; - GError *error = NULL; - - /* Export the D-Bus interface to a unique object path. This - * effectively starts a new authentication session with the - * method caller. */ - - connection = g_dbus_method_invocation_get_connection (invocation); - sender = g_dbus_method_invocation_get_sender (invocation); - - auth_object_path = e_data_factory_construct_path ( - E_DATA_FACTORY (server)); - - authenticator = e_authentication_mediator_new ( - connection, auth_object_path, sender, &error); - - if (error != NULL) { - g_warn_if_fail (authenticator == NULL); - g_dbus_method_invocation_take_error (invocation, error); - g_free (auth_object_path); - return TRUE; - } - - g_return_val_if_fail ( - E_IS_SOURCE_AUTHENTICATOR (authenticator), FALSE); - - /* Create the authentication session. */ - session = e_source_registry_server_new_auth_session ( - server, authenticator, source_uid); - - /* Configure the authentication session. */ - g_object_set ( - session, - "prompt-title", prompt_title, - "prompt-message", prompt_message, - "prompt-description", prompt_description, - NULL); - - /* Before adding the authentication session to the server we - * must handshake with the client requesting authentication. - * We do this by returning the object path of the exported - * Authenticator interface and then waiting for the client to - * acknowledge by calling the Ready() method on the interface. - * This indicates the client is ready to receive signals. - * - * XXX Note this asynchronous operation is not cancellable - * but it does time out on its own after a few minutes. */ - e_authentication_mediator_wait_for_client ( - E_AUTHENTICATION_MEDIATOR (authenticator), - NULL, source_registry_server_wait_for_client_cb, - g_object_ref (session)); - - e_dbus_source_manager_complete_authenticate ( - dbus_interface, invocation, auth_object_path); - - g_object_unref (authenticator); - g_object_unref (session); - g_free (auth_object_path); - - return TRUE; -} - static gboolean source_registry_server_create_source (ESourceRegistryServer *server, const gchar *uid, @@ -1036,6 +556,19 @@ source_registry_server_adopt_orphans (ESourceRegistryServer *server, } static void +source_registry_server_constructed (GObject *object) +{ + ESourceRegistryServer *server; + + server = E_SOURCE_REGISTRY_SERVER (object); + + /* Chain up to parent's method. */ + G_OBJECT_CLASS (e_source_registry_server_parent_class)->constructed (object); + + server->priv->credentials_provider = e_server_side_source_credentials_provider_new (server); +} + +static void source_registry_server_dispose (GObject *object) { ESourceRegistryServerPrivate *priv; @@ -1047,23 +580,14 @@ source_registry_server_dispose (GObject *object) priv->main_context = NULL; } - if (priv->object_manager != NULL) { - g_object_unref (priv->object_manager); - priv->object_manager = NULL; - } - - if (priv->source_manager != NULL) { - g_object_unref (priv->source_manager); - priv->source_manager = NULL; - } + g_clear_object (&priv->object_manager); + g_clear_object (&priv->source_manager); + g_clear_object (&priv->credentials_provider); g_hash_table_remove_all (priv->sources); g_hash_table_remove_all (priv->orphans); g_hash_table_remove_all (priv->monitors); - g_hash_table_remove_all (priv->running_auths); - g_hash_table_remove_all (priv->waiting_auths); - /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (e_source_registry_server_parent_class)-> dispose (object); @@ -1083,10 +607,6 @@ source_registry_server_finalize (GObject *object) g_mutex_clear (&priv->sources_lock); g_mutex_clear (&priv->orphans_lock); - g_mutex_clear (&priv->auth_lock); - g_hash_table_destroy (priv->running_auths); - g_hash_table_destroy (priv->waiting_auths); - /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (e_source_registry_server_parent_class)-> finalize (object); @@ -1116,9 +636,6 @@ source_registry_server_quit_server (EDBusServer *server, priv = E_SOURCE_REGISTRY_SERVER_GET_PRIVATE (server); - source_request_server_auth_request_cancel_all ( - E_SOURCE_REGISTRY_SERVER (server)); - /* This makes the object manager unexport all objects. */ g_dbus_object_manager_server_set_connection ( priv->object_manager, NULL); @@ -1273,6 +790,7 @@ e_source_registry_server_class_init (ESourceRegistryServerClass *class) g_type_class_add_private (class, sizeof (ESourceRegistryServerPrivate)); object_class = G_OBJECT_CLASS (class); + object_class->constructed = source_registry_server_constructed; object_class->dispose = source_registry_server_dispose; object_class->finalize = source_registry_server_finalize; @@ -1400,8 +918,6 @@ e_source_registry_server_init (ESourceRegistryServer *server) GHashTable *sources; GHashTable *orphans; GHashTable *monitors; - GHashTable *running_auths; - GHashTable *waiting_auths; const gchar *object_path; object_path = E_SOURCE_REGISTRY_SERVER_OBJECT_PATH; @@ -1429,18 +945,6 @@ e_source_registry_server_init (ESourceRegistryServer *server) (GDestroyNotify) g_object_unref, (GDestroyNotify) g_object_unref); - running_auths = g_hash_table_new_full ( - (GHashFunc) g_str_hash, - (GEqualFunc) g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) auth_request_unref); - - waiting_auths = g_hash_table_new_full ( - (GHashFunc) g_str_hash, - (GEqualFunc) g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) free_auth_queue); - server->priv = E_SOURCE_REGISTRY_SERVER_GET_PRIVATE (server); server->priv->main_context = g_main_context_ref_thread_default (); server->priv->object_manager = object_manager; @@ -1450,19 +954,6 @@ e_source_registry_server_init (ESourceRegistryServer *server) server->priv->monitors = monitors; g_mutex_init (&server->priv->sources_lock); g_mutex_init (&server->priv->orphans_lock); - g_mutex_init (&server->priv->auth_lock); - server->priv->waiting_auths = waiting_auths; - server->priv->running_auths = running_auths; - - g_signal_connect ( - source_manager, "handle-allow-auth-prompt-all", - G_CALLBACK (source_registry_server_allow_auth_prompt_all_cb), - server); - - g_signal_connect ( - source_manager, "handle-authenticate", - G_CALLBACK (source_registry_server_authenticate_cb), - server); g_signal_connect ( source_manager, "handle-create-sources", @@ -1491,6 +982,25 @@ e_source_registry_server_new (void) } /** + * e_source_registry_server_ref_credentials_provider: + * @server: an #ESourceRegistryServer + * + * Returns a referenced #ESourceRegistryCredentialsProvider. + * + * Returns: A referenced #ESourceRegistryCredentialsProvider. Unref it with + * g_object_unref(), when no longer needed. + * + * Since: 3.14 + **/ +ESourceCredentialsProvider * +e_source_registry_server_ref_credentials_provider (ESourceRegistryServer *server) +{ + g_return_val_if_fail (E_IS_SOURCE_REGISTRY_SERVER (server), NULL); + + return g_object_ref (server->priv->credentials_provider); +} + +/** * e_source_registry_server_add_source: * @server: an #ESourceRegistryServer * @source: an #ESource @@ -2320,187 +1830,3 @@ e_source_registry_server_ref_backend_factory (ESourceRegistryServer *server, * We specify this in source_registry_server_class_init(). */ return E_COLLECTION_BACKEND_FACTORY (factory); } - -/** - * e_source_registry_server_new_auth_session: - * @server: an #ESourceRegistryServer - * @authenticator: an #ESourceAuthenticator - * @source_uid: a data source identifier - * - * Convenience function instantiates an appropriate authentication - * session type for @source_uid. - * - * If @server has an #EServerSideSource instance for @source_uid, then - * its #EServerSideSource:auth-session-type is used to instantiate a new - * authentication session. Otherwise a plain #EAuthenticationSession is - * instantiated. - * - * Unreference the returned #EAuthenticationSession with g_object_unref() - * when finished with it. - * - * Returns: a new #EAuthenticationSession for @source_uid - * - * Since: 3.8 - **/ -EAuthenticationSession * -e_source_registry_server_new_auth_session (ESourceRegistryServer *server, - ESourceAuthenticator *authenticator, - const gchar *source_uid) -{ - GType auth_session_type = E_TYPE_AUTHENTICATION_SESSION; - ESource *source; - - g_return_val_if_fail (E_IS_SOURCE_REGISTRY_SERVER (server), NULL); - g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATOR (authenticator), NULL); - g_return_val_if_fail (source_uid != NULL, NULL); - - source = e_source_registry_server_ref_source (server, source_uid); - if (source != NULL) { - auth_session_type = - e_server_side_source_get_auth_session_type ( - E_SERVER_SIDE_SOURCE (source)); - g_object_unref (source); - } - - g_return_val_if_fail ( - g_type_is_a ( - auth_session_type, - E_TYPE_AUTHENTICATION_SESSION), NULL); - - return g_object_new ( - auth_session_type, - "server", server, - "authenticator", authenticator, - "source-uid", source_uid, NULL); -} - -/** - * e_source_registry_server_authenticate_sync: - * @server: an #ESourceRegistryServer - * @session: an #EAuthenticationSession - * @cancellable: optional #GCancellable object, or %NULL - * @error: return location for a #GError, or %NULL - * - * Queues the @session behind any ongoing or pending authentication - * sessions for the same data source, and eventually executes @session - * (see e_authentication_session_execute_sync() for more details). - * - * This function blocks until @session is finished executing. For a - * non-blocking variation see e_source_registry_server_authenticate(). - * - * If an error occurs, the function sets @error and returns %FALSE. - * - * Returns: %TRUE on success, %FALSE on failure - * - * Since: 3.6 - **/ -gboolean -e_source_registry_server_authenticate_sync (ESourceRegistryServer *server, - EAuthenticationSession *session, - GCancellable *cancellable, - GError **error) -{ - EAsyncClosure *closure; - GAsyncResult *result; - gboolean success; - - g_return_val_if_fail (E_IS_SOURCE_REGISTRY_SERVER (server), FALSE); - g_return_val_if_fail (E_IS_AUTHENTICATION_SESSION (session), FALSE); - - closure = e_async_closure_new (); - - e_source_registry_server_authenticate ( - server, session, cancellable, - e_async_closure_callback, closure); - - result = e_async_closure_wait (closure); - - success = e_source_registry_server_authenticate_finish ( - server, result, error); - - e_async_closure_free (closure); - - return success; -} - -/** - * e_source_registry_server_authenticate: - * @server: an #ESourceRegistryServer - * @session: an #EAuthenticationSession - * @cancellable: optional #GCancellable object, or %NULL - * @callback: a #GAsyncReadyCallback to call when the request is satisfied - * @user_data: data to pass to the callback function - * - * Queues the @session behind any ongoing or pending authentication - * sessions for the same data source, and eventually executes @session - * (see e_authentication_session_execute_sync() for more details). - * - * This function returns immediately after enqueuing @session. When - * @session is finished executing, @callback will be called. You can - * then call e_source_registry_server_authenticate_finish() to get the - * result of the operation. - * - * Since: 3.6 - **/ -void -e_source_registry_server_authenticate (ESourceRegistryServer *server, - EAuthenticationSession *session, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *simple; - AuthRequest *request; - const gchar *uid; - - g_return_if_fail (E_IS_SOURCE_REGISTRY_SERVER (server)); - g_return_if_fail (E_IS_AUTHENTICATION_SESSION (session)); - - uid = e_authentication_session_get_source_uid (session); - g_return_if_fail (uid != NULL); - - simple = g_simple_async_result_new ( - G_OBJECT (server), callback, user_data, - e_source_registry_server_authenticate); - - g_simple_async_result_set_check_cancellable (simple, cancellable); - - request = auth_request_new (session, simple, cancellable); - source_registry_server_auth_request_push (server, uid, request); - auth_request_unref (request); - - source_registry_server_maybe_start_auth_session (server, uid); - - g_object_unref (simple); -} - -/** - * e_source_registry_server_authenticate_finish: - * @server: an #ESourceRegistryServer - * @result: a #GAsyncResult - * @error: return location for a #GError, or %NULL - * - * Finishes the operation started with e_source_registry_server_authenticate(). - * If an error occurred, the function will set @error and return %FALSE. - * - * Returns: %TRUE on success, %FALSE on failure - * - * Since: 3.6 - **/ -gboolean -e_source_registry_server_authenticate_finish (ESourceRegistryServer *server, - GAsyncResult *result, - GError **error) -{ - GSimpleAsyncResult *simple; - - g_return_val_if_fail ( - g_simple_async_result_is_valid ( - result, G_OBJECT (server), - e_source_registry_server_authenticate), FALSE); - - simple = G_SIMPLE_ASYNC_RESULT (result); - - /* Assume success unless a GError is set. */ - return !g_simple_async_result_propagate_error (simple, error); -} |