[frogr] Add API in FspSession to exchange an old token for a new one



commit a1c97a0c151f29df1e3990b232e6b51cafba35f3
Author: Mario Sanchez Prada <msanchez igalia com>
Date:   Thu Apr 5 04:03:08 2012 +0200

    Add API in FspSession to exchange an old token for a new one

 src/flicksoup/fsp-error.c   |    1 +
 src/flicksoup/fsp-error.h   |    1 +
 src/flicksoup/fsp-parser.c  |   78 ++++++++++++++++++++++++++++++-
 src/flicksoup/fsp-parser.h  |    6 ++
 src/flicksoup/fsp-session.c |  108 +++++++++++++++++++++++++++++++++++++++++-
 src/flicksoup/fsp-session.h |   10 ++++
 src/frogr-controller.c      |    1 +
 7 files changed, 200 insertions(+), 5 deletions(-)
---
diff --git a/src/flicksoup/fsp-error.c b/src/flicksoup/fsp-error.c
index dfaef18..e576b2e 100644
--- a/src/flicksoup/fsp-error.c
+++ b/src/flicksoup/fsp-error.c
@@ -264,6 +264,7 @@ fsp_error_get_from_response_code        (FspErrorMethod method, gint code)
     {
       switch (method)
         {
+        case FSP_ERROR_METHOD_EXCHANGE_TOKEN:
         case FSP_ERROR_METHOD_GET_UPLOAD_STATUS:
         case FSP_ERROR_METHOD_GROUP_GET_LIST:
           /* We shouldn't get errors in this range for these methods,
diff --git a/src/flicksoup/fsp-error.h b/src/flicksoup/fsp-error.h
index 76e3693..8202962 100644
--- a/src/flicksoup/fsp-error.h
+++ b/src/flicksoup/fsp-error.h
@@ -89,6 +89,7 @@ typedef enum {
 
 typedef enum {
   FSP_ERROR_METHOD_UNDEFINED,
+  FSP_ERROR_METHOD_EXCHANGE_TOKEN,
   FSP_ERROR_METHOD_GET_UPLOAD_STATUS,
   FSP_ERROR_METHOD_PHOTO_UPLOAD,
   FSP_ERROR_METHOD_PHOTO_GET_INFO,
diff --git a/src/flicksoup/fsp-parser.c b/src/flicksoup/fsp-parser.c
index 2ec72ed..4b7b6f6 100644
--- a/src/flicksoup/fsp-parser.c
+++ b/src/flicksoup/fsp-parser.c
@@ -68,6 +68,9 @@ _get_error_method_from_parser           (gpointer (*body_parser)
                                          (xmlDoc  *doc,
                                           GError **error));
 static gpointer
+_exchange_token_parser                  (xmlDoc  *doc,
+                                         GError **error);
+static gpointer
 _get_upload_status_parser               (xmlDoc  *doc,
                                          GError **error);
 static gpointer
@@ -261,7 +264,9 @@ _get_error_method_from_parser           (gpointer (*body_parser)
 {
   FspErrorMethod error_method = FSP_ERROR_METHOD_UNDEFINED;
 
-  if (body_parser == _get_upload_status_parser)
+  if (body_parser == _exchange_token_parser)
+    error_method = FSP_ERROR_METHOD_EXCHANGE_TOKEN;
+  else if (body_parser == _get_upload_status_parser)
     error_method = FSP_ERROR_METHOD_GET_UPLOAD_STATUS;
   else if (body_parser == _photo_get_upload_result_parser)
     error_method = FSP_ERROR_METHOD_PHOTO_UPLOAD;
@@ -335,6 +340,54 @@ _process_xml_response                          (FspParser  *self,
 }
 
 static gpointer
+_exchange_token_parser                  (xmlDoc  *doc,
+                                         GError **error)
+{
+  xmlXPathContext *xpathCtx = NULL;
+  xmlXPathObject * xpathObj = NULL;
+  FspDataAuthToken *auth_token = NULL;
+  GError *err = NULL;
+
+  g_return_val_if_fail (doc != NULL, NULL);
+
+  xpathCtx = xmlXPathNewContext (doc);
+  xpathObj = xmlXPathEvalExpression ((xmlChar *)"/rsp/auth/access_token", xpathCtx);
+
+  if ((xpathObj != NULL) && (xpathObj->nodesetval->nodeNr > 0))
+    {
+      /* Matching nodes found */
+      xmlNode *node = NULL;
+
+      auth_token = FSP_DATA_AUTH_TOKEN (fsp_data_new (FSP_AUTH_TOKEN));
+      node = xpathObj->nodesetval->nodeTab[0];
+      if (node && !g_strcmp0 ((gchar *) node->name, "access_token"))
+        {
+          xmlChar *value = NULL;
+
+          value = xmlGetProp (node, (const xmlChar *) "oauth_token");
+          auth_token->token = g_strdup ((gchar *) value);
+          xmlFree (value);
+
+          value = xmlGetProp (node, (const xmlChar *) "oauth_token_secret");
+          auth_token->token_secret = g_strdup ((gchar *) value);
+          xmlFree (value);
+        }
+    }
+  else
+    err = g_error_new (FSP_ERROR, FSP_ERROR_MISSING_DATA,
+                       "No 'auth' node found in the response");
+  /* Free */
+  xmlXPathFreeObject (xpathObj);
+  xmlXPathFreeContext (xpathCtx);
+
+  /* Propagate error */
+  if (err != NULL)
+    g_propagate_error (error, err);
+
+  return auth_token;
+}
+
+static gpointer
 _get_upload_status_parser               (xmlDoc  *doc,
                                          GError **error)
 {
@@ -419,7 +472,7 @@ _get_upload_status_parser               (xmlDoc  *doc,
     }
   else
     err = g_error_new (FSP_ERROR, FSP_ERROR_MISSING_DATA,
-                       "No 'auth' node found in the response");
+                       "No 'user' node found in the response");
   /* Free */
   xmlXPathFreeObject (xpathObj);
   xmlXPathFreeContext (xpathCtx);
