[grilo] grilo-test-ui: Add functions to authorize Flickr access



commit 25f081efcabeeb6026e6eb2a7822c68d044bcd01
Author: Juan A. Suarez Romero <jasuarez igalia com>
Date:   Thu Jul 15 10:16:45 2010 +0200

    grilo-test-ui: Add functions to authorize Flickr access
    
    Instead of being based on an external library, add required code in test-ui
    itself to get frob, token and login link.
    
    Users can take a look at this code to know how to get a valid token.

 configure.ac                      |    5 +-
 tools/grilo-test-ui/Makefile.am   |    4 +-
 tools/grilo-test-ui/flickr-auth.c |  257 +++++++++++++++++++++++++++++++++++++
 tools/grilo-test-ui/flickr-auth.h |   43 ++++++
 tools/grilo-test-ui/main.c        |   26 +---
 5 files changed, 310 insertions(+), 25 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 964c47b..7a5a92d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -156,14 +156,11 @@ GOBJECT_INTROSPECTION_CHECK([0.6.7])
 PKG_CHECK_MODULES(DEPS, glib-2.0 \
 			gobject-2.0 \
 			gmodule-2.0 \
+                        gio-2.0 \
 			libxml-2.0)
 
 # Tools
 
-PKG_CHECK_MODULES(GRL_FLICKR, grilo-flickr,
-                              [AC_DEFINE(HAVE_GRILO_FLICKR, 1, grilo-flickr library)],
-                              [AC_MSG_WARN(grilo-flickr not found)])
-
 PKG_CHECK_MODULES(GTU, gtk+-2.0 \
                        gconf-2.0,
                        BUILD_GRILO_TEST_UI=yes,
diff --git a/tools/grilo-test-ui/Makefile.am b/tools/grilo-test-ui/Makefile.am
index f7d0b27..e6169dd 100644
--- a/tools/grilo-test-ui/Makefile.am
+++ b/tools/grilo-test-ui/Makefile.am
@@ -10,7 +10,9 @@ INCLUDES = $(DEPS_CFLAGS)
 bin_PROGRAMS = grilo-test-ui
 
 grilo_test_ui_SOURCES =	\
-	main.c
+	main.c		\
+	flickr-auth.h	\
+	flickr-auth.c
 
 grilo_test_ui_CFLAGS =		\
 	-DPREFIX=$(prefix)	\
diff --git a/tools/grilo-test-ui/flickr-auth.c b/tools/grilo-test-ui/flickr-auth.c
new file mode 100644
index 0000000..16b8af6
--- /dev/null
+++ b/tools/grilo-test-ui/flickr-auth.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "flickr-auth.h"
+
+#include <gio/gio.h>
+#include <string.h>
+#include <libxml/xpath.h>
+
+#define FLICKR_ENDPOINT  "http://api.flickr.com/services/rest/?";
+#define FLICKR_AUTHPOINT "http://flickr.com/services/auth/?";
+
+#define FLICKR_AUTH_GETFROB_METHOD  "flickr.auth.getFrob"
+#define FLICKR_AUTH_GETTOKEN_METHOD "flickr.auth.getToken"
+
+#define FLICKR_AUTH_GETFROB                     \
+  FLICKR_ENDPOINT                               \
+  "api_key=%s"                                  \
+  "&api_sig=%s"                                 \
+  "&method=" FLICKR_AUTH_GETFROB_METHOD
+
+#define FLICKR_AUTH_GETTOKEN                    \
+  FLICKR_ENDPOINT                               \
+  "api_key=%s"                                  \
+  "&api_sig=%s"                                 \
+  "&method=" FLICKR_AUTH_GETTOKEN_METHOD        \
+  "&frob=%s"
+
+#define FLICKR_AUTH_LOGINLINK                   \
+  FLICKR_AUTHPOINT                              \
+  "api_key=%s"                                  \
+  "&api_sig=%s"                                 \
+  "&frob=%s"                                    \
+  "&perms=%s"
+
+static gchar *
+get_xpath_element (const gchar *content,
+                   const gchar *xpath_element)
+{
+  gchar *element = NULL;
+  xmlDocPtr xmldoc = NULL;
+  xmlXPathContextPtr xpath_ctx = NULL;
+  xmlXPathObjectPtr xpath_res = NULL;
+
+  xmldoc = xmlReadMemory (content, xmlStrlen ((xmlChar *) content), NULL, NULL,
+                          XML_PARSE_RECOVER | XML_PARSE_NOBLANKS);
+  if (xmldoc) {
+    xpath_ctx = xmlXPathNewContext (xmldoc);
+    if (xpath_ctx) {
+      xpath_res = xmlXPathEvalExpression ((xmlChar *) xpath_element, xpath_ctx);
+      if (xpath_res && xpath_res->nodesetval->nodeTab) {
+        element =
+          (gchar *) xmlNodeListGetString (xmldoc,
+                                          xpath_res->nodesetval->nodeTab[0]->xmlChildrenNode,
+                                          1);
+      }
+    }
+  }
+
+  /* Free data */
+  if (xmldoc) {
+    xmlFreeDoc (xmldoc);
+  }
+
+  if (xpath_ctx) {
+    xmlXPathFreeContext (xpath_ctx);
+  }
+
+  if (xpath_res) {
+    xmlXPathFreeObject (xpath_res);
+  }
+
+  return element;
+}
+
+static gchar *
+get_api_sig (const gchar *secret, ...)
+{
+  GHashTable *hash;
+  GList *key_iter;
+  GList *keys;
+  GString *to_sign;
+  gchar *api_sig;
+  gchar *key;
+  gchar *value;
+  gint text_size = strlen (secret);
+  va_list va_params;
+
+  hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+  va_start (va_params, secret);
+  while ((key = va_arg (va_params, gchar *))) {
+    text_size += strlen (key);
+    value = va_arg (va_params, gchar *);
+    text_size += strlen (value);
+    g_hash_table_insert (hash, key, value);
+  }
+  va_end (va_params);
+
+  to_sign = g_string_sized_new (text_size);
+  g_string_append (to_sign, secret);
+
+  keys = g_hash_table_get_keys (hash);
+  keys = g_list_sort (keys, (GCompareFunc) g_strcmp0);
+  for (key_iter = keys; key_iter; key_iter = g_list_next (key_iter)) {
+    g_string_append (to_sign, key_iter->data);
+    g_string_append (to_sign, g_hash_table_lookup (hash, key_iter->data));
+  }
+
+  api_sig = g_compute_checksum_for_string (G_CHECKSUM_MD5, to_sign->str, -1);
+  g_hash_table_unref (hash);
+  g_list_free (keys);
+  g_string_free (to_sign, TRUE);
+
+  return api_sig;
+}
+
+gchar *
+flickr_get_frob (const gchar *key,
+                 const gchar *secret)
+{
+  gchar *api_sig;
+  gchar *url;
+  GVfs *vfs;
+  GFile *uri;
+  gchar *contents;
+  GError *error = NULL;
+  gchar *frob = NULL;
+
+  g_return_val_if_fail (key, NULL);
+  g_return_val_if_fail (secret, NULL);
+
+  api_sig = get_api_sig (secret,
+                         "api_key", key,
+                         "method", FLICKR_AUTH_GETFROB_METHOD,
+                         NULL);
+
+  /* Build url */
+  url = g_strdup_printf (FLICKR_AUTH_GETFROB, key, api_sig);
+  g_free (api_sig);
+
+  /* Load content */
+  vfs = g_vfs_get_default ();
+  uri = g_vfs_get_file_for_uri (vfs, url);
+  g_free (url);
+  if (!g_file_load_contents (uri, NULL, &contents, NULL, NULL, &error)) {
+    g_warning ("Unable to get Flickr's frob: %s", error->message);
+    return NULL;
+  }
+
+  /* Get frob */
+  frob = get_xpath_element (contents, "/rsp/frob");
+  g_free (contents);
+  if (!frob) {
+    g_warning ("Can not get Flickr's frob");
+  }
+
+  return frob;
+}
+
+gchar *
+flickr_get_token (const gchar *key,
+                  const gchar *secret,
+                  const gchar *frob)
+{
+  GError *error = NULL;
+  GFile *uri;
+  GVfs *vfs;
+  gchar *api_sig;
+  gchar *contents;
+  gchar *token;
+  gchar *url;
+
+  g_return_val_if_fail (key, NULL);
+  g_return_val_if_fail (secret, NULL);
+  g_return_val_if_fail (frob, NULL);
+
+  api_sig = get_api_sig (secret,
+                         "method", FLICKR_AUTH_GETTOKEN_METHOD,
+                         "api_key", key,
+                         "frob", frob,
+                         NULL);
+
+  /* Build url */
+  url = g_strdup_printf (FLICKR_AUTH_GETTOKEN,
+                         key,
+                         api_sig,
+                         frob);
+  g_free (api_sig);
+
+  /* Load content */
+  vfs = g_vfs_get_default ();
+  uri = g_vfs_get_file_for_uri (vfs, url);
+  g_free (url);
+  if (!g_file_load_contents (uri, NULL, &contents, NULL, NULL, &error)) {
+    g_warning ("Unable to get Flickr's token: %s", error->message);
+    return NULL;
+  }
+
+  /* Get token */
+  token = get_xpath_element (contents, "/rsp/auth/token");
+  g_free (contents);
+  if (!token) {
+    g_warning ("Can not get Flickr's token");
+  }
+
+  return token;
+}
+
+gchar *
+flickr_get_login_link (const gchar *key,
+                       const gchar *secret,
+                       const gchar *frob,
+                       const gchar *perm)
+{
+  gchar *api_sig;
+  gchar *url;
+
+  g_return_val_if_fail (key, NULL);
+  g_return_val_if_fail (secret, NULL);
+  g_return_val_if_fail (frob, NULL);
+  g_return_val_if_fail (perm, NULL);
+
+  api_sig = get_api_sig (secret,
+                         "api_key", key,
+                         "frob", frob,
+                         "perms", perm,
+                         NULL);
+
+  url = g_strdup_printf (FLICKR_AUTH_LOGINLINK,
+                         key,
+                         api_sig,
+                         frob,
+                         perm);
+  g_free (api_sig);
+
+  return url;
+}
diff --git a/tools/grilo-test-ui/flickr-auth.h b/tools/grilo-test-ui/flickr-auth.h
new file mode 100644
index 0000000..0fd663e
--- /dev/null
+++ b/tools/grilo-test-ui/flickr-auth.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef _FLICKR_AUTH_H_
+#define _FLICKR_AUTH_H_
+
+#include <glib.h>
+
+gchar *
+flickr_get_frob (const gchar *key,
+                 const gchar *secret);
+
+gchar *
+flickr_get_token (const gchar *key,
+                  const gchar *secret,
+                  const gchar *frob);
+
+gchar *
+flickr_get_login_link (const gchar *key,
+                       const gchar *secret,
+                       const gchar *frob,
+                       const gchar *perm);
+
+#endif /* _FLICKR_AUTH_H_ */
diff --git a/tools/grilo-test-ui/main.c b/tools/grilo-test-ui/main.c
index 9e38b4f..01eaffd 100644
--- a/tools/grilo-test-ui/main.c
+++ b/tools/grilo-test-ui/main.c
@@ -28,9 +28,7 @@
 #include <string.h>
 #include <gconf/gconf-client.h>
 
-#ifdef HAVE_GRILO_FLICKR
-#include <grl-flickr-auth.h>
-#endif
+#include "flickr-auth.h"
 
 #undef G_LOG_DOMAIN
 #define G_LOG_DOMAIN "test-ui"
@@ -172,10 +170,8 @@ static const gchar *ui_definition =
 "<ui>"
 " <menubar name='MainMenu'>"
 "  <menu name='FileMenu' action='FileMenuAction' >"
-"   <menuitem name='Quit' action='QuitAction' />"
-#if HAVE_GRILO_FLICKR
 "   <menuitem name='Authorize Flickr' action='AuthorizeFlickrAction' />"
-#endif
+"   <menuitem name='Quit' action='QuitAction' />"
 "  </menu>"
 " </menubar>"
 "</ui>";
@@ -183,17 +179,13 @@ static const gchar *ui_definition =
 static void show_plugins (void);
 static void quit_cb (GtkAction *action);
 
-#ifdef HAVE_GRILO_FLICKR
 static gchar *authorize_flickr (void);
 static void authorize_flickr_cb (GtkAction *action);
-#endif
 
 static GtkActionEntry entries[] = {
   { "FileMenuAction", NULL, "_File" },
+  { "AuthorizeFlickrAction", GTK_STOCK_CONNECT, "_Authorize Flickr", NULL, "AuthorizeFlickr", G_CALLBACK (authorize_flickr_cb)},
   { "QuitAction", GTK_STOCK_QUIT, "_Quit", "<control>Q", "Quit", G_CALLBACK (quit_cb) }
-#ifdef HAVE_GRILO_FLICKR
-  ,{ "AuthorizeFlickrAction", GTK_STOCK_CONNECT, "_Authorize Flickr", NULL, "AuthorizeFlickr", G_CALLBACK (authorize_flickr_cb)}
-#endif
 };
 
 static void
@@ -202,13 +194,11 @@ quit_cb (GtkAction *action)
   gtk_main_quit ();
 }
 
