[evolution-ews] Move authentication of backends back to the client



commit 115540270568f7730730f04d49ce118cb913497d
Author: Milan Crha <mcrha redhat com>
Date:   Mon Feb 2 14:52:23 2015 +0100

    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.

 configure.ac                                       |    4 +-
 src/addressbook/e-book-backend-ews.c               |  188 ++++++-------
 src/calendar/e-cal-backend-ews.c                   |  114 ++++----
 src/collection/e-ews-backend.c                     |   85 +++++--
 src/collection/e-ews-backend.h                     |    1 +
 src/configuration/e-ews-config-utils.c             |  243 ++++++++---------
 src/configuration/e-ews-config-utils.h             |   20 ++-
 src/configuration/e-ews-edit-folder-permissions.c  |    2 +-
 src/configuration/e-mail-config-ews-autodiscover.c |  212 ++++++++-------
 .../e-mail-config-ews-delegates-page.c             |  286 ++++++++++----------
 src/configuration/e-mail-config-ews-gal.c          |   18 +-
 .../e-mail-config-ews-oal-combo-box.c              |  238 +++++++++--------
 src/configuration/e-mail-config-ews-ooo-page.c     |  210 +++++++--------
 src/server/e-ews-connection.c                      |  155 +++++------
 src/server/e-ews-connection.h                      |    9 +
 15 files changed, 916 insertions(+), 869 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 6ca3e7d..42cf9fa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -55,8 +55,8 @@ m4_define([eds_minimum_version], [$EVOREQVER])
 m4_define([evo_minimum_version], [$EVOREQVER])
 
 dnl Keep these two definitions in agreement.
-m4_define([glib_minimum_version], [2.34])
-m4_define([glib_encoded_version], [GLIB_VERSION_2_34])
+m4_define([glib_minimum_version], [2.40])
+m4_define([glib_encoded_version], [GLIB_VERSION_2_40])
 
 dnl Keep these two definitions in agreement.
 m4_define([gdk_minimum_version], [3.0])