@@ -1095,6 +1148,27 @@ fsp_parser_get_access_token             (FspParser   *self,
   return auth_token;
 }
 
+FspDataAuthToken *
+fsp_parser_exchange_token               (FspParser  *self,
+                                         const gchar      *buffer,
+                                         gulong            buf_size,
+                                         GError          **error)
+{
+  FspDataAuthToken *auth_token = NULL;
+
+  g_return_val_if_fail (FSP_IS_PARSER (self), NULL);
+  g_return_val_if_fail (buffer != NULL, NULL);
+
+  /* Process the response */
+  auth_token =
+    FSP_DATA_AUTH_TOKEN (_process_xml_response (self, buffer, buf_size,
+                                                _exchange_token_parser,
+                                                error));
+
+  /* Return value */
+  return auth_token;
+}
+
 FspDataUploadStatus *
 fsp_parser_get_upload_status            (FspParser  *self,
                                          const gchar      *buffer,
diff --git a/src/flicksoup/fsp-parser.h b/src/flicksoup/fsp-parser.h
index 03bd06b..daf4941 100644
--- a/src/flicksoup/fsp-parser.h
+++ b/src/flicksoup/fsp-parser.h
@@ -79,6 +79,12 @@ fsp_parser_get_access_token             (FspParser  *self,
                                          gulong            buf_size,
                                          GError          **error);
 
+FspDataAuthToken *
+fsp_parser_exchange_token               (FspParser  *self,
+                                         const gchar      *buffer,
+                                         gulong            buf_size,
+                                         GError          **error);
+
 FspDataUploadStatus *
 fsp_parser_get_upload_status            (FspParser  *self,
                                          const gchar      *buffer,
diff --git a/src/flicksoup/fsp-session.c b/src/flicksoup/fsp-session.c
index ff36d0d..88de8dd 100644
--- a/src/flicksoup/fsp-session.c
+++ b/src/flicksoup/fsp-session.c
@@ -138,6 +138,12 @@ static void
 _get_access_token_soup_session_cb       (SoupSession *session,
                                          SoupMessage *msg,
                                          gpointer     data);
+
+static void
+_exchange_token_soup_session_cb         (SoupSession *session,
+                                         SoupMessage *msg,
+                                         gpointer     data);
+
 static void
 _get_upload_status_soup_session_cb      (SoupSession *session,
                                          SoupMessage *msg,
@@ -515,6 +521,20 @@ _get_access_token_soup_session_cb       (SoupSession *session,
 }
 
 static void
+_exchange_token_soup_session_cb         (SoupSession *session,
+                                         SoupMessage *msg,
+                                         gpointer     data)
+{
+  g_assert (SOUP_IS_MESSAGE (msg));
+  g_assert (data != NULL);
+
+  /* Handle message with the right parser */
+  _handle_soup_response (msg,
+                         (FspParserFunc) fsp_parser_exchange_token,
+                         data);
+}
+
+static void
 _get_upload_status_soup_session_cb      (SoupSession *session,
                                          SoupMessage *msg,
                                          gpointer     data)
@@ -1181,13 +1201,19 @@ _get_signed_url                       (FspSession          *self,
   /* Get the hash table for the params */
   table = _get_params_table_from_valist (first_param, args);
 
+  /* Fill the table with mandatory parameters */
   if (auth_method == AUTHORIZATION_METHOD_OAUTH_1)
     {
       _fill_hash_table_with_oauth_params (table, priv->api_key, priv->token);
       signing_key = g_strdup_printf ("%s&%s", priv->secret, priv->token_secret ? priv->token_secret : "");
     }
   else
-    signing_key = g_strdup (priv->secret);
+    {
+      g_hash_table_insert (table, g_strdup ("api_key"), g_strdup (priv->api_key));
+      if (priv->token)
+        g_hash_table_insert (table, g_strdup ("auth_token"), g_strdup (priv->token));
+      signing_key = g_strdup (priv->secret);
+    }
 
   api_sig = _get_api_signature_from_hash_table (url, table, signing_key, http_method, auth_method);
   g_free (signing_key);
@@ -1861,13 +1887,89 @@ fsp_session_complete_auth_finish        (FspSession    *self,
                                                 error));
 
   /* Complete the authorization saving the token if present */
-  if (auth_token != NULL && auth_token->token != NULL)
-    fsp_session_set_token (self, auth_token->token);
+  if (auth_token != NULL)
+    {
+      if (auth_token->token != NULL)
+        fsp_session_set_token (self, auth_token->token);
+
+      if (auth_token->token_secret != NULL)
+        fsp_session_set_token_secret (self, auth_token->token_secret);
+    }
 
   return auth_token;
 }
 
 void
+fsp_session_exchange_token_async        (FspSession          *self,
+                                         GCancellable        *c,
+                                         GAsyncReadyCallback cb,
+                                         gpointer             data)
+{
+  FspSessionPrivate *priv = NULL;
+
+  g_return_if_fail (FSP_IS_SESSION (self));
+  g_return_if_fail (cb != NULL);
+
+  priv = self->priv;
+  if (priv->token != NULL)
+    {
+      gchar *url = NULL;
+
+      /* Build the signed url */
+      url = _get_signed_url (self,
+                             FLICKR_API_BASE_URL,
+                             AUTHORIZATION_METHOD_ORIGINAL,
+                             "GET",
+                             "method", "flickr.auth.oauth.getAccessToken",
+                             NULL);
+
+      /* Perform the async request */
+      _perform_async_request (priv->soup_session, url,
+                              _exchange_token_soup_session_cb, G_OBJECT (self),
+                              c, cb, fsp_session_exchange_token_async, data);
+
+      g_free (url);
+    }
+  else
+    {
+      GError *err = NULL;
+
+      /* Build and report error */
+      err = g_error_new (FSP_ERROR, FSP_ERROR_OAUTH_NOT_AUTHORIZED_YET, "Not authorized yet");
+      g_simple_async_report_gerror_in_idle (G_OBJECT (self),
+                                            cb, data, err);
+      /* Ensure we clean things up */
+      _clear_token_information (self);
+    }
+}
+
+void
+fsp_session_exchange_token_finish       (FspSession    *self,
+                                         GAsyncResult  *res,
+                                         GError       **error)
+{
+  FspDataAuthToken *auth_token = NULL;
+
+  g_return_if_fail (FSP_IS_SESSION (self));
+  g_return_if_fail (G_IS_ASYNC_RESULT (res));
+
+  auth_token =
+    FSP_DATA_AUTH_TOKEN (_finish_async_request (G_OBJECT (self), res,
+                                                fsp_session_exchange_token_async,
+                                                error));
+  if (auth_token != NULL)
+    {
+      if (auth_token->token != NULL)
+        fsp_session_set_token (self, auth_token->token);
+
+      if (auth_token->token_secret != NULL)
+        fsp_session_set_token_secret (self, auth_token->token_secret);
+
+      fsp_data_free (FSP_DATA (auth_token));
+    }
+}
+
+void
 fsp_session_check_auth_info_async       (FspSession          *self,
                                          GCancellable        *c,
                                          GAsyncReadyCallback  cb,
diff --git a/src/flicksoup/fsp-session.h b/src/flicksoup/fsp-session.h
index 1e8ba06..9c63fc3 100644
--- a/src/flicksoup/fsp-session.h
+++ b/src/flicksoup/fsp-session.h
@@ -111,6 +111,16 @@ fsp_session_complete_auth_finish        (FspSession    *self,
                                          GError       **error);
 
 void
+fsp_session_exchange_token_async        (FspSession          *self,
+                                         GCancellable        *c,
+                                         GAsyncReadyCallback cb,
+                                         gpointer             data);
+void
+fsp_session_exchange_token_finish       (FspSession    *self,
+                                         GAsyncResult  *res,
+                                         GError       **error);
+
+void
 fsp_session_check_auth_info_async       (FspSession          *self,
                                          GCancellable        *c,
                                          GAsyncReadyCallback cb,
diff --git a/src/frogr-controller.c b/src/frogr-controller.c
index ec4691a..ba0fad0 100644
--- a/src/frogr-controller.c
+++ b/src/frogr-controller.c
@@ -2097,6 +2097,7 @@ frogr_controller_init (FrogrController *self)
       if (token != NULL)
         fsp_session_set_token (priv->session, token);
 
+      /* If available, set token secret */
       token_secret = frogr_account_get_token_secret (priv->account);
       if (token_secret != NULL)
         fsp_session_set_token_secret (priv->session, token_secret);



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