[evolution-kolab/experimental: 5/6] CamelKolabSession: Add a "backend" constructor property.



commit e303d9e670346291b90bf54d237617cdbc6ecf06
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Aug 28 23:31:12 2012 -0400

    CamelKolabSession: Add a "backend" constructor property.
    
    CamelKolabSession's authenticate_sync() needs an EBackend and an
    EMailAuthenticator from libemail-engine to perform authentication.
    
    The EBackend must be passed down through various configure() functions.
    
    This also breaks test-kolab-mail-access.c for the moment.

 src/addressbook/e-book-backend-kolab.c             |    1 +
 src/calendar/e-cal-backend-kolab.c                 |    1 +
 src/collection/e-kolab-backend.c                   |   10 +-
 src/libekolab/camel-kolab-session.c                |  190 +++++++++++++-------
 src/libekolab/camel-kolab-session.h                |   15 ++-
 src/libekolab/kolab-mail-access.c                  |    4 +
 src/libekolab/kolab-mail-access.h                  |    1 +
 src/libekolab/kolab-mail-imap-client.c             |    7 +-
 src/libekolab/kolab-mail-imap-client.h             |    3 +
 .../integration/libekolab/test-kolab-mail-access.c |    4 +-
 10 files changed, 156 insertions(+), 80 deletions(-)
