[evolution-data-server] Bug 761450 - [CalDAV] Refresh expired OAuth2 token beforehand



commit 3fa36f8f0be0107c63aaa254e551e3858c781988
Author: Milan Crha <mcrha redhat com>
Date:   Mon Sep 5 22:24:44 2016 +0200

    Bug 761450 - [CalDAV] Refresh expired OAuth2 token beforehand

 calendar/backends/caldav/e-cal-backend-caldav.c |   26 +++++++++++++++++--
 libedataserver/e-soup-auth-bearer.c             |   30 ++++++++++++++--------
 libedataserver/e-soup-auth-bearer.h             |    1 +
 3 files changed, 43 insertions(+), 14 deletions(-)
---
diff --git a/calendar/backends/caldav/e-cal-backend-caldav.c b/calendar/backends/caldav/e-cal-backend-caldav.c
index 164d918..53f7d0e 100644
--- a/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -131,7 +131,7 @@ struct _ECalBackendCalDAVPrivate {
         * message than a generic SOUP_STATUS_UNAUTHORIZED description. */
        GError *bearer_auth_error;
        GMutex bearer_auth_error_lock;
-       gboolean using_bearer_auth;
+       ESoupAuthBearer *using_bearer_auth;
 };
 
 /* Forward Declarations */
@@ -404,7 +404,7 @@ caldav_maybe_prepare_bearer_auth (ECalBackendCalDAV *cbdav,
 
        success = caldav_setup_bearer_auth (cbdav, E_SOUP_AUTH_BEARER (soup_auth), cancellable, error);
        if (success) {
-               cbdav->priv->using_bearer_auth = TRUE;
+               cbdav->priv->using_bearer_auth = g_object_ref (soup_auth);
 
                soup_auth_manager_use_auth (
                        SOUP_AUTH_MANAGER (feature),
@@ -1147,7 +1147,11 @@ soup_authenticate (SoupSession *session,
        extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
        auth_extension = e_source_get_extension (source, extension_name);
 
-       cbdav->priv->using_bearer_auth = E_IS_SOUP_AUTH_BEARER (auth);
+       if (E_IS_SOUP_AUTH_BEARER (auth)) {
+               g_warn_if_fail ((gpointer) cbdav->priv->using_bearer_auth == (gpointer) auth);
+               g_clear_object (&cbdav->priv->using_bearer_auth);
+               cbdav->priv->using_bearer_auth = g_object_ref (auth);
+       }
 
        if (retrying)
                return;
@@ -1231,6 +1235,21 @@ send_and_handle_redirection (ECalBackendCalDAV *cbdav,
 
        e_soup_ssl_trust_connect (msg, e_backend_get_source (E_BACKEND (cbdav)));
 
+       if (cbdav->priv->using_bearer_auth &&
+           e_soup_auth_bearer_is_expired (cbdav->priv->using_bearer_auth)) {
+               GError *local_error = NULL;
+
+               if (!caldav_setup_bearer_auth (cbdav, cbdav->priv->using_bearer_auth, cancellable, 
&local_error)) {
+                       if (local_error) {
+                               soup_message_set_status_full (msg, SOUP_STATUS_BAD_REQUEST, 
local_error->message);
+                               g_propagate_error (error, local_error);
+                       } else {
+                               soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
+                       }
+                       return;
+               }
+       }
+
        soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
        soup_message_add_header_handler (msg, "got_body", "Location", G_CALLBACK (redirect_handler), 
cbdav->priv->session);
        soup_message_headers_append (msg->request_headers, "Connection", "close");
@@ -5545,6 +5564,7 @@ e_cal_backend_caldav_dispose (GObject *object)
 
        g_clear_object (&priv->store);
        g_clear_object (&priv->session);
+       g_clear_object (&priv->using_bearer_auth);
 
        /* Chain up to parent's dispose() method. */
        G_OBJECT_CLASS (parent_class)->dispose (object);
diff --git a/libedataserver/e-soup-auth-bearer.c b/libedataserver/e-soup-auth-bearer.c
index 4cdd029..f44be33 100644
--- a/libedataserver/e-soup-auth-bearer.c
+++ b/libedataserver/e-soup-auth-bearer.c
@@ -56,17 +56,6 @@ G_DEFINE_TYPE (
        e_soup_auth_bearer,
        SOUP_TYPE_AUTH)
 
-static gboolean
-e_soup_auth_bearer_is_expired (ESoupAuthBearer *bearer)
-{
-       gboolean expired = FALSE;
-
-       if (bearer->priv->expiry != EXPIRY_INVALID)
-               expired = (bearer->priv->expiry < time (NULL));
-
-       return expired;
-}
-
 static void
 e_soup_auth_bearer_finalize (GObject *object)
 {
@@ -197,3 +186,22 @@ e_soup_auth_bearer_set_access_token (ESoupAuthBearer *bearer,
                        SOUP_AUTH_IS_AUTHENTICATED);
 }
 
+/**
+ * e_soup_auth_bearer_is_expired:
+ * @bearer: an #ESoupAuthBearer
+ *
+ * Returns: Whether the set token is expired. It is considered expired even
+ *   if the e_soup_auth_bearer_set_access_token() was called set yet.
+ *
+ * Since: 3.24
+ **/
+gboolean
+e_soup_auth_bearer_is_expired (ESoupAuthBearer *bearer)
+{
+       gboolean expired = TRUE;
+
+       if (bearer->priv->expiry != EXPIRY_INVALID)
+               expired = (bearer->priv->expiry < time (NULL));
+
+       return expired;
+}
diff --git a/libedataserver/e-soup-auth-bearer.h b/libedataserver/e-soup-auth-bearer.h
index 8f08aeb..8aaffbf 100644
--- a/libedataserver/e-soup-auth-bearer.h
+++ b/libedataserver/e-soup-auth-bearer.h
@@ -71,6 +71,7 @@ void          e_soup_auth_bearer_set_access_token
                                                (ESoupAuthBearer *bearer,
                                                 const gchar *access_token,
                                                 gint expires_in_seconds);
+gboolean       e_soup_auth_bearer_is_expired   (ESoupAuthBearer *bearer);
 
 G_END_DECLS
 


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