[evolution-data-server/gnome-3-36] I#199 - ESoupAuthBearer: Is not thread safe



commit bb551af692be01da2d79a6f32927ae1f77ddb793
Author: Milan Crha <mcrha redhat com>
Date:   Fri Mar 6 09:02:28 2020 +0100

    I#199 - ESoupAuthBearer: Is not thread safe
    
    Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/199

 src/libedataserver/e-soup-auth-bearer.c | 50 +++++++++++++++++++++++++++++----
 1 file changed, 45 insertions(+), 5 deletions(-)
---
diff --git a/src/libedataserver/e-soup-auth-bearer.c b/src/libedataserver/e-soup-auth-bearer.c
index ea4c1eca9..ba3e210fa 100644
--- a/src/libedataserver/e-soup-auth-bearer.c
+++ b/src/libedataserver/e-soup-auth-bearer.c
@@ -41,6 +41,7 @@
 #define EXPIRY_INVALID ((time_t) -1)
 
 struct _ESoupAuthBearerPrivate {
+       GMutex property_lock;
        gchar *access_token;
        time_t expiry;
 };
@@ -50,6 +51,17 @@ G_DEFINE_TYPE_WITH_PRIVATE (
        e_soup_auth_bearer,
        SOUP_TYPE_AUTH)
 
+static gboolean
+e_soup_auth_bearer_is_expired_locked (ESoupAuthBearer *bearer)
+{
+       gboolean expired = TRUE;
+
+       if (bearer->priv->expiry != EXPIRY_INVALID)
+               expired = (bearer->priv->expiry <= time (NULL));
+
+       return expired;
+}
+
 static void
 e_soup_auth_bearer_finalize (GObject *object)
 {
@@ -57,6 +69,7 @@ e_soup_auth_bearer_finalize (GObject *object)
 
        priv = E_SOUP_AUTH_BEARER (object)->priv;
 
+       g_mutex_clear (&priv->property_lock);
        g_free (priv->access_token);
 
        /* Chain up to parent's finalize() method. */
@@ -75,9 +88,13 @@ e_soup_auth_bearer_update (SoupAuth *auth,
 
                bearer = E_SOUP_AUTH_BEARER (auth);
 
+               g_mutex_lock (&bearer->priv->property_lock);
+
                /* Expire the token, it's likely to be invalid. */
                bearer->priv->expiry = EXPIRY_INVALID;
 
+               g_mutex_unlock (&bearer->priv->property_lock);
+
                return FALSE;
        }
 
@@ -101,9 +118,13 @@ e_soup_auth_bearer_is_authenticated (SoupAuth *auth)
 
        bearer = E_SOUP_AUTH_BEARER (auth);
 
-       if (!e_soup_auth_bearer_is_expired (bearer))
+       g_mutex_lock (&bearer->priv->property_lock);
+
+       if (!e_soup_auth_bearer_is_expired_locked (bearer))
                authenticated = (bearer->priv->access_token != NULL);
 
+       g_mutex_unlock (&bearer->priv->property_lock);
+
        return authenticated;
 }
 
@@ -112,10 +133,17 @@ e_soup_auth_bearer_get_authorization (SoupAuth *auth,
                                       SoupMessage *message)
 {
        ESoupAuthBearer *bearer;
+       gchar *res;
 
        bearer = E_SOUP_AUTH_BEARER (auth);
 
-       return g_strdup_printf ("Bearer %s", bearer->priv->access_token);
+       g_mutex_lock (&bearer->priv->property_lock);
+
+       res = g_strdup_printf ("Bearer %s", bearer->priv->access_token);
+
+       g_mutex_unlock (&bearer->priv->property_lock);
+
+       return res;
 }
 
 static void
@@ -144,6 +172,8 @@ e_soup_auth_bearer_init (ESoupAuthBearer *bearer)
 {
        bearer->priv = e_soup_auth_bearer_get_instance_private (bearer);
        bearer->priv->expiry = EXPIRY_INVALID;
+
+       g_mutex_init (&bearer->priv->property_lock);
 }
 
 /**
@@ -173,6 +203,13 @@ e_soup_auth_bearer_set_access_token (ESoupAuthBearer *bearer,
 
        was_authenticated = soup_auth_is_authenticated (SOUP_AUTH (bearer));
 
+       g_mutex_lock (&bearer->priv->property_lock);
+
+       if (g_strcmp0 (bearer->priv->access_token, access_token) == 0) {
+               g_mutex_unlock (&bearer->priv->property_lock);
+               return;
+       }
+
        g_free (bearer->priv->access_token);
        bearer->priv->access_token = g_strdup (access_token);
 
@@ -181,6 +218,8 @@ e_soup_auth_bearer_set_access_token (ESoupAuthBearer *bearer,
        else
                bearer->priv->expiry = EXPIRY_INVALID;
 
+       g_mutex_unlock (&bearer->priv->property_lock);
+
        now_authenticated = soup_auth_is_authenticated (SOUP_AUTH (bearer));
 
        if (was_authenticated != now_authenticated)
@@ -201,12 +240,13 @@ e_soup_auth_bearer_set_access_token (ESoupAuthBearer *bearer,
 gboolean
 e_soup_auth_bearer_is_expired (ESoupAuthBearer *bearer)
 {
-       gboolean expired = TRUE;
+       gboolean expired;
 
        g_return_val_if_fail (E_IS_SOUP_AUTH_BEARER (bearer), TRUE);
 
-       if (bearer->priv->expiry != EXPIRY_INVALID)
-               expired = (bearer->priv->expiry <= time (NULL));
+       g_mutex_lock (&bearer->priv->property_lock);
+       expired = e_soup_auth_bearer_is_expired_locked (bearer);
+       g_mutex_unlock (&bearer->priv->property_lock);
 
        return expired;
 }


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