[evolution-data-server/account-mgmt] Support GoaExchange and GoaPasswordBased.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/account-mgmt] Support GoaExchange and GoaPasswordBased.
- Date: Wed, 30 May 2012 12:14:25 +0000 (UTC)
commit 87dd0931f998ab4fa5036cc55834cec1a074adfe
Author: Matthew Barnes <mbarnes redhat com>
Date: Tue May 29 15:32:58 2012 -0400
Support GoaExchange and GoaPasswordBased.
configure.ac | 6 +-
modules/online-accounts/module-online-accounts.c | 136 ++++++++++++++++++++++
2 files changed, 141 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 669567e..775c9c0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -38,7 +38,6 @@ m4_define([gtk_minimum_version], [3.2])
m4_define([gconf_minimum_version], [2.0.0]) dnl XXX Just a Guess
m4_define([gcr_minimum_version], [3.3])
m4_define([gnome_keyring_minimum_version], [2.20.1])
-m4_define([goa_minimum_version], [3.1.1])
m4_define([libxml_minimum_version], [2.0.0]) dnl XXX Just a Guess
m4_define([libsoup_minimum_version], [2.38.1])
m4_define([libgdata_minimum_version], [0.10])
@@ -407,6 +406,11 @@ if test "x$enable_goa" = xyes; then
fi
AM_CONDITIONAL(HAVE_GOA, [test x$enable_goa = xyes])
+dnl GoaPasswordBased was introduced in version 3.5.
+if `$PKG_CONFIG --atleast-version=3.5 goa-1.0`; then
+ AC_DEFINE(HAVE_GOA_PASSWORD_BASED,1,[Have GoaPasswordBased in goa-1.0])
+fi
+
if test x$os_win32 = xno; then
PKG_CHECK_MODULES(GIO_UNIX, [gio-unix-2.0])
fi
diff --git a/modules/online-accounts/module-online-accounts.c b/modules/online-accounts/module-online-accounts.c
index 76570d2..041c963 100644
--- a/modules/online-accounts/module-online-accounts.c
+++ b/modules/online-accounts/module-online-accounts.c
@@ -19,9 +19,12 @@
/* XXX Yeah, yeah... */
#define GOA_API_IS_SUBJECT_TO_CHANGE
+#include <config.h>
#include <goa/goa.h>
+#include <gnome-keyring.h>
#include <libedataserver/e-uid.h>
+#include <libedataserver/e-data-server-util.h>
#include <libedataserver/e-source-authentication.h>
#include <libedataserver/e-source-collection.h>
#include <libedataserver/e-source-goa.h>
@@ -60,6 +63,20 @@ struct _EOnlineAccountsClass {
EExtensionClass parent_class;
};
+/* The keyring definintions are copied from e-authentication-session.c */
+
+#define KEYRING_ITEM_ATTRIBUTE_NAME "e-source-uid"
+#define KEYRING_ITEM_DISPLAY_FORMAT "Evolution Data Source %s"
+
+static GnomeKeyringPasswordSchema schema = {
+ GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ {
+ { KEYRING_ITEM_ATTRIBUTE_NAME,
+ GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
+ { NULL, 0 }
+ }
+};
+
/* Module Entry Points */
void e_module_load (GTypeModule *type_module);
void e_module_unload (GTypeModule *type_module);
@@ -82,6 +99,9 @@ online_accounts_get_backend_name (const gchar *goa_provider_type)
* of other registry modules, possibly even from 3rd party
* packages. No way around it. */
+ if (g_strcmp0 (goa_provider_type, "exchange") == 0)
+ eds_backend_name = "ews";
+
if (g_strcmp0 (goa_provider_type, "google") == 0)
eds_backend_name = "google";
@@ -176,6 +196,118 @@ online_accounts_new_source (EOnlineAccounts *extension)
return source;
}
+/* Helper for online_accounts_config_collection() */
+static void
+online_accounts_config_exchange (EOnlineAccounts *extension,
+ ESource *source,
+ GoaObject *goa_object)
+{
+#ifdef HAVE_GOA_PASSWORD_BASED
+ GoaExchange *goa_exchange;
+ ESourceExtension *source_extension;
+ const gchar *extension_name;
+
+ goa_exchange = goa_object_get_exchange (goa_object);
+
+ if (goa_exchange == NULL)
+ return;
+
+ extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+ source_extension = e_source_get_extension (source, extension_name);
+
+ g_object_bind_property (
+ goa_exchange, "host",
+ source_extension, "host",
+ G_BINDING_SYNC_CREATE);
+
+ g_object_unref (goa_exchange);
+#endif /* HAVE_GOA_PASSWORD_BASED */
+}
+
+/* Helper for online_accounts_config_collection() */
+static void
+online_accounts_config_password (EOnlineAccounts *extension,
+ ESource *source,
+ GoaObject *goa_object)
+{
+#ifdef HAVE_GOA_PASSWORD_BASED
+ GoaAccount *goa_account;
+ GoaPasswordBased *goa_password_based;
+ GnomeKeyringResult keyring_result;
+ EAsyncClosure *closure;
+ GAsyncResult *result;
+ const gchar *uid;
+ gchar *arg_id;
+ gchar *display_name;
+ gchar *password = NULL;
+ GError *error = NULL;
+
+ /* If the GNOME Online Account is password-based, we use its
+ * password to seed our own keyring entry for the collection
+ * source which avoids having to special-case authentication
+ * like we do for OAuth. Plus, if the stored password is no
+ * good we'll prompt for a new one instead of just giving up. */
+
+ goa_password_based = goa_object_get_password_based (goa_object);
+
+ if (goa_password_based == NULL)
+ return;
+
+ closure = e_async_closure_new ();
+
+ /* XXX The GOA documentation doesn't explain the string
+ * argument in goa_password_based_get_password() so
+ * we'll pass in the identity and hope for the best. */
+ goa_account = goa_object_get_account (goa_object);
+ arg_id = goa_account_dup_identity (goa_account);
+ g_object_unref (goa_account);
+
+ goa_password_based_call_get_password (
+ goa_password_based, arg_id, NULL,
+ e_async_closure_callback, closure);
+
+ g_free (arg_id);
+
+ result = e_async_closure_wait (closure);
+
+ goa_password_based_call_get_password_finish (
+ goa_password_based, &password, result, &error);
+
+ if (error != NULL) {
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ goto exit;
+ }
+
+ uid = e_source_get_uid (source);
+ display_name = g_strdup_printf (KEYRING_ITEM_DISPLAY_FORMAT, uid);
+
+ /* XXX Just call gnome-keyring synchronously. I know it's
+ * evil, but I want to know the password has been stored
+ * before returning from this function. We'll be moving
+ * to libsecret soon anyway, which is more GIO-based, so
+ * we could then reuse the EAsyncClosure here. */
+ keyring_result = gnome_keyring_store_password_sync (
+ &schema, GNOME_KEYRING_DEFAULT, display_name,
+ password, KEYRING_ITEM_ATTRIBUTE_NAME, uid, NULL);
+
+ g_free (display_name);
+
+ /* If we fail to store the password, we'll just end up prompting
+ * for a password like normal. Annoying, maybe, but not the end
+ * of the world. Still leave a breadcrumb for debugging though. */
+ if (keyring_result != GNOME_KEYRING_RESULT_OK) {
+ const gchar *message;
+ message = gnome_keyring_result_to_message (keyring_result);
+ g_warning ("%s: %s", G_STRFUNC, message);
+ }
+
+exit:
+ e_async_closure_free (closure);
+ g_object_unref (goa_password_based);
+#endif /* HAVE_GOA_PASSWORD_BASED */
+}
+
static void
online_accounts_config_collection (EOnlineAccounts *extension,
ESource *source,
@@ -242,6 +374,10 @@ online_accounts_config_collection (EOnlineAccounts *extension,
g_object_unref (goa_account);
+ /* Handle optional GOA interfaces. */
+ online_accounts_config_exchange (extension, source, goa_object);
+ online_accounts_config_password (extension, source, goa_object);
+
/* The data source should not be removable by clients. */
e_server_side_source_set_removable (
E_SERVER_SIDE_SOURCE (source), FALSE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]