---
diff --git a/src/addressbook/e-book-backend-kolab.c b/src/addressbook/e-book-backend-kolab.c
index c22b33d..a333dc8 100644
--- a/src/addressbook/e-book-backend-kolab.c
+++ b/src/addressbook/e-book-backend-kolab.c
@@ -376,6 +376,7 @@ book_backend_kolab_open (EBookBackendSync *backend,
 
 	/* configure and bring up KolabMailAccess instance */
 	ok = kolab_mail_access_configure (priv->book_koma,
+	                                  E_BACKEND (backend),
 	                                  ksettings,
 	                                  &tmp_err);
 	if (! ok)
diff --git a/src/calendar/e-cal-backend-kolab.c b/src/calendar/e-cal-backend-kolab.c
index b829781..9b3109b 100644
--- a/src/calendar/e-cal-backend-kolab.c
+++ b/src/calendar/e-cal-backend-kolab.c
@@ -436,6 +436,7 @@ cal_backend_kolab_open (ECalBackendSync *backend,
 
 	/* configure and bring up KolabMailAccess instance */
 	ok = kolab_mail_access_configure (priv->cal_koma,
+	                                  E_BACKEND (backend),
 	                                  ksettings,
 	                                  &tmp_err);
 	if (! ok)
diff --git a/src/collection/e-kolab-backend.c b/src/collection/e-kolab-backend.c
index bd52aa2..0c28a0a 100644
--- a/src/collection/e-kolab-backend.c
+++ b/src/collection/e-kolab-backend.c
@@ -336,7 +336,9 @@ e_kolab_backend_ref_mail_access_sync (EKolabBackend *backend,
 
 	koma = g_object_new (KOLAB_TYPE_MAIL_ACCESS, NULL);
 
-	if (!kolab_mail_access_configure (koma, settings_handler, error)) {
+	success = kolab_mail_access_configure (
+		koma, E_BACKEND (backend), settings_handler, error);
+	if (!success) {
 		g_object_unref (settings_handler);
 		g_object_unref (koma);
 		return NULL;
@@ -348,10 +350,8 @@ e_kolab_backend_ref_mail_access_sync (EKolabBackend *backend,
 		return NULL;
 	}
 
-	success = e_backend_authenticate_sync (
-		E_BACKEND (backend),
-		E_SOURCE_AUTHENTICATOR (koma),
-		cancellable, error);
+	success = kolab_mail_access_set_opmode (
+		koma, KOLAB_MAIL_ACCESS_OPMODE_ONLINE, cancellable, error);
 	if (!success) {
 		g_object_unref (settings_handler);
 		g_object_unref (koma);
diff --git a/src/libekolab/camel-kolab-session.c b/src/libekolab/camel-kolab-session.c
index 56e7a87..9c6957e 100644
--- a/src/libekolab/camel-kolab-session.c
+++ b/src/libekolab/camel-kolab-session.c
@@ -44,6 +44,7 @@
 #include <prtypes.h>
 
 #include <libedataserverui/libedataserverui.h>
+#include <libemail-engine/e-mail-authenticator.h>
 
 /* Kolab error reporting */
 #include <libekolabutil/kolab-util-error.h>
@@ -57,12 +58,18 @@ static gchar *nss_tok_pin = NULL; /* FIXME better solution for this */
 
 /*----------------------------------------------------------------------------*/
 
-typedef struct _CamelKolabSessionPrivate CamelKolabSessionPrivate;
 struct _CamelKolabSessionPrivate {
 	/* TODO get rid of this workaround */
 	gchar *nss_tok_pwd;
 
 	gboolean is_initialized;
+
+	GWeakRef backend;
+};
+
+enum {
+	PROP_0,
+	PROP_BACKEND
 };
 
 #define CAMEL_KOLAB_SESSION_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CAMEL_TYPE_KOLAB_SESSION, CamelKolabSessionPrivate))
@@ -74,13 +81,57 @@ G_DEFINE_TYPE (CamelKolabSession, camel_kolab_session, CAMEL_TYPE_SESSION)
 static void
 camel_kolab_session_init (CamelKolabSession *self)
 {
-	CamelKolabSessionPrivate *priv = NULL;
+	self->priv = CAMEL_KOLAB_SESSION_PRIVATE (self);
+}
 
-	g_assert (CAMEL_IS_KOLAB_SESSION (self));
-	priv = CAMEL_KOLAB_SESSION_PRIVATE (self);
+static void
+camel_kolab_session_set_backend (CamelKolabSession *session,
+                                 EBackend *backend)
+{
+	g_return_if_fail (E_IS_BACKEND (backend));
+
+	g_weak_ref_set (&session->priv->backend, backend);
+}
+
+static void
+camel_kolab_session_set_property (GObject *object,
+                                  guint property_id,
+                                  const GValue *value,
+                                  GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_BACKEND:
+			camel_kolab_session_set_backend (
+				CAMEL_KOLAB_SESSION (object),
+				g_value_get_object (value));
+			return;
+
+		default:
+			break;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+camel_kolab_session_get_property (GObject *object,
+                                  guint property_id,
+                                  GValue *value,
+                                  GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_BACKEND:
+			g_value_take_object (
+				value,
+				camel_kolab_session_ref_backend (
+				CAMEL_KOLAB_SESSION (object)));
+			return;
+
+		default:
+			break;
+	}
 
-	priv->nss_tok_pwd = NULL;
-	priv->is_initialized = FALSE;
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 }
 
 static void
@@ -104,6 +155,8 @@ camel_kolab_session_finalize (GObject *object)
 	if (priv->nss_tok_pwd != NULL)
 		g_free (priv->nss_tok_pwd);
 
+	g_weak_ref_set (&priv->backend, NULL);
+
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (camel_kolab_session_parent_class)->finalize (object);
 }
@@ -137,11 +190,12 @@ kolab_session_authenticate_sync (CamelSession *session,
                                  GCancellable *cancellable,
                                  GError **error)
 {
+	CamelKolabSession *kolab_session;
+	ESourceAuthenticator *auth;
 	CamelServiceAuthType *authtype = NULL;
 	CamelAuthenticationResult result;
-	CamelProvider *provider;
-	const gchar *password;
-	guint32 password_flags;
+	EBackend *backend;
+	gboolean authenticated;
 	GError *local_error = NULL;
 
 	/* this is a dupe of mail_session_authenticate_sync()
@@ -155,7 +209,9 @@ kolab_session_authenticate_sync (CamelSession *session,
 	/* Do not chain up.  Camel's default method is only an example for
 	 * subclasses to follow.  Instead we mimic most of its logic here. */
 
-	provider = camel_service_get_provider (service);
+	/* Treat a mechanism name of "none" as NULL. */
+	if (g_strcmp0 (mechanism, "none") == 0)
+		mechanism = NULL;
 
 	/* APOP is one case where a non-SASL mechanism name is passed, so
 	 * don't bail if the CamelServiceAuthType struct comes back NULL. */
@@ -165,11 +221,13 @@ kolab_session_authenticate_sync (CamelSession *session,
 	/* If the SASL mechanism does not involve a user
 	 * password, then it gets one shot to authenticate. */
 	if (authtype != NULL && !authtype->need_password) {
-		result = camel_service_authenticate_sync (service, mechanism, cancellable, error);
+		result = camel_service_authenticate_sync (
+			service, mechanism, cancellable, error);
 		if (result == CAMEL_AUTHENTICATION_REJECTED)
-			g_set_error (error, CAMEL_SERVICE_ERROR,
-			             CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
-			             _("%s authentication failed"), mechanism);
+			g_set_error (
+				error, CAMEL_SERVICE_ERROR,
+				CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
+				_("%s authentication failed"), mechanism);
 		return (result == CAMEL_AUTHENTICATION_ACCEPTED);
 	}
 
@@ -190,9 +248,8 @@ kolab_session_authenticate_sync (CamelSession *session,
 		 *     detect errors. */
 		sasl = camel_sasl_new (service_name, mechanism, service);
 		if (sasl != NULL) {
-			success = camel_sasl_try_empty_password_sync (sasl,
-			                                              cancellable,
-			                                              &local_error);
+			success = camel_sasl_try_empty_password_sync (
+				sasl, cancellable, &local_error);
 			g_object_unref (sasl);
 		}
 
@@ -207,61 +264,19 @@ kolab_session_authenticate_sync (CamelSession *session,
 
 	g_clear_error (&local_error);
 
-	password_flags = CAMEL_SESSION_PASSWORD_SECRET;
-
- retry:
-	password = camel_service_get_password (service);
-
-	if (password == NULL) {
-		CamelSettings *settings;
-		CamelNetworkSettings *network_settings;
-		const gchar *host;
-		const gchar *user;
-		gchar *prompt;
-		gchar *new_passwd;
-
-		settings = camel_service_ref_settings (service);
-
-		network_settings = CAMEL_NETWORK_SETTINGS (settings);
-		host = camel_network_settings_get_host (network_settings);
-		user = camel_network_settings_get_user (network_settings);
-
-		prompt = camel_session_build_password_prompt (provider->name,
-		                                              user,
-		                                              host);
+	kolab_session = CAMEL_KOLAB_SESSION (session);
+	backend = camel_kolab_session_ref_backend (kolab_session);
 
-		g_object_unref (settings);
+	auth = e_mail_authenticator_new (service, mechanism);
 
-		new_passwd = camel_session_get_password (session, service, prompt, "password",
-		                                         password_flags, &local_error);
-		camel_service_set_password (service, new_passwd);
-		password = camel_service_get_password (service);
-		g_free (new_passwd);
+	authenticated = e_backend_authenticate_sync (
+		backend, auth, cancellable, error);
 
-		g_free (prompt);
-
-		if (local_error != NULL) {
-			g_propagate_error (error, local_error);
-			return FALSE;
-		}
-
-		if (password == NULL) {
-			g_set_error (error, CAMEL_SERVICE_ERROR,
-			             CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
-			             _("No password was provided"));
-			return FALSE;
-		}
-	}
+	g_object_unref (auth);
 
-	result = camel_service_authenticate_sync (service, mechanism, cancellable, error);
+	g_object_unref (backend);
 
-	if (result == CAMEL_AUTHENTICATION_REJECTED) {
-		password_flags |= CAMEL_SESSION_PASSWORD_REPROMPT;
-		camel_service_set_password (service, NULL);
-		goto retry;
-	}
-
-	return (result == CAMEL_AUTHENTICATION_ACCEPTED);
+	return authenticated;
 }
 
 /*----------------------------------------------------------------------------*/
@@ -276,18 +291,55 @@ camel_kolab_session_class_init (CamelKolabSessionClass *klass)
 
 	g_type_class_add_private (klass, sizeof (CamelKolabSessionPrivate));
 
-	object_class->set_property = G_OBJECT_CLASS (parent_class)->set_property;
-	object_class->get_property = G_OBJECT_CLASS (parent_class)->get_property;
+	object_class->set_property = camel_kolab_session_set_property;
+	object_class->get_property = camel_kolab_session_get_property;
 	object_class->dispose = camel_kolab_session_dispose;
 	object_class->finalize = camel_kolab_session_finalize;
 
 	session_class->add_service = parent_class->add_service;
 	session_class->authenticate_sync = kolab_session_authenticate_sync;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_BACKEND,
+		g_param_spec_object (
+			"backend",
+			"Backend",
+			"Backend used for authentication",
+			E_TYPE_BACKEND,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT_ONLY |
+			G_PARAM_STATIC_STRINGS));
 }
 
 /*----------------------------------------------------------------------------*/
 /* public API */
 
+CamelKolabSession *
+camel_kolab_session_new (EBackend *backend,
+                         const gchar *user_data_dir,
+                         const gchar *user_cache_dir)
+{
+	g_return_val_if_fail (E_IS_BACKEND (backend), NULL);
+	g_return_val_if_fail (user_data_dir != NULL, NULL);
+	g_return_val_if_fail (user_cache_dir != NULL, NULL);
+
+	return g_object_new (
+		CAMEL_TYPE_KOLAB_SESSION,
+		"backend", backend,
+		"user-data-dir", user_data_dir,
+		"user-cache-dir", user_cache_dir,
+		NULL);
+}
+
+EBackend *
+camel_kolab_session_ref_backend (CamelKolabSession *self)
+{
+	g_return_val_if_fail (CAMEL_IS_KOLAB_SESSION (self), NULL);
+
+	return g_weak_ref_get (&self->priv->backend);
+}
+
 gboolean
 camel_kolab_session_bringup (CamelKolabSession *self,
                              GCancellable *cancellable,
diff --git a/src/libekolab/camel-kolab-session.h b/src/libekolab/camel-kolab-session.h
index 6da4bcc..3aeefaa 100644
--- a/src/libekolab/camel-kolab-session.h
+++ b/src/libekolab/camel-kolab-session.h
@@ -44,6 +44,8 @@
 #include <glib-object.h>
 #include <gio/gio.h>
 
+#include <libebackend/libebackend.h>
+
 #include <libekolabutil/camel-system-headers.h>
 
 /*----------------------------------------------------------------------------*/
@@ -75,12 +77,15 @@
 G_BEGIN_DECLS
 
 typedef struct _CamelKolabSession CamelKolabSession;
+typedef struct _CamelKolabSessionClass CamelKolabSessionClass;
+typedef struct _CamelKolabSessionPrivate CamelKolabSessionPrivate;
+
 struct _CamelKolabSession {
 	CamelSession parent;
+	CamelKolabSessionPrivate *priv;
 };
 
 
-typedef struct _CamelKolabSessionClass CamelKolabSessionClass;
 struct _CamelKolabSessionClass {
 	CamelSessionClass parent_class;
 	/* TODO check what else is needed here */
@@ -89,6 +94,14 @@ struct _CamelKolabSessionClass {
 GType
 camel_kolab_session_get_type (void);
 
+CamelKolabSession *
+camel_kolab_session_new (EBackend *backend,
+                         const gchar *user_data_dir,
+                         const gchar *user_cache_dir);
+
+EBackend *
+camel_kolab_session_ref_backend (CamelKolabSession *self);
+
 gboolean
 camel_kolab_session_bringup (CamelKolabSession *self,
                              GCancellable *cancellable,
diff --git a/src/libekolab/kolab-mail-access.c b/src/libekolab/kolab-mail-access.c
index dece45a..64e2651 100644
--- a/src/libekolab/kolab-mail-access.c
+++ b/src/libekolab/kolab-mail-access.c
@@ -1629,6 +1629,7 @@ mail_access_get_strans_func (KolabMailAccess *self,
 /**
  * kolab_mail_access_configure:
  * @self: a #KolabMailAccess instance
+ * @backend: an #EBackend
  * @ksettings: an already-configured #KolabSettingsHandler instance
  * @err: a #GError object (or NULL)
  *
@@ -1647,6 +1648,7 @@ mail_access_get_strans_func (KolabMailAccess *self,
  */
 gboolean
 kolab_mail_access_configure (KolabMailAccess *self,
+                             EBackend *backend,
                              KolabSettingsHandler *ksettings,
                              GError **err)
 {
@@ -1659,6 +1661,7 @@ kolab_mail_access_configure (KolabMailAccess *self,
 	GError *tmp_err = NULL;
 
 	g_assert (KOLAB_IS_MAIL_ACCESS (self));
+	g_assert (E_IS_BACKEND (backend));
 	g_assert (KOLAB_IS_SETTINGS_HANDLER (ksettings));
 	g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
 
@@ -1697,6 +1700,7 @@ kolab_mail_access_configure (KolabMailAccess *self,
 		goto exit;
 
 	ok = kolab_mail_imap_client_configure (priv->client,
+	                                       backend,
 	                                       priv->ksettings,
 	                                       priv->mimebuilder,
 	                                       &tmp_err);
diff --git a/src/libekolab/kolab-mail-access.h b/src/libekolab/kolab-mail-access.h
index 9efb3d5..49b7382 100644
--- a/src/libekolab/kolab-mail-access.h
+++ b/src/libekolab/kolab-mail-access.h
@@ -138,6 +138,7 @@ kolab_mail_access_get_type (void) G_GNUC_CONST;
 
 gboolean
 kolab_mail_access_configure (KolabMailAccess *self,
+                             EBackend *backend,
                              KolabSettingsHandler *ksettings,
                              GError **err);
 
diff --git a/src/libekolab/kolab-mail-imap-client.c b/src/libekolab/kolab-mail-imap-client.c
index 9709966..625f603 100644
--- a/src/libekolab/kolab-mail-imap-client.c
+++ b/src/libekolab/kolab-mail-imap-client.c
@@ -689,6 +689,7 @@ mail_imap_client_query_foldernames (KolabMailImapClient *self,
 
 gboolean
 kolab_mail_imap_client_configure (KolabMailImapClient *self,
+                                  EBackend *backend,
                                   KolabSettingsHandler *ksettings,
                                   KolabMailMimeBuilder *mimebuilder,
                                   GError **err)
@@ -700,6 +701,7 @@ kolab_mail_imap_client_configure (KolabMailImapClient *self,
 	GError *tmp_err = NULL;
 
 	g_assert (KOLAB_IS_MAIL_IMAP_CLIENT (self));
+	g_assert (E_IS_BACKEND (backend));
 	g_assert (KOLAB_IS_SETTINGS_HANDLER (ksettings));
 	g_assert (KOLAB_IS_MAIL_MIME_BUILDER (mimebuilder));
 	g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
@@ -754,10 +756,7 @@ kolab_mail_imap_client_configure (KolabMailImapClient *self,
 	}
 
 	/* create session object */
-	priv->session = g_object_new (CAMEL_TYPE_KOLAB_SESSION,
-	                              CAMEL_KOLAB_SESSION_PROP_DATA_DIR, data_dir,
-	                              CAMEL_KOLAB_SESSION_PROP_CACHE_DIR, cache_dir,
-	                              NULL);
+	priv->session = camel_kolab_session_new (backend, data_dir, cache_dir);
 
 	/* set to offline state first */
 	camel_session_set_online (CAMEL_SESSION (priv->session), FALSE);
diff --git a/src/libekolab/kolab-mail-imap-client.h b/src/libekolab/kolab-mail-imap-client.h
index cea72ac..31d9be8 100644
--- a/src/libekolab/kolab-mail-imap-client.h
+++ b/src/libekolab/kolab-mail-imap-client.h
@@ -70,6 +70,8 @@
 #include <glib-object.h>
 #include <gio/gio.h>
 
+#include <libebackend/libebackend.h>
+
 #include "kolab-mail-handle.h"
 #include "kolab-mail-mime-builder.h"
 #include "kolab-settings-handler.h"
@@ -104,6 +106,7 @@ kolab_mail_imap_client_get_type (void) G_GNUC_CONST;
 
 gboolean
 kolab_mail_imap_client_configure (KolabMailImapClient *self,
+                                  EBackend *backend,
                                   KolabSettingsHandler *ksettings,
                                   KolabMailMimeBuilder *mimebuilder,
                                   GError **err);
diff --git a/src/tests/integration/libekolab/test-kolab-mail-access.c b/src/tests/integration/libekolab/test-kolab-mail-access.c
index d56d060..65f8bd7 100644
--- a/src/tests/integration/libekolab/test-kolab-mail-access.c
+++ b/src/tests/integration/libekolab/test-kolab-mail-access.c
@@ -334,7 +334,9 @@ test_kolab_mail_access (KolabFolderContextID context)
 	kmailaccess = KOLAB_MAIL_ACCESS (g_object_new (KOLAB_TYPE_MAIL_ACCESS, NULL));
 
 	/* configure mail access subsystem */
-	ok = kolab_mail_access_configure (kmailaccess, ksettings, &tmp_err);
+	/* FIXME Need to pass an EBackend here.
+	 *       As currently written, this call will abort. */
+	ok = kolab_mail_access_configure (kmailaccess, NULL, ksettings, &tmp_err);
 	if (! ok)
 		goto test_part_cleanup;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]