[evolution] Change how UI deals with XOAUTH2 for Camel providers



commit 42203a3d009c2f0651985033506b23f88dad50b3
Author: Milan Crha <mcrha redhat com>
Date:   Tue Jan 23 13:54:45 2018 +0100

    Change how UI deals with XOAUTH2 for Camel providers
    
    As it had been before this change, once any account had Google built-in
    OAuth2 authentication, it had been offered to every account of that provider,
    which is wrong. This change adds/removes particular built-in OAuth2
    authentication methods on demand, also when changing server host name,
    without influencing any other account.

 src/e-util/e-auth-combo-box.c        |   68 +++++++++++++++++++++++++++--
 src/e-util/e-auth-combo-box.h        |    5 ++
 src/libemail-engine/e-mail-session.c |   16 -------
 src/mail/e-mail-config-auth-check.c  |   79 ++++++++++++++++++++++++++++++++++
 4 files changed, 148 insertions(+), 20 deletions(-)
---
diff --git a/src/e-util/e-auth-combo-box.c b/src/e-util/e-auth-combo-box.c
index ff2ec86..b495ca2 100644
--- a/src/e-util/e-auth-combo-box.c
+++ b/src/e-util/e-auth-combo-box.c
@@ -222,7 +222,8 @@ e_auth_combo_box_get_preference_level (const gchar *authproto)
                "CRAM-MD5",
                "DIGEST-MD5",
                "NTLM",
-               "GSSAPI"
+               "GSSAPI",
+               "XOAUTH2"
        };
        gint ii;
 
@@ -230,7 +231,9 @@ e_auth_combo_box_get_preference_level (const gchar *authproto)
                return -1;
 
        for (ii = 0; ii < G_N_ELEMENTS (protos); ii++) {
-               if (g_ascii_strcasecmp (protos[ii], authproto) == 0)
+               if (g_ascii_strcasecmp (protos[ii], authproto) == 0 ||
+                   (g_ascii_strcasecmp (protos[ii], "XOAUTH2") == 0 &&
+                    camel_sasl_is_xoauth2_alias (authproto)))
                        return ii;
        }
 
