[evolution-data-server] Claim missing user name when authenticating



commit a3b98ac6ee7030f1ad737d313ae18550fdf31bb3
Author: Milan Crha <mcrha redhat com>
Date:   Wed Apr 9 12:00:30 2014 +0200

    Claim missing user name when authenticating
    
    When user's CalDAV/HTTP calendar or WebDAV address book had missing
    set login user name, the UI did not show anything useful, the worse
    it reasked for a password which were not used at all, because libsoup's
    session on the factory side failed in authentication due to runtime
    check about non-NULL user name. This makes it return "Authentication
    required" error to the UI, instead of asking for the password.

 .../backends/webdav/e-book-backend-webdav.c        |   99 +++++++++++++------
 calendar/backends/caldav/e-cal-backend-caldav.c    |   15 ++-
 calendar/backends/http/e-cal-backend-http.c        |   22 ++++-
 3 files changed, 94 insertions(+), 42 deletions(-)
---
diff --git a/addressbook/backends/webdav/e-book-backend-webdav.c 
b/addressbook/backends/webdav/e-book-backend-webdav.c
index 2cdae05..00b9b0c 100644
--- a/addressbook/backends/webdav/e-book-backend-webdav.c
+++ b/addressbook/backends/webdav/e-book-backend-webdav.c
@@ -856,7 +856,9 @@ download_contacts (EBookBackendWebdav *webdav,
        message = send_propfind (webdav, cancellable);
        status = message->status_code;
 
-       if (status == 401 || status == 407) {
+       if (status == SOUP_STATUS_UNAUTHORIZED ||
+           status == SOUP_STATUS_PROXY_UNAUTHORIZED ||
+           status == SOUP_STATUS_FORBIDDEN) {
                g_object_unref (message);
                g_free (new_ctag);
                if (book_view)
@@ -1140,9 +1142,10 @@ soup_authenticate (SoupSession *session,
        if (retrying)
                return;
 
-       if (priv->username != NULL) {
+       if (!priv->username || !*priv->username)
+               soup_message_set_status (message, SOUP_STATUS_FORBIDDEN);
+       else
                soup_auth_authenticate (auth, priv->username, priv->password);
-       }
 }
 
 static void
@@ -1226,6 +1229,57 @@ book_backend_webdav_get_backend_property (EBookBackend *backend,
 }
 
 static gboolean
+book_backend_webdav_test_can_connect (EBookBackendWebdav *webdav,
+                                     GCancellable *cancellable,
+                                     GError **error)
+{
+       SoupMessage *message;
+       gboolean res = FALSE;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND_WEBDAV (webdav), FALSE);
+
+       /* Send a PROPFIND to test whether user/password is correct. */
+       message = send_propfind (webdav, cancellable);
+
+       switch (message->status_code) {
+               case SOUP_STATUS_OK:
+               case SOUP_STATUS_MULTI_STATUS:
+                       res = TRUE;
+                       break;
+
+               case SOUP_STATUS_UNAUTHORIZED:
+               case SOUP_STATUS_PROXY_UNAUTHORIZED:
+                       g_free (webdav->priv->username);
+                       webdav->priv->username = NULL;
+                       g_free (webdav->priv->password);
+                       webdav->priv->password = NULL;
+                       g_set_error_literal (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_FAILED,
+                               e_client_error_to_string (E_CLIENT_ERROR_AUTHENTICATION_FAILED));
+                       break;
+
+               case SOUP_STATUS_FORBIDDEN:
+                       g_free (webdav->priv->username);
+                       webdav->priv->username = NULL;
+                       g_free (webdav->priv->password);
+                       webdav->priv->password = NULL;
+                       g_set_error_literal (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_REQUIRED,
+                               e_client_error_to_string (E_CLIENT_ERROR_AUTHENTICATION_REQUIRED));
+                       break;
+
+               default:
+                       g_set_error (
+                               error, SOUP_HTTP_ERROR,
+                               message->status_code,
+                               "%s", message->reason_phrase);
+                       break;
+       }
+
+       g_object_unref (message);
+
+       return res;
+}
+
+static gboolean
 book_backend_webdav_open_sync (EBookBackend *backend,
                                GCancellable *cancellable,
                                GError **error)
@@ -1330,6 +1384,8 @@ book_backend_webdav_open_sync (EBookBackend *backend,
                        E_BACKEND (backend),
                        E_SOURCE_AUTHENTICATOR (backend),
                        cancellable, error);
+       else
+               success = book_backend_webdav_test_can_connect (webdav, cancellable, error);
 
        soup_uri_free (suri);
 
@@ -1726,8 +1782,8 @@ book_backend_webdav_try_password_sync (ESourceAuthenticator *authenticator,
        ESourceAuthentication *auth_extension;
        ESourceAuthenticationResult result;
        ESource *source;
-       SoupMessage *message;
        const gchar *extension_name;
+       GError *local_error = NULL;
 
        source = e_backend_get_source (E_BACKEND (authenticator));
        extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
@@ -1737,35 +1793,16 @@ book_backend_webdav_try_password_sync (ESourceAuthenticator *authenticator,
                e_source_authentication_dup_user (auth_extension);
        webdav->priv->password = g_strdup (password->str);
 
-       /* Send a PROPFIND to test whether user/password is correct. */
-       message = send_propfind (webdav, cancellable);
-
-       switch (message->status_code) {
-               case SOUP_STATUS_OK:
-               case SOUP_STATUS_MULTI_STATUS:
-                       result = E_SOURCE_AUTHENTICATION_ACCEPTED;
-                       break;
-
-               case SOUP_STATUS_UNAUTHORIZED:
-               case SOUP_STATUS_PROXY_UNAUTHORIZED:  /* XXX really? */
-                       g_free (webdav->priv->username);
-                       webdav->priv->username = NULL;
-                       g_free (webdav->priv->password);
-                       webdav->priv->password = NULL;
-                       result = E_SOURCE_AUTHENTICATION_REJECTED;
-                       break;
-
-               default:
-                       g_set_error (
-                               error, SOUP_HTTP_ERROR,
-                               message->status_code,
-                               "%s", message->reason_phrase);
-                       result = E_SOURCE_AUTHENTICATION_ERROR;
-                       break;
+       if (book_backend_webdav_test_can_connect (webdav, cancellable, &local_error)) {
+               result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+       } else if (g_error_matches (local_error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_FAILED)) {
+               result = E_SOURCE_AUTHENTICATION_REJECTED;
+               g_clear_error (&local_error);
+       } else {
+               result = E_SOURCE_AUTHENTICATION_ERROR;
+               g_propagate_error (error, local_error);
        }
 
-       g_object_unref (message);
-
        return result;
 }
 
diff --git a/calendar/backends/caldav/e-cal-backend-caldav.c b/calendar/backends/caldav/e-cal-backend-caldav.c
index f0f84b8..cf94361 100644
--- a/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -580,18 +580,18 @@ status_code_to_result (SoupMessage *message,
                                E_CAL_BACKEND (cbdav), FALSE);
                }
                break;
-       case 404:
+       case SOUP_STATUS_NOT_FOUND:
                if (is_opening)
                        g_propagate_error (perror, EDC_ERROR (NoSuchCal));
                else
                        g_propagate_error (perror, EDC_ERROR (ObjectNotFound));
                break;
 
-       case 403:
-               g_propagate_error (perror, EDC_ERROR (AuthenticationFailed));
+       case SOUP_STATUS_FORBIDDEN:
+               g_propagate_error (perror, EDC_ERROR (AuthenticationRequired));
                break;
 
-       case 401:
+       case SOUP_STATUS_UNAUTHORIZED:
                if (priv && priv->auth_required)
                        g_propagate_error (perror, EDC_ERROR (AuthenticationFailed));
                else
@@ -1045,7 +1045,10 @@ soup_authenticate (SoupSession *session,
                gchar *user;
 
                user = e_source_authentication_dup_user (auth_extension);
-               soup_auth_authenticate (auth, user, cbdav->priv->password);
+               if (!user || !*user)
+                       soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
+               else
+                       soup_auth_authenticate (auth, user, cbdav->priv->password);
                g_free (user);
        }
 }
@@ -2992,7 +2995,7 @@ caldav_do_open (ECalBackendSync *backend,
 
                open_calendar (cbdav, cancellable, &local_error);
 
-               if (g_error_matches (local_error, E_DATA_CAL_ERROR, AuthenticationRequired) || 
g_error_matches (local_error, E_DATA_CAL_ERROR, AuthenticationFailed)) {
+               if (g_error_matches (local_error, E_DATA_CAL_ERROR, AuthenticationFailed)) {
                        g_clear_error (&local_error);
                        caldav_authenticate (
                                cbdav, FALSE, cancellable, perror);
diff --git a/calendar/backends/http/e-cal-backend-http.c b/calendar/backends/http/e-cal-backend-http.c
index 13e4abd..6ecda5d 100644
--- a/calendar/backends/http/e-cal-backend-http.c
+++ b/calendar/backends/http/e-cal-backend-http.c
@@ -91,6 +91,10 @@ soup_authenticate (SoupSession *session,
        ESourceAuthentication *auth_extension;
        ESource *source;
        const gchar *extension_name;
+       gchar *user;
+
+       if (retrying)
+               return;
 
        cbhttp = E_CAL_BACKEND_HTTP (data);
 
@@ -98,13 +102,14 @@ soup_authenticate (SoupSession *session,
        extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
        auth_extension = e_source_get_extension (source, extension_name);
 
-       if (!retrying && cbhttp->priv->password != NULL) {
-               gchar *user;
+       user = e_source_authentication_dup_user (auth_extension);
 
-               user = e_source_authentication_dup_user (auth_extension);
+       if (!user || !*user)
+               soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
+       else if (cbhttp->priv->password != NULL)
                soup_auth_authenticate (auth, user, cbhttp->priv->password);
-               g_free (user);
-       }
+
+       g_free (user);
 }
 
 /* Dispose handler for the file backend */
@@ -782,6 +787,9 @@ begin_retrieval_cb (GIOSchedulerJob *job,
                        E_BACKEND (backend),
                        E_SOURCE_AUTHENTICATOR (backend),
                        cancellable, &error);
+       } else if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_FORBIDDEN)) {
+               g_clear_error (&error);
+               error = EDC_ERROR (AuthenticationRequired);
        }
 
        backend->priv->is_loading = FALSE;
@@ -936,8 +944,12 @@ e_cal_backend_http_open (ECalBackendSync *backend,
                                registry, source,
                                E_SOURCE_AUTHENTICATOR (backend),
                                cancellable, &local_error);
+               } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_FORBIDDEN)) {
+                       g_clear_error (&local_error);
+                       local_error = EDC_ERROR (AuthenticationRequired);
                }
 
+
                if (local_error != NULL)
                        g_propagate_error (perror, g_error_copy (local_error));
        }


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