-#ifdef HAVE_GRILO_FLICKR
 static void
 authorize_flickr_cb (GtkAction *action)
 {
   authorize_flickr ();
 }
-#endif
 
 static GtkTreeModel *
 create_browser_model (void)
@@ -1212,7 +1202,6 @@ load_flickr_token (void)
   return token;
 }
 
-#ifdef HAVE_GRILO_FLICKR
 static void
 save_flickr_token (const gchar *token)
 {
@@ -1247,13 +1236,13 @@ authorize_flickr (void)
   gchar *login_link;
   GtkWidget *ok_button;
 
-  gchar *frob = grl_flickr_get_frob (FLICKR_KEY, FLICKR_SECRET);
+  gchar *frob = flickr_get_frob (FLICKR_KEY, FLICKR_SECRET);
   if (!frob) {
     g_warning ("Unable to obtain a Flickr's frob");
     return NULL;
   }
 
-  login_link = grl_flickr_get_login_link (FLICKR_KEY, FLICKR_SECRET, frob, "read");
+  login_link = flickr_get_login_link (FLICKR_KEY, FLICKR_SECRET, frob, "read");
   view = gtk_text_view_new ();
   gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)),
                             FLICKR_AUTHORIZE_MSG,
@@ -1290,7 +1279,7 @@ authorize_flickr (void)
 
   gtk_widget_show_all (dialog);
   if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
-    token = grl_flickr_get_token (FLICKR_KEY, FLICKR_SECRET, frob);
+    token = flickr_get_token (FLICKR_KEY, FLICKR_SECRET, frob);
     if (token) {
       save_flickr_token (token);
     } else {
@@ -1311,7 +1300,6 @@ authorize_flickr (void)
 
   return token;
 }
-#endif
 
 static void
 set_flickr_config (void)
@@ -1329,7 +1317,6 @@ set_flickr_config (void)
 
   token = load_flickr_token ();
 
-#ifdef HAVE_GRILO_FLICKR
   if (!token) {
     token = authorize_flickr ();
     if (!token) {
@@ -1337,7 +1324,6 @@ set_flickr_config (void)
       save_flickr_token ("");
     }
   }
-#endif
 
   if (token && token[0] != '\0') {
     config = grl_config_new ("grl-flickr", NULL);



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