@@ -244,6 +247,7 @@ e_auth_combo_box_update_available (EAuthComboBox *combo_box,
        GtkComboBox *gtk_combo_box;
        GtkTreeModel *model;
        GtkTreeIter iter;
+       GList *xoauth2_available;
        gint active_index;
        gint available_index = -1;
        gint chosen_preference_level = -1;
@@ -252,6 +256,15 @@ e_auth_combo_box_update_available (EAuthComboBox *combo_box,
 
        g_return_if_fail (E_IS_AUTH_COMBO_BOX (combo_box));
 
+       for (xoauth2_available = available_authtypes; xoauth2_available; xoauth2_available = g_list_next 
(xoauth2_available)) {
+               CamelServiceAuthType *auth_type = xoauth2_available->data;
+
+               if (auth_type && (g_strcmp0 (auth_type->authproto, "XOAUTH2") == 0 ||
+                   camel_sasl_is_xoauth2_alias (auth_type->authproto))) {
+                       break;
+               }
+       }
+
        gtk_combo_box = GTK_COMBO_BOX (combo_box);
        model = gtk_combo_box_get_model (gtk_combo_box);
        active_index = gtk_combo_box_get_active (gtk_combo_box);
@@ -266,8 +279,8 @@ e_auth_combo_box_update_available (EAuthComboBox *combo_box,
                gtk_tree_model_get (
                        model, &iter, COLUMN_AUTHTYPE, &authtype, -1);
 
-               available = (g_list_find (
-                       available_authtypes, authtype) != NULL);
+               available = g_list_find (available_authtypes, authtype) ||
+                       (xoauth2_available && camel_sasl_is_xoauth2_alias (authtype->authproto));
 
                gtk_list_store_set (
                        GTK_LIST_STORE (model), &iter,
@@ -334,3 +347,50 @@ e_auth_combo_box_pick_highest_available (EAuthComboBox *combo_box)
        if (highest_available_index != -1)
                gtk_combo_box_set_active (gtk_combo_box, highest_available_index);
 }
+
+void
+e_auth_combo_box_add_auth_type (EAuthComboBox *combo_box,
+                               CamelServiceAuthType *auth_type)
+{
+       GtkTreeModel *model;
+       GtkTreeIter iter;
+
+       g_return_if_fail (E_IS_AUTH_COMBO_BOX (combo_box));
+       g_return_if_fail (auth_type != NULL);
+
+       model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
+       gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+
+       gtk_list_store_set (
+               GTK_LIST_STORE (model), &iter,
+               COLUMN_MECHANISM, auth_type->authproto,
+               COLUMN_DISPLAY_NAME, auth_type->name,
+               COLUMN_AUTHTYPE, auth_type,
+               -1);
+}
+
+void
+e_auth_combo_box_remove_auth_type (EAuthComboBox *combo_box,
+                                  CamelServiceAuthType *auth_type)
+{
+       GtkTreeModel *model;
+       GtkTreeIter iter;
+
+       g_return_if_fail (E_IS_AUTH_COMBO_BOX (combo_box));
+       g_return_if_fail (auth_type != NULL);
+
+       model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
+
+       if (!gtk_tree_model_get_iter_first (model, &iter))
+               return;
+
+       do {
+               CamelServiceAuthType *stored_type = NULL;
+
+               gtk_tree_model_get (model, &iter, COLUMN_AUTHTYPE, &stored_type, -1);
+               if (stored_type == auth_type) {
+                       gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+                       break;
+               }
+       } while (gtk_tree_model_iter_next (model, &iter));
+}
diff --git a/src/e-util/e-auth-combo-box.h b/src/e-util/e-auth-combo-box.h
index 3482838..612fd9c 100644
--- a/src/e-util/e-auth-combo-box.h
+++ b/src/e-util/e-auth-combo-box.h
@@ -64,6 +64,11 @@ GtkWidget *  e_auth_combo_box_new            (void);
 CamelProvider *        e_auth_combo_box_get_provider   (EAuthComboBox *combo_box);
 void           e_auth_combo_box_set_provider   (EAuthComboBox *combo_box,
                                                 CamelProvider *provider);
+void           e_auth_combo_box_add_auth_type  (EAuthComboBox *combo_box,
+                                                CamelServiceAuthType *auth_type);
+void           e_auth_combo_box_remove_auth_type
+                                               (EAuthComboBox *combo_box,
+                                                CamelServiceAuthType *auth_type);
 void           e_auth_combo_box_update_available
                                                (EAuthComboBox *combo_box,
                                                 GList *available_authtypes);
diff --git a/src/libemail-engine/e-mail-session.c b/src/libemail-engine/e-mail-session.c
index be0bd92..9809e1e 100644
--- a/src/libemail-engine/e-mail-session.c
+++ b/src/libemail-engine/e-mail-session.c
@@ -1194,7 +1194,6 @@ mail_session_add_service (CamelSession *session,
        if (CAMEL_IS_SERVICE (service)) {
                ESource *source;
                ESource *tmp_source;
-               EOAuth2Service *oauth2_service;
 
                /* Each CamelService has a corresponding ESource. */
                source = e_source_registry_ref_source (registry, uid);
@@ -1222,21 +1221,6 @@ mail_session_add_service (CamelSession *session,
                 * URL-based directory to a UID-based directory
                 * if necessary. */
                camel_service_migrate_files (service);
-
-               /* Kind of hack, to add also correct OAuth2 SASL implementation */
-               oauth2_service = e_oauth2_services_find (e_source_registry_get_oauth2_services (registry), 
source);
-               if (oauth2_service) {
-                       CamelServiceAuthType *auth_type;
-
-                       auth_type = camel_sasl_authtype (e_oauth2_service_get_name (oauth2_service));
-                       if (auth_type) {
-                               CamelProvider *provider;
-
-                               provider = camel_service_get_provider (service);
-                               if (provider && !g_list_find (provider->authtypes, auth_type))
-                                       provider->authtypes = g_list_append (provider->authtypes, auth_type);
-                       }
-               }
        }
 
        return service;
diff --git a/src/mail/e-mail-config-auth-check.c b/src/mail/e-mail-config-auth-check.c
index 3284fb8..6046793 100644
--- a/src/mail/e-mail-config-auth-check.c
+++ b/src/mail/e-mail-config-auth-check.c
@@ -37,6 +37,8 @@ struct _EMailConfigAuthCheckPrivate {
        gchar *active_mechanism;
 
        GtkWidget *combo_box;  /* not referenced */
+       gulong host_changed_id;
+       CamelServiceAuthType *used_xoauth2;
 };
 
 struct _AsyncContext {
@@ -234,6 +236,47 @@ mail_config_auth_check_init_mechanism (EMailConfigAuthCheck *auth_check)
 }
 
 static void
+mail_config_auth_check_host_changed_cb (CamelNetworkSettings *network_settings,
+                                       GParamSpec *param,
+                                       EMailConfigAuthCheck *auth_check)
+{
+       EMailConfigServiceBackend *backend;
+       ESourceRegistry *registry;
+       EOAuth2Service *oauth2_service;
+       CamelProvider *provider;
+       CamelServiceAuthType *change_authtype = NULL;
+
+       g_return_if_fail (CAMEL_IS_NETWORK_SETTINGS (network_settings));
+       g_return_if_fail (E_IS_MAIL_CONFIG_AUTH_CHECK (auth_check));
+
+       backend = e_mail_config_auth_check_get_backend (auth_check);
+       provider = e_mail_config_service_backend_get_provider (backend);
+
+       registry = e_mail_config_service_page_get_registry (e_mail_config_service_backend_get_page (backend));
+       oauth2_service = e_oauth2_services_find (e_source_registry_get_oauth2_services (registry),
+               e_mail_config_service_backend_get_source (backend));
+       if (!oauth2_service) {
+               oauth2_service = e_oauth2_services_guess (e_source_registry_get_oauth2_services (registry),
+                       provider ? provider->protocol : NULL, camel_network_settings_get_host 
(network_settings));
+       }
+
+       if (oauth2_service)
+               change_authtype = camel_sasl_authtype (e_oauth2_service_get_name (oauth2_service));
+
+       g_clear_object (&oauth2_service);
+
+       if (change_authtype != auth_check->priv->used_xoauth2) {
+               if (auth_check->priv->used_xoauth2)
+                       e_auth_combo_box_remove_auth_type (E_AUTH_COMBO_BOX (auth_check->priv->combo_box), 
auth_check->priv->used_xoauth2);
+
+               auth_check->priv->used_xoauth2 = change_authtype;
+
+               if (auth_check->priv->used_xoauth2)
+                       e_auth_combo_box_add_auth_type (E_AUTH_COMBO_BOX (auth_check->priv->combo_box), 
auth_check->priv->used_xoauth2);
+       }
+}
+
+static void
 mail_config_auth_check_set_backend (EMailConfigAuthCheck *auth_check,
                                     EMailConfigServiceBackend *backend)
 {
@@ -299,6 +342,14 @@ mail_config_auth_check_dispose (GObject *object)
        priv = E_MAIL_CONFIG_AUTH_CHECK_GET_PRIVATE (object);
 
        if (priv->backend != NULL) {
+               if (priv->host_changed_id) {
+                       CamelSettings *settings;
+
+                       settings = e_mail_config_service_backend_get_settings (priv->backend);
+                       if (settings)
+                               e_signal_disconnect_notify_handler (settings, &priv->host_changed_id);
+               }
+
                g_object_unref (priv->backend);
                priv->backend = NULL;
        }
@@ -328,6 +379,7 @@ mail_config_auth_check_constructed (GObject *object)
        EMailConfigAuthCheck *auth_check;
        EMailConfigServiceBackend *backend;
        CamelProvider *provider;
+       CamelSettings *settings;
        GtkWidget *widget;
        const gchar *text;
 
@@ -354,6 +406,31 @@ mail_config_auth_check_constructed (GObject *object)
        auth_check->priv->combo_box = widget;  /* do not reference */
        gtk_widget_show (widget);
 
+       settings = e_mail_config_service_backend_get_settings (backend);
+       if (CAMEL_IS_NETWORK_SETTINGS (settings)) {
+               ESourceRegistry *registry;
+               EOAuth2Service *oauth2_service;
+
+               auth_check->priv->host_changed_id = e_signal_connect_notify (
+                       settings, "notify::host", G_CALLBACK (mail_config_auth_check_host_changed_cb), 
auth_check);
+
+               registry = e_mail_config_service_page_get_registry (e_mail_config_service_backend_get_page 
(backend));
+               oauth2_service = e_oauth2_services_find (e_source_registry_get_oauth2_services (registry),
+                       e_mail_config_service_backend_get_source (backend));
+               if (!oauth2_service) {
+                       oauth2_service = e_oauth2_services_guess (e_source_registry_get_oauth2_services 
(registry),
+                               provider ? provider->protocol : NULL, camel_network_settings_get_host 
(CAMEL_NETWORK_SETTINGS (settings)));
+               }
+
+               if (oauth2_service)
+                       auth_check->priv->used_xoauth2 = camel_sasl_authtype (e_oauth2_service_get_name 
(oauth2_service));
+
+               g_clear_object (&oauth2_service);
+
+               if (auth_check->priv->used_xoauth2)
+                       e_auth_combo_box_add_auth_type (E_AUTH_COMBO_BOX (auth_check->priv->combo_box), 
auth_check->priv->used_xoauth2);
+       }
+
        e_binding_bind_property (
                widget, "active-id",
                auth_check, "active-mechanism",
@@ -405,6 +482,8 @@ static void
 e_mail_config_auth_check_init (EMailConfigAuthCheck *auth_check)
 {
        auth_check->priv = E_MAIL_CONFIG_AUTH_CHECK_GET_PRIVATE (auth_check);
+       auth_check->priv->host_changed_id = 0;
+       auth_check->priv->used_xoauth2 = NULL;
 
        gtk_orientable_set_orientation (
                GTK_ORIENTABLE (auth_check),


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