[frogr] Implemented 2nd phase of authorization process in terms of OAuth.



commit accd0aaaf6bd1d3cef49816447f26e737325023e
Author: Mario Sanchez Prada <msanchez igalia com>
Date:   Wed Apr 4 14:31:55 2012 +0200

    Implemented 2nd phase of authorization process in terms of OAuth.

 src/examples/example.c      |    2 +-
 src/flicksoup/fsp-error.c   |    1 -
 src/flicksoup/fsp-error.h   |    6 +-
 src/flicksoup/fsp-parser.c  |  155 ++++++++++++++-----------------------------
 src/flicksoup/fsp-parser.h  |    2 +-
 src/flicksoup/fsp-session.c |   82 ++++++++++++++++-------
 src/flicksoup/fsp-session.h |    1 +
 src/frogr-auth-dialog.c     |   35 ++++++++--
 src/frogr-controller.c      |   20 ++++--
 src/frogr-controller.h      |    2 +-
 10 files changed, 162 insertions(+), 144 deletions(-)
---
diff --git a/src/examples/example.c b/src/examples/example.c
index c44a377..00e5656 100644
--- a/src/examples/example.c
+++ b/src/examples/example.c
@@ -589,7 +589,7 @@ get_auth_url_cb                         (GObject      *object,
 
       /* Continue finishing the authorization */
       g_print ("Finishing authorization...\n");
-      fsp_session_complete_auth_async (session, NULL, complete_auth_cb, NULL);
+      fsp_session_complete_auth_async (session, NULL, NULL, complete_auth_cb, NULL);
 
       g_free (auth_url);
     }