diff --git a/src/addressbook/e-book-backend-ews.c b/src/addressbook/e-book-backend-ews.c
index 43beef1..61ab157 100644
--- a/src/addressbook/e-book-backend-ews.c
+++ b/src/addressbook/e-book-backend-ews.c
@@ -129,8 +129,6 @@ enum {
 #define PRIV_UNLOCK(p) (g_rec_mutex_unlock (&(p)->rec_mutex))
 
 /* Forward Declarations */
-static void    e_book_backend_ews_authenticator_init
-                               (ESourceAuthenticatorInterface *iface);
 static void    e_book_backend_ews_initable_init
                                (GInitableIface *iface);
 static gpointer ews_update_items_thread (gpointer data);
@@ -141,9 +139,6 @@ G_DEFINE_TYPE_WITH_CODE (
        e_book_backend_ews,
        E_TYPE_BOOK_BACKEND,
        G_IMPLEMENT_INTERFACE (
-               E_TYPE_SOURCE_AUTHENTICATOR,
-               e_book_backend_ews_authenticator_init)
-       G_IMPLEMENT_INTERFACE (
                G_TYPE_INITABLE,
                e_book_backend_ews_initable_init))
 
@@ -238,6 +233,7 @@ book_backend_ews_ensure_connected (EBookBackendEws *bbews,
                                   GCancellable *cancellable,
                                   GError **perror)
 {
+       CamelEwsSettings *ews_settings;
        GError *local_error = NULL;
 
        g_return_val_if_fail (E_IS_BOOK_BACKEND_EWS (bbews), FALSE);
@@ -251,10 +247,15 @@ book_backend_ews_ensure_connected (EBookBackendEws *bbews,
 
        PRIV_UNLOCK (bbews->priv);
 
-       e_backend_authenticate_sync (
-               E_BACKEND (bbews),
-               E_SOURCE_AUTHENTICATOR (bbews),
-               cancellable, &local_error);
+       ews_settings = book_backend_ews_get_collection_settings (bbews);
+
+       if (e_ews_connection_utils_get_without_password (ews_settings)) {
+               e_backend_schedule_authenticate (E_BACKEND (bbews), NULL);
+       } else {
+               e_backend_credentials_required_sync (E_BACKEND (bbews),
+                       E_SOURCE_CREDENTIALS_REASON_REQUIRED, NULL, 0, NULL,
+                       cancellable, &local_error);
+       }
 
        if (!local_error)
                return TRUE;
@@ -1458,7 +1459,7 @@ e_book_backend_ews_create_contacts (EBookBackend *backend,
        ebews = E_BOOK_BACKEND_EWS (backend);
        priv = ebews->priv;
 
-       if (!e_backend_get_online (E_BACKEND (backend))) {
+       if (!e_backend_get_online (E_BACKEND (backend)) || !ebews->priv->cnc) {
                if (!priv->is_writable) {
                        e_data_book_respond_create_contacts (book, opid, EDB_ERROR (PERMISSION_DENIED), NULL);
                        return;
@@ -1597,7 +1598,7 @@ e_book_backend_ews_remove_contacts (EBookBackend *backend,
 
        priv = ebews->priv;
 
-       if (!e_backend_get_online (E_BACKEND (backend))) {
+       if (!e_backend_get_online (E_BACKEND (backend)) || !ebews->priv->cnc) {
                if (!priv->is_writable) {
                        e_data_book_respond_remove_contacts (book, opid, EDB_ERROR (PERMISSION_DENIED), NULL);
                        return;
@@ -1823,7 +1824,7 @@ e_book_backend_ews_modify_contacts (EBookBackend *backend,
        ebews = E_BOOK_BACKEND_EWS (backend);
        priv = ebews->priv;
 
-       if (!e_backend_get_online (E_BACKEND (backend))) {
+       if (!e_backend_get_online (E_BACKEND (backend)) || !ebews->priv->cnc) {
                if (!priv->is_writable) {
                        e_data_book_respond_modify_contacts (book, opid, EDB_ERROR (PERMISSION_DENIED), NULL);
                        return;
@@ -1916,7 +1917,7 @@ e_book_backend_ews_get_contact (EBookBackend *backend,
 
        ebews =  E_BOOK_BACKEND_EWS (backend);
 
-       if (!e_backend_get_online (E_BACKEND (backend))) {
+       if (!e_backend_get_online (E_BACKEND (backend)) || !ebews->priv->cnc) {
                e_data_book_respond_get_contact (book, opid, EDB_ERROR (REPOSITORY_OFFLINE), NULL);
                return;
        }
@@ -1950,7 +1951,7 @@ e_book_backend_ews_get_contact_list (EBookBackend *backend,
        if (priv->summary)
                e_book_sqlite_get_key_value_int (priv->summary, E_BOOK_SQL_IS_POPULATED_KEY, &populated, 
NULL);
 
-       if (!e_backend_get_online (E_BACKEND (backend))) {
+       if (!e_backend_get_online (E_BACKEND (backend)) || !ebews->priv->cnc) {
                if (populated) {
                search_db:
                        if (e_book_sqlite_lock (priv->summary, EBSQL_LOCK_READ, cancellable, &error)) {
@@ -3001,7 +3002,7 @@ ebews_fetch_items (EBookBackendEws *ebews, GSList *items, GSList **contacts,
        GSList *new_items = NULL;
        gboolean ret = FALSE;
 
-       if (!book_backend_ews_ensure_connected (ebews, cancellable, error)) {
+       if (!book_backend_ews_ensure_connected (ebews, cancellable, error) || !ebews->priv->cnc) {
                g_slist_free_full (items, g_object_unref);
                return ret;
        }
@@ -3186,14 +3187,22 @@ delta_thread (gpointer data)
 }
 
 static gboolean
-fetch_deltas (EBookBackendEws *ebews)
+fetch_deltas (EBookBackendEws *ebews,
+             gboolean force_update)
 {
        EBookBackendEwsPrivate *priv = ebews->priv;
        GError *error = NULL;
 
        /* If the thread is already running just return back */
-       if (priv->dthread)
+       if (priv->dthread) {
+               if (force_update && priv->dlock) {
+                       g_mutex_lock (&priv->dlock->mutex);
+                       g_cond_signal (&priv->dlock->cond);
+                       g_mutex_unlock (&priv->dlock->mutex);
+               }
+
                return FALSE;
+       }
 
        if (!priv->dlock) {
                priv->dlock = g_new0 (SyncDelta, 1);
@@ -3212,7 +3221,8 @@ fetch_deltas (EBookBackendEws *ebews)
 }
 
 static void
-ebews_start_refreshing (EBookBackendEws *ebews)
+ebews_start_refreshing (EBookBackendEws *ebews,
+                       gboolean force_update)
 {
        EBookBackendEwsPrivate *priv;
 
@@ -3222,7 +3232,7 @@ ebews_start_refreshing (EBookBackendEws *ebews)
 
        if (e_backend_get_online (E_BACKEND (ebews)) &&
            priv->cnc != NULL && priv->marked_for_offline)
-               fetch_deltas (ebews);
+               fetch_deltas (ebews, force_update);
 
        PRIV_UNLOCK (priv);
 }
@@ -3298,7 +3308,7 @@ e_book_backend_ews_start_view (EBookBackend *backend,
        g_hash_table_insert (priv->ops, book_view, cancellable);
        PRIV_UNLOCK (priv);
 
-       if (!e_backend_get_online (E_BACKEND (backend))) {
+       if (!e_backend_get_online (E_BACKEND (backend)) || !priv->cnc) {
                if (priv->summary)
                        e_book_sqlite_get_key_value_int (priv->summary, E_BOOK_SQL_IS_POPULATED_KEY, 
&is_populated, NULL);
                if (is_populated) {
@@ -3306,33 +3316,12 @@ e_book_backend_ews_start_view (EBookBackend *backend,
                        goto out;
                }
 
-               error = EDB_ERROR (OFFLINE_UNAVAILABLE);
                goto out;
        }
 
-       if (priv->cnc == NULL) {
-               e_backend_authenticate_sync (
-                       E_BACKEND (backend),
-                       E_SOURCE_AUTHENTICATOR (backend),
-                       cancellable, &error);
-               if (g_error_matches (error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_NORESPONSE)) {
-                       /* possibly server unreachable, try offline */
-                       if (priv->summary)
-                               e_book_sqlite_get_key_value_int (priv->summary, E_BOOK_SQL_IS_POPULATED_KEY, 
&is_populated, NULL);
-                       if (is_populated) {
-                               g_clear_error (&error);
-                               fetch_from_offline (ebews, book_view, query, cancellable, &error);
-                               goto out;
-                       }
-               }
-
-               if (error != NULL)
-                       goto out;
-       }
-
        g_return_if_fail (priv->cnc != NULL);
 
-       ebews_start_refreshing (ebews);
+       ebews_start_refreshing (ebews, FALSE);
 
        if (priv->summary)
                e_book_sqlite_get_key_value_int (priv->summary, E_BOOK_SQL_IS_POPULATED_KEY, &is_populated, 
NULL);
@@ -3549,6 +3538,10 @@ e_book_backend_ews_notify_online_cb (EBookBackend *backend,
                        ebews->priv->is_writable = !ebews->priv->is_gal;
 
                        e_book_backend_set_writable (backend, ebews->priv->is_writable);
+
+                       e_backend_schedule_credentials_required (E_BACKEND (backend),
+                               E_SOURCE_CREDENTIALS_REASON_REQUIRED, NULL, 0, NULL,
+                               ebews->priv->cancellable, G_STRFUNC);
                }
        }
 }
@@ -3899,6 +3892,7 @@ e_book_backend_ews_open_sync (EBookBackend *backend,
        CamelEwsSettings *ews_settings;
        EBookBackendEws *ebews;
        EBookBackendEwsPrivate * priv;
+       ESource *source;
        gboolean need_to_authenticate;
        gchar *revision = NULL;
 
@@ -3909,20 +3903,15 @@ e_book_backend_ews_open_sync (EBookBackend *backend,
                return TRUE;
 
        ews_settings = book_backend_ews_get_collection_settings (ebews);
+       source = e_backend_get_source (E_BACKEND (ebews));
+
+       e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTING);
 
        PRIV_LOCK (priv);
        need_to_authenticate = priv->cnc == NULL && e_backend_is_destination_reachable (E_BACKEND (backend), 
cancellable, NULL);
 
        PRIV_UNLOCK (priv);
 
-       if (need_to_authenticate &&
-           !e_backend_authenticate_sync (E_BACKEND (backend),
-                                         E_SOURCE_AUTHENTICATOR (backend),
-                                         cancellable, error)) {
-               convert_error_to_edb_error (error);
-               return FALSE;
-       }
-
        e_book_sqlite_get_key_value (priv->summary, "revision", &revision, NULL);
        if (revision) {
                e_book_backend_notify_property_changed (backend,
@@ -3931,22 +3920,32 @@ e_book_backend_ews_open_sync (EBookBackend *backend,
                g_free (revision);
        }
 
-       if (ebews->priv->is_gal)
-               return TRUE;
+       if (!ebews->priv->is_gal) {
+               PRIV_LOCK (priv);
+               priv->listen_notifications = camel_ews_settings_get_listen_notifications (ews_settings);
 
-       PRIV_LOCK (priv);
-       priv->listen_notifications = camel_ews_settings_get_listen_notifications (ews_settings);
+               if (priv->listen_notifications)
+                       ebews_listen_notifications_cb (ebews, NULL, ews_settings);
 
-       if (priv->listen_notifications)
-               ebews_listen_notifications_cb (ebews, NULL, ews_settings);
+               PRIV_UNLOCK (priv);
 
-       PRIV_UNLOCK (priv);
+               g_signal_connect_swapped (
+                       ews_settings,
+                       "notify::listen-notifications",
+                       G_CALLBACK (ebews_listen_notifications_cb),
+                       ebews);
+       }
+
+       if (ebews->priv->cnc)
+               e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED);
+       else
+               e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED);
 
-       g_signal_connect_swapped (
-               ews_settings,
-               "notify::listen-notifications",
-               G_CALLBACK (ebews_listen_notifications_cb),
-               ebews);
+       if (need_to_authenticate &&
+           !book_backend_ews_ensure_connected (ebews, cancellable, error)) {
+               convert_error_to_edb_error (error);
+               return FALSE;
+       }
 
        return TRUE;
 }
@@ -4117,69 +4116,58 @@ e_book_backend_ews_finalize (GObject *object)
        G_OBJECT_CLASS (e_book_backend_ews_parent_class)->finalize (object);
 }
 
-static gboolean
-book_backend_ews_get_without_password (ESourceAuthenticator *authenticator)
-{
-       EBookBackendEws *backend;
-       CamelEwsSettings *ews_settings;
-
-       backend = E_BOOK_BACKEND_EWS (authenticator);
-       ews_settings = book_backend_ews_get_collection_settings (backend);
-
-       return e_ews_connection_utils_get_without_password (ews_settings);
-}
-
 static ESourceAuthenticationResult
-book_backend_ews_try_password_sync (ESourceAuthenticator *authenticator,
-                                    const GString *password,
-                                    GCancellable *cancellable,
-                                    GError **error)
+e_book_backend_ews_authenticate_sync (EBackend *backend,
+                                     const ENamedParameters *credentials,
+                                     gchar **out_certificate_pem,
+                                     GTlsCertificateFlags *out_certificate_errors,
+                                     GCancellable *cancellable,
+                                     GError **error)
 {
-       EBookBackendEws *backend;
+       EBookBackendEws *ews_backend;
        EEwsConnection *connection;
        ESourceAuthenticationResult result;
        CamelEwsSettings *ews_settings;
        gchar *hosturl;
 
-       backend = E_BOOK_BACKEND_EWS (authenticator);
-       ews_settings = book_backend_ews_get_collection_settings (backend);
+       ews_backend = E_BOOK_BACKEND_EWS (backend);
+       ews_settings = book_backend_ews_get_collection_settings (ews_backend);
        hosturl = camel_ews_settings_dup_hosturl (ews_settings);
 
        connection = e_ews_connection_new (hosturl, ews_settings);
 
        g_object_bind_property (
-               backend, "proxy-resolver",
+               ews_backend, "proxy-resolver",
                connection, "proxy-resolver",
                G_BINDING_SYNC_CREATE);
 
-       result = e_source_authenticator_try_password_sync (
-               E_SOURCE_AUTHENTICATOR (connection),
-               password, cancellable, error);
+       result = e_ews_connection_try_credentials_sync (connection, credentials, cancellable, error);
 
        if (result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
 
-               PRIV_LOCK (backend->priv);
+               PRIV_LOCK (ews_backend->priv);
 
-               if (backend->priv->cnc != NULL)
-                       g_object_unref (backend->priv->cnc);
-               backend->priv->cnc = g_object_ref (connection);
-               backend->priv->is_writable = !backend->priv->is_gal;
+               if (ews_backend->priv->cnc != NULL)
+                       g_object_unref (ews_backend->priv->cnc);
+               ews_backend->priv->cnc = g_object_ref (connection);
+               ews_backend->priv->is_writable = !ews_backend->priv->is_gal;
 
                g_signal_connect_swapped (
-                       backend->priv->cnc,
+                       ews_backend->priv->cnc,
                        "server-notification",
                        G_CALLBACK (ebews_server_notification_cb),
                        backend);
 
-               PRIV_UNLOCK (backend->priv);
+               PRIV_UNLOCK (ews_backend->priv);
 
-               e_backend_set_online (E_BACKEND (backend), TRUE);
+               e_backend_set_online (backend, TRUE);
+               ebews_start_refreshing (ews_backend, TRUE);
        } else {
-               backend->priv->is_writable = FALSE;
-               e_backend_set_online (E_BACKEND (backend), FALSE);
+               ews_backend->priv->is_writable = FALSE;
+               e_backend_set_online (backend, FALSE);
        }
 
-       e_book_backend_set_writable (E_BOOK_BACKEND (backend), backend->priv->is_writable);
+       e_book_backend_set_writable (E_BOOK_BACKEND (backend), ews_backend->priv->is_writable);
 
        g_object_unref (connection);
 
@@ -4406,6 +4394,7 @@ e_book_backend_ews_class_init (EBookBackendEwsClass *klass)
        parent_class->configure_direct        = e_book_backend_ews_configure_direct;
 
        backend_class->get_destination_address = e_book_backend_ews_get_destination_address;
+       backend_class->authenticate_sync = e_book_backend_ews_authenticate_sync;
 
        object_class->constructed             = e_book_backend_ews_constructed;
        object_class->dispose                 = e_book_backend_ews_dispose;
@@ -4413,13 +4402,6 @@ e_book_backend_ews_class_init (EBookBackendEwsClass *klass)
 }
 
 static void
-e_book_backend_ews_authenticator_init (ESourceAuthenticatorInterface *iface)
-{
-       iface->get_without_password = book_backend_ews_get_without_password;
-       iface->try_password_sync = book_backend_ews_try_password_sync;
-}
-
-static void
 e_book_backend_ews_initable_init (GInitableIface *iface)
 {
        iface->init = book_backend_ews_initable_init;
diff --git a/src/calendar/e-cal-backend-ews.c b/src/calendar/e-cal-backend-ews.c
index b245930..e5bf25d 100644
--- a/src/calendar/e-cal-backend-ews.c
+++ b/src/calendar/e-cal-backend-ews.c
@@ -135,16 +135,8 @@ struct _ECalBackendEwsPrivate {
 static void ews_cal_component_get_item_id (ECalComponent *comp, gchar **itemid, gchar **changekey);
 static gboolean ews_start_sync (gpointer data);
 static gpointer ews_start_sync_thread (gpointer data);
-static void    e_cal_backend_ews_authenticator_init
-                               (ESourceAuthenticatorInterface *iface);
 
-G_DEFINE_TYPE_WITH_CODE (
-       ECalBackendEws,
-       e_cal_backend_ews,
-       E_TYPE_CAL_BACKEND,
-       G_IMPLEMENT_INTERFACE (
-               E_TYPE_SOURCE_AUTHENTICATOR,
-               e_cal_backend_ews_authenticator_init))
+G_DEFINE_TYPE (ECalBackendEws, e_cal_backend_ews, E_TYPE_CAL_BACKEND)
 
 static CamelEwsSettings *
 cal_backend_ews_get_collection_settings (ECalBackendEws *backend)
@@ -240,6 +232,7 @@ cal_backend_ews_ensure_connected (ECalBackendEws *cbews,
                                  GCancellable *cancellable,
                                  GError **perror)
 {
+       CamelEwsSettings *ews_settings;
        GError *local_error = NULL;
 
        g_return_val_if_fail (E_IS_CAL_BACKEND_EWS (cbews), FALSE);
@@ -253,10 +246,15 @@ cal_backend_ews_ensure_connected (ECalBackendEws *cbews,
 
        PRIV_UNLOCK (cbews->priv);
 
-       e_backend_authenticate_sync (
-               E_BACKEND (cbews),
-               E_SOURCE_AUTHENTICATOR (cbews),
-               cancellable, &local_error);
+       ews_settings = cal_backend_ews_get_collection_settings (cbews);
+
+       if (e_ews_connection_utils_get_without_password (ews_settings)) {
+               e_backend_schedule_authenticate (E_BACKEND (cbews), NULL);
+       } else {
+               e_backend_credentials_required_sync (E_BACKEND (cbews),
+                       E_SOURCE_CREDENTIALS_REASON_REQUIRED, NULL, 0, NULL,
+                       cancellable, &local_error);
+       }
 
        if (!local_error)
                return TRUE;
@@ -397,6 +395,11 @@ e_cal_backend_ews_discard_alarm (ECalBackend *backend,
 
        PRIV_UNLOCK (priv);
 
+       if (!cbews->priv->cnc) {
+               e_data_cal_respond_discard_alarm (cal, context, EDC_ERROR (RepositoryOffline));
+               return;
+       }
+
        if (!cal_backend_ews_ensure_connected (cbews, cancellable, &local_error)) {
                convert_error_to_edc_error (&local_error);
                e_data_cal_respond_discard_alarm (cal, context, local_error);
@@ -774,6 +777,8 @@ e_cal_backend_ews_open (ECalBackend *backend,
        source = e_backend_get_source (E_BACKEND (cbews));
        ews_settings = cal_backend_ews_get_collection_settings (cbews);
 
+       e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTING);
+
        PRIV_LOCK (priv);
 
        if (!priv->store) {
@@ -803,11 +808,13 @@ e_cal_backend_ews_open (ECalBackend *backend,
 
        PRIV_UNLOCK (priv);
 
+       if (cbews->priv->cnc)
+               e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED);
+       else
+               e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED);
+
        if (need_to_authenticate)
-               ret = e_backend_authenticate_sync (
-                               E_BACKEND (backend),
-                               E_SOURCE_AUTHENTICATOR (backend),
-                               cancellable, &error);
+               ret = cal_backend_ews_ensure_connected (cbews, cancellable, &error);
 
        if (ret) {
                e_cal_backend_set_writable (backend, TRUE);
@@ -1151,6 +1158,11 @@ e_cal_backend_ews_remove_object (ECalBackend *backend,
         */
        e_data_cal_error_if_fail (E_IS_CAL_BACKEND_EWS (cbews), InvalidArg);
 
+       if (!cbews->priv->cnc) {
+               e_data_cal_respond_discard_alarm (cal, context, EDC_ERROR (RepositoryOffline));
+               return;
+       }
+
        if (!cal_backend_ews_ensure_connected (cbews, cancellable, &error)) {
                convert_error_to_edc_error (&error);
                e_data_cal_respond_remove_objects (cal, context, error, NULL, NULL, NULL);
@@ -1671,7 +1683,7 @@ e_cal_backend_ews_create_objects (ECalBackend *backend,
        kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend));
 
        /* make sure we're not offline */
-       if (!e_backend_get_online (E_BACKEND (backend))) {
+       if (!e_backend_get_online (E_BACKEND (backend)) || !cbews->priv->cnc) {
                g_propagate_error (&error, EDC_ERROR (RepositoryOffline));
                goto exit;
        }
@@ -1899,7 +1911,7 @@ e_cal_backend_ews_modify_object (ECalBackend *backend,
        priv = cbews->priv;
        kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend));
 
-       if (!e_backend_get_online (E_BACKEND (backend))) {
+       if (!e_backend_get_online (E_BACKEND (backend)) || !cbews->priv->cnc) {
                g_propagate_error (&error, EDC_ERROR (RepositoryOffline));
                goto exit;
        }
@@ -2450,7 +2462,7 @@ e_cal_backend_ews_receive_objects (ECalBackend *backend,
        priv = cbews->priv;
 
        /* make sure we're not offline */
-       if (!e_backend_get_online (E_BACKEND (backend))) {
+       if (!e_backend_get_online (E_BACKEND (backend)) || !cbews->priv->cnc) {
                g_propagate_error (&error, EDC_ERROR (RepositoryOffline));
                goto exit;
        }
@@ -2664,7 +2676,7 @@ e_cal_backend_ews_send_objects (ECalBackend *backend,
        priv = cbews->priv;
 
        /* make sure we're not offline */
-       if (!e_backend_get_online (E_BACKEND (backend))) {
+       if (!e_backend_get_online (E_BACKEND (backend)) || !cbews->priv->cnc) {
                g_propagate_error (&error, EDC_ERROR (RepositoryOffline));
                goto exit;
        }
@@ -3912,7 +3924,7 @@ e_cal_backend_ews_get_free_busy (ECalBackend *backend,
        GSList *users_copy = NULL;
 
        /* make sure we're not offline */
-       if (!e_backend_get_online (E_BACKEND (backend))) {
+       if (!e_backend_get_online (E_BACKEND (backend)) || !cbews->priv->cnc) {
                g_propagate_error (&error, EDC_ERROR (RepositoryOffline));
                goto exit;
        }
@@ -4215,32 +4227,22 @@ e_cal_backend_ews_finalize (GObject *object)
        G_OBJECT_CLASS (e_cal_backend_ews_parent_class)->finalize (object);
 }
 
-static gboolean
-cal_backend_ews_get_without_password (ESourceAuthenticator *authenticator)
-{
-       ECalBackendEws *backend;
-       CamelEwsSettings *ews_settings;
-
-       backend = E_CAL_BACKEND_EWS (authenticator);
-       ews_settings = cal_backend_ews_get_collection_settings (backend);
-
-       return e_ews_connection_utils_get_without_password (ews_settings);
-}
-
 static ESourceAuthenticationResult
-cal_backend_ews_try_password_sync (ESourceAuthenticator *authenticator,
-                                   const GString *password,
-                                   GCancellable *cancellable,
-                                   GError **error)
+e_cal_backend_ews_authenticate_sync (EBackend *backend,
+                                    const ENamedParameters *credentials,
+                                    gchar **out_certificate_pem,
+                                    GTlsCertificateFlags *out_certificate_errors,
+                                    GCancellable *cancellable,
+                                    GError **error)
 {
-       ECalBackendEws *backend;
+       ECalBackendEws *cal_backend;
        EEwsConnection *connection;
        ESourceAuthenticationResult result;
        CamelEwsSettings *ews_settings;
        gchar *hosturl;
 
-       backend = E_CAL_BACKEND_EWS (authenticator);
-       ews_settings = cal_backend_ews_get_collection_settings (backend);
+       cal_backend = E_CAL_BACKEND_EWS (backend);
+       ews_settings = cal_backend_ews_get_collection_settings (cal_backend);
        hosturl = camel_ews_settings_dup_hosturl (ews_settings);
 
        connection = e_ews_connection_new (hosturl, ews_settings);
@@ -4250,30 +4252,28 @@ cal_backend_ews_try_password_sync (ESourceAuthenticator *authenticator,
                connection, "proxy-resolver",
                G_BINDING_SYNC_CREATE);
 
-       result = e_source_authenticator_try_password_sync (
-               E_SOURCE_AUTHENTICATOR (connection),
-               password, cancellable, error);
+       result = e_ews_connection_try_credentials_sync (connection, credentials, cancellable, error);
 
        if (result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
 
-               PRIV_LOCK (backend->priv);
+               PRIV_LOCK (cal_backend->priv);
 
-               g_free (backend->priv->user_email);
-               backend->priv->user_email = camel_ews_settings_dup_email (ews_settings);
+               g_free (cal_backend->priv->user_email);
+               cal_backend->priv->user_email = camel_ews_settings_dup_email (ews_settings);
 
-               if (backend->priv->cnc != NULL)
-                       g_object_unref (backend->priv->cnc);
-               backend->priv->cnc = g_object_ref (connection);
+               if (cal_backend->priv->cnc != NULL)
+                       g_object_unref (cal_backend->priv->cnc);
+               cal_backend->priv->cnc = g_object_ref (connection);
 
                g_signal_connect_swapped (
-                       backend->priv->cnc,
+                       cal_backend->priv->cnc,
                        "server-notification",
                        G_CALLBACK (cbews_server_notification_cb),
                        backend);
 
-               PRIV_UNLOCK (backend->priv);
+               PRIV_UNLOCK (cal_backend->priv);
 
-               ews_start_sync (backend);
+               ews_start_sync (cal_backend);
        }
 
        g_object_unref (connection);
@@ -4301,6 +4301,7 @@ e_cal_backend_ews_class_init (ECalBackendEwsClass *class)
        object_class->finalize = e_cal_backend_ews_finalize;
 
        backend_class->get_destination_address = e_cal_backend_ews_get_destination_address;
+       backend_class->authenticate_sync = e_cal_backend_ews_authenticate_sync;
 
        /* Property accessors */
        cal_backend_class->get_backend_property = e_cal_backend_ews_get_backend_property;
@@ -4328,13 +4329,6 @@ e_cal_backend_ews_class_init (ECalBackendEwsClass *class)
 }
 
 static void
-e_cal_backend_ews_authenticator_init (ESourceAuthenticatorInterface *iface)
-{
-       iface->get_without_password = cal_backend_ews_get_without_password;
-       iface->try_password_sync = cal_backend_ews_try_password_sync;
-}
-
-static void
 e_cal_backend_ews_init (ECalBackendEws *cbews)
 {
        cbews->priv = G_TYPE_INSTANCE_GET_PRIVATE (cbews, E_TYPE_CAL_BACKEND_EWS, ECalBackendEwsPrivate);
diff --git a/src/collection/e-ews-backend.c b/src/collection/e-ews-backend.c
index 42791e5..5df7ccb 100644
--- a/src/collection/e-ews-backend.c
+++ b/src/collection/e-ews-backend.c
@@ -24,6 +24,7 @@
 
 #include <glib/gi18n-lib.h>
 
+#include "server/e-ews-connection-utils.h"
 #include "server/e-source-ews-folder.h"
 
 #define E_EWS_BACKEND_GET_PRIVATE(obj) \
@@ -43,6 +44,7 @@ struct _EEwsBackendPrivate {
        gchar *sync_state;
        GMutex sync_state_lock;
 
+       ENamedParameters *credentials;
        EEwsConnection *connection;
        GMutex connection_lock;
 
@@ -579,6 +581,8 @@ ews_backend_finalize (GObject *object)
 
        g_mutex_clear (&priv->connection_lock);
 
+       e_named_parameters_free (priv->credentials);
+
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (e_ews_backend_parent_class)->finalize (object);
 }
@@ -684,10 +688,21 @@ ews_backend_populate (ECollectionBackend *backend)
 
        ews_backend_add_gal_source (ews_backend);
 
-       if (e_backend_get_online (E_BACKEND (backend)))
-               e_ews_backend_sync_folders (ews_backend, NULL, ews_backend_folders_synced_cb, NULL);
-       else
+       if (e_backend_get_online (E_BACKEND (backend))) {
+               CamelEwsSettings *ews_settings;
+
+               ews_settings = ews_backend_get_settings (ews_backend);
+
+               if (e_ews_connection_utils_get_without_password (ews_settings)) {
+                       e_backend_schedule_authenticate (E_BACKEND (backend), NULL);
+               } else {
+                       e_backend_credentials_required_sync (E_BACKEND (backend),
+                               E_SOURCE_CREDENTIALS_REASON_REQUIRED, NULL, 0, NULL,
+                               NULL, NULL);
+               }
+       } else {
                ews_backend_claim_old_resources (backend);
+       }
 }
 
 static gchar *
@@ -815,8 +830,7 @@ ews_backend_create_resource_sync (ECollectionBackend *backend,
        }
 
        if (!success) {
-               connection = e_ews_backend_ref_connection_sync (
-                       E_EWS_BACKEND (backend), cancellable, error);
+               connection = e_ews_backend_ref_connection_sync (E_EWS_BACKEND (backend), NULL, cancellable, 
error);
                if (connection == NULL)
                        return FALSE;
 
@@ -923,8 +937,7 @@ ews_backend_delete_resource_sync (ECollectionBackend *backend,
        const gchar *extension_name;
        gboolean success = FALSE;
 
-       connection = e_ews_backend_ref_connection_sync (
-               E_EWS_BACKEND (backend), cancellable, error);
+       connection = e_ews_backend_ref_connection_sync (E_EWS_BACKEND (backend), NULL, cancellable, error);
        if (connection == NULL)
                return FALSE;
 
@@ -1004,6 +1017,44 @@ ews_backend_get_destination_address (EBackend *backend,
        return result;
 }
 
+static ESourceAuthenticationResult
+ews_backend_authenticate_sync (EBackend *backend,
+                              const ENamedParameters *credentials,
+                              gchar **out_certificate_pem,
+                              GTlsCertificateFlags *out_certificate_errors,
+                              GCancellable *cancellable,
+                              GError **error)
+{
+       EEwsBackend *ews_backend;
+       EEwsConnection *connection;
+       CamelEwsSettings *ews_settings;
+       ESourceAuthenticationResult result = E_SOURCE_AUTHENTICATION_ERROR;
+       gchar *hosturl;
+
+       g_return_val_if_fail (E_IS_EWS_BACKEND (backend), E_SOURCE_AUTHENTICATION_ERROR);
+
+       ews_backend = E_EWS_BACKEND (backend);
+       ews_settings = ews_backend_get_settings (ews_backend);
+       g_return_val_if_fail (ews_settings != NULL, E_SOURCE_AUTHENTICATION_ERROR);
+
+       g_mutex_lock (&ews_backend->priv->connection_lock);
+       g_clear_object (&ews_backend->priv->connection);
+       e_named_parameters_free (ews_backend->priv->credentials);
+       ews_backend->priv->credentials = e_named_parameters_new_clone (credentials);
+       g_mutex_unlock (&ews_backend->priv->connection_lock);
+
+       connection = e_ews_backend_ref_connection_sync (ews_backend, &result, cancellable, error);
+       g_clear_object (&connection);
+
+       if (result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
+               e_collection_backend_authenticate_children (E_COLLECTION_BACKEND (backend), credentials);
+
+               e_ews_backend_sync_folders (ews_backend, NULL, ews_backend_folders_synced_cb, NULL);
+       }
+
+       return result;
+}
+
 static void
 e_ews_backend_class_init (EEwsBackendClass *class)
 {
@@ -1028,6 +1079,7 @@ e_ews_backend_class_init (EEwsBackendClass *class)
 
        backend_class = E_BACKEND_CLASS (class);
        backend_class->get_destination_address = ews_backend_get_destination_address;
+       backend_class->authenticate_sync = ews_backend_authenticate_sync;
 
        /* This generates an ESourceCamel subtype for CamelEwsSettings. */
        e_source_camel_generate_subtype ("ews", CAMEL_TYPE_EWS_SETTINGS);
@@ -1067,8 +1119,7 @@ ews_backend_ref_connection_thread (GSimpleAsyncResult *simple,
        EEwsConnection *connection;
        GError *error = NULL;
 
-       connection = e_ews_backend_ref_connection_sync (
-               E_EWS_BACKEND (object), cancellable, &error);
+       connection = e_ews_backend_ref_connection_sync (E_EWS_BACKEND (object), NULL, cancellable, &error);
 
        /* Sanity check. */
        g_return_if_fail (
@@ -1085,10 +1136,12 @@ ews_backend_ref_connection_thread (GSimpleAsyncResult *simple,
 
 EEwsConnection *
 e_ews_backend_ref_connection_sync (EEwsBackend *backend,
+                                  ESourceAuthenticationResult *result,
                                    GCancellable *cancellable,
                                    GError **error)
 {
        EEwsConnection *connection = NULL;
+       ESourceAuthenticationResult local_result;
        CamelEwsSettings *settings;
        gchar *hosturl;
        gboolean success;
@@ -1102,7 +1155,7 @@ e_ews_backend_ref_connection_sync (EEwsBackend *backend,
 
        /* If we already have an authenticated
         * connection object, just return that. */
-       if (connection != NULL)
+       if (connection != NULL || !backend->priv->credentials)
                return connection;
 
        settings = ews_backend_get_settings (backend);
@@ -1115,10 +1168,11 @@ e_ews_backend_ref_connection_sync (EEwsBackend *backend,
                connection, "proxy-resolver",
                G_BINDING_SYNC_CREATE);
 
-       success = e_backend_authenticate_sync (
-               E_BACKEND (backend),
-               E_SOURCE_AUTHENTICATOR (connection),
-               cancellable, error);
+       local_result = e_ews_connection_try_credentials_sync (connection, backend->priv->credentials, 
cancellable, error);
+       if (result)
+               *result = local_result;
+
+       success = local_result == E_SOURCE_AUTHENTICATION_ACCEPTED;
 
        if (success) {
                g_mutex_lock (&backend->priv->connection_lock);
@@ -1255,8 +1309,7 @@ e_ews_backend_sync_folders_sync (EEwsBackend *backend,
                return TRUE;
        }
 
-       connection = e_ews_backend_ref_connection_sync (
-               backend, cancellable, error);
+       connection = e_ews_backend_ref_connection_sync (backend, NULL, cancellable, error);
 
        if (connection == NULL) {
                backend->priv->need_update_folders = TRUE;
diff --git a/src/collection/e-ews-backend.h b/src/collection/e-ews-backend.h
index a7bc873..9e23184 100644
--- a/src/collection/e-ews-backend.h
+++ b/src/collection/e-ews-backend.h
@@ -62,6 +62,7 @@ void          e_ews_backend_type_register     (GTypeModule *type_module);
 EEwsConnection *
                e_ews_backend_ref_connection_sync
                                                (EEwsBackend *backend,
+                                                ESourceAuthenticationResult *result,
                                                 GCancellable *cancellable,
                                                 GError **error);
 void           e_ews_backend_ref_connection    (EEwsBackend *backend,
diff --git a/src/configuration/e-ews-config-utils.c b/src/configuration/e-ews-config-utils.c
index 89cd651..774a0a2 100644
--- a/src/configuration/e-ews-config-utils.c
+++ b/src/configuration/e-ews-config-utils.c
@@ -26,6 +26,7 @@
 
 #include <gtk/gtk.h>
 #include <libedataserver/libedataserver.h>
+#include <libedataserverui/libedataserverui.h>
 
 #include <e-util/e-util.h>
 #include <mail/em-folder-tree.h>
@@ -57,6 +58,7 @@ struct RunWithFeedbackData
        GObject *with_object;
        EEwsSetupFunc thread_func;
        EEwsSetupFunc idle_func;
+       EEwsSetupFunc finish_idle_func;
        gpointer user_data;
        GDestroyNotify free_user_data;
        GError *error;
@@ -107,6 +109,9 @@ run_with_feedback_idle (gpointer user_data)
                was_cancelled = TRUE;
        }
 
+       if (rfd->finish_idle_func)
+               rfd->finish_idle_func (rfd->with_object, rfd->user_data, rfd->cancellable, &rfd->error);
+
        if (!was_cancelled) {
                if (rfd->error) {
                        g_dbus_error_strip_remote_error (rfd->error);
@@ -197,6 +202,7 @@ e_ews_config_utils_run_in_thread_with_feedback_general (GtkWindow *parent,
        rfd->with_object = g_object_ref (with_object);
        rfd->thread_func = thread_func;
        rfd->idle_func = idle_func;
+       rfd->finish_idle_func = NULL;
        rfd->user_data = user_data;
        rfd->free_user_data = free_user_data;
        rfd->error = NULL;
@@ -251,137 +257,90 @@ e_ews_config_utils_run_in_thread_with_feedback_modal (GtkWindow *parent,
        e_ews_config_utils_run_in_thread_with_feedback_general (parent, with_object, description, 
thread_func, idle_func, user_data, free_user_data, TRUE);
 }
 
-typedef struct _EEwsConfigUtilsAuthenticator EEwsConfigUtilsAuthenticator;
-typedef struct _EEwsConfigUtilsAuthenticatorClass EEwsConfigUtilsAuthenticatorClass;
+void
+e_ews_config_utils_run_in_thread (GObject *with_object,
+                                 EEwsSetupFunc thread_func,
+                                 EEwsSetupFunc idle_func,
+                                 gpointer user_data,
+                                 GDestroyNotify free_user_data,
+                                 GCancellable *cancellable)
+{
+       struct RunWithFeedbackData *rfd;
+       GThread *thread;
 
-struct _EEwsConfigUtilsAuthenticator {
-       GObject parent;
+       g_return_if_fail (with_object != NULL);
+       g_return_if_fail (thread_func != NULL);
 
-       ESourceRegistry *registry;
+       rfd = g_new0 (struct RunWithFeedbackData, 1);
+       rfd->parent = NULL;
+       rfd->dialog = NULL;
+       rfd->cancellable = cancellable ? g_object_ref (cancellable) : g_cancellable_new ();
+       rfd->with_object = g_object_ref (with_object);
+       rfd->thread_func = thread_func;
+       rfd->idle_func = NULL;
+       rfd->finish_idle_func = idle_func;
+       rfd->user_data = user_data;
+       rfd->free_user_data = free_user_data;
+       rfd->error = NULL;
+       rfd->run_modal = FALSE;
+
+       thread = g_thread_new (NULL, run_with_feedback_thread, rfd);
+       g_thread_unref (thread);
+}
+
+typedef struct _TryCredentialsData {
        CamelEwsSettings *ews_settings;
+       const gchar *connect_url;
+       EEwsConfigUtilTryCredentialsFunc try_credentials_func;
+       gpointer user_data;
        EEwsConnection *conn;
-};
-
-struct _EEwsConfigUtilsAuthenticatorClass {
-       GObjectClass parent_class;
-};
+} TryCredentialsData;
 
 static gboolean
-ews_config_utils_authenticator_get_without_password (ESourceAuthenticator *auth)
+ews_config_utils_try_credentials_sync (ECredentialsPrompter *prompter,
+                                      ESource *source,
+                                      const ENamedParameters *credentials,
+                                      gboolean *out_authenticated,
+                                      gpointer user_data,
+                                      GCancellable *cancellable,
+                                      GError **error)
 {
-       EEwsConfigUtilsAuthenticator *authenticator = (EEwsConfigUtilsAuthenticator *) auth;
-       return e_ews_connection_utils_get_without_password (authenticator->ews_settings);
-}
-
-static ESourceAuthenticationResult
-ews_config_utils_authenticator_try_password_sync (ESourceAuthenticator *auth,
-                                                  const GString *password,
-                                                  GCancellable *cancellable,
-                                                  GError **error)
-{
-       EEwsConfigUtilsAuthenticator *authenticator = (EEwsConfigUtilsAuthenticator *) auth;
-       CamelNetworkSettings *network_settings;
-       gchar *hosturl, *user;
-       EwsFolderId *fid;
-       GSList *ids = NULL, *folders = NULL;
-       GError *local_error = NULL;
-
-       network_settings = CAMEL_NETWORK_SETTINGS (authenticator->ews_settings);
-
-       hosturl = camel_ews_settings_dup_hosturl (authenticator->ews_settings);
-       user = camel_network_settings_dup_user (network_settings);
-
-       authenticator->conn = e_ews_connection_new (
-               hosturl, authenticator->ews_settings);
-       e_ews_connection_set_password (authenticator->conn, password->str);
+       TryCredentialsData *data = user_data;
+       ESourceAuthenticationResult auth_result;
+       gchar *hosturl;
+       gboolean res = TRUE;
 
+       hosturl = camel_ews_settings_dup_hosturl (data->ews_settings);
+       data->conn = e_ews_connection_new (data->connect_url ? data->connect_url : hosturl, 
data->ews_settings);
        g_free (hosturl);
-       g_free (user);
-
-       g_warn_if_fail (authenticator->conn);
-
-       /* test whether connection works with some simple operation */
-       fid = g_new0 (EwsFolderId, 1);
-       fid->id = g_strdup ("inbox");
-       fid->is_distinguished_id = TRUE;
-       ids = g_slist_append (ids, fid);
-
-       e_ews_connection_get_folder_sync (
-               authenticator->conn, EWS_PRIORITY_MEDIUM, "Default",
-               NULL, ids, &folders, cancellable, &local_error);
-
-       e_ews_folder_id_free (fid);
-       g_slist_free (ids);
-       g_slist_free_full (folders, g_object_unref);
-
-       if (local_error) {
-               g_object_unref (authenticator->conn);
-               authenticator->conn = NULL;
 
-               if (g_error_matches (
-                   local_error, EWS_CONNECTION_ERROR,
-                   EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED)) {
-                       g_clear_error (&local_error);
-                       return E_SOURCE_AUTHENTICATION_REJECTED;
-               }
-
-               g_propagate_error (error, local_error);
+       e_ews_connection_update_credentials (data->conn, credentials);
 
-               return E_SOURCE_AUTHENTICATION_ERROR;
+       if (data->try_credentials_func)
+               auth_result = data->try_credentials_func (data->conn, credentials, data->user_data, 
cancellable, error);
+       else
+               auth_result = e_ews_connection_try_credentials_sync (data->conn, credentials, cancellable, 
error);
+
+       if (auth_result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
+               *out_authenticated = TRUE;
+       } else if (auth_result == E_SOURCE_AUTHENTICATION_REJECTED) {
+               *out_authenticated = FALSE;
+               g_clear_object (&data->conn);
+               g_clear_error (error);
+       } else {
+               res = FALSE;
+               g_clear_object (&data->conn);
        }
 
-       return E_SOURCE_AUTHENTICATION_ACCEPTED;
-}
-
-#define E_TYPE_EWS_CONFIG_UTILS_AUTHENTICATOR (e_ews_config_utils_authenticator_get_type ())
-
-GType e_ews_config_utils_authenticator_get_type (void) G_GNUC_CONST;
-
-static void e_ews_config_utils_authenticator_authenticator_init (ESourceAuthenticatorInterface *iface);
-
-G_DEFINE_TYPE_EXTENDED (EEwsConfigUtilsAuthenticator, e_ews_config_utils_authenticator, G_TYPE_OBJECT, 0,
-       G_IMPLEMENT_INTERFACE (E_TYPE_SOURCE_AUTHENTICATOR, 
e_ews_config_utils_authenticator_authenticator_init))
-
-static void
-ews_config_utils_authenticator_finalize (GObject *object)
-{
-       EEwsConfigUtilsAuthenticator *authenticator = (EEwsConfigUtilsAuthenticator *) object;
-
-       g_object_unref (authenticator->registry);
-       g_object_unref (authenticator->ews_settings);
-       if (authenticator->conn)
-               g_object_unref (authenticator->conn);
-
-       G_OBJECT_CLASS (e_ews_config_utils_authenticator_parent_class)->finalize (object);
-}
-
-static void
-e_ews_config_utils_authenticator_class_init (EEwsConfigUtilsAuthenticatorClass *class)
-{
-       GObjectClass *object_class;
-
-       object_class = G_OBJECT_CLASS (class);
-       object_class->finalize = ews_config_utils_authenticator_finalize;
-}
-
-static void
-e_ews_config_utils_authenticator_authenticator_init (ESourceAuthenticatorInterface *iface)
-{
-       iface->get_without_password =
-               ews_config_utils_authenticator_get_without_password;
-       iface->try_password_sync =
-               ews_config_utils_authenticator_try_password_sync;
-}
-
-static void
-e_ews_config_utils_authenticator_init (EEwsConfigUtilsAuthenticator *authenticator)
-{
+       return res;
 }
 
 EEwsConnection *
-e_ews_config_utils_open_connection_for (ESourceRegistry *registry,
-                                        ESource *source,
+e_ews_config_utils_open_connection_for (ESource *source,
                                         CamelEwsSettings *ews_settings,
+                                       const gchar *connect_url,
+                                       EEwsConfigUtilTryCredentialsFunc try_credentials_func,
+                                       gpointer user_data,
                                         GCancellable *cancellable,
                                         GError **perror)
 {
@@ -389,7 +348,6 @@ e_ews_config_utils_open_connection_for (ESourceRegistry *registry,
        CamelNetworkSettings *network_settings;
        GError *local_error = NULL;
 
-       g_return_val_if_fail (registry != NULL, NULL);
        g_return_val_if_fail (source != NULL, NULL);
        g_return_val_if_fail (ews_settings != NULL, NULL);
 
@@ -397,25 +355,58 @@ e_ews_config_utils_open_connection_for (ESourceRegistry *registry,
 
        /* use the one from mailer, if there, otherwise open new */
        conn = e_ews_connection_find (
-               camel_ews_settings_get_hosturl (ews_settings),
+               connect_url && *connect_url ? connect_url : camel_ews_settings_get_hosturl (ews_settings),
                camel_network_settings_get_user (network_settings));
-       if (conn)
+       if (conn) {
+               if (try_credentials_func &&
+                   try_credentials_func (conn, NULL, user_data, cancellable, perror) != 
E_SOURCE_AUTHENTICATION_ACCEPTED) {
+                       g_clear_object (&conn);
+               }
                return conn;
+       }
 
        while (!conn && !g_cancellable_is_cancelled (cancellable) && !local_error) {
-               EEwsConfigUtilsAuthenticator *authenticator = g_object_new 
(E_TYPE_EWS_CONFIG_UTILS_AUTHENTICATOR, NULL);
+               if (e_ews_connection_utils_get_without_password (ews_settings)) {
+                       ESourceAuthenticationResult result;
+                       gchar *hosturl;
+
+                       hosturl = camel_ews_settings_dup_hosturl (ews_settings);
+                       conn = e_ews_connection_new (connect_url && *connect_url ? connect_url : hosturl, 
ews_settings);
+                       g_free (hosturl);
 
-               authenticator->ews_settings = g_object_ref (ews_settings);
-               authenticator->registry = g_object_ref (registry);
+                       e_ews_connection_update_credentials (conn, NULL);
 
-               e_source_registry_authenticate_sync (
-                       registry, source, E_SOURCE_AUTHENTICATOR (authenticator),
-                       cancellable, &local_error);
+                       if (try_credentials_func)
+                               result = try_credentials_func (conn, NULL, user_data, cancellable, 
&local_error);
+                       else
+                               result = e_ews_connection_try_credentials_sync (conn, NULL, cancellable, 
&local_error);
+
+                       if (result != E_SOURCE_AUTHENTICATION_ACCEPTED) {
+                               g_clear_object (&conn);
+                               break;
+                       }
+               } else {
+                       EShell *shell;
+                       TryCredentialsData data;
 
-               if (authenticator->conn)
-                       conn = g_object_ref (authenticator->conn);
+                       shell = e_shell_get_default ();
 
-               g_object_unref (authenticator);
+                       data.ews_settings = g_object_ref (ews_settings);
+                       data.connect_url = connect_url && *connect_url ? connect_url : NULL;
+                       data.try_credentials_func = try_credentials_func;
+                       data.user_data = user_data;
+                       data.conn = NULL;
+
+                       e_credentials_prompter_loop_prompt_sync (e_shell_get_credentials_prompter (shell),
+                               source, E_CREDENTIALS_PROMPTER_PROMPT_FLAG_ALLOW_SOURCE_SAVE,
+                               ews_config_utils_try_credentials_sync, &data, cancellable, &local_error);
+
+                       if (data.conn)
+                               conn = g_object_ref (data.conn);
+
+                       g_clear_object (&data.ews_settings);
+                       g_clear_object (&data.conn);
+               }
        }
 
        if (local_error)
@@ -660,9 +651,9 @@ ews_settings_get_folder_sizes_thread (gpointer user_data)
        g_return_val_if_fail (fsd != NULL, NULL);
 
        cnc = e_ews_config_utils_open_connection_for (
-                       fsd->registry,
                        fsd->source,
                        fsd->ews_settings,
+                       NULL, NULL, NULL,
                        fsd->cancellable,
                        &fsd->error);
 
diff --git a/src/configuration/e-ews-config-utils.h b/src/configuration/e-ews-config-utils.h
index a5e15d9..95379c4 100644
--- a/src/configuration/e-ews-config-utils.h
+++ b/src/configuration/e-ews-config-utils.h
@@ -47,9 +47,25 @@ void                 e_ews_config_utils_run_in_thread_with_feedback_modal    (GtkWindow 
*parent,
                                                                                 gpointer user_data,
                                                                                 GDestroyNotify 
free_user_data);
 
-EEwsConnection *       e_ews_config_utils_open_connection_for                  (ESourceRegistry *registry,
-                                                                                ESource *source,
+void                   e_ews_config_utils_run_in_thread                        (GObject *with_object,
+                                                                                EEwsSetupFunc thread_func,
+                                                                                EEwsSetupFunc idle_func,
+                                                                                gpointer user_data,
+                                                                                GDestroyNotify 
free_user_data,
+                                                                                GCancellable *cancellable);
+
+typedef ESourceAuthenticationResult
+                       (* EEwsConfigUtilTryCredentialsFunc)                    (EEwsConnection *cnc,
+                                                                                const ENamedParameters 
*credentials,
+                                                                                gpointer user_data,
+                                                                                GCancellable *cancellable,
+                                                                                GError **error);
+
+EEwsConnection *       e_ews_config_utils_open_connection_for                  (ESource *source,
                                                                                 CamelEwsSettings 
*ews_settings,
+                                                                                const gchar *connect_url,
+                                                                                
EEwsConfigUtilTryCredentialsFunc try_credentials_func,
+                                                                                gpointer user_data,
                                                                                 GCancellable *cancellable,
                                                                                 GError **perror);
 
diff --git a/src/configuration/e-ews-edit-folder-permissions.c 
b/src/configuration/e-ews-edit-folder-permissions.c
index 28b8d7e..110582b 100644
--- a/src/configuration/e-ews-edit-folder-permissions.c
+++ b/src/configuration/e-ews-edit-folder-permissions.c
@@ -689,9 +689,9 @@ read_folder_permissions_thread (GObject *dialog,
        g_return_if_fail (widgets->folder_id != NULL);
 
        widgets->conn = e_ews_config_utils_open_connection_for (
-               widgets->registry,
                widgets->source,
                widgets->ews_settings,
+               NULL, NULL, NULL,
                cancellable,
                perror);
 
diff --git a/src/configuration/e-mail-config-ews-autodiscover.c 
b/src/configuration/e-mail-config-ews-autodiscover.c
index f8485c7..f32db35 100644
--- a/src/configuration/e-mail-config-ews-autodiscover.c
+++ b/src/configuration/e-mail-config-ews-autodiscover.c
@@ -24,6 +24,8 @@
 
 #include <glib/gi18n-lib.h>
 
+#include <libedataserverui/libedataserverui.h>
+#include <shell/e-shell.h>
 #include <mail/e-mail-config-service-page.h>
 
 #include "server/e-ews-connection.h"
@@ -42,6 +44,9 @@ struct _EMailConfigEwsAutodiscoverPrivate {
 struct _AsyncContext {
        EMailConfigEwsAutodiscover *autodiscover;
        EActivity *activity;
+       ESource *source;
+       CamelEwsSettings *ews_settings;
+       gchar *email_address;
 };
 
 enum {
@@ -49,31 +54,40 @@ enum {
        PROP_BACKEND
 };
 
-/* Forward Declarations */
-static void    e_mail_config_ews_autodiscover_authenticator_init
-                               (ESourceAuthenticatorInterface *iface);
-
-G_DEFINE_DYNAMIC_TYPE_EXTENDED (
-       EMailConfigEwsAutodiscover,
-       e_mail_config_ews_autodiscover,
-       GTK_TYPE_BUTTON,
-       0,
-       G_IMPLEMENT_INTERFACE_DYNAMIC (
-               E_TYPE_SOURCE_AUTHENTICATOR,
-               e_mail_config_ews_autodiscover_authenticator_init))
+G_DEFINE_DYNAMIC_TYPE (EMailConfigEwsAutodiscover, e_mail_config_ews_autodiscover, GTK_TYPE_BUTTON)
 
 static void
-async_context_free (AsyncContext *async_context)
+async_context_free (gpointer ptr)
 {
-       if (async_context->autodiscover != NULL)
-               g_object_unref (async_context->autodiscover);
+       AsyncContext *async_context = ptr;
 
-       if (async_context->activity != NULL)
-               g_object_unref (async_context->activity);
+       if (!async_context)
+               return;
+
+       g_clear_object (&async_context->autodiscover);
+       g_clear_object (&async_context->activity);
+       g_clear_object (&async_context->source);
+       g_clear_object (&async_context->ews_settings);
+       g_free (async_context->email_address);
 
        g_slice_free (AsyncContext, async_context);
 }
 
+static gboolean
+mail_config_ews_autodiscover_finish (EMailConfigEwsAutodiscover *autodiscover,
+                                    GAsyncResult *result,
+                                    GError **error)
+{
+       g_return_val_if_fail (E_IS_MAIL_CONFIG_EWS_AUTODISCOVER (autodiscover), FALSE);
+       g_return_val_if_fail (g_task_is_valid (result, autodiscover), FALSE);
+
+       g_return_val_if_fail (
+               g_async_result_is_tagged (
+               result, mail_config_ews_autodiscover_finish), FALSE);
+
+       return g_task_propagate_boolean (G_TASK (result), error);
+}
+
 static void
 mail_config_ews_autodiscover_run_cb (GObject *source_object,
                                      GAsyncResult *result,
@@ -89,8 +103,7 @@ mail_config_ews_autodiscover_run_cb (GObject *source_object,
        autodiscover = async_context->autodiscover;
        alert_sink = e_activity_get_alert_sink (async_context->activity);
 
-       e_source_registry_authenticate_finish (
-               E_SOURCE_REGISTRY (source_object), result, &error);
+       mail_config_ews_autodiscover_finish (E_MAIL_CONFIG_EWS_AUTODISCOVER (source_object), result, &error);
 
        backend = e_mail_config_ews_autodiscover_get_backend (autodiscover);
        settings = e_mail_config_service_backend_get_settings (backend);
@@ -111,8 +124,71 @@ mail_config_ews_autodiscover_run_cb (GObject *source_object,
        }
 
        gtk_widget_set_sensitive (GTK_WIDGET (autodiscover), TRUE);
+}
+
+static gboolean
+mail_config_ews_autodiscover_sync (ECredentialsPrompter *prompter,
+                                  ESource *source,
+                                  const ENamedParameters *credentials,
+                                  gboolean *out_authenticated,
+                                  gpointer user_data,
+                                  GCancellable *cancellable,
+                                  GError **error)
+{
+       AsyncContext *async_context = user_data;
+       GError *local_error = NULL;
+       gboolean res = TRUE;
+
+       e_ews_autodiscover_ws_url_sync (
+               async_context->ews_settings, async_context->email_address,
+               credentials && e_named_parameters_get (credentials, E_SOURCE_CREDENTIAL_PASSWORD) ?
+               e_named_parameters_get (credentials, E_SOURCE_CREDENTIAL_PASSWORD) : "",
+               cancellable, &local_error);
+
+       if (local_error == NULL) {
+               *out_authenticated = TRUE;
+       } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+               *out_authenticated = FALSE;
+               g_error_free (local_error);
+       } else {
+               res = FALSE;
+               g_propagate_error (error, local_error);
+       }
 
-       async_context_free (async_context);
+       return res;
+}
+
+static void
+mail_config_ews_autodiscover_run_thread (GTask *task,
+                                        gpointer source_object,
+                                        gpointer task_data,
+                                        GCancellable *cancellable)
+{
+       AsyncContext *async_context = task_data;
+       GError *local_error = NULL;
+       gboolean success = FALSE;
+
+       if (!g_cancellable_set_error_if_cancelled (cancellable, &local_error) && !local_error) {
+               if (e_ews_connection_utils_get_without_password (async_context->ews_settings)) {
+                       success = e_ews_autodiscover_ws_url_sync (
+                               async_context->ews_settings, async_context->email_address, "",
+                               cancellable, &local_error);
+               } else {
+                       EShell *shell;
+
+                       shell = e_shell_get_default ();
+
+                       success = e_credentials_prompter_loop_prompt_sync (e_shell_get_credentials_prompter 
(shell),
+                               async_context->source, E_CREDENTIALS_PROMPTER_PROMPT_FLAG_ALLOW_SOURCE_SAVE,
+                               mail_config_ews_autodiscover_sync, async_context, cancellable, &local_error);
+               }
+       }
+
+       if (local_error != NULL) {
+               g_task_return_error (task, local_error);
+       } else {
+               g_task_return_boolean (task, success);
+       }
 }
 
 static void
@@ -122,20 +198,17 @@ mail_config_ews_autodiscover_run (EMailConfigEwsAutodiscover *autodiscover)
        EMailConfigServicePage *page;
        EMailConfigServiceBackend *backend;
        CamelSettings *settings;
-       ESourceRegistry *registry;
        ESource *source;
        GCancellable *cancellable;
        AsyncContext *async_context;
+       GTask *task;
 
        backend = e_mail_config_ews_autodiscover_get_backend (autodiscover);
        page = e_mail_config_service_backend_get_page (backend);
        source = e_mail_config_service_backend_get_source (backend);
        settings = e_mail_config_service_backend_get_settings (backend);
 
-       registry = e_mail_config_service_page_get_registry (page);
-
-       activity = e_mail_config_activity_page_new_activity (
-               E_MAIL_CONFIG_ACTIVITY_PAGE (page));
+       activity = e_mail_config_activity_page_new_activity (E_MAIL_CONFIG_ACTIVITY_PAGE (page));
        cancellable = e_activity_get_cancellable (activity);
 
        e_activity_set_text (activity, _("Querying Autodiscover service"));
@@ -145,20 +218,26 @@ mail_config_ews_autodiscover_run (EMailConfigEwsAutodiscover *autodiscover)
        async_context = g_slice_new0 (AsyncContext);
        async_context->autodiscover = g_object_ref (autodiscover);
        async_context->activity = activity;  /* takes ownership */
+       async_context->source = g_object_ref (source);
+       async_context->ews_settings = g_object_ref (settings);
+       async_context->email_address = g_strdup (e_mail_config_service_page_get_email_address (page));
 
        /*
-        * e_source_registry_authenticate() will be run in a new a thread, which
-        * one will invoke camel_ews_settings_set_{oaburl,hosturl}(), emiting
-        * signals that are bound to GTK+ UI signals, causing GTK+ calls in this
+        * The GTask will be run in a new thread, which will invoke
+        * camel_ews_settings_set_{oaburl,hosturl}(), emiting signals that
+        * are bound to GTK+ UI signals, causing GTK+ calls in this
         * secondary thread and consequently a crash. To avoid this, let's stop
         * the property changes notifications while we are not in the main thread.
         */
        g_object_freeze_notify (G_OBJECT (settings));
-       e_source_registry_authenticate (
-               registry, source,
-               E_SOURCE_AUTHENTICATOR (autodiscover),
-               cancellable, mail_config_ews_autodiscover_run_cb,
-               async_context);
+
+       task = g_task_new (autodiscover, cancellable, mail_config_ews_autodiscover_run_cb, async_context);
+       g_task_set_source_tag (task, mail_config_ews_autodiscover_finish);
+       g_task_set_task_data (task, async_context, async_context_free);
+
+       g_task_run_in_thread (task, mail_config_ews_autodiscover_run_thread);
+
+       g_object_unref (task);
 }
 
 static void
@@ -246,64 +325,6 @@ mail_config_ews_autodiscover_clicked (GtkButton *button)
        mail_config_ews_autodiscover_run (autodiscover);
 }
 
-static gboolean
-mail_config_ews_autodiscover_get_without_password (ESourceAuthenticator *auth)
-{
-       EMailConfigEwsAutodiscover *autodiscover;
-       EMailConfigServiceBackend *backend;
-       CamelSettings *settings;
-       CamelEwsSettings *ews_settings;
-
-       autodiscover = E_MAIL_CONFIG_EWS_AUTODISCOVER (auth);
-       backend = e_mail_config_ews_autodiscover_get_backend (autodiscover);
-       settings = e_mail_config_service_backend_get_settings (backend);
-       ews_settings = CAMEL_EWS_SETTINGS (settings);
-
-       return e_ews_connection_utils_get_without_password (ews_settings);
-}
-
-static ESourceAuthenticationResult
-mail_config_ews_autodiscover_try_password_sync (ESourceAuthenticator *auth,
-                                                const GString *password,
-                                                GCancellable *cancellable,
-                                                GError **error)
-{
-       EMailConfigEwsAutodiscover *autodiscover;
-       EMailConfigServiceBackend *backend;
-       EMailConfigServicePage *page;
-       CamelSettings *settings;
-       CamelEwsSettings *ews_settings;
-       ESourceAuthenticationResult result;
-       const gchar *email_address;
-       GError *local_error = NULL;
-
-       autodiscover = E_MAIL_CONFIG_EWS_AUTODISCOVER (auth);
-       backend = e_mail_config_ews_autodiscover_get_backend (autodiscover);
-       page = e_mail_config_service_backend_get_page (backend);
-       settings = e_mail_config_service_backend_get_settings (backend);
-
-       email_address = e_mail_config_service_page_get_email_address (page);
-
-       ews_settings = CAMEL_EWS_SETTINGS (settings);
-
-       e_ews_autodiscover_ws_url_sync (
-               ews_settings, email_address, password->str,
-               cancellable, &local_error);
-
-       if (local_error == NULL) {
-               result = E_SOURCE_AUTHENTICATION_ACCEPTED;
-       } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
-               result = E_SOURCE_AUTHENTICATION_REJECTED;
-               g_error_free (local_error);
-
-       } else {
-               result = E_SOURCE_AUTHENTICATION_ERROR;
-               g_propagate_error (error, local_error);
-       }
-
-       return result;
-}
-
 static void
 e_mail_config_ews_autodiscover_class_init (EMailConfigEwsAutodiscoverClass *class)
 {
@@ -335,15 +356,6 @@ e_mail_config_ews_autodiscover_class_init (EMailConfigEwsAutodiscoverClass *clas
 }
 
 static void
-e_mail_config_ews_autodiscover_authenticator_init (ESourceAuthenticatorInterface *iface)
-{
-       iface->get_without_password =
-               mail_config_ews_autodiscover_get_without_password;
-       iface->try_password_sync =
-               mail_config_ews_autodiscover_try_password_sync;
-}
-
-static void
 e_mail_config_ews_autodiscover_class_finalize (EMailConfigEwsAutodiscoverClass *class)
 {
 }
diff --git a/src/configuration/e-mail-config-ews-delegates-page.c 
b/src/configuration/e-mail-config-ews-delegates-page.c
index e837c25..894f150 100644
--- a/src/configuration/e-mail-config-ews-delegates-page.c
+++ b/src/configuration/e-mail-config-ews-delegates-page.c
@@ -73,6 +73,8 @@ struct _EMailConfigEwsDelegatesPagePrivate {
 struct _AsyncContext {
        EMailConfigEwsDelegatesPage *page;
        EActivity *activity;
+       ESource *source;
+       GObject *settings;
 };
 
 enum {
@@ -86,8 +88,6 @@ enum {
 /* Forward Declarations */
 static void    e_mail_config_ews_delegates_page_interface_init
                                        (EMailConfigPageInterface *iface);
-static void    e_mail_config_ews_delegates_page_authenticator_init
-                                       (ESourceAuthenticatorInterface *iface);
 static void    add_to_tree_view        (EMailConfigEwsDelegatesPage *page,
                                         EwsDelegateInfo *di,
                                         gboolean select);
@@ -102,19 +102,23 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED (
        0,
        G_IMPLEMENT_INTERFACE_DYNAMIC (
                E_TYPE_MAIL_CONFIG_PAGE,
-               e_mail_config_ews_delegates_page_interface_init)
-       G_IMPLEMENT_INTERFACE_DYNAMIC (
-               E_TYPE_SOURCE_AUTHENTICATOR,
-               e_mail_config_ews_delegates_page_authenticator_init))
+               e_mail_config_ews_delegates_page_interface_init))
 
 static void
-async_context_free (AsyncContext *async_context)
+async_context_free (gpointer ptr)
 {
-       if (async_context->page != NULL)
-               g_object_unref (async_context->page);
+       AsyncContext *async_context = ptr;
+
+       if (!async_context)
+               return;
+
+       if (async_context->settings)
+               g_object_thaw_notify (async_context->settings);
 
-       if (async_context->activity != NULL)
-               g_object_unref (async_context->activity);
+       g_clear_object (&async_context->page);
+       g_clear_object (&async_context->activity);
+       g_clear_object (&async_context->source);
+       g_clear_object (&async_context->settings);
 
        g_slice_free (AsyncContext, async_context);
 }
@@ -229,80 +233,6 @@ copy_delegate_info (const EwsDelegateInfo *src)
 }
 
 static void
-mail_config_ews_delegates_page_refresh_cb (GObject *source_object,
-                                           GAsyncResult *result,
-                                           gpointer user_data)
-{
-       ESourceRegistry *registry;
-       AsyncContext *async_context;
-       EAlertSink *alert_sink;
-       GError *error = NULL;
-
-       registry = E_SOURCE_REGISTRY (source_object);
-       async_context = (AsyncContext *) user_data;
-
-       alert_sink = e_activity_get_alert_sink (async_context->activity);
-
-       e_source_registry_authenticate_finish (registry, result, &error);
-
-       if (e_activity_handle_cancellation (async_context->activity, error)) {
-               g_error_free (error);
-
-       } else if (error != NULL) {
-               e_alert_submit (
-                       alert_sink,
-                       "ews:query-delegates-error",
-                       error->message, NULL);
-               g_error_free (error);
-
-       } else {
-               EMailConfigEwsDelegatesPage *page = async_context->page;
-               GtkWidget *radio = page->priv->deliver_copy_me_radio;
-               GtkTreeModel *model;
-               const GSList *iter;
-
-               g_mutex_lock (&page->priv->delegates_lock);
-
-               switch (page->priv->deliver_to) {
-               case EwsDelegateDeliver_DelegatesOnly:
-                       radio = page->priv->deliver_delegates_only_radio;
-                       break;
-               case EwsDelegateDeliver_DelegatesAndMe:
-                       radio = page->priv->deliver_delegates_and_me_radio;
-                       break;
-               case EwsDelegateDeliver_DelegatesAndSendInformationToMe:
-                       radio = page->priv->deliver_copy_me_radio;
-                       break;
-               }
-
-               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
-
-               model = gtk_tree_view_get_model (GTK_TREE_VIEW (page->priv->users_tree_view));
-               gtk_list_store_clear (GTK_LIST_STORE (model));
-
-               for (iter = page->priv->orig_delegates; iter; iter = iter->next) {
-                       const EwsDelegateInfo *orig_di = iter->data;
-                       EwsDelegateInfo *di;
-
-                       if (!orig_di) {
-                               g_warn_if_reached ();
-                               continue;
-                       }
-
-                       di = copy_delegate_info (orig_di);
-
-                       add_to_tree_view (page, di, FALSE);
-               }
-
-               g_mutex_unlock (&page->priv->delegates_lock);
-
-               enable_delegates_page_widgets (page, page->priv->connection != NULL);
-       }
-
-       async_context_free (async_context);
-}
-
-static void
 mail_config_ews_delegates_page_set_account_source (EMailConfigEwsDelegatesPage *page,
                                                    ESource *account_source)
 {
@@ -830,10 +760,9 @@ retrieve_user_permissions_thread_cb (GObject *ppage,
                conn = g_object_ref (page->priv->connection);
        else
                conn = e_ews_config_utils_open_connection_for (
-                       e_mail_config_ews_delegates_page_get_registry (page),
                        e_mail_config_ews_delegates_page_get_collection_source (page),
                        CAMEL_EWS_SETTINGS (mail_config_ews_delegates_page_get_settings (page)),
-                       cancellable, perror);
+                       NULL, NULL, NULL, cancellable, perror);
 
        g_object_unref (service);
 
@@ -1501,53 +1430,29 @@ sort_by_display_name_cb (gconstpointer a,
        return g_utf8_collate (aname, bname);
 }
 
-static gboolean
-mail_config_ews_delegates_page_get_without_password (ESourceAuthenticator *auth)
-{
-       EMailConfigEwsDelegatesPage *page;
-       CamelSettings *settings;
-       CamelEwsSettings *ews_settings;
-
-       page = E_MAIL_CONFIG_EWS_DELEGATES_PAGE (auth);
-       settings = mail_config_ews_delegates_page_get_settings (page);
-       ews_settings = CAMEL_EWS_SETTINGS (settings);
-
-       return e_ews_connection_utils_get_without_password (ews_settings);
-}
-
 static ESourceAuthenticationResult
-mail_config_ews_delegates_page_try_password_sync (ESourceAuthenticator *auth,
-                                                  const GString *password,
-                                                  GCancellable *cancellable,
-                                                  GError **error)
+mail_config_ews_delegates_page_try_credentials_sync (EEwsConnection *connection,
+                                                    const ENamedParameters *credentials,
+                                                    gpointer user_data,
+                                                    GCancellable *cancellable,
+                                                    GError **error)
 {
-       EMailConfigEwsDelegatesPage *page;
-       CamelSettings *settings;
-       CamelEwsSettings *ews_settings;
+       AsyncContext *async_context = user_data;
        ESourceAuthenticationResult result;
        EwsDelegateDeliver deliver_to;
        GSList *delegates;
-       const gchar *hosturl;
        const gchar *mailbox;
        GError *local_error = NULL;
 
        if (g_cancellable_set_error_if_cancelled (cancellable, error))
                return E_SOURCE_AUTHENTICATION_ERROR;
 
-       page = E_MAIL_CONFIG_EWS_DELEGATES_PAGE (auth);
-       mailbox = mail_config_ews_delegates_page_get_mailbox (page);
-       settings = mail_config_ews_delegates_page_get_settings (page);
+       mailbox = mail_config_ews_delegates_page_get_mailbox (async_context->page);
 
-       ews_settings = CAMEL_EWS_SETTINGS (settings);
-       hosturl = camel_ews_settings_get_hosturl (ews_settings);
+       g_clear_object (&async_context->page->priv->connection);
+       e_ews_connection_set_mailbox (connection, mailbox);
 
-       if (page->priv->connection)
-               g_object_unref (page->priv->connection);
-       page->priv->connection = e_ews_connection_new (hosturl, ews_settings);
-       e_ews_connection_set_password (page->priv->connection, password->str);
-       e_ews_connection_set_mailbox (page->priv->connection, mailbox);
-
-       if (e_ews_connection_get_delegate_sync (page->priv->connection, G_PRIORITY_DEFAULT, NULL, TRUE,
+       if (e_ews_connection_get_delegate_sync (connection, G_PRIORITY_DEFAULT, NULL, TRUE,
                &deliver_to, &delegates, cancellable, &local_error) ||
            g_error_matches (local_error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_ITEMNOTFOUND)) {
                if (local_error) {
@@ -1558,22 +1463,24 @@ mail_config_ews_delegates_page_try_password_sync (ESourceAuthenticator *auth,
 
                result = E_SOURCE_AUTHENTICATION_ACCEPTED;
 
+               async_context->page->priv->connection = g_object_ref (connection);
+
                /* The page takes ownership of the settings. */
-               g_mutex_lock (&page->priv->delegates_lock);
-               g_slist_free_full (page->priv->orig_delegates, (GDestroyNotify) ews_delegate_info_free);
+               g_mutex_lock (&async_context->page->priv->delegates_lock);
+               g_slist_free_full (async_context->page->priv->orig_delegates, (GDestroyNotify) 
ews_delegate_info_free);
 
-               page->priv->deliver_to = deliver_to;
-               page->priv->orig_delegates = g_slist_sort (delegates, sort_by_display_name_cb);
-               g_mutex_unlock (&page->priv->delegates_lock);
+               async_context->page->priv->deliver_to = deliver_to;
+               async_context->page->priv->orig_delegates = g_slist_sort (delegates, sort_by_display_name_cb);
+               g_mutex_unlock (&async_context->page->priv->delegates_lock);
 
        } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
                result = E_SOURCE_AUTHENTICATION_REJECTED;
-               g_clear_object (&page->priv->connection);
+               g_clear_object (&async_context->page->priv->connection);
                g_error_free (local_error);
 
        } else {
                result = E_SOURCE_AUTHENTICATION_ERROR;
-               g_clear_object (&page->priv->connection);
+               g_clear_object (&async_context->page->priv->connection);
                g_propagate_error (error, local_error);
        }
 
@@ -1581,6 +1488,100 @@ mail_config_ews_delegates_page_try_password_sync (ESourceAuthenticator *auth,
 }
 
 static void
+mail_config_ews_delegates_page_refresh_thread_cb (GObject *with_object,
+                                                 gpointer user_data,
+                                                 GCancellable *cancellable,
+                                                 GError **perror)
+{
+       AsyncContext *async_context = user_data;
+       CamelEwsSettings *ews_settings;
+       EEwsConnection *connection;
+
+       if (g_cancellable_set_error_if_cancelled (cancellable, perror))
+               return;
+
+       ews_settings = CAMEL_EWS_SETTINGS (async_context->settings);
+       connection = e_ews_config_utils_open_connection_for (async_context->source, ews_settings, NULL,
+               mail_config_ews_delegates_page_try_credentials_sync, async_context, cancellable, perror);
+
+       g_clear_object (&connection);
+}
+
+static void
+mail_config_ews_delegates_page_refresh_idle_cb (GObject *with_object,
+                                               gpointer user_data,
+                                               GCancellable *cancellable,
+                                               GError **perror)
+{
+       AsyncContext *async_context;
+       EAlertSink *alert_sink;
+       GError *error = NULL;
+
+       async_context = (AsyncContext *) user_data;
+
+       if (perror) {
+               error = *perror;
+               *perror = NULL;
+       }
+
+       alert_sink = e_activity_get_alert_sink (async_context->activity);
+
+       if (e_activity_handle_cancellation (async_context->activity, error)) {
+               g_error_free (error);
+
+       } else if (error != NULL) {
+               e_alert_submit (
+                       alert_sink,
+                       "ews:query-delegates-error",
+                       error->message, NULL);
+               g_error_free (error);
+
+       } else {
+               EMailConfigEwsDelegatesPage *page = async_context->page;
+               GtkWidget *radio = page->priv->deliver_copy_me_radio;
+               GtkTreeModel *model;
+               const GSList *iter;
+
+               g_mutex_lock (&page->priv->delegates_lock);
+
+               switch (page->priv->deliver_to) {
+               case EwsDelegateDeliver_DelegatesOnly:
+                       radio = page->priv->deliver_delegates_only_radio;
+                       break;
+               case EwsDelegateDeliver_DelegatesAndMe:
+                       radio = page->priv->deliver_delegates_and_me_radio;
+                       break;
+               case EwsDelegateDeliver_DelegatesAndSendInformationToMe:
+                       radio = page->priv->deliver_copy_me_radio;
+                       break;
+               }
+
+               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
+
+               model = gtk_tree_view_get_model (GTK_TREE_VIEW (page->priv->users_tree_view));
+               gtk_list_store_clear (GTK_LIST_STORE (model));
+
+               for (iter = page->priv->orig_delegates; iter; iter = iter->next) {
+                       const EwsDelegateInfo *orig_di = iter->data;
+                       EwsDelegateInfo *di;
+
+                       if (!orig_di) {
+                               g_warn_if_reached ();
+                               continue;
+                       }
+
+                       di = copy_delegate_info (orig_di);
+
+                       add_to_tree_view (page, di, FALSE);
+               }
+
+               g_mutex_unlock (&page->priv->delegates_lock);
+
+               enable_delegates_page_widgets (page, page->priv->connection != NULL);
+       }
+}
+
+static void
 e_mail_config_ews_delegates_page_class_init (EMailConfigEwsDelegatesPageClass *class)
 {
        GObjectClass *object_class;
@@ -1650,15 +1651,6 @@ e_mail_config_ews_delegates_page_interface_init (EMailConfigPageInterface *iface
 }
 
 static void
-e_mail_config_ews_delegates_page_authenticator_init (ESourceAuthenticatorInterface *iface)
-{
-       iface->get_without_password =
-               mail_config_ews_delegates_page_get_without_password;
-       iface->try_password_sync =
-               mail_config_ews_delegates_page_try_password_sync;
-}
-
-static void
 e_mail_config_ews_delegates_page_class_finalize (EMailConfigEwsDelegatesPageClass *class)
 {
 }
@@ -1703,18 +1695,15 @@ e_mail_config_ews_delegates_page_new (ESourceRegistry *registry,
 void
 e_mail_config_ews_delegates_page_refresh (EMailConfigEwsDelegatesPage *page)
 {
-       ESourceAuthenticator *authenticator;
-       ESourceRegistry *registry;
        ESource *source;
        EActivity *activity;
        GCancellable *cancellable;
+       CamelSettings *settings;
        AsyncContext *async_context;
 
        g_return_if_fail (E_IS_MAIL_CONFIG_EWS_DELEGATES_PAGE (page));
 
-       registry = e_mail_config_ews_delegates_page_get_registry (page);
        source = e_mail_config_ews_delegates_page_get_collection_source (page);
-       authenticator = E_SOURCE_AUTHENTICATOR (page);
 
        if (page->priv->refresh_cancellable) {
                g_cancellable_cancel (page->priv->refresh_cancellable);
@@ -1729,13 +1718,22 @@ e_mail_config_ews_delegates_page_refresh (EMailConfigEwsDelegatesPage *page)
        e_activity_set_text (
                activity, _("Retrieving \"Delegates\" settings"));
 
+       settings = mail_config_ews_delegates_page_get_settings (page);
+
        async_context = g_slice_new0 (AsyncContext);
        async_context->page = g_object_ref (page);
        async_context->activity = activity;  /* takes ownership */
+       async_context->source = g_object_ref (source);
+       async_context->settings = g_object_ref (settings);
+
+       /* Property changes can cause update of the UI, but this runs in a thread,
+          thus freeze the notify till be back in UI thread */
+       g_object_freeze_notify (async_context->settings);
 
-       e_source_registry_authenticate (
-               registry, source, authenticator, cancellable,
-               mail_config_ews_delegates_page_refresh_cb, async_context);
+       e_ews_config_utils_run_in_thread (G_OBJECT (page),
+               mail_config_ews_delegates_page_refresh_thread_cb,
+               mail_config_ews_delegates_page_refresh_idle_cb,
+               async_context, async_context_free, cancellable);
 }
 
 ESourceRegistry *
diff --git a/src/configuration/e-mail-config-ews-gal.c b/src/configuration/e-mail-config-ews-gal.c
index bd6abf5..1f5b27b 100644
--- a/src/configuration/e-mail-config-ews-gal.c
+++ b/src/configuration/e-mail-config-ews-gal.c
@@ -123,14 +123,16 @@ mail_config_ews_gal_oal_selected_to_active_id (GBinding *binding,
        target_object = g_binding_get_target (binding);
        combo_box = GTK_COMBO_BOX (target_object);
 
-       /* The combo box might already have the OAL ID, in which case
-        * we simply make it the active combo box row.  Otherwise we
-        * have to add a new row and make it the active row. */
-       if (!gtk_combo_box_set_active_id (combo_box, active_id)) {
-               gtk_combo_box_text_append (
-                       GTK_COMBO_BOX_TEXT (combo_box),
-                       active_id, active_text);
-               gtk_combo_box_set_active_id (combo_box, active_id);
+       if (g_strcmp0 (active_id, gtk_combo_box_get_active_id (combo_box)) != 0) {
+               /* The combo box might already have the OAL ID, in which case
+                * we simply make it the active combo box row.  Otherwise we
+                * have to add a new row and make it the active row. */
+               if (!gtk_combo_box_set_active_id (combo_box, active_id)) {
+                       gtk_combo_box_text_append (
+                               GTK_COMBO_BOX_TEXT (combo_box),
+                               active_id, active_text);
+                       gtk_combo_box_set_active_id (combo_box, active_id);
+               }
        }
 
        g_value_set_string (target_value, active_id);
diff --git a/src/configuration/e-mail-config-ews-oal-combo-box.c 
b/src/configuration/e-mail-config-ews-oal-combo-box.c
index 1dcef79..a70d6a3 100644
--- a/src/configuration/e-mail-config-ews-oal-combo-box.c
+++ b/src/configuration/e-mail-config-ews-oal-combo-box.c
@@ -20,13 +20,14 @@
 #include <config.h>
 #endif
 
-#include "e-mail-config-ews-oal-combo-box.h"
-
 #include <mail/e-mail-config-service-page.h>
 
 #include "server/e-ews-connection.h"
 #include "server/e-ews-connection-utils.h"
 
+#include "e-ews-config-utils.h"
+#include "e-mail-config-ews-oal-combo-box.h"
+
 #define E_MAIL_CONFIG_EWS_OAL_COMBO_BOX_GET_PRIVATE(obj) \
        (G_TYPE_INSTANCE_GET_PRIVATE \
        ((obj), E_TYPE_MAIL_CONFIG_EWS_OAL_COMBO_BOX, EMailConfigEwsOalComboBoxPrivate))
@@ -47,18 +48,33 @@ enum {
        PROP_BACKEND
 };
 
-/* Forward Declarations */
-static void    e_mail_config_ews_oal_combo_box_authenticator_init
-                               (ESourceAuthenticatorInterface *iface);
+G_DEFINE_DYNAMIC_TYPE (EMailConfigEwsOalComboBox, e_mail_config_ews_oal_combo_box, GTK_TYPE_COMBO_BOX_TEXT)
+
+typedef struct _AsyncContext {
+       EMailConfigEwsOalComboBox *combo_box;
+       GSimpleAsyncResult *simple;
+       ESource *source;
+       GObject *settings;
+} AsyncContext;
+
+static void
+async_context_free (gpointer ptr)
+{
+       AsyncContext *async_context = ptr;
+
+       if (!async_context)
+               return;
 
-G_DEFINE_DYNAMIC_TYPE_EXTENDED (
-       EMailConfigEwsOalComboBox,
-       e_mail_config_ews_oal_combo_box,
-       GTK_TYPE_COMBO_BOX_TEXT,
-       0,
-       G_IMPLEMENT_INTERFACE_DYNAMIC (
-               E_TYPE_SOURCE_AUTHENTICATOR,
-               e_mail_config_ews_oal_combo_box_authenticator_init))
+       if (async_context->settings)
+               g_object_thaw_notify (async_context->settings);
+
+       g_clear_object (&async_context->combo_box);
+       g_clear_object (&async_context->simple);
+       g_clear_object (&async_context->source);
+       g_clear_object (&async_context->settings);
+
+       g_slice_free (AsyncContext, async_context);
+}
 
 static void
 mail_config_ews_oal_combo_box_set_backend (EMailConfigEwsOalComboBox *combo_box,
@@ -136,78 +152,6 @@ mail_config_ews_oal_combo_box_finalize (GObject *object)
                finalize (object);
 }
 
-static gboolean
-mail_config_ews_oal_combo_box_get_without_password (ESourceAuthenticator *auth)
-{
-       EMailConfigEwsOalComboBox *combo_box;
-       EMailConfigServiceBackend *backend;
-       CamelSettings *settings;
-       CamelEwsSettings *ews_settings;
-
-       combo_box = E_MAIL_CONFIG_EWS_OAL_COMBO_BOX (auth);
-       backend = e_mail_config_ews_oal_combo_box_get_backend (combo_box);
-       settings = e_mail_config_service_backend_get_settings (backend);
-
-       ews_settings = CAMEL_EWS_SETTINGS (settings);
-
-       return e_ews_connection_utils_get_without_password (ews_settings);
-}
-
-static ESourceAuthenticationResult
-mail_config_ews_oal_combo_box_try_password_sync (ESourceAuthenticator *auth,
-                                                 const GString *password,
-                                                 GCancellable *cancellable,
-                                                 GError **error)
-{
-       EMailConfigEwsOalComboBox *combo_box;
-       EMailConfigServiceBackend *backend;
-       CamelSettings *settings;
-       CamelEwsSettings *ews_settings;
-       ESourceAuthenticationResult result;
-       EEwsConnection *cnc;
-       GSList *oal_items = NULL;
-       const gchar *oab_url;
-       GError *local_error = NULL;
-
-       combo_box = E_MAIL_CONFIG_EWS_OAL_COMBO_BOX (auth);
-       backend = e_mail_config_ews_oal_combo_box_get_backend (combo_box);
-       settings = e_mail_config_service_backend_get_settings (backend);
-
-       ews_settings = CAMEL_EWS_SETTINGS (settings);
-       oab_url = camel_ews_settings_get_oaburl (ews_settings);
-
-       cnc = e_ews_connection_new (oab_url, ews_settings);
-       e_ews_connection_set_password (cnc, password->str);
-
-       e_ews_connection_get_oal_list_sync (
-               cnc, &oal_items, cancellable, &local_error);
-
-       g_object_unref (cnc);
-
-       if (local_error == NULL) {
-               result = E_SOURCE_AUTHENTICATION_ACCEPTED;
-
-               /* Deposit results in the private struct for
-                * the update_finish() function to pick up. */
-               g_mutex_lock (&combo_box->priv->oal_items_lock);
-               g_slist_free_full (
-                       combo_box->priv->oal_items,
-                       (GDestroyNotify) ews_oal_free);
-               combo_box->priv->oal_items = oal_items;
-               g_mutex_unlock (&combo_box->priv->oal_items_lock);
-
-       } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
-               result = E_SOURCE_AUTHENTICATION_REJECTED;
-               g_error_free (local_error);
-
-       } else {
-               result = E_SOURCE_AUTHENTICATION_ERROR;
-               g_propagate_error (error, local_error);
-       }
-
-       return result;
-}
-
 static void
 e_mail_config_ews_oal_combo_box_class_init (EMailConfigEwsOalComboBoxClass *class)
 {
@@ -235,15 +179,6 @@ e_mail_config_ews_oal_combo_box_class_init (EMailConfigEwsOalComboBoxClass *clas
 }
 
 static void
-e_mail_config_ews_oal_combo_box_authenticator_init (ESourceAuthenticatorInterface *iface)
-{
-       iface->get_without_password =
-               mail_config_ews_oal_combo_box_get_without_password;
-       iface->try_password_sync =
-               mail_config_ews_oal_combo_box_try_password_sync;
-}
-
-static void
 e_mail_config_ews_oal_combo_box_class_finalize (EMailConfigEwsOalComboBoxClass *class)
 {
 }
@@ -285,26 +220,90 @@ e_mail_config_ews_oal_combo_box_get_backend (EMailConfigEwsOalComboBox *combo_bo
        return combo_box->priv->backend;
 }
 
-/* Helper for e_mail_config_ews_oal_combo_box_update() */
+static ESourceAuthenticationResult
+mail_config_ews_aol_combo_box_update_try_credentials_sync (EEwsConnection *connection,
+                                                          const ENamedParameters *credentials,
+                                                          gpointer user_data,
+                                                          GCancellable *cancellable,
+                                                          GError **error)
+{
+       AsyncContext *async_context = user_data;
+       EMailConfigEwsOalComboBox *combo_box;
+       ESourceAuthenticationResult result;
+       GSList *oal_items = NULL;
+       GError *local_error = NULL;
+
+       combo_box = E_MAIL_CONFIG_EWS_OAL_COMBO_BOX (async_context->combo_box);
+
+       e_ews_connection_get_oal_list_sync (connection, &oal_items, cancellable, &local_error);
+
+       if (local_error == NULL) {
+               result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+
+               /* Deposit results in the private struct for
+                * the update_finish() function to pick up. */
+               g_mutex_lock (&combo_box->priv->oal_items_lock);
+               g_slist_free_full (
+                       combo_box->priv->oal_items,
+                       (GDestroyNotify) ews_oal_free);
+               combo_box->priv->oal_items = oal_items;
+               g_mutex_unlock (&combo_box->priv->oal_items_lock);
+
+       } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
+               result = E_SOURCE_AUTHENTICATION_REJECTED;
+               g_error_free (local_error);
+
+       } else {
+               result = E_SOURCE_AUTHENTICATION_ERROR;
+               g_propagate_error (error, local_error);
+       }
+
+       return result;
+}
+
 static void
-mail_config_ews_oal_combo_box_update_cb (GObject *source_object,
-                                         GAsyncResult *result,
-                                         gpointer user_data)
+mail_config_ews_aol_combo_box_update_thread_cb (GObject *with_object,
+                                               gpointer user_data,
+                                               GCancellable *cancellable,
+                                               GError **perror)
 {
-       GSimpleAsyncResult *simple;
+       AsyncContext *async_context = user_data;
+       CamelEwsSettings *ews_settings;
+       const gchar *oab_url;
+       EEwsConnection *connection;
+
+       if (g_cancellable_set_error_if_cancelled (cancellable, perror))
+               return;
+
+       ews_settings = CAMEL_EWS_SETTINGS (async_context->settings);
+       oab_url = camel_ews_settings_get_oaburl (ews_settings);
+
+       connection = e_ews_config_utils_open_connection_for (async_context->source, ews_settings, oab_url,
+               mail_config_ews_aol_combo_box_update_try_credentials_sync, async_context, cancellable, 
perror);
+
+       g_clear_object (&connection);
+}
+
+static void
+mail_config_ews_aol_combo_box_update_idle_cb (GObject *with_object,
+                                             gpointer user_data,
+                                             GCancellable *cancellable,
+                                             GError **perror)
+{
+       AsyncContext *async_context;
        GError *error = NULL;
 
-       simple = G_SIMPLE_ASYNC_RESULT (user_data);
+       async_context = (AsyncContext *) user_data;
 
-       e_source_registry_authenticate_finish (
-               E_SOURCE_REGISTRY (source_object), result, &error);
+       if (perror) {
+               error = *perror;
+               *perror = NULL;
+       }
 
        if (error != NULL)
-               g_simple_async_result_take_error (simple, error);
-
-       g_simple_async_result_complete (simple);
+               g_simple_async_result_take_error (async_context->simple, error);
 
-       g_object_unref (simple);
+       g_simple_async_result_complete (async_context->simple);
 }
 
 void
@@ -314,28 +313,35 @@ e_mail_config_ews_oal_combo_box_update (EMailConfigEwsOalComboBox *combo_box,
                                         gpointer user_data)
 {
        GSimpleAsyncResult *simple;
-       EMailConfigServicePage *page;
        EMailConfigServiceBackend *backend;
-       ESourceAuthenticator *authenticator;
-       ESourceRegistry *registry;
+       AsyncContext *async_context;
+       CamelSettings *settings;
        ESource *source;
 
        g_return_if_fail (E_IS_MAIL_CONFIG_EWS_OAL_COMBO_BOX (combo_box));
 
        backend = e_mail_config_ews_oal_combo_box_get_backend (combo_box);
-       page = e_mail_config_service_backend_get_page (backend);
+       settings = e_mail_config_service_backend_get_settings (backend);
        source = e_mail_config_service_backend_get_source (backend);
-       registry = e_mail_config_service_page_get_registry (page);
-
-       authenticator = E_SOURCE_AUTHENTICATOR (combo_box);
 
        simple = g_simple_async_result_new (
                G_OBJECT (combo_box), callback, user_data,
                e_mail_config_ews_oal_combo_box_update);
 
-       e_source_registry_authenticate (
-               registry, source, authenticator, cancellable,
-               mail_config_ews_oal_combo_box_update_cb, simple);
+       async_context = g_slice_new0 (AsyncContext);
+       async_context->combo_box = g_object_ref (combo_box);
+       async_context->simple = simple;  /* takes ownership */
+       async_context->source = g_object_ref (source);
+       async_context->settings = g_object_ref (settings);
+
+       /* Property changes can cause update of the UI, but this runs in a thread,
+          thus freeze the notify till be back in UI thread */
+       g_object_freeze_notify (async_context->settings);
+
+       e_ews_config_utils_run_in_thread (G_OBJECT (combo_box),
+               mail_config_ews_aol_combo_box_update_thread_cb,
+               mail_config_ews_aol_combo_box_update_idle_cb,
+               async_context, async_context_free, cancellable);
 }
 
 gboolean
diff --git a/src/configuration/e-mail-config-ews-ooo-page.c b/src/configuration/e-mail-config-ews-ooo-page.c
index e882654..de83c1c 100644
--- a/src/configuration/e-mail-config-ews-ooo-page.c
+++ b/src/configuration/e-mail-config-ews-ooo-page.c
@@ -20,8 +20,6 @@
 #include <config.h>
 #endif
 
-#include "e-mail-config-ews-ooo-page.h"
-
 #include <string.h>
 #include <unistd.h>
 
@@ -35,6 +33,10 @@
 #include "server/e-ews-connection-utils.h"
 #include "server/e-ews-oof-settings.h"
 
+#include "e-ews-config-utils.h"
+
+#include "e-mail-config-ews-ooo-page.h"
+
 #define E_MAIL_CONFIG_EWS_OOO_PAGE_GET_PRIVATE(obj) \
        (G_TYPE_INSTANCE_GET_PRIVATE \
        ((obj), E_TYPE_MAIL_CONFIG_EWS_OOO_PAGE, EMailConfigEwsOooPagePrivate))
@@ -70,6 +72,8 @@ struct _EMailConfigEwsOooPagePrivate {
 struct _AsyncContext {
        EMailConfigEwsOooPage *page;
        EActivity *activity;
+       ESource *source;
+       GObject *settings;
 };
 
 enum {
@@ -83,8 +87,6 @@ enum {
 /* Forward Declarations */
 static void    e_mail_config_ews_ooo_page_interface_init
                                (EMailConfigPageInterface *iface);
-static void    e_mail_config_ews_ooo_page_authenticator_init
-                               (ESourceAuthenticatorInterface *iface);
 
 G_DEFINE_DYNAMIC_TYPE_EXTENDED (
        EMailConfigEwsOooPage,
@@ -93,19 +95,23 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED (
        0,
        G_IMPLEMENT_INTERFACE_DYNAMIC (
                E_TYPE_MAIL_CONFIG_PAGE,
-               e_mail_config_ews_ooo_page_interface_init)
-       G_IMPLEMENT_INTERFACE_DYNAMIC (
-               E_TYPE_SOURCE_AUTHENTICATOR,
-               e_mail_config_ews_ooo_page_authenticator_init))
+               e_mail_config_ews_ooo_page_interface_init))
 
 static void
-async_context_free (AsyncContext *async_context)
+async_context_free (gpointer ptr)
 {
-       if (async_context->page != NULL)
-               g_object_unref (async_context->page);
+       AsyncContext *async_context = ptr;
 
-       if (async_context->activity != NULL)
-               g_object_unref (async_context->activity);
+       if (!async_context)
+               return;
+
+       if (async_context->settings)
+               g_object_thaw_notify (async_context->settings);
+
+       g_clear_object (&async_context->page);
+       g_clear_object (&async_context->activity);
+       g_clear_object (&async_context->source);
+       g_clear_object (&async_context->settings);
 
        g_slice_free (AsyncContext, async_context);
 }
@@ -214,48 +220,6 @@ mail_config_ews_ooo_page_display_settings (EMailConfigEwsOooPage *page,
 }
 
 static void
-mail_config_ews_ooo_page_refresh_cb (GObject *source_object,
-                                     GAsyncResult *result,
-                                     gpointer user_data)
-{
-       ESourceRegistry *registry;
-       AsyncContext *async_context;
-       EAlertSink *alert_sink;
-       GError *error = NULL;
-
-       registry = E_SOURCE_REGISTRY (source_object);
-       async_context = (AsyncContext *) user_data;
-
-       alert_sink = e_activity_get_alert_sink (async_context->activity);
-
-       e_source_registry_authenticate_finish (registry, result, &error);
-
-       if (e_activity_handle_cancellation (async_context->activity, error)) {
-               g_error_free (error);
-
-       } else if (error != NULL) {
-               e_alert_submit (
-                       alert_sink,
-                       "ews:query-ooo-error",
-                       error->message, NULL);
-               g_error_free (error);
-
-       } else {
-               EMailConfigEwsOooPage *page = async_context->page;
-
-               g_mutex_lock (&page->priv->oof_settings_lock);
-
-               if (page->priv->oof_settings != NULL)
-                       mail_config_ews_ooo_page_display_settings (
-                               page, page->priv->oof_settings);
-
-               g_mutex_unlock (&page->priv->oof_settings_lock);
-       }
-
-       async_context_free (async_context);
-}
-
-static void
 mail_config_ews_ooo_page_set_account_source (EMailConfigEwsOooPage *page,
                                              ESource *account_source)
 {
@@ -794,55 +758,26 @@ mail_config_ews_ooo_page_submit_finish (EMailConfigPage *page,
        return !g_simple_async_result_propagate_error (simple, error);
 }
 
-static gboolean
-mail_config_ews_ooo_page_get_without_password (ESourceAuthenticator *auth)
-{
-       EMailConfigEwsOooPage *page;
-       CamelSettings *settings;
-       CamelEwsSettings *ews_settings;
-
-       page = E_MAIL_CONFIG_EWS_OOO_PAGE (auth);
-       settings = mail_config_ews_ooo_page_get_settings (page);
-       ews_settings = CAMEL_EWS_SETTINGS (settings);
-
-       return e_ews_connection_utils_get_without_password (ews_settings);
-}
-
 static ESourceAuthenticationResult
-mail_config_ews_ooo_page_try_password_sync (ESourceAuthenticator *auth,
-                                            const GString *password,
-                                            GCancellable *cancellable,
-                                            GError **error)
+mail_config_ews_ooo_page_try_credentials_sync (EEwsConnection *connection,
+                                              const ENamedParameters *credentials,
+                                              gpointer user_data,
+                                              GCancellable *cancellable,
+                                              GError **error)
 {
+       AsyncContext *async_context = user_data;
        EMailConfigEwsOooPage *page;
-       CamelSettings *settings;
-       CamelEwsSettings *ews_settings;
        ESourceAuthenticationResult result;
-       EEwsConnection *connection;
        EEwsOofSettings *oof_settings;
-       const gchar *hosturl;
        const gchar *mailbox;
        GError *local_error = NULL;
 
-       if (g_cancellable_set_error_if_cancelled (cancellable, error))
-               return E_SOURCE_AUTHENTICATION_ERROR;
+       page = async_context->page;
 
-       page = E_MAIL_CONFIG_EWS_OOO_PAGE (auth);
        mailbox = mail_config_ews_ooo_page_get_mailbox (page);
-       settings = mail_config_ews_ooo_page_get_settings (page);
-
-       ews_settings = CAMEL_EWS_SETTINGS (settings);
-       hosturl = camel_ews_settings_get_hosturl (ews_settings);
-
-       connection = e_ews_connection_new (hosturl, ews_settings);
-       e_ews_connection_set_password (connection, password->str);
-
        e_ews_connection_set_mailbox (connection, mailbox);
 
-       oof_settings = e_ews_oof_settings_new_sync (
-               connection, cancellable, &local_error);
-
-       g_object_unref (connection);
+       oof_settings = e_ews_oof_settings_new_sync (connection, cancellable, &local_error);
 
        if (oof_settings != NULL) {
                result = E_SOURCE_AUTHENTICATION_ACCEPTED;
@@ -869,6 +804,68 @@ mail_config_ews_ooo_page_try_password_sync (ESourceAuthenticator *auth,
 }
 
 static void
+mail_config_ews_ooo_page_refresh_thread_cb (GObject *with_object,
+                                           gpointer user_data,
+                                           GCancellable *cancellable,
+                                           GError **perror)
+{
+       AsyncContext *async_context = user_data;
+       CamelEwsSettings *ews_settings;
+       EEwsConnection *connection;
+
+       if (g_cancellable_set_error_if_cancelled (cancellable, perror))
+               return;
+
+       ews_settings = CAMEL_EWS_SETTINGS (async_context->settings);
+       connection = e_ews_config_utils_open_connection_for (async_context->source, ews_settings, NULL,
+               mail_config_ews_ooo_page_try_credentials_sync, async_context, cancellable, perror);
+
+       g_clear_object (&connection);
+}
+
+static void
+mail_config_ews_ooo_page_refresh_idle_cb (GObject *with_object,
+                                         gpointer user_data,
+                                         GCancellable *cancellable,
+                                         GError **perror)
+{
+       AsyncContext *async_context;
+       EAlertSink *alert_sink;
+       GError *error = NULL;
+
+       async_context = (AsyncContext *) user_data;
+
+       if (perror) {
+               error = *perror;
+               *perror = NULL;
+       }
+
+       alert_sink = e_activity_get_alert_sink (async_context->activity);
+
+       if (e_activity_handle_cancellation (async_context->activity, error)) {
+               g_error_free (error);
+
+       } else if (error != NULL) {
+               e_alert_submit (
+                       alert_sink,
+                       "ews:query-ooo-error",
+                       error->message, NULL);
+               g_error_free (error);
+
+       } else {
+               EMailConfigEwsOooPage *page = async_context->page;
+
+               g_mutex_lock (&page->priv->oof_settings_lock);
+
+               if (page->priv->oof_settings != NULL)
+                       mail_config_ews_ooo_page_display_settings (
+                               page, page->priv->oof_settings);
+
+               g_mutex_unlock (&page->priv->oof_settings_lock);
+       }
+}
+
+static void
 e_mail_config_ews_ooo_page_class_init (EMailConfigEwsOooPageClass *class)
 {
        GObjectClass *object_class;
@@ -938,15 +935,6 @@ e_mail_config_ews_ooo_page_interface_init (EMailConfigPageInterface *iface)
 }
 
 static void
-e_mail_config_ews_ooo_page_authenticator_init (ESourceAuthenticatorInterface *iface)
-{
-       iface->get_without_password =
-               mail_config_ews_ooo_page_get_without_password;
-       iface->try_password_sync =
-               mail_config_ews_ooo_page_try_password_sync;
-}
-
-static void
 e_mail_config_ews_ooo_page_class_finalize (EMailConfigEwsOooPageClass *class)
 {
 }
@@ -991,18 +979,15 @@ e_mail_config_ews_ooo_page_new (ESourceRegistry *registry,
 void
 e_mail_config_ews_ooo_page_refresh (EMailConfigEwsOooPage *page)
 {
-       ESourceAuthenticator *authenticator;
-       ESourceRegistry *registry;
        ESource *source;
        EActivity *activity;
        GCancellable *cancellable;
+       CamelSettings *settings;
        AsyncContext *async_context;
 
        g_return_if_fail (E_IS_MAIL_CONFIG_EWS_OOO_PAGE (page));
 
-       registry = e_mail_config_ews_ooo_page_get_registry (page);
        source = e_mail_config_ews_ooo_page_get_collection_source (page);
-       authenticator = E_SOURCE_AUTHENTICATOR (page);
 
        if (page->priv->refresh_cancellable) {
                g_cancellable_cancel (page->priv->refresh_cancellable);
@@ -1017,13 +1002,22 @@ e_mail_config_ews_ooo_page_refresh (EMailConfigEwsOooPage *page)
        e_activity_set_text (
                activity, _("Retrieving \"Out of Office\" settings"));
 
+       settings = mail_config_ews_ooo_page_get_settings (page);
+
        async_context = g_slice_new0 (AsyncContext);
        async_context->page = g_object_ref (page);
        async_context->activity = activity;  /* takes ownership */
+       async_context->source = g_object_ref (source);
+       async_context->settings = g_object_ref (settings);
+
+       /* Property changes can cause update of the UI, but this runs in a thread,
+          thus freeze the notify till be back in UI thread */
+       g_object_freeze_notify (async_context->settings);
 
-       e_source_registry_authenticate (
-               registry, source, authenticator, cancellable,
-               mail_config_ews_ooo_page_refresh_cb, async_context);
+       e_ews_config_utils_run_in_thread (G_OBJECT (page),
+               mail_config_ews_ooo_page_refresh_thread_cb,
+               mail_config_ews_ooo_page_refresh_idle_cb,
+               async_context, async_context_free, cancellable);
 }
 
 ESourceRegistry *
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index ad14f92..ce7120a 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -170,17 +170,7 @@ struct _EwsUrls {
        gpointer future2;
 };
 
-/* Forward Declarations */
-static void    e_ews_connection_authenticator_init
-                               (ESourceAuthenticatorInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (
-       EEwsConnection,
-       e_ews_connection,
-       G_TYPE_OBJECT,
-       G_IMPLEMENT_INTERFACE (
-               E_TYPE_SOURCE_AUTHENTICATOR,
-               e_ews_connection_authenticator_init))
+G_DEFINE_TYPE (EEwsConnection, e_ews_connection, G_TYPE_OBJECT)
 
 /* Static Functions */
 
@@ -491,19 +481,6 @@ typedef struct _EwsScheduleData
        gpointer queue_user_data;
 } EwsScheduleData;
 
-static gboolean
-ews_connection_get_without_password (ESourceAuthenticator *authenticator)
-{
-       gboolean result;
-       EEwsConnection *cnc = E_EWS_CONNECTION (authenticator);
-       CamelEwsSettings *ews_settings = e_ews_connection_ref_settings (cnc);
-
-       result = e_ews_connection_utils_get_without_password (ews_settings);
-
-       g_object_unref (ews_settings);
-       return result;
-}
-
 /* this is run in priv->soup_thread */
 static gboolean
 ews_connection_scheduled_cb (gpointer user_data)
@@ -938,7 +915,7 @@ sync_hierarchy_response_cb (ESoapResponse *response,
        /*
         * During the first connection, we are able to get the current version of the Exchange server.
         * For Addressbook/Calendar backends, we are ensuring it happens during the
-        * ews_connection_try_password_sync(), that calls e_e_ews_connection_get_folder_sync() and then
+        * e_ews_connection_try_credentials_sync(), that calls e_e_ews_connection_get_folder_sync() and then
         * we are able to get the current version of the server from this first response.
         *
         * For Camel, the first connection is done calling e_ews_connection_sync_folder_hierarchy_sync().
@@ -1051,7 +1028,7 @@ get_folder_response_cb (ESoapResponse *response,
        /*
         * During the first connection, we are able to get the current version of the Exchange server.
         * For Addressbook/Calendar backends, we are ensuring it happens during the
-        * ews_connection_try_password_sync(), that calls e_e_ews_connection_get_folder_sync() and then
+        * e_ews_connection_try_credentials_sync(), that calls e_e_ews_connection_get_folder_sync() and then
         * we are able to get the current version of the server from this first response.
         *
         * For Camel, the first connection is done calling e_ews_connection_sync_folder_hierarchy_sync().
@@ -1670,56 +1647,6 @@ ews_connection_constructor (GType gtype, guint n_properties,
        return obj;
 }
 
-static ESourceAuthenticationResult
-ews_connection_try_password_sync (ESourceAuthenticator *authenticator,
-                                  const GString *password,
-                                  GCancellable *cancellable,
-                                  GError **error)
-{
-       EEwsConnection *connection;
-       ESourceAuthenticationResult result;
-       EwsFolderId *fid = NULL;
-       GSList *ids = NULL;
-       GError *local_error = NULL;
-
-       connection = E_EWS_CONNECTION (authenticator);
-
-       e_ews_connection_set_password (connection, password->str);
-
-       fid = g_new0 (EwsFolderId, 1);
-       fid->id = g_strdup ("inbox");
-       fid->is_distinguished_id = TRUE;
-       ids = g_slist_append (ids, fid);
-
-       e_ews_connection_get_folder_sync (
-               connection, EWS_PRIORITY_MEDIUM, "Default",
-               NULL, ids, NULL, cancellable, &local_error);
-
-       g_slist_free_full (ids, (GDestroyNotify) e_ews_folder_id_free);
-
-       if (local_error == NULL) {
-               result = E_SOURCE_AUTHENTICATION_ACCEPTED;
-       } else {
-               gboolean auth_failed;
-
-               auth_failed = g_error_matches (
-                       local_error, EWS_CONNECTION_ERROR,
-                       EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED);
-
-               if (auth_failed) {
-                       g_clear_error (&local_error);
-                       result = E_SOURCE_AUTHENTICATION_REJECTED;
-               } else {
-                       g_propagate_error (error, local_error);
-                       result = E_SOURCE_AUTHENTICATION_ERROR;
-               }
-
-               e_ews_connection_set_password (connection, NULL);
-       }
-
-       return result;
-}
-
 static void
 e_ews_connection_class_init (EEwsConnectionClass *class)
 {
@@ -1784,13 +1711,6 @@ e_ews_connection_folders_list_free (gpointer data)
        g_slist_free_full ((GSList *) data, g_free);
 }
 
-static void
-e_ews_connection_authenticator_init (ESourceAuthenticatorInterface *iface)
-{
-       iface->get_without_password = ews_connection_get_without_password;
-       iface->try_password_sync = ews_connection_try_password_sync;
-}
-
 static gpointer
 e_ews_soup_thread (gpointer user_data)
 {
@@ -2283,6 +2203,75 @@ e_ews_connection_new (const gchar *uri,
        return e_ews_connection_new_full (uri, settings, TRUE);
 }
 
+void
+e_ews_connection_update_credentials (EEwsConnection *cnc,
+                                    const ENamedParameters *credentials)
+{
+       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
+
+       if (credentials) {
+               e_ews_connection_set_password (cnc, e_named_parameters_get (credentials, 
E_SOURCE_CREDENTIAL_PASSWORD));
+
+               if (e_named_parameters_get (credentials, E_SOURCE_CREDENTIAL_USERNAME)) {
+                       CamelNetworkSettings *network_settings;
+
+                       network_settings = CAMEL_NETWORK_SETTINGS (cnc->priv->settings);
+                       camel_network_settings_set_user (network_settings, e_named_parameters_get 
(credentials, E_SOURCE_CREDENTIAL_USERNAME));
+               }
+       } else {
+               e_ews_connection_set_password (cnc, NULL);
+       }
+}
+
+ESourceAuthenticationResult
+e_ews_connection_try_credentials_sync (EEwsConnection *cnc,
+                                      const ENamedParameters *credentials,
+                                      GCancellable *cancellable,
+                                      GError **error)
+{
+       ESourceAuthenticationResult result;
+       EwsFolderId *fid = NULL;
+       GSList *ids = NULL;
+       GError *local_error = NULL;
+
+       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), E_SOURCE_AUTHENTICATION_ERROR);
+
+       e_ews_connection_update_credentials (cnc, credentials);
+
+       fid = g_new0 (EwsFolderId, 1);
+       fid->id = g_strdup ("inbox");
+       fid->is_distinguished_id = TRUE;
+       ids = g_slist_append (ids, fid);
+
+       e_ews_connection_get_folder_sync (
+               cnc, EWS_PRIORITY_MEDIUM, "Default",
+               NULL, ids, NULL, cancellable, &local_error);
+
+       g_slist_free_full (ids, (GDestroyNotify) e_ews_folder_id_free);
+
+       if (local_error == NULL) {
+               result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+       } else {
+               gboolean auth_failed;
+
+               auth_failed = g_error_matches (
+                       local_error, EWS_CONNECTION_ERROR,
+                       EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED);
+
+               if (auth_failed) {
+                       g_clear_error (&local_error);
+                       result = E_SOURCE_AUTHENTICATION_REJECTED;
+               } else {
+                       g_propagate_error (error, local_error);
+                       result = E_SOURCE_AUTHENTICATION_ERROR;
+               }
+
+               e_ews_connection_set_password (cnc, NULL);
+       }
+
+       return result;
+}
+
 const gchar *
 e_ews_connection_get_uri (EEwsConnection *cnc)
 {
diff --git a/src/server/e-ews-connection.h b/src/server/e-ews-connection.h
index 2670e97..31dc788 100644
--- a/src/server/e-ews-connection.h
+++ b/src/server/e-ews-connection.h
@@ -395,6 +395,15 @@ EEwsConnection *e_ews_connection_new               (const gchar *uri,
 EEwsConnection *e_ews_connection_new_full      (const gchar *uri,
                                                 CamelEwsSettings *settings,
                                                 gboolean allow_connection_reuse);
+void           e_ews_connection_update_credentials
+                                               (EEwsConnection *cnc,
+                                                const ENamedParameters *credentials);
+ESourceAuthenticationResult
+               e_ews_connection_try_credentials_sync
+                                               (EEwsConnection *cnc,
+                                                const ENamedParameters *credentials,
+                                                GCancellable *cancellable,
+                                                GError **error);
 const gchar *  e_ews_connection_get_uri        (EEwsConnection *cnc);
 const gchar *  e_ews_connection_get_password   (EEwsConnection *cnc);
 gchar *                e_ews_connection_dup_password   (EEwsConnection *cnc);


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