[libgdata] core: Add support for OAuth 2.0 to the GOA authoriser
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgdata] core: Add support for OAuth 2.0 to the GOA authoriser
- Date: Sun, 21 Oct 2012 11:00:22 +0000 (UTC)
commit 811ccbefe1b711a29763700a2bbb5b54b06384d5
Author: Philip Withnall <philip tecnocode co uk>
Date: Sun Oct 21 11:54:56 2012 +0100
core: Add support for OAuth 2.0 to the GOA authoriser
This is based very heavily on work by Matthew Barnes <mbarnes redhat com> for
EDSâ EGDataGoaAuthorizer:
â http://git.gnome.org/browse/evolution-data-server/commit/addressbook/backends/google/e-gdata-goa-authorizer.c?id=f23f88b2b5e4662730bada1797378fbddfe7ddfa
â http://git.gnome.org/browse/evolution-data-server/commit/addressbook/backends/google/e-gdata-goa-authorizer.c?id=870bcc9eced87f74807cfeacb16f995a797eb277
As he mentions, this hasnât been tested against GOA 3.7 yet, so may well not
work.
Closes: https://bugzilla.gnome.org/show_bug.cgi?id=685289
gdata/gdata-goa-authorizer.c | 82 +++++++++++++++++++++++++++++++++++------
1 files changed, 70 insertions(+), 12 deletions(-)
---
diff --git a/gdata/gdata-goa-authorizer.c b/gdata/gdata-goa-authorizer.c
index 6f0c525..8b2ed65 100644
--- a/gdata/gdata-goa-authorizer.c
+++ b/gdata/gdata-goa-authorizer.c
@@ -97,8 +97,8 @@ G_DEFINE_TYPE_WITH_CODE (GDataGoaAuthorizer, gdata_goa_authorizer, G_TYPE_OBJECT
G_IMPLEMENT_INTERFACE (GDATA_TYPE_AUTHORIZER, gdata_goa_authorizer_interface_init))
static GHashTable *
-gdata_goa_authorizer_get_parameters (SoupMessage *message, const gchar *consumer_key, const gchar *consumer_secret, const gchar *access_token,
- const gchar *access_token_secret)
+gdata_goa_authorizer_get_oauth1_parameters (SoupMessage *message, const gchar *consumer_key, const gchar *consumer_secret, const gchar *access_token,
+ const gchar *access_token_secret)
{
GString *query;
GString *base_string;
@@ -226,7 +226,7 @@ gdata_goa_authorizer_get_parameters (SoupMessage *message, const gchar *consumer
}
static void
-gdata_goa_authorizer_add_authorization (GDataAuthorizer *authorizer, SoupMessage *message)
+gdata_goa_authorizer_add_oauth1_authorization (GDataAuthorizer *authorizer, SoupMessage *message)
{
GDataGoaAuthorizerPrivate *priv;
GoaOAuthBased *goa_oauth_based;
@@ -263,7 +263,8 @@ gdata_goa_authorizer_add_authorization (GDataAuthorizer *authorizer, SoupMessage
consumer_key = goa_oauth_based_get_consumer_key (goa_oauth_based);
consumer_secret = goa_oauth_based_get_consumer_secret (goa_oauth_based);
- parameters = gdata_goa_authorizer_get_parameters (message, consumer_key, consumer_secret, priv->access_token, priv->access_token_secret);
+ parameters = gdata_goa_authorizer_get_oauth1_parameters (message, consumer_key, consumer_secret,
+ priv->access_token, priv->access_token_secret);
authorization = g_string_new ("OAuth ");
@@ -295,6 +296,48 @@ gdata_goa_authorizer_add_authorization (GDataAuthorizer *authorizer, SoupMessage
g_object_unref (goa_oauth_based);
}
+static void
+gdata_goa_authorizer_add_oauth2_authorization (GDataAuthorizer *authorizer, SoupMessage *message)
+{
+ GDataGoaAuthorizerPrivate *priv;
+ GString *authorization;
+
+ /* This MUST be called with the mutex already locked. */
+
+ priv = GDATA_GOA_AUTHORIZER (authorizer)->priv;
+
+ /* We can't add an Authorization header without an access token. Let the request fail. GData should refresh us if it gets back a
+ * "401 Authorization required" response from Google, and then automatically retry the request. */
+ if (priv->access_token == NULL) {
+ return;
+ }
+
+ authorization = g_string_new ("OAuth ");
+ g_string_append (authorization, priv->access_token);
+
+ /* Use replace here, not append, to make sure there's only one "Authorization" header. */
+ soup_message_headers_replace (message->request_headers, "Authorization", authorization->str);
+
+ g_string_free (authorization, TRUE);
+}
+
+static void
+gdata_goa_authorizer_add_authorization (GDataAuthorizer *authorizer, SoupMessage *message)
+{
+ GDataGoaAuthorizerPrivate *priv;
+
+ /* This MUST be called with the mutex already locked. */
+
+ priv = GDATA_GOA_AUTHORIZER (authorizer)->priv;
+
+ /* Prefer OAuth 2.0 over OAuth 1.0. */
+ if (goa_object_peek_oauth2_based (priv->goa_object) != NULL) {
+ gdata_goa_authorizer_add_oauth2_authorization (authorizer, message);
+ } else if (goa_object_peek_oauth_based (priv->goa_object) != NULL) {
+ gdata_goa_authorizer_add_oauth1_authorization (authorizer, message);
+ }
+}
+
static gboolean
gdata_goa_authorizer_is_authorized (GDataAuthorizer *authorizer, GDataAuthorizationDomain *domain)
{
@@ -431,9 +474,10 @@ static gboolean
gdata_goa_authorizer_refresh_authorization (GDataAuthorizer *authorizer, GCancellable *cancellable, GError **error)
{
GDataGoaAuthorizerPrivate *priv;
- GoaOAuthBased *goa_oauth_based;
+ GoaOAuthBased *goa_oauth1_based;
+ GoaOAuth2Based *goa_oauth2_based;
GoaAccount *goa_account;
- gboolean success = TRUE;
+ gboolean success = FALSE;
priv = GDATA_GOA_AUTHORIZER (authorizer)->priv;
@@ -446,15 +490,29 @@ gdata_goa_authorizer_refresh_authorization (GDataAuthorizer *authorizer, GCancel
priv->access_token_secret = NULL;
goa_account = goa_object_get_account (priv->goa_object);
- goa_oauth_based = goa_object_get_oauth_based (priv->goa_object);
+ goa_oauth1_based = goa_object_get_oauth_based (priv->goa_object);
+ goa_oauth2_based = goa_object_get_oauth2_based (priv->goa_object);
- success &= goa_account_call_ensure_credentials_sync (goa_account, NULL, cancellable, error);
+ success = goa_account_call_ensure_credentials_sync (goa_account, NULL, cancellable, error);
- success &= goa_oauth_based_call_get_access_token_sync (goa_oauth_based, &priv->access_token, &priv->access_token_secret, NULL,
- cancellable, error);
+ if (success == FALSE) {
+ goto exit;
+ }
- g_object_unref (goa_account);
- g_object_unref (goa_oauth_based);
+ /* Prefer OAuth 2.0 over OAuth 1.0. */
+ if (goa_oauth2_based != NULL) {
+ success = goa_oauth2_based_call_get_access_token_sync (goa_oauth2_based, &priv->access_token, NULL, cancellable, error);
+ } else if (goa_oauth1_based != NULL) {
+ success = goa_oauth_based_call_get_access_token_sync (goa_oauth1_based, &priv->access_token, &priv->access_token_secret, NULL,
+ cancellable, error);
+ } else {
+ g_warn_if_reached (); /* should never happen */
+ }
+
+exit:
+ g_clear_object (&goa_account);
+ g_clear_object (&goa_oauth1_based);
+ g_clear_object (&goa_oauth2_based);
g_static_mutex_unlock (&mutex);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]