diff --git a/src/flicksoup/fsp-error.c b/src/flicksoup/fsp-error.c
index 5a1357c..dfaef18 100644
--- a/src/flicksoup/fsp-error.c
+++ b/src/flicksoup/fsp-error.c
@@ -264,7 +264,6 @@ fsp_error_get_from_response_code        (FspErrorMethod method, gint code)
     {
       switch (method)
         {
-        case FSP_ERROR_METHOD_GET_AUTH_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 fb10d33..76e3693 100644
--- a/src/flicksoup/fsp-error.h
+++ b/src/flicksoup/fsp-error.h
@@ -79,8 +79,9 @@ typedef enum {
   FSP_ERROR_SERVICE_UNAVAILABLE,
 
   /* Errors from flicksoup only */
-  FSP_ERROR_REQUEST_TOKEN,
-  FSP_ERROR_ACCESS_TOKEN,
+  FSP_ERROR_OAUTH_UNKNOWN_ERROR,
+  FSP_ERROR_OAUTH_NOT_AUTHORIZED_YET,
+  FSP_ERROR_OAUTH_VERIFIER_INVALID,
 
   /* Default fallback for other kind of errors */
   FSP_ERROR_OTHER
@@ -88,7 +89,6 @@ typedef enum {
 
 typedef enum {
   FSP_ERROR_METHOD_UNDEFINED,
-  FSP_ERROR_METHOD_GET_AUTH_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 c882b20..2ec72ed 100644
--- a/src/flicksoup/fsp-parser.c
+++ b/src/flicksoup/fsp-parser.c
@@ -22,6 +22,12 @@
 
 #include "fsp-error.h"
 
+#ifdef HAVE_LIBSOUP_GNOME
+#include <libsoup/soup-gnome.h>
+#else
+#include <libsoup/soup.h>
+#endif
+
 #include <libxml/parser.h>
 #include <libxml/xpath.h>
 
@@ -62,9 +68,6 @@ _get_error_method_from_parser           (gpointer (*body_parser)
                                          (xmlDoc  *doc,
                                           GError **error));
 static gpointer
-_get_auth_token_parser                  (xmlDoc  *doc,
-                                         GError **error);
-static gpointer
 _get_upload_status_parser               (xmlDoc  *doc,
                                          GError **error);
 static gpointer
@@ -258,9 +261,7 @@ _get_error_method_from_parser           (gpointer (*body_parser)
 {
   FspErrorMethod error_method = FSP_ERROR_METHOD_UNDEFINED;
 
-  if (body_parser == _get_auth_token_parser)
-    error_method = FSP_ERROR_METHOD_GET_AUTH_TOKEN;
-  else if (body_parser == _get_upload_status_parser)
+  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;
@@ -334,94 +335,6 @@ _process_xml_response                          (FspParser  *self,
 }
 
 static gpointer
-_get_auth_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", xpathCtx);
-
-  if ((xpathObj != NULL) && (xpathObj->nodesetval->nodeNr > 0))
-    {
-      /* Matching nodes found */
-      xmlNode *node = NULL;
-      xmlChar *content = NULL;
-
-      auth_token = FSP_DATA_AUTH_TOKEN (fsp_data_new (FSP_AUTH_TOKEN));
-
-      /* Traverse children of the 'auth' node */
-      node = xpathObj->nodesetval->nodeTab[0];
-      for (node = node->children; node != NULL; node = node->next)
-        {
-          if (node->type != XML_ELEMENT_NODE)
-            continue;
-
-          /* Token string */
-          if (!g_strcmp0 ((gchar *) node->name, "token"))
-            {
-              content = xmlNodeGetContent (node);
-              auth_token->token = g_strdup ((gchar *) content);
-              xmlFree (content);
-            }
-
-          /* Permissions */
-          if (!g_strcmp0 ((gchar *) node->name, "perms"))
-            {
-              content = xmlNodeGetContent (node);
-              auth_token->permissions = g_strdup ((gchar *) content);
-              xmlFree (content);
-            }
-
-          /* User profile */
-          if (!g_strcmp0 ((gchar *) node->name, "user"))
-            {
-              xmlChar *value = NULL;
-
-              value = xmlGetProp (node, (const xmlChar *) "nsid");
-              auth_token->nsid = g_strdup ((gchar *) value);
-              xmlFree (value);
-
-              value = xmlGetProp (node, (const xmlChar *) "username");
-              auth_token->username = g_strdup ((gchar *) value);
-              xmlFree (value);
-
-              value = xmlGetProp (node, (const xmlChar *) "fullname");
-              auth_token->fullname = g_strdup ((gchar *) value);
-              xmlFree (value);
-            }
-        }
-
-      if (!auth_token->token)
-        {
-          /* If we don't get enough information, return NULL */
-          g_object_unref (auth_token);
-          auth_token = NULL;
-
-          err = g_error_new (FSP_ERROR, FSP_ERROR_MISSING_DATA,
-                             "No token found in the response");
-        }
-    }
-  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)
 {
@@ -1116,9 +1029,8 @@ fsp_parser_get_request_token            (FspParser   *self,
   if (!auth_token->token || !auth_token->token_secret)
     {
       GError *err = NULL;
-      err = g_error_new (FSP_ERROR, FSP_ERROR_REQUEST_TOKEN,
-                         "An error happened requesting a new token");
-
+      err = g_error_new (FSP_ERROR, FSP_ERROR_OAUTH_UNKNOWN_ERROR,
+                         "An unknown error happened requesting a new token");
       /* Propagate error */
       if (err != NULL)
         g_propagate_error (error, err);
@@ -1129,20 +1041,55 @@ fsp_parser_get_request_token            (FspParser   *self,
 }
 
 FspDataAuthToken *
-fsp_parser_get_auth_token               (FspParser  *self,
-                                         const gchar      *buffer,
-                                         gulong            buf_size,
-                                         GError          **error)
+fsp_parser_get_access_token             (FspParser   *self,
+                                         const gchar *buffer,
+                                         gulong       buf_size,
+                                         GError     **error)
 {
   FspDataAuthToken *auth_token = NULL;
+  gchar *response_str = NULL;
+  gchar **response_array = NULL;
+  gint i = 0;
 
   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,
-                                                _get_auth_token_parser, error));
+  auth_token = FSP_DATA_AUTH_TOKEN (fsp_data_new (FSP_AUTH_TOKEN));
+  response_str = g_strndup (buffer, buf_size);
+  response_array = g_strsplit (response_str, "&", -1);
+  g_free (response_str);
+
+  for (i = 0; response_array[i]; i++)
+    {
+      if (g_str_has_prefix (response_array[i], "fullname="))
+        auth_token->fullname = soup_uri_decode (&response_array[i][9]);
+
+      if (g_str_has_prefix (response_array[i], "username="))
+        auth_token->username = soup_uri_decode (&response_array[i][9]);
+
+      if (g_str_has_prefix (response_array[i], "user_nsid="))
+        auth_token->nsid = soup_uri_decode (&response_array[i][10]);
+
+      if (g_str_has_prefix (response_array[i], "oauth_token="))
+        auth_token->token = g_strdup (&response_array[i][12]);
+
+      if (g_str_has_prefix (response_array[i], "oauth_token_secret="))
+        auth_token->token_secret = g_strdup (&response_array[i][19]);
+    }
+  g_strfreev (response_array);
+
+  /* Create the GError if needed*/
+  if (!auth_token->token || !auth_token->token_secret)
+    {
+      GError *err = NULL;
+      err = g_error_new (FSP_ERROR, FSP_ERROR_OAUTH_UNKNOWN_ERROR,
+                         "An unknown error happened getting a permanent token");
+
+      /* Propagate error */
+      if (err != NULL)
+        g_propagate_error (error, err);
+    }
 
   /* Return value */
   return auth_token;
diff --git a/src/flicksoup/fsp-parser.h b/src/flicksoup/fsp-parser.h
index 5d5b0e3..03bd06b 100644
--- a/src/flicksoup/fsp-parser.h
+++ b/src/flicksoup/fsp-parser.h
@@ -74,7 +74,7 @@ fsp_parser_get_request_token            (FspParser  *self,
                                          GError          **error);
 
 FspDataAuthToken *
-fsp_parser_get_auth_token               (FspParser  *self,
+fsp_parser_get_access_token             (FspParser  *self,
                                          const gchar      *buffer,
                                          gulong            buf_size,
                                          GError          **error);
diff --git a/src/flicksoup/fsp-session.c b/src/flicksoup/fsp-session.c
index e6bbc66..923dc01 100644
--- a/src/flicksoup/fsp-session.c
+++ b/src/flicksoup/fsp-session.c
@@ -136,7 +136,7 @@ _get_request_token_session_cb           (SoupSession *session,
                                          SoupMessage *msg,
                                          gpointer     data);
 static void
-_get_auth_token_soup_session_cb         (SoupSession *session,
+_get_access_token_soup_session_cb       (SoupSession *session,
                                          SoupMessage *msg,
                                          gpointer     data);
 static void
@@ -234,6 +234,9 @@ _get_signed_url                       (FspSession          *self,
                                        ... );
 
 static void
+_clear_token_information              (FspSession *self);
+
+static void
 _perform_async_request                  (SoupSession         *soup_session,
                                          const gchar         *url,
                                          SoupSessionCallback  request_cb,
@@ -491,7 +494,7 @@ _get_request_token_session_cb           (SoupSession *session,
 }
 
 static void
-_get_auth_token_soup_session_cb         (SoupSession *session,
+_get_access_token_soup_session_cb       (SoupSession *session,
                                          SoupMessage *msg,
                                          gpointer data)
 {
@@ -500,7 +503,7 @@ _get_auth_token_soup_session_cb         (SoupSession *session,
 
   /* Handle message with the right parser */
   _handle_soup_response (msg,
-                         (FspParserFunc) fsp_parser_get_auth_token,
+                         (FspParserFunc) fsp_parser_get_access_token,
                          data);
 }
 
@@ -919,12 +922,27 @@ _check_errors_on_soup_response           (SoupMessage  *msg,
                                           GError      **error)
 {
   GError *err = NULL;
+  gchar *response_str = NULL;
 
   g_assert (SOUP_IS_MESSAGE (msg));
 
-  /* Check non-succesful SoupMessage's only */
-  if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
+  /* First check it's not an OAuth problem */
+  response_str = g_strndup (msg->response_body->data, msg->response_body->length);
+  if (g_str_has_prefix (response_str, "oauth_problem="))
     {
+      if (!g_strcmp0 (&response_str[14], "token_rejected"))
+        err = g_error_new (FSP_ERROR, FSP_ERROR_OAUTH_NOT_AUTHORIZED_YET,
+                           "[OAuth]: The access token has been rejected");
+      else if (!g_strcmp0 (&response_str[14], "verifier_invalid"))
+        err = g_error_new (FSP_ERROR, FSP_ERROR_OAUTH_VERIFIER_INVALID,
+                           "[OAuth] The verification code is invalid");
+      else
+        err = g_error_new (FSP_ERROR, FSP_ERROR_OAUTH_UNKNOWN_ERROR,
+                           "[OAuth] unknown error");
+    }
+  else if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
+    {
+      /* Check non-succesful SoupMessage's only */
       if (msg->status_code == SOUP_STATUS_CANCELLED)
         err = g_error_new (FSP_ERROR, FSP_ERROR_CANCELLED,
                            "Cancelled by user");
@@ -939,6 +957,8 @@ _check_errors_on_soup_response           (SoupMessage  *msg,
                            "Network error");
     }
 
+  g_free (response_str);
+
   /* Propagate error */
   if (err != NULL)
     g_propagate_error (error, err);
@@ -1145,6 +1165,27 @@ _get_signed_url                       (FspSession          *self,
 }
 
 static void
+_clear_token_information              (FspSession *self)
+{
+  FspSessionPrivate *priv = NULL;
+
+  g_return_if_fail (FSP_IS_SESSION (self));
+
+  priv = self->priv;
+  if (priv->token)
+    {
+      g_free (priv->token);
+      priv->token = NULL;
+    }
+
+  if (priv->token_secret)
+    {
+      g_free (priv->token_secret);
+      priv->token_secret = NULL; 
+    }
+}
+
+static void
 _perform_async_request                  (SoupSession         *soup_session,
                                          const gchar         *url,
                                          SoupSessionCallback  request_cb,
@@ -1653,20 +1694,12 @@ fsp_session_get_auth_url_async          (FspSession          *self,
                                          GAsyncReadyCallback  cb,
                                          gpointer             data)
 {
-  FspSessionPrivate *priv = NULL;
   gchar *url = NULL;
 
   g_return_if_fail (FSP_IS_SESSION (self));
 
-  priv = self->priv;
-
-  /* We need to make sure that any token is removed at this point to
-     avoid calculating the signature wrongly, and also because they
-     will get replaced anyway by the new token. */
-  g_free (priv->token);
-  priv->token = NULL;
-  g_free (priv->token_secret);
-  priv->token_secret = NULL;
+  /* If we're here, we're no longer interested in former tokens */
+  _clear_token_information (self);
 
   /* Build the signed url */
   url = _get_signed_url (self,
@@ -1676,7 +1709,7 @@ fsp_session_get_auth_url_async          (FspSession          *self,
                          NULL);
 
   /* Perform the async request */
-  _perform_async_request (priv->soup_session, url,
+  _perform_async_request (self->priv->soup_session, url,
                           _get_request_token_session_cb, G_OBJECT (self),
                           c, cb, fsp_session_get_auth_url_async, data);
 
@@ -1726,6 +1759,7 @@ fsp_session_get_auth_url_finish         (FspSession    *self,
 
 void
 fsp_session_complete_auth_async         (FspSession          *self,
+                                         const gchar         *code,
                                          GCancellable        *c,
                                          GAsyncReadyCallback  cb,
                                          gpointer             data)
@@ -1742,15 +1776,15 @@ fsp_session_complete_auth_async         (FspSession          *self,
 
       /* Build the signed url */
       url = _get_signed_url (self,
-                             FLICKR_API_BASE_URL,
-                             AUTHORIZATION_METHOD_ORIGINAL,
-                             "method", "flickr.auth.getToken",
-                             "api_key", priv->api_key,
+                             FLICKR_ACCESS_TOKEN_OAUTH_URL,
+                             AUTHORIZATION_METHOD_OAUTH_1,
+                             "oauth_token", priv->token,
+                             "oauth_verifier", code,
                              NULL);
 
       /* Perform the async request */
       _perform_async_request (priv->soup_session, url,
-                              _get_auth_token_soup_session_cb, G_OBJECT (self),
+                              _get_access_token_soup_session_cb, G_OBJECT (self),
                               c, cb, fsp_session_complete_auth_async, data);
 
       g_free (url);
@@ -1760,9 +1794,11 @@ fsp_session_complete_auth_async         (FspSession          *self,
       GError *err = NULL;
 
       /* Build and report error */
-      err = g_error_new (FSP_ERROR, FSP_ERROR_ACCESS_TOKEN, "No access token got");
+      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);
     }
 }
 
@@ -1815,7 +1851,7 @@ fsp_session_check_auth_info_async       (FspSession          *self,
 
       /* Perform the async request */
       _perform_async_request (priv->soup_session, url,
-                              _get_auth_token_soup_session_cb, G_OBJECT (self),
+                              _get_access_token_soup_session_cb, G_OBJECT (self),
                               c, cb, fsp_session_check_auth_info_async, data);
 
       g_free (url);
diff --git a/src/flicksoup/fsp-session.h b/src/flicksoup/fsp-session.h
index eb7690f..1e8ba06 100644
--- a/src/flicksoup/fsp-session.h
+++ b/src/flicksoup/fsp-session.h
@@ -101,6 +101,7 @@ fsp_session_get_auth_url_finish         (FspSession    *self,
 
 void
 fsp_session_complete_auth_async         (FspSession          *self,
+                                         const gchar         *code,
                                          GCancellable        *c,
                                          GAsyncReadyCallback cb,
                                          gpointer             data);
diff --git a/src/frogr-auth-dialog.c b/src/frogr-auth-dialog.c
index 31673e0..c369236 100644
--- a/src/frogr-auth-dialog.c
+++ b/src/frogr-auth-dialog.c
@@ -100,11 +100,12 @@ _code_entry_text_inserted_cb (GtkEditable *editable, gchar *new_text,
 }
 
 static GtkWidget *
-_build_verification_code_entry_widget ()
+_build_verification_code_entry_widget (GtkWidget *dialog)
 {
   GtkWidget *hbox = NULL;
   GtkWidget *entry = NULL;
   GtkWidget *separator = NULL;
+  gchar *entry_key = NULL;
   gint i = 0;
 
   hbox = frogr_gtk_compat_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
@@ -115,10 +116,13 @@ _build_verification_code_entry_widget ()
       gtk_entry_set_width_chars (GTK_ENTRY (entry), 3);
       gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, FALSE, 6);
 
+      entry_key = g_strdup_printf ("vercode-%d", i + 1);
+      g_object_set_data (G_OBJECT (dialog), entry_key, entry);
+      g_free (entry_key);
+
       g_signal_connect (G_OBJECT (entry), "insert-text",
                     G_CALLBACK (_code_entry_text_inserted_cb),
                     NULL);
-
       if (i < 2)
         {
           separator = frogr_gtk_compat_separator_new (GTK_ORIENTATION_HORIZONTAL);
@@ -155,7 +159,7 @@ _ask_for_auth_confirmation (GtkWindow *parent)
   vbox = frogr_gtk_compat_box_new (GTK_ORIENTATION_VERTICAL, 0);
 
   /* Entry widgets for the verification code */
-  ver_code_entry = _build_verification_code_entry_widget ();
+  ver_code_entry = _build_verification_code_entry_widget (dialog);
   gtk_box_pack_start (GTK_BOX (vbox), ver_code_entry, TRUE, TRUE, 0);
 
   /* Description label */
@@ -171,13 +175,34 @@ _ask_for_auth_confirmation (GtkWindow *parent)
   gtk_widget_show_all (dialog);
 }
 
+static const gchar*
+_get_entry_code_for_dialog (GtkDialog *dialog, const gchar *entry_key)
+{
+  GtkWidget *entry = g_object_get_data (G_OBJECT (dialog), entry_key);
+  if (entry == NULL)
+    return NULL;
+
+  return gtk_entry_get_text (GTK_ENTRY (entry));
+}
+
 static void
 _ask_for_auth_confirmation_response_cb (GtkDialog *dialog, gint response, gpointer data)
 {
   if (response == GTK_RESPONSE_OK)
     {
-      FrogrController *controller = frogr_controller_get_instance();
-      frogr_controller_complete_auth (controller);
+      const gchar *vercode_part1 = NULL;
+      const gchar *vercode_part2 = NULL;
+      const gchar *vercode_part3 = NULL;
+      gchar *vercode_full = NULL;
+
+      vercode_part1 = _get_entry_code_for_dialog (dialog, "vercode-1");
+      vercode_part2 = _get_entry_code_for_dialog (dialog, "vercode-2");
+      vercode_part3 = _get_entry_code_for_dialog (dialog, "vercode-3");
+
+      vercode_full = g_strdup_printf ("%s-%s-%s", vercode_part1, vercode_part2, vercode_part3);
+
+      frogr_controller_complete_auth (frogr_controller_get_instance(), vercode_full);
+      g_free (vercode_full);
     }
 
   gtk_widget_destroy (GTK_WIDGET (dialog));
diff --git a/src/frogr-controller.c b/src/frogr-controller.c
index 64a3ad1..117b986 100644
--- a/src/frogr-controller.c
+++ b/src/frogr-controller.c
@@ -357,9 +357,19 @@ _notify_error_to_user (FrogrController *self, GError *error)
       error_function = frogr_util_show_error_dialog;
       break;
 
-    case FSP_ERROR_REQUEST_TOKEN:
-    case FSP_ERROR_ACCESS_TOKEN:
-      msg = g_strdup_printf (_("Unable to authenticate in flickr"));
+    case FSP_ERROR_OAUTH_UNKNOWN_ERROR:
+      msg = g_strdup_printf (_("Unable to authenticate in flickr\nPlease try again."));
+      error_function = frogr_util_show_error_dialog;
+      break;
+
+    case FSP_ERROR_OAUTH_NOT_AUTHORIZED_YET:
+      msg = g_strdup_printf (_("You have not properly authorized %s yet.\n"
+                               "Please try again."), APP_SHORTNAME);
+      error_function = frogr_util_show_error_dialog;
+      break;
+
+    case FSP_ERROR_OAUTH_VERIFIER_INVALID:
+      msg = g_strdup_printf (_("Invalid verification code.\nPlease try again."));
       error_function = frogr_util_show_error_dialog;
       break;
 
@@ -2507,7 +2517,7 @@ frogr_controller_open_auth_url (FrogrController *self)
 }
 
 void
-frogr_controller_complete_auth (FrogrController *self)
+frogr_controller_complete_auth (FrogrController *self, const gchar *verification_code)
 {
   FrogrControllerPrivate *priv = FROGR_CONTROLLER_GET_PRIVATE (self);
 
@@ -2516,7 +2526,7 @@ frogr_controller_complete_auth (FrogrController *self)
   priv->fetching_auth_token = TRUE;
   _enable_cancellable (self, TRUE);
 
-  fsp_session_complete_auth_async (priv->session, priv->last_cancellable, _complete_auth_cb, self);
+  fsp_session_complete_auth_async (priv->session, verification_code, priv->last_cancellable, _complete_auth_cb, self);
   gdk_threads_add_timeout (DEFAULT_TIMEOUT, (GSourceFunc) _show_progress_on_idle, GINT_TO_POINTER (FETCHING_AUTH_TOKEN));
 
   /* Make sure we show proper feedback if connection is too slow */
diff --git a/src/frogr-controller.h b/src/frogr-controller.h
index c831afc..b71e27a 100644
--- a/src/frogr-controller.h
+++ b/src/frogr-controller.h
@@ -108,7 +108,7 @@ void frogr_controller_show_add_to_group_dialog (FrogrController *self,
 
 void frogr_controller_open_auth_url (FrogrController *self);
 
-void frogr_controller_complete_auth (FrogrController *self);
+void frogr_controller_complete_auth (FrogrController *self, const gchar *verification_code);
 
 gboolean frogr_controller_is_authorized (FrogrController *self);
 



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