[evolution-data-server/account-mgmt] EAuthenticationSession: Add an execute() class method.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/account-mgmt] EAuthenticationSession: Add an execute() class method.
- Date: Wed, 30 May 2012 12:14:20 +0000 (UTC)
commit d3e71fe762f1027e95910b3e8fa439cff4e5728f
Author: Matthew Barnes <mbarnes redhat com>
Date: Tue May 29 13:13:12 2012 -0400
EAuthenticationSession: Add an execute() class method.
libebackend/e-authentication-session.c | 607 ++++++++++++++++++--------------
libebackend/e-authentication-session.h | 19 +
2 files changed, 359 insertions(+), 267 deletions(-)
---
diff --git a/libebackend/e-authentication-session.c b/libebackend/e-authentication-session.c
index 53a593b..0e6ebd1 100644
--- a/libebackend/e-authentication-session.c
+++ b/libebackend/e-authentication-session.c
@@ -372,6 +372,319 @@ authentication_session_constructed (GObject *object)
}
}
+/* Helper for authentication_session_execute() */
+static void
+authentication_session_execute_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ async_context->auth_result =
+ e_authentication_session_execute_sync (
+ E_AUTHENTICATION_SESSION (object),
+ cancellable, &error);
+
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
+}
+
+static EAuthenticationSessionResult
+authentication_session_execute_sync (EAuthenticationSession *session,
+ GCancellable *cancellable,
+ GError **error)
+{
+ ESourceAuthenticator *authenticator;
+ EAuthenticationSessionResult session_result;
+ ESourceAuthenticationResult auth_result;
+ ESourceRegistryServer *server;
+ ESource *source;
+ GcrPrompt *prompt;
+ GString *password_string;
+ gboolean allow_auth_prompt;
+ const gchar *label;
+ const gchar *source_uid;
+ const gchar *prompt_password;
+ gchar *stored_password = NULL;
+ gboolean success;
+ GError *local_error = NULL;
+
+ /* XXX I moved the execute() operation into a class method thinking
+ * we might someday want to subclass EAuthenticationSession and
+ * override this method to make it behave differently.
+ *
+ * It would be a little premature to do this now, but we might
+ * also want to use the basic algorithm here as a template and
+ * turn the password lookup/delete/store operations into class
+ * methods that could also be overridden. I reserved adequate
+ * space in the class struct for this should the need arise.
+ *
+ * For now though we'll keep it simple. I don't want to over-
+ * engineer this too much in trying to make it future-proof.
+ */
+
+ authentication_session_msg (session, "Initiated");
+
+ server = e_authentication_session_get_server (session);
+ source_uid = e_authentication_session_get_source_uid (session);
+ authenticator = e_authentication_session_get_authenticator (session);
+
+ success = e_authentication_session_lookup_password_sync (
+ session, cancellable, &stored_password, error);
+
+ if (!success) {
+ session_result = E_AUTHENTICATION_SESSION_ERROR;
+ goto exit;
+ }
+
+ auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
+
+ /* If we found a stored password, signal the client without
+ * interrupting the user. Note, if the client responds with
+ * REJECTED, we'll have to interrupt the user after all. */
+ if (stored_password != NULL) {
+ password_string = g_string_new (stored_password);
+
+ auth_result = e_source_authenticator_try_password_sync (
+ authenticator, password_string, cancellable, error);
+
+ g_string_free (password_string, TRUE);
+ password_string = NULL;
+
+ g_free (stored_password);
+ stored_password = NULL;
+ }
+
+ if (auth_result == E_SOURCE_AUTHENTICATION_ERROR) {
+ session_result = E_AUTHENTICATION_SESSION_ERROR;
+ goto exit;
+ }
+
+ if (auth_result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
+ session_result = E_AUTHENTICATION_SESSION_SUCCESS;
+ goto exit;
+ }
+
+ g_warn_if_fail (auth_result == E_SOURCE_AUTHENTICATION_REJECTED);
+
+ /* The stored password is bad so delete it from the keyring.
+ * Failure here does not affect the outcome of this operation,
+ * but leave a breadcrumb as evidence that something went wrong. */
+
+ e_authentication_session_delete_password_sync (
+ session, cancellable, &local_error);
+
+ if (local_error != NULL) {
+ g_warning ("%s: %s", G_STRFUNC, local_error->message);
+ g_clear_error (&local_error);
+ }
+
+ /* This will return NULL if the authenticating data source
+ * has not yet been submitted to the D-Bus registry service. */
+ source = e_source_registry_server_ref_source (server, source_uid);
+ if (source != NULL) {
+ allow_auth_prompt =
+ e_server_side_source_get_allow_auth_prompt (
+ E_SERVER_SIDE_SOURCE (source));
+ g_object_unref (source);
+ } else {
+ allow_auth_prompt = TRUE;
+ }
+
+ /* Check if we're allowed to interrupt the user for a password.
+ * If not, we have no choice but to dismiss the authentication
+ * request. */
+ if (!allow_auth_prompt) {
+ session_result = E_AUTHENTICATION_SESSION_DISMISSED;
+ goto exit;
+ }
+
+ /* Configure a system prompt. */
+
+ prompt = gcr_system_prompt_open (
+ SYSTEM_PROMPT_TIMEOUT, cancellable, error);
+
+ if (prompt == NULL) {
+ session_result = E_AUTHENTICATION_SESSION_ERROR;
+ goto exit;
+ }
+
+ g_object_bind_property (
+ session, "prompt-title",
+ prompt, "title",
+ G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property (
+ session, "prompt-message",
+ prompt, "message",
+ G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property (
+ session, "prompt-description",
+ prompt, "description",
+ G_BINDING_SYNC_CREATE);
+
+ label = _("Add this password to your keyring");
+ gcr_prompt_set_choice_label (prompt, label);
+ gcr_prompt_set_choice_chosen (prompt, TRUE);
+
+try_again:
+
+ /* Prompt the user for a password. */
+
+ prompt_password = gcr_prompt_password (
+ prompt, cancellable, &local_error);
+
+ if (local_error != NULL) {
+ session_result = E_AUTHENTICATION_SESSION_ERROR;
+ g_propagate_error (error, local_error);
+ local_error = NULL;
+ goto close_prompt;
+ }
+
+ /* No password and no error indicates a dismissal. */
+ if (prompt_password == NULL) {
+ session_result = E_AUTHENTICATION_SESSION_DISMISSED;
+ goto close_prompt;
+ }
+
+ /* Attempt authentication with the provided password. */
+
+ password_string = g_string_new (prompt_password);
+
+ auth_result = e_source_authenticator_try_password_sync (
+ authenticator, password_string, cancellable, error);
+
+ g_string_free (password_string, TRUE);
+ password_string = NULL;
+
+ if (auth_result == E_SOURCE_AUTHENTICATION_ERROR) {
+ session_result = E_AUTHENTICATION_SESSION_ERROR;
+ goto close_prompt;
+ }
+
+ if (auth_result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
+ gboolean permanently;
+
+ permanently = gcr_prompt_get_choice_chosen (prompt);
+ session_result = E_AUTHENTICATION_SESSION_SUCCESS;
+
+ /* Failure here does not affect the outcome of this
+ * operation, but leave a breadcrumb as evidence that
+ * something went wrong. */
+
+ e_authentication_session_store_password_sync (
+ session, prompt_password, permanently,
+ cancellable, &local_error);
+
+ if (local_error != NULL) {
+ g_warning ("%s: %s", G_STRFUNC, local_error->message);
+ g_clear_error (&local_error);
+ }
+
+ goto close_prompt;
+ }
+
+ g_warn_if_fail (auth_result == E_SOURCE_AUTHENTICATION_REJECTED);
+
+ gcr_prompt_set_warning (prompt, _("Password was incorrect"));
+
+ goto try_again;
+
+close_prompt:
+
+ /* Failure here does not affect the outcome of this operation,
+ * but leave a breadcrumb as evidence that something went wrong. */
+
+ gcr_system_prompt_close (
+ GCR_SYSTEM_PROMPT (prompt),
+ cancellable, &local_error);
+
+ if (local_error != NULL) {
+ g_warning ("%s: %s", G_STRFUNC, local_error->message);
+ g_clear_error (&local_error);
+ }
+
+ g_object_unref (prompt);
+
+exit:
+
+ switch (session_result) {
+ case E_AUTHENTICATION_SESSION_ERROR:
+ authentication_session_msg (
+ session, "Complete (ERROR)");
+ break;
+ case E_AUTHENTICATION_SESSION_SUCCESS:
+ authentication_session_msg (
+ session, "Complete (SUCCESS)");
+ break;
+ case E_AUTHENTICATION_SESSION_DISMISSED:
+ authentication_session_msg (
+ session, "Complete (DISMISSED)");
+ break;
+ default:
+ g_warn_if_reached ();
+ }
+
+ return session_result;
+}
+
+static void
+authentication_session_execute (EAuthenticationSession *session,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_if_fail (E_IS_AUTHENTICATION_SESSION (session));
+
+ async_context = g_slice_new0 (AsyncContext);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (session), callback, user_data,
+ e_authentication_session_execute);
+
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, authentication_session_execute_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static EAuthenticationSessionResult
+authentication_session_execute_finish (EAuthenticationSession *session,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (session),
+ e_authentication_session_execute),
+ E_AUTHENTICATION_SESSION_DISMISSED);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return E_AUTHENTICATION_SESSION_ERROR;
+
+ return async_context->auth_result;
+}
+
static void
e_authentication_session_class_init (EAuthenticationSessionClass *class)
{
@@ -387,6 +700,10 @@ e_authentication_session_class_init (EAuthenticationSessionClass *class)
object_class->finalize = authentication_session_finalize;
object_class->constructed = authentication_session_constructed;
+ class->execute_sync = authentication_session_execute_sync;
+ class->execute = authentication_session_execute;
+ class->execute_finish = authentication_session_execute_finish;
+
g_object_class_install_property (
object_class,
PROP_AUTHENTICATOR,
@@ -792,29 +1109,9 @@ e_authentication_session_set_prompt_description (EAuthenticationSession *session
g_free (session->priv->prompt_description);
session->priv->prompt_description = g_strdup (prompt_description);
- g_mutex_unlock (session->priv->property_lock);
-
- g_object_notify (G_OBJECT (session), "prompt-description");
-}
-
-/* Helper for e_authentication_session_execute() */
-static void
-authentication_session_execute_thread (GSimpleAsyncResult *simple,
- GObject *object,
- GCancellable *cancellable)
-{
- AsyncContext *async_context;
- GError *error = NULL;
-
- async_context = g_simple_async_result_get_op_res_gpointer (simple);
-
- async_context->auth_result =
- e_authentication_session_execute_sync (
- E_AUTHENTICATION_SESSION (object),
- cancellable, &error);
+ g_mutex_unlock (session->priv->property_lock);
- if (error != NULL)
- g_simple_async_result_take_error (simple, error);
+ g_object_notify (G_OBJECT (session), "prompt-description");
}
/**
@@ -846,229 +1143,18 @@ e_authentication_session_execute_sync (EAuthenticationSession *session,
GCancellable *cancellable,
GError **error)
{
- ESourceAuthenticator *authenticator;
- EAuthenticationSessionResult session_result;
- ESourceAuthenticationResult auth_result;
- ESourceRegistryServer *server;
- ESource *source;
- GcrPrompt *prompt;
- GString *password_string;
- gboolean allow_auth_prompt;
- const gchar *label;
- const gchar *source_uid;
- const gchar *prompt_password;
- gchar *stored_password = NULL;
- gboolean success;
- GError *local_error = NULL;
+ EAuthenticationSessionClass *class;
g_return_val_if_fail (
E_IS_AUTHENTICATION_SESSION (session),
E_AUTHENTICATION_SESSION_DISMISSED);
- authentication_session_msg (session, "Initiated");
-
- server = e_authentication_session_get_server (session);
- source_uid = e_authentication_session_get_source_uid (session);
- authenticator = e_authentication_session_get_authenticator (session);
-
- success = e_authentication_session_lookup_password_sync (
- session, cancellable, &stored_password, error);
-
- if (!success) {
- session_result = E_AUTHENTICATION_SESSION_ERROR;
- goto exit;
- }
-
- auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
-
- /* If we found a stored password, signal the client without
- * interrupting the user. Note, if the client responds with
- * REJECTED, we'll have to interrupt the user after all. */
- if (stored_password != NULL) {
- password_string = g_string_new (stored_password);
-
- auth_result = e_source_authenticator_try_password_sync (
- authenticator, password_string, cancellable, error);
-
- g_string_free (password_string, TRUE);
- password_string = NULL;
-
- g_free (stored_password);
- stored_password = NULL;
- }
-
- if (auth_result == E_SOURCE_AUTHENTICATION_ERROR) {
- session_result = E_AUTHENTICATION_SESSION_ERROR;
- goto exit;
- }
-
- if (auth_result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
- session_result = E_AUTHENTICATION_SESSION_SUCCESS;
- goto exit;
- }
-
- g_warn_if_fail (auth_result == E_SOURCE_AUTHENTICATION_REJECTED);
-
- /* The stored password is bad so delete it from the keyring.
- * Failure here does not affect the outcome of this operation,
- * but leave a breadcrumb as evidence that something went wrong. */
-
- e_authentication_session_delete_password_sync (
- session, cancellable, &local_error);
-
- if (local_error != NULL) {
- g_warning ("%s: %s", G_STRFUNC, local_error->message);
- g_clear_error (&local_error);
- }
-
- /* This will return NULL if the authenticating data source
- * has not yet been submitted to the D-Bus registry service. */
- source = e_source_registry_server_ref_source (server, source_uid);
- if (source != NULL) {
- allow_auth_prompt =
- e_server_side_source_get_allow_auth_prompt (
- E_SERVER_SIDE_SOURCE (source));
- g_object_unref (source);
- } else {
- allow_auth_prompt = TRUE;
- }
-
- /* Check if we're allowed to interrupt the user for a password.
- * If not, we have no choice but to dismiss the authentication
- * request. */
- if (!allow_auth_prompt) {
- session_result = E_AUTHENTICATION_SESSION_DISMISSED;
- goto exit;
- }
-
- /* Configure a system prompt. */
-
- prompt = gcr_system_prompt_open (
- SYSTEM_PROMPT_TIMEOUT, cancellable, error);
-
- if (prompt == NULL) {
- session_result = E_AUTHENTICATION_SESSION_ERROR;
- goto exit;
- }
-
- g_object_bind_property (
- session, "prompt-title",
- prompt, "title",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- session, "prompt-message",
- prompt, "message",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- session, "prompt-description",
- prompt, "description",
- G_BINDING_SYNC_CREATE);
-
- label = _("Add this password to your keyring");
- gcr_prompt_set_choice_label (prompt, label);
- gcr_prompt_set_choice_chosen (prompt, TRUE);
-
-try_again:
-
- /* Prompt the user for a password. */
-
- prompt_password = gcr_prompt_password (
- prompt, cancellable, &local_error);
-
- if (local_error != NULL) {
- session_result = E_AUTHENTICATION_SESSION_ERROR;
- g_propagate_error (error, local_error);
- local_error = NULL;
- goto close_prompt;
- }
-
- /* No password and no error indicates a dismissal. */
- if (prompt_password == NULL) {
- session_result = E_AUTHENTICATION_SESSION_DISMISSED;
- goto close_prompt;
- }
-
- /* Attempt authentication with the provided password. */
-
- password_string = g_string_new (prompt_password);
-
- auth_result = e_source_authenticator_try_password_sync (
- authenticator, password_string, cancellable, error);
-
- g_string_free (password_string, TRUE);
- password_string = NULL;
-
- if (auth_result == E_SOURCE_AUTHENTICATION_ERROR) {
- session_result = E_AUTHENTICATION_SESSION_ERROR;
- goto close_prompt;
- }
-
- if (auth_result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
- gboolean permanently;
-
- permanently = gcr_prompt_get_choice_chosen (prompt);
- session_result = E_AUTHENTICATION_SESSION_SUCCESS;
-
- /* Failure here does not affect the outcome of this
- * operation, but leave a breadcrumb as evidence that
- * something went wrong. */
-
- e_authentication_session_store_password_sync (
- session, prompt_password, permanently,
- cancellable, &local_error);
-
- if (local_error != NULL) {
- g_warning ("%s: %s", G_STRFUNC, local_error->message);
- g_clear_error (&local_error);
- }
-
- goto close_prompt;
- }
-
- g_warn_if_fail (auth_result == E_SOURCE_AUTHENTICATION_REJECTED);
-
- gcr_prompt_set_warning (prompt, _("Password was incorrect"));
-
- goto try_again;
-
-close_prompt:
-
- /* Failure here does not affect the outcome of this operation,
- * but leave a breadcrumb as evidence that something went wrong. */
-
- gcr_system_prompt_close (
- GCR_SYSTEM_PROMPT (prompt),
- cancellable, &local_error);
-
- if (local_error != NULL) {
- g_warning ("%s: %s", G_STRFUNC, local_error->message);
- g_clear_error (&local_error);
- }
-
- g_object_unref (prompt);
-
-exit:
-
- switch (session_result) {
- case E_AUTHENTICATION_SESSION_ERROR:
- authentication_session_msg (
- session, "Complete (ERROR)");
- break;
- case E_AUTHENTICATION_SESSION_SUCCESS:
- authentication_session_msg (
- session, "Complete (SUCCESS)");
- break;
- case E_AUTHENTICATION_SESSION_DISMISSED:
- authentication_session_msg (
- session, "Complete (DISMISSED)");
- break;
- default:
- g_warn_if_reached ();
- }
+ class = E_AUTHENTICATION_SESSION_GET_CLASS (session);
+ g_return_val_if_fail (
+ class->execute_sync != NULL,
+ E_AUTHENTICATION_SESSION_DISMISSED);
- return session_result;
+ return class->execute_sync (session, cancellable, error);
}
/**
@@ -1094,27 +1180,15 @@ e_authentication_session_execute (EAuthenticationSession *session,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *simple;
- AsyncContext *async_context;
+ EAuthenticationSessionClass *class;
g_return_if_fail (E_IS_AUTHENTICATION_SESSION (session));
- async_context = g_slice_new0 (AsyncContext);
-
- simple = g_simple_async_result_new (
- G_OBJECT (session), callback, user_data,
- e_authentication_session_execute);
-
- g_simple_async_result_set_check_cancellable (simple, cancellable);
-
- g_simple_async_result_set_op_res_gpointer (
- simple, async_context, (GDestroyNotify) async_context_free);
-
- g_simple_async_result_run_in_thread (
- simple, authentication_session_execute_thread,
- io_priority, cancellable);
+ class = E_AUTHENTICATION_SESSION_GET_CLASS (session);
+ g_return_if_fail (class->execute != NULL);
- g_object_unref (simple);
+ return class->execute (
+ session, io_priority, cancellable, callback, user_data);
}
/**
@@ -1138,22 +1212,21 @@ e_authentication_session_execute_finish (EAuthenticationSession *session,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
- AsyncContext *async_context;
+ EAuthenticationSessionClass *class;
g_return_val_if_fail (
- g_simple_async_result_is_valid (
- result, G_OBJECT (session),
- e_authentication_session_execute),
+ E_IS_AUTHENTICATION_SESSION (session),
+ E_AUTHENTICATION_SESSION_DISMISSED);
+ g_return_val_if_fail (
+ G_IS_ASYNC_RESULT (result),
E_AUTHENTICATION_SESSION_DISMISSED);
- simple = G_SIMPLE_ASYNC_RESULT (result);
- async_context = g_simple_async_result_get_op_res_gpointer (simple);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return E_AUTHENTICATION_SESSION_ERROR;
+ class = E_AUTHENTICATION_SESSION_GET_CLASS (session);
+ g_return_val_if_fail (
+ class->execute_finish != NULL,
+ E_AUTHENTICATION_SESSION_DISMISSED);
- return async_context->auth_result;
+ return class->execute_finish (session, result, error);
}
/* Helper for e_authentication_session_store_password() */
diff --git a/libebackend/e-authentication-session.h b/libebackend/e-authentication-session.h
index bcd896e..4ef4e78 100644
--- a/libebackend/e-authentication-session.h
+++ b/libebackend/e-authentication-session.h
@@ -82,6 +82,25 @@ struct _EAuthenticationSession {
struct _EAuthenticationSessionClass {
GObjectClass parent_class;
+
+ /* Methods */
+ EAuthenticationSessionResult
+ (*execute_sync) (EAuthenticationSession *session,
+ GCancellable *cancellable,
+ GError **error);
+ void (*execute) (EAuthenticationSession *session,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ EAuthenticationSessionResult
+ (*execute_finish)
+ (EAuthenticationSession *session,
+ GAsyncResult *result,
+ GError **error);
+
+ /* Reserved slots. */
+ gpointer reserved[16];
};
GQuark e_authentication_session_error_quark
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]