[libgdata] Bug 653535 — Let GDataAuthorizer re-process request after refreshing
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgdata] Bug 653535 — Let GDataAuthorizer re-process request after refreshing
- Date: Wed, 29 Jun 2011 08:08:05 +0000 (UTC)
commit 5494aef7d705b9a4ad2d0da7db6dd6c0a43f9560
Author: Philip Withnall <philip tecnocode co uk>
Date: Wed Jun 29 08:56:02 2011 +0100
Bug 653535 â Let GDataAuthorizer re-process request after refreshing
After receiving a 401 status (unauthorised) from the server and refreshing
the current GDataAuthorizer, re-process the message in question with the
authoriser before re-sending it, so that it has updated credentials set on
it.
This involves a slight change in the semantics of
GDataAuthorizer->process_request, which now has to handle being called
multiple times on a given message.
Closes: bgo#653535
gdata/gdata-authorizer.h | 3 ++-
gdata/gdata-client-login-authorizer.c | 2 +-
gdata/gdata-oauth1-authorizer.c | 2 +-
gdata/gdata-service.c | 17 ++++++++++++++++-
4 files changed, 20 insertions(+), 4 deletions(-)
---
diff --git a/gdata/gdata-authorizer.h b/gdata/gdata-authorizer.h
index 5898348..3df0da0 100644
--- a/gdata/gdata-authorizer.h
+++ b/gdata/gdata-authorizer.h
@@ -48,7 +48,8 @@ typedef struct _GDataAuthorizer GDataAuthorizer; /* dummy typedef */
* GDataAuthorizerInterface:
* @parent: the parent type
* @process_request: a function to append authorization headers to queries before they are submitted to the online service under the given
- * authorization domain (which may be %NULL); this must be implemented and must be thread safe
+ * authorization domain (which may be %NULL); this must be implemented and must be thread safe, and must also handle being called multiple times on
+ * the same #SoupMessage instance (so must be careful to replace headers rather than append them, for example)
* @is_authorized_for_domain: a function to check whether the authorizer is authorized against the given domain; this must be implemented and must
* be thread safe
* @refresh_authorization: (allow-none): a function to force a refresh of any authorization tokens the authorizer holds, returning %TRUE if a refresh
diff --git a/gdata/gdata-client-login-authorizer.c b/gdata/gdata-client-login-authorizer.c
index ab7f66c..ce50522 100644
--- a/gdata/gdata-client-login-authorizer.c
+++ b/gdata/gdata-client-login-authorizer.c
@@ -401,7 +401,7 @@ process_request (GDataAuthorizer *self, GDataAuthorizationDomain *domain, SoupMe
g_warning ("Not authorizing a non-HTTPS message with the user's ClientLogin auth token as the connection isn't secure.");
} else {
gchar *authorisation_header = g_strdup_printf ("GoogleLogin auth=%s", auth_token);
- soup_message_headers_append (message->request_headers, "Authorization", authorisation_header);
+ soup_message_headers_replace (message->request_headers, "Authorization", authorisation_header);
g_free (authorisation_header);
}
}
diff --git a/gdata/gdata-oauth1-authorizer.c b/gdata/gdata-oauth1-authorizer.c
index 0b635dc..bce48b7 100644
--- a/gdata/gdata-oauth1-authorizer.c
+++ b/gdata/gdata-oauth1-authorizer.c
@@ -558,7 +558,7 @@ sign_message (GDataOAuth1Authorizer *self, SoupMessage *message, const gchar *to
g_string_append_uri_escaped (authorization_header, nonce, NULL, FALSE);
g_string_append (authorization_header, "\",oauth_version=\"1.0\"");
- soup_message_headers_append (message->request_headers, "Authorization", authorization_header->str);
+ soup_message_headers_replace (message->request_headers, "Authorization", authorization_header->str);
g_string_free (authorization_header, TRUE);
free (signature);
diff --git a/gdata/gdata-service.c b/gdata/gdata-service.c
index 848914c..74c0e21 100644
--- a/gdata/gdata-service.c
+++ b/gdata/gdata-service.c
@@ -284,6 +284,10 @@ real_append_query_headers (GDataService *self, GDataAuthorizationDomain *domain,
/* Set the authorisation header */
if (self->priv->authorizer != NULL) {
gdata_authorizer_process_request (self->priv->authorizer, domain, message);
+
+ /* Store the authorisation domain on the message so that we can access it again after refreshing authorisation if necessary.
+ * See _gdata_service_send_message(). */
+ g_object_set_data_full (G_OBJECT (message), "gdata-authorization-domain", g_object_ref (domain), (GDestroyNotify) g_object_unref);
}
/* Set the GData-Version header to tell it we want to use the v2 API */
@@ -680,11 +684,22 @@ _gdata_service_send_message (GDataService *self, SoupMessage *message, GCancella
}
/* Not authorised, or authorisation has expired. If we were authorised in the first place, attempt to refresh the authorisation and
- * try sending the message again (but only once, so we don't get caught in an infinite loop of denied authorisation errors). */
+ * try sending the message again (but only once, so we don't get caught in an infinite loop of denied authorisation errors).
+ *
+ * Note that we have to re-process the message with the authoriser so that its authorisation headers get updated after the refresh
+ * (bgo#653535). */
if (message->status_code == SOUP_STATUS_UNAUTHORIZED) {
GDataAuthorizer *authorizer = self->priv->authorizer;
if (authorizer != NULL && gdata_authorizer_refresh_authorization (authorizer, cancellable, NULL) == TRUE) {
+ GDataAuthorizationDomain *domain;
+
+ /* Re-process the request */
+ domain = g_object_get_data (G_OBJECT (message), "gdata-authorization-domain");
+ g_assert (domain == NULL || GDATA_IS_AUTHORIZATION_DOMAIN (domain));
+
+ gdata_authorizer_process_request (authorizer, domain, message);
+
/* Send the message again */
g_clear_error (error);
_gdata_service_actually_send_message (self->priv->session, message, cancellable, error);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]