[evolution-data-server/account-mgmt] EAuthenticationSession: Add an execute() class method.



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]