From 82a3c762e400dcee2129df9423bb4ed0b30a6743 Mon Sep 17 00:00:00 2001 From: Marek Chalupa Date: Wed, 3 Apr 2013 08:33:00 +0200 Subject: [PATCH] Flickr plugin modified to use OAuth authentication api In new file(s) flickr-oauth.[ch] are functions providing signing and creating request to flickr api, either non-authorized or authorized via OAuth. In gflickr.c are new wrapper functions for abovementioned functions (just for simplicity, e.g.: flickroauth_create_api_url (6 args..) --> create_url (3 args) etc. ) and the API in this file is modified to use these function. Old authentication functions was deleted. GFlickr object was modified to use oauth token and token secret. In the same manner was modified grl-flicker.c Into configure.ac and Makefile.am was written appropriate changes. --- configure.ac | 11 +- src/flickr/Makefile.am | 4 +- src/flickr/flickr-oauth.c | 166 +++++++++++++ src/flickr/flickr-oauth.h | 57 +++++ src/flickr/gflickr.c | 604 +++++++++------------------------------------- src/flickr/gflickr.h | 18 +- src/flickr/grl-flickr.c | 52 ++-- 7 files changed, 386 insertions(+), 526 deletions(-) create mode 100644 src/flickr/flickr-oauth.c create mode 100644 src/flickr/flickr-oauth.h diff --git a/configure.ac b/configure.ac index f8f3bfa..f5ace9d 100644 --- a/configure.ac +++ b/configure.ac @@ -131,6 +131,8 @@ PKG_CHECK_MODULES(LIBSOUP, libsoup-2.4, HAVE_LIBSOUP=yes, HAVE_LIBSOUP=no) PKG_CHECK_MODULES(GTHREAD, gthread-2.0, HAVE_GTHREAD=yes, HAVE_GTHREAD=no) +PKG_CHECK_MODULES(OAUTH, oauth, HAVE_OAUTH=yes, HAVE_OAUTH=no) + PKG_CHECK_MODULES(TOTEM_PL_PARSER, totem-plparser >= 3.4.1, HAVE_TOTEM_PL_PARSER=yes, HAVE_TOTEM_PL_PARSER=no) PKG_CHECK_MODULES([JSON], [json-glib-1.0], HAVE_JSON_GLIB=yes, HAVE_JSON_GLIB=no) @@ -453,11 +455,14 @@ AC_ARG_ENABLE(flickr, if test "x$HAVE_XML" = "xno"; then AC_MSG_ERROR([xml2 not found, install it or use --disable-flickr]) fi + if test "x$HAVE_OAUTH" = "xno"; then + AC_MSG_ERROR([liboauth not found, install it or use --disable-flickr]) + fi ;; esac ], [ - if test "x$HAVE_GRLNET" = "xyes" -a "x$HAVE_XML" = "xyes"; then + if test "x$HAVE_GRLNET" = "xyes" -a "x$HAVE_XML" = "xyes" -a "x$HAVE_OAUTH" = "xyes"; then enable_flickr=yes else enable_flickr=no @@ -475,9 +480,9 @@ FLICKR_PLUGIN_ID="grl-flickr" AC_SUBST(FLICKR_PLUGIN_ID) AC_DEFINE_UNQUOTED([FLICKR_PLUGIN_ID], ["$FLICKR_PLUGIN_ID"], [Flickr plugin ID]) -DEPS_FLICKR_CFLAGS="$DEPS_CFLAGS $XML_CFLAGS $GRLNET_CFLAGS" +DEPS_FLICKR_CFLAGS="$DEPS_CFLAGS $XML_CFLAGS $GRLNET_CFLAGS $OAUTH_CFLAGS" AC_SUBST(DEPS_FLICKR_CFLAGS) -DEPS_FLICKR_LIBS="$DEPS_LIBS $XML_LIBS $GRLNET_LIBS" +DEPS_FLICKR_LIBS="$DEPS_LIBS $XML_LIBS $GRLNET_LIBS $OAUTH_LIBS" AC_SUBST(DEPS_FLICKR_LIBS) # ---------------------------------------------------------- diff --git a/src/flickr/Makefile.am b/src/flickr/Makefile.am index 5bdc09f..7c2a5d1 100644 --- a/src/flickr/Makefile.am +++ b/src/flickr/Makefile.am @@ -22,7 +22,9 @@ libgrlflickr_la_SOURCES = \ grl-flickr.c \ grl-flickr.h \ gflickr.c \ - gflickr.h + gflickr.h \ + flickr-oauth.c\ + flickr-oauth.h libplugindir = $(GRL_PLUGINS_DIR) flickrlibxmldir = $(GRL_PLUGINS_DIR) diff --git a/src/flickr/flickr-oauth.c b/src/flickr/flickr-oauth.c new file mode 100644 index 0000000..60f0f8b --- /dev/null +++ b/src/flickr/flickr-oauth.c @@ -0,0 +1,166 @@ +#include "flickr-oauth.h" + +#include +#include + +#include +#include + +/* ----------------- private functions declarations ----------------- */ + +static gchar * +get_timestamp (void); + +static void +free_params (gchar **params, gint params_no); + +/* -------------------------- public API -------------------------- */ + +gchar * +flickroauth_get_signature (const gchar *consumer_secret, + const gchar *token_secret, + const gchar *url, + gchar **params, + gint params_no) +{ + gchar *params_string; + gchar *base_string; + gchar *encryption_key; + gchar *signature; + + qsort (params, params_no, sizeof (gchar *), oauth_cmpstringp); + + params_string = oauth_serialize_url (params_no, 0, params); + + base_string = oauth_catenc (3, FLICKR_OAUTH_HTTP_METHOD, + url, params_string); + + g_free (params_string); + + if (token_secret == NULL) + encryption_key = g_strdup_printf ("%s&", consumer_secret); + else + encryption_key = g_strdup_printf ("%s&%s", + consumer_secret, + token_secret); + + signature = oauth_sign_hmac_sha1 (base_string, encryption_key); + + g_free (encryption_key); + g_free (base_string); + + return signature; +} + + +gchar * +flickroauth_create_api_url (const gchar *consumer_key, + const gchar *consumer_secret, + const gchar *oauth_token, + const gchar *oauth_token_secret, + gchar **params, + const guint params_no) +{ + guint i; + gchar *nonce; + gchar *timestamp; + gchar *signature; + gchar *url; + gchar *params_string; + + g_return_val_if_fail (consumer_key, NULL); + + /* handle Non-authorised call */ + if (oauth_token == NULL) + { + params_string = oauth_serialize_url (params_no, 0, params); + + url = g_strdup_printf ("%s?api_key=%s&%s", FLICKR_API_URL, + consumer_key, + params_string); + + g_free (params_string); + + return url; + } + + /* there are 7 pre-filled parameters in authorize call*/ + guint params_all_no = params_no + 7; + gchar **params_all = g_malloc ((params_all_no) * sizeof (gchar *)); + + if (params_all == NULL) + return NULL; + + nonce = oauth_gen_nonce (); + timestamp = get_timestamp (); + + params_all[0] = g_strdup_printf ("oauth_nonce=%s", nonce); + params_all[1] = g_strdup_printf ("oauth_timestamp=%s", timestamp); + params_all[2] = g_strdup_printf ("oauth_consumer_key=%s", + consumer_key); + params_all[3] = g_strdup_printf ("oauth_signature_method=%s", + FLICKR_OAUTH_SIGNATURE_METHOD); + params_all[4] = g_strdup_printf ("oauth_version=%s", + FLICKR_OAUTH_VERSION); + params_all[5] = g_strdup_printf ("oauth_token=%s", oauth_token); + + /* copy user parameters to the params_all */ + for (i = 0; i < params_no; i++) + params_all[7 + i - 1] = g_strdup (params[i]); + + g_free (nonce); + g_free (timestamp); + + signature = flickroauth_get_signature (consumer_secret, + oauth_token_secret, + FLICKR_API_URL, params_all, + params_all_no - 1); + + params_all[params_all_no - 1] = g_strdup_printf ("oauth_signature=%s", + signature); + g_free (signature); + + params_string = oauth_serialize_url (params_all_no, 0, params_all); + + free_params (params_all, params_all_no); + g_free (params_all); + + url = g_strdup_printf ("%s?%s", FLICKR_API_URL, params_string); + + return url; +} + +inline gchar * +flickroauth_authorization_url (const gchar *oauth_token, + const gchar *perms) +{ + gchar *url; + if (perms == NULL) + url = g_strdup_printf ("%s?oauth_token=%s", FLICKR_OAUTH_AUTHPOINT, + oauth_token); + else + url = g_strdup_printf ("%s?oauth_token=%s&perms=%s", + FLICKR_OAUTH_AUTHPOINT, + oauth_token, perms); + + return url; +} + +/* ----------------------- private functions ----------------------- */ + +inline static gchar * +get_timestamp (void) +{ + GTimeVal tm; + g_get_current_time (&tm); + + return g_strdup_printf ("%lu", tm.tv_sec); +} + +static void +free_params (gchar **params, gint params_no) +{ + gint i; + for (i = 0; i < params_no; i++) + g_free (params[i]); +} diff --git a/src/flickr/flickr-oauth.h b/src/flickr/flickr-oauth.h new file mode 100644 index 0000000..772c9bd --- /dev/null +++ b/src/flickr/flickr-oauth.h @@ -0,0 +1,57 @@ +/* + * Authors: Marek Chalupa + * + * 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 + +#ifndef FLICKR_OAUTH_H +#define FLICKR_OAUTH_H + +#define FLICKR_API_URL "http://api.flickr.com/services/rest" +#define FLICKR_OAUTH_AUTHPOINT "http://www.flickr.com/services/oauth/authorize" + +/* OAuth definitions */ +#define FLICKR_OAUTH_SIGNATURE_METHOD "HMAC-SHA1" +#define FLICKR_OAUTH_VERSION "1.0" +#define FLICKR_OAUTH_CALLBACK "oob" +#define FLICKR_OAUTH_HTTP_METHOD "GET" + + +/* public API */ + +gchar * +flickroauth_get_signature (const gchar *consumer_secret, + const gchar *token_secret, + const gchar *url, + gchar **params, + gint params_no); + +gchar * +flickroauth_create_api_url (const gchar *consumer_key, + const gchar *consumer_secret, + const gchar *oauth_token, + const gchar *oauth_token_secret, + gchar **params, + const guint params_no); + +gchar * +flickroauth_authorization_url (const gchar *oauth_token, const gchar *perms); + +#endif /* FLICKR_OAUTH_H */ + diff --git a/src/flickr/gflickr.c b/src/flickr/gflickr.c index c7b1b0b..91ad7c3 100644 --- a/src/flickr/gflickr.c +++ b/src/flickr/gflickr.c @@ -1,4 +1,5 @@ #include "gflickr.h" +#include "flickr-oauth.h" #include "grl-flickr.h" /* log domain */ #include @@ -25,8 +26,6 @@ #define FLICKR_PHOTO_LARGEST_URL \ "http://farm%s.static.flickr.com/%s/%s_%s_b.jpg" -#define FLICKR_ENDPOINT "http://api.flickr.com/services/rest/?" -#define FLICKR_AUTHPOINT "http://flickr.com/services/auth/?" #define FLICKR_PHOTOS_SEARCH_METHOD "flickr.photos.search" #define FLICKR_PHOTOS_GETINFO_METHOD "flickr.photos.getInfo" @@ -34,96 +33,8 @@ #define FLICKR_PHOTOSETS_GETLIST_METHOD "flickr.photosets.getList" #define FLICKR_PHOTOSETS_GETPHOTOS_METHOD "flickr.photosets.getPhotos" #define FLICKR_TAGS_GETHOTLIST_METHOD "flickr.tags.getHotList" -#define FLICKR_AUTH_GETFROB_METHOD "flickr.auth.getFrob" -#define FLICKR_AUTH_GETTOKEN_METHOD "flickr.auth.getToken" -#define FLICKR_AUTH_CHECKTOKEN_METHOD "flickr.auth.checkToken" - -#define FLICKR_PHOTOS_SEARCH \ - FLICKR_ENDPOINT \ - "api_key=%s" \ - "&api_sig=%s" \ - "&method=" FLICKR_PHOTOS_SEARCH_METHOD \ - "&user_id=%s" \ - "&extras=date_taken,owner_name,url_o,url_t" \ - "&per_page=%d" \ - "&page=%d" \ - "&media=photos" \ - "&tags=%s" \ - "&text=%s" \ - "%s" - -#define FLICKR_PHOTOS_GETRECENT \ - FLICKR_ENDPOINT \ - "api_key=%s" \ - "&api_sig=%s" \ - "&method=" FLICKR_PHOTOS_GETRECENT_METHOD \ - "&extras=date_taken,owner_name,url_o,url_t" \ - "&per_page=%d" \ - "&page=%d" \ - "%s" - -#define FLICKR_PHOTOSETS_GETLIST \ - FLICKR_ENDPOINT \ - "api_key=%s" \ - "&api_sig=%s" \ - "&method=" FLICKR_PHOTOSETS_GETLIST_METHOD \ - "%s" \ - "%s" - -#define FLICKR_PHOTOSETS_GETPHOTOS \ - FLICKR_ENDPOINT \ - "api_key=%s" \ - "&api_sig=%s" \ - "&method=" FLICKR_PHOTOSETS_GETPHOTOS_METHOD \ - "&photoset_id=%s" \ - "&extras=date_taken,owner_name,url_o,url_t" \ - "&per_page=%d" \ - "&page=%d" \ - "&media=photos" \ - "%s" - -#define FLICKR_TAGS_GETHOTLIST \ - FLICKR_ENDPOINT \ - "api_key=%s" \ - "&api_sig=%s" \ - "&method=" FLICKR_TAGS_GETHOTLIST_METHOD \ - "&count=%d" \ - "%s" - -#define FLICKR_PHOTOS_GETINFO \ - FLICKR_ENDPOINT \ - "api_key=%s" \ - "&api_sig=%s" \ - "&method=" FLICKR_PHOTOS_GETINFO_METHOD \ - "&photo_id=%ld" \ - "%s" - -#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_CHECKTOKEN \ - FLICKR_ENDPOINT \ - "api_key=%s" \ - "&api_sig=%s" \ - "&method=" FLICKR_AUTH_CHECKTOKEN_METHOD \ - "&auth_token=%s" - -#define FLICKR_AUTH_LOGINLINK \ - FLICKR_AUTHPOINT \ - "api_key=%s" \ - "&api_sig=%s" \ - "&frob=%s" \ - "&perms=%s" +#define FLICKR_OAUTH_CHECKTOKEN_METHOD "flickr.auth.oauth.checkToken" + typedef void (*ParseXML) (const gchar *xml_result, gpointer user_data); @@ -136,9 +47,11 @@ typedef struct { } GFlickrData; struct _GFlickrPrivate { - gchar *api_key; - gchar *auth_secret; - gchar *auth_token; + gchar *consumer_key; + gchar *consumer_secret; + gchar *oauth_token; + gchar *oauth_token_secret; + gint per_page; GrlNetWc *wc; @@ -163,6 +76,12 @@ static void g_flickr_init (GFlickr *f) { f->priv = G_FLICKR_GET_PRIVATE (f); + + f->priv->consumer_key = NULL; + f->priv->consumer_secret = NULL; + f->priv->oauth_token = NULL; + f->priv->oauth_token_secret = NULL; + f->priv->per_page = 100; } @@ -170,9 +89,10 @@ static void g_flickr_finalize (GObject *object) { GFlickr *f = G_FLICKR (object); - g_free (f->priv->api_key); - g_free (f->priv->auth_token); - g_free (f->priv->auth_secret); + g_free (f->priv->consumer_key); + g_free (f->priv->consumer_secret); + g_free (f->priv->oauth_token); + g_free (f->priv->oauth_token_secret); if (f->priv->wc) g_object_unref (f->priv->wc); @@ -181,100 +101,47 @@ g_flickr_finalize (GObject *object) } GFlickr * -g_flickr_new (const gchar *api_key, const gchar *auth_secret, const gchar *auth_token) +g_flickr_new (const gchar *consumer_key, + const gchar *consumer_secret, + const gchar *oauth_token, + const gchar *oauth_token_secret) { - g_return_val_if_fail (api_key && auth_secret, NULL); + g_return_val_if_fail (consumer_key && consumer_secret, NULL); GFlickr *f = g_object_new (G_FLICKR_TYPE, NULL); - f->priv->api_key = g_strdup (api_key); - f->priv->auth_secret = g_strdup (auth_secret); - f->priv->auth_token = g_strdup (auth_token); + f->priv->consumer_key = g_strdup (consumer_key); + f->priv->consumer_secret = g_strdup (consumer_secret); + + if (oauth_token != NULL) { + if (oauth_token_secret == NULL) + GRL_WARNING ("No token secret given."); + + f->priv->oauth_token = g_strdup (oauth_token); + f->priv->oauth_token_secret = g_strdup (oauth_token_secret); + + } return f; } /* -------------------- PRIVATE API -------------------- */ -static gchar * -get_api_sig (const gchar *secret, ...) +inline static gchar * +create_url (GFlickr *f, gchar **params, const guint params_no) { - 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; + return flickroauth_create_api_url (f->priv->consumer_key, + f->priv->consumer_secret, + f->priv->oauth_token, + f->priv->oauth_token_secret, + params, params_no); } -static gchar * -get_xpath_element (const gchar *content, - const gchar *xpath_element) +inline static void +free_params (gchar **params, gint no) { - 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; + gint i = 0; + for (; i < no; i++) + g_free (params[i]); } static gboolean @@ -637,34 +504,16 @@ g_flickr_photos_getInfo (GFlickr *f, GFlickrHashTableCb callback, gpointer user_data) { - gchar *auth; - g_return_if_fail (G_IS_FLICKR (f)); - gchar *str_photo_id = g_strdup_printf ("%ld", photo_id); - gchar *api_sig = get_api_sig (f->priv->auth_secret, - "api_key", f->priv->api_key, - "method", FLICKR_PHOTOS_GETINFO_METHOD, - "photo_id", str_photo_id, - f->priv->auth_token? "auth_token": "", - f->priv->auth_token? f->priv->auth_token: "", - NULL); - g_free (str_photo_id); + gchar *params[2]; - /* Build the request */ - if (f->priv->auth_token) { - auth = g_strdup_printf ("&auth_token=%s", f->priv->auth_token); - } else { - auth = g_strdup (""); - } + params[0] = g_strdup_printf ("photo_id=%ld", photo_id); + params[1] = g_strdup_printf ("method=%s", FLICKR_PHOTOS_GETINFO_METHOD); - gchar *request = g_strdup_printf (FLICKR_PHOTOS_GETINFO, - f->priv->api_key, - api_sig, - photo_id, - auth); - g_free (api_sig); - g_free (auth); + gchar *request = create_url (f, params, 2); + + free_params (params, 2); GFlickrData *gfd = g_slice_new (GFlickrData); gfd->flickr = g_object_ref (f); @@ -685,59 +534,37 @@ g_flickr_photos_search (GFlickr *f, GFlickrListCb callback, gpointer user_data) { - gchar *auth; g_return_if_fail (G_IS_FLICKR (f)); - if (!user_id) { + if (user_id == NULL) { user_id = ""; } - if (!text) { + if (text == NULL) { text = ""; } - if (!tags) { + if (tags == NULL) { tags = ""; } - gchar *strpage = g_strdup_printf ("%d", page); - gchar *strperpage = g_strdup_printf ("%d", f->priv->per_page); - - gchar *api_sig = - get_api_sig (f->priv->auth_secret, - "api_key", f->priv->api_key, - "extras", "date_taken,owner_name,url_o,url_t", - "media", "photos", - "method", FLICKR_PHOTOS_SEARCH_METHOD, - "user_id", user_id, - "page", strpage, - "per_page", strperpage, - "tags", tags, - "text", text, - f->priv->auth_token? "auth_token": "", - f->priv->auth_token? f->priv->auth_token: "", - NULL); - g_free (strpage); - g_free (strperpage); + gchar *params[8]; + + params[0] = g_strdup ("extras=date_taken,owner_name,url_0,url_t"); + params[1] = g_strdup ("media=photos"); + params[2] = g_strdup_printf ("user_id=%s", user_id); + params[3] = g_strdup_printf ("page=%d", page); + params[4] = g_strdup_printf ("per_page=%d", f->priv->per_page); + params[5] = g_strdup_printf ("tags=%s", tags); + params[6] = g_strdup_printf ("text=%s", text); + params[7] = g_strdup_printf ("method=%s", FLICKR_PHOTOS_SEARCH_METHOD); + /* Build the request */ - if (f->priv->auth_token) { - auth = g_strdup_printf ("&auth_token=%s", f->priv->auth_token); - } else { - auth = g_strdup (""); - } - gchar *request = g_strdup_printf (FLICKR_PHOTOS_SEARCH, - f->priv->api_key, - api_sig, - user_id, - f->priv->per_page, - page, - tags, - text, - auth); - g_free (api_sig); - g_free (auth); + gchar *request = create_url (f, params, 8); + + free_params (params, 8); GFlickrData *gfd = g_slice_new (GFlickrData); gfd->flickr = g_object_ref (f); @@ -755,41 +582,19 @@ g_flickr_photos_getRecent (GFlickr *f, GFlickrListCb callback, gpointer user_data) { - gchar *auth; g_return_if_fail (G_IS_FLICKR (f)); - gchar *strpage = g_strdup_printf ("%d", page); - gchar *strperpage = g_strdup_printf ("%d", f->priv->per_page); - - gchar *api_sig = - get_api_sig (f->priv->auth_secret, - "api_key", f->priv->api_key, - "extras", "date_taken,owner_name,url_o,url_t", - "media", "photos", - "method", FLICKR_PHOTOS_GETRECENT_METHOD, - "page", strpage, - "per_page", strperpage, - f->priv->auth_token? "auth_token": "", - f->priv->auth_token? f->priv->auth_token: "", - NULL); - g_free (strpage); - g_free (strperpage); + gchar *params[5]; - /* Build the request */ - if (f->priv->auth_token) { - auth = g_strdup_printf ("&auth_token=%s", f->priv->auth_token); - } else { - auth = g_strdup (""); - } + params[0] = g_strdup ("extras=date_taken,owner_name,url_o,url_t"); + params[1] = g_strdup ("media=photos"); + params[2] = g_strdup_printf ("method=%s", FLICKR_PHOTOS_GETRECENT_METHOD); + params[3] = g_strdup_printf ("page=%d", page); + params[4] = g_strdup_printf ("per_page=%d", f->priv->per_page); - gchar *request = g_strdup_printf (FLICKR_PHOTOS_GETRECENT, - f->priv->api_key, - api_sig, - f->priv->per_page, - page, - auth); - g_free (api_sig); - g_free (auth); + gchar *request = create_url (f, params, 5); + + free_params (params, 5); GFlickrData *gfd = g_slice_new (GFlickrData); gfd->flickr = g_object_ref (f); @@ -894,34 +699,16 @@ g_flickr_tags_getHotList (GFlickr *f, GFlickrListCb callback, gpointer user_data) { - gchar *auth; - g_return_if_fail (G_IS_FLICKR (f)); - gchar *strcount = g_strdup_printf ("%d", count); + gchar *params[2]; - gchar *api_sig = get_api_sig (f->priv->auth_secret, - "api_key", f->priv->api_key, - "count", strcount, - "method", FLICKR_TAGS_GETHOTLIST_METHOD, - f->priv->auth_token? "auth_token": "", - f->priv->auth_token? f->priv->auth_token: "", - NULL); - g_free (strcount); + params[0] = g_strdup_printf ("count=%d", count); + params[1] = g_strdup_printf ("method=%s", FLICKR_TAGS_GETHOTLIST_METHOD); - /* Build the request */ - if (f->priv->auth_token) { - auth = g_strdup_printf ("&auth_token=%s", f->priv->auth_token); - } else { - auth = g_strdup (""); - } - gchar *request = g_strdup_printf (FLICKR_TAGS_GETHOTLIST, - f->priv->api_key, - api_sig, - count, - auth); - g_free (api_sig); - g_free (auth); + gchar *request = create_url (f, params, 2); + + free_params (params, 2); GFlickrData *gfd = g_slice_new (GFlickrData); gfd->flickr = g_object_ref (f); @@ -939,40 +726,19 @@ g_flickr_photosets_getList (GFlickr *f, GFlickrListCb callback, gpointer user_data) { - gchar *user; - gchar *auth; - - gchar *api_sig = get_api_sig (f->priv->auth_secret, - "api_key", f->priv->api_key, - "method", FLICKR_PHOTOSETS_GETLIST_METHOD, - user_id? "user_id": "", - user_id? user_id: "", - f->priv->auth_token? "auth_token": "", - f->priv->auth_token? f->priv->auth_token: "", - NULL); + /* Either we insert user_id or not */ + gint params_no = (user_id == NULL) ? 1 : 2; + + gchar *params[2]; - /* Build the request */ - if (user_id) { - user = g_strdup_printf ("&user_id=%s", user_id); - } else { - user = g_strdup (""); - } + params[0] = g_strdup_printf ("method=%s", FLICKR_PHOTOSETS_GETLIST_METHOD); + + if (user_id != NULL) + params[1] = g_strdup_printf ("user_id=%s", user_id); - if (f->priv->auth_token) { - auth = g_strdup_printf ("&auth_token=%s", f->priv->auth_token); - } else { - auth = g_strdup (""); - } + gchar *request = create_url (f, params, params_no); - gchar *request = g_strdup_printf (FLICKR_PHOTOSETS_GETLIST, - f->priv->api_key, - api_sig, - user, - auth); - - g_free (api_sig); - g_free (user); - g_free (auth); + free_params (params, params_no); GFlickrData *gfd = g_slice_new (GFlickrData); gfd->flickr = g_object_ref (f); @@ -991,46 +757,21 @@ g_flickr_photosets_getPhotos (GFlickr *f, GFlickrListCb callback, gpointer user_data) { - gchar *auth; - g_return_if_fail (G_IS_FLICKR (f)); g_return_if_fail (photoset_id); - gchar *strpage = g_strdup_printf ("%d", page); - gchar *strperpage = g_strdup_printf ("%d", f->priv->per_page); - - gchar *api_sig = - get_api_sig (f->priv->auth_secret, - "api_key", f->priv->api_key, - "photoset_id", photoset_id, - "extras", "date_taken,owner_name,url_o,url_t", - "media", "photos", - "method", FLICKR_PHOTOSETS_GETPHOTOS_METHOD, - "page", strpage, - "per_page", strperpage, - f->priv->auth_token? "auth_token": "", - f->priv->auth_token? f->priv->auth_token: "", - NULL); - - g_free (strpage); - g_free (strperpage); + gchar *params[6]; - /* Build the request */ - if (f->priv->auth_token) { - auth = g_strdup_printf ("&auth_token=%s", f->priv->auth_token); - } else { - auth = g_strdup (""); - } + params[0] = g_strdup_printf ("photoset_id=%s", photoset_id); + params[1] = g_strdup ("extras=date_taken,owner_name,url_o,url_t,media"); + params[2] = g_strdup ("media=photos"); + params[3] = g_strdup_printf ("page=%d", page); + params[4] = g_strdup_printf ("per_page=%d", f->priv->per_page); + params[5] = g_strdup_printf ("method=%s", FLICKR_PHOTOSETS_GETPHOTOS_METHOD); - gchar *request = g_strdup_printf (FLICKR_PHOTOSETS_GETPHOTOS, - f->priv->api_key, - api_sig, - photoset_id, - f->priv->per_page, - page, - auth); - g_free (api_sig); - g_free (auth); + gchar *request = create_url (f, params, 6); + + free_params (params, 6); GFlickrData *gfd = g_slice_new (GFlickrData); gfd->flickr = g_object_ref (f); @@ -1042,123 +783,7 @@ g_flickr_photosets_getPhotos (GFlickr *f, g_free (request); } -gchar * -g_flickr_auth_getFrob (GFlickr *f) -{ - gchar *api_sig; - gchar *url; - GVfs *vfs; - GFile *uri; - gchar *contents; - GError *error = NULL; - gchar *frob = NULL; - - g_return_val_if_fail (G_IS_FLICKR (f), NULL); - - api_sig = get_api_sig (f->priv->auth_secret, - "api_key", f->priv->api_key, - "method", "flickr.auth.getFrob", - NULL); - - /* Build url */ - url = g_strdup_printf (FLICKR_AUTH_GETFROB, - f->priv->api_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)) { - GRL_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) { - GRL_WARNING ("Can not get Flickr's frob"); - } - - return frob; -} - -gchar * -g_flickr_auth_loginLink (GFlickr *f, - const gchar *frob, - const gchar *perm) -{ - gchar *api_sig; - gchar *url; - - g_return_val_if_fail (G_IS_FLICKR (f), NULL); - g_return_val_if_fail (frob, NULL); - g_return_val_if_fail (perm, NULL); - - api_sig = get_api_sig (f->priv->auth_secret, - "api_key", f->priv->api_key, - "frob", frob, - "perms", perm, - NULL); - - url = g_strdup_printf (FLICKR_AUTH_LOGINLINK, - f->priv->api_key, - api_sig, - frob, - perm); - g_free (api_sig); - - return url; -} - -gchar * -g_flickr_auth_getToken (GFlickr *f, - const gchar *frob) -{ - GError *error = NULL; - GFile *uri; - GVfs *vfs; - gchar *api_sig; - gchar *contents; - gchar *token; - gchar *url; - - g_return_val_if_fail (G_IS_FLICKR (f), NULL); - g_return_val_if_fail (frob, NULL); - - api_sig = get_api_sig (f->priv->auth_secret, - "method", "flickr.auth.getToken", - "api_key", f->priv->api_key, - "frob", frob, - NULL); - - /* Build url */ - url = g_strdup_printf (FLICKR_AUTH_GETTOKEN, - f->priv->api_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)) { - GRL_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) { - GRL_WARNING ("Can not get Flickr's token"); - } - - return token; -} +/* ---------- Helper authorization functions ---------- */ void g_flickr_auth_checkToken (GFlickr *f, @@ -1166,25 +791,18 @@ g_flickr_auth_checkToken (GFlickr *f, GFlickrHashTableCb callback, gpointer user_data) { - gchar *api_sig; gchar *request; + gchar *params[1]; g_return_if_fail (G_IS_FLICKR (f)); g_return_if_fail (token); g_return_if_fail (callback); - api_sig = get_api_sig (f->priv->auth_secret, - "method", FLICKR_AUTH_CHECKTOKEN_METHOD, - "api_key", f->priv->api_key, - "auth_token", token, - NULL); - - /* Build request */ - request = g_strdup_printf (FLICKR_AUTH_CHECKTOKEN, - f->priv->api_key, - api_sig, - token); - g_free (api_sig); + params[0] = g_strdup_printf ("method=%s", FLICKR_OAUTH_CHECKTOKEN_METHOD); + + request = create_url (f, params, 1); + + free_params (params, 1); GFlickrData *gfd = g_slice_new (GFlickrData); gfd->flickr = g_object_ref (f); diff --git a/src/flickr/gflickr.h b/src/flickr/gflickr.h index 7ce5413..8984648 100644 --- a/src/flickr/gflickr.h +++ b/src/flickr/gflickr.h @@ -25,6 +25,7 @@ #ifndef _G_FLICKR_H_ #define _G_FLICKR_H_ +#include "flickr-oauth.h" #include #define G_FLICKR_TYPE \ @@ -81,7 +82,10 @@ typedef void (*GFlickrCheckToken) (GFlickr *f, GHashTable *tokeninfo, gpointer u GType g_flickr_get_type (void); -GFlickr *g_flickr_new (const gchar *api_key, const gchar *auth_secret, const gchar *auth_token); +GFlickr *g_flickr_new (const gchar *consumer_key, + const gchar *consumer_secret, + const gchar *oauth_token, + const gchar *oauth_token_secret); void g_flickr_set_per_page (GFlickr *f, gint per_page); @@ -134,17 +138,6 @@ g_flickr_photosets_getPhotos (GFlickr *f, GFlickrListCb callback, gpointer user_data); -gchar * -g_flickr_auth_getFrob (GFlickr *f); - -gchar * -g_flickr_auth_loginLink (GFlickr *f, - const gchar *frob, - const gchar *perm); - -gchar * -g_flickr_auth_getToken (GFlickr *f, - const gchar *frob); void g_flickr_auth_checkToken (GFlickr *f, @@ -154,4 +147,5 @@ g_flickr_auth_checkToken (GFlickr *f, GDateTime * g_flickr_parse_date (const gchar *date); + #endif /* _G_FLICKR_H_ */ diff --git a/src/flickr/grl-flickr.c b/src/flickr/grl-flickr.c index baa23d8..c342416 100644 --- a/src/flickr/grl-flickr.c +++ b/src/flickr/grl-flickr.c @@ -88,7 +88,8 @@ static GrlFlickrSource *grl_flickr_source_public_new (const gchar *flickr_api_ke static void grl_flickr_source_personal_new (GrlPlugin *plugin, const gchar *flickr_api_key, const gchar *flickr_secret, - const gchar *flickr_token); + const gchar *flickr_token, + const gchar *token_secret); static void grl_flickr_source_finalize (GObject *object); @@ -118,13 +119,13 @@ grl_flickr_plugin_init (GrlRegistry *registry, gchar *flickr_key; gchar *flickr_secret; gchar *flickr_token; + gchar *flickr_token_secret; + GrlConfig *config; gboolean public_source_created = FALSE; GRL_LOG_DOMAIN_INIT (flickr_log_domain, "flickr"); - GRL_DEBUG ("flickr_plugin_init"); - if (!configs) { GRL_INFO ("Configuration not provided! Plugin not loaded"); return FALSE; @@ -135,20 +136,23 @@ grl_flickr_plugin_init (GrlRegistry *registry, flickr_key = grl_config_get_api_key (config); flickr_token = grl_config_get_api_token (config); + flickr_token_secret = grl_config_get_api_token_secret (config); flickr_secret = grl_config_get_api_secret (config); if (!flickr_key || !flickr_secret) { GRL_INFO ("Required API key or secret configuration not provdied. " " Plugin not loaded"); - } else if (flickr_token) { + } else if (flickr_token && flickr_secret) { grl_flickr_source_personal_new (plugin, flickr_key, flickr_secret, - flickr_token); + flickr_token, + flickr_token_secret); } else if (public_source_created) { GRL_WARNING ("Only one public source can be created"); } else { - GrlFlickrSource *source = grl_flickr_source_public_new (flickr_key, flickr_secret); + GrlFlickrSource *source = grl_flickr_source_public_new (flickr_key, + flickr_secret); public_source_created = TRUE; grl_registry_register_source (registry, plugin, @@ -191,7 +195,8 @@ grl_flickr_source_public_new (const gchar *flickr_api_key, "source-desc", PUBLIC_SOURCE_DESC, "supported-media", GRL_MEDIA_TYPE_IMAGE, NULL); - source->priv->flickr = g_flickr_new (flickr_api_key, flickr_secret, NULL); + source->priv->flickr = g_flickr_new (flickr_api_key, flickr_secret, + NULL, NULL); return source; } @@ -200,12 +205,16 @@ static void grl_flickr_source_personal_new (GrlPlugin *plugin, const gchar *flickr_api_key, const gchar *flickr_secret, - const gchar *flickr_token) + const gchar *flickr_token, + const gchar *flickr_token_secret) { GFlickr *f; - f = g_flickr_new (flickr_api_key, flickr_secret, flickr_token); - g_flickr_auth_checkToken (f, flickr_token, token_info_cb, (gpointer) plugin); + f = g_flickr_new (flickr_api_key, flickr_secret, + flickr_token, flickr_token_secret); + + g_flickr_auth_checkToken (f, flickr_token, token_info_cb, + (gpointer) plugin); } static void @@ -383,7 +392,8 @@ getInfo_cb (GFlickr *f, GHashTable *photo, gpointer user_data) update_media (rs->media, photo); } - rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL); + rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, + NULL); } static void @@ -514,7 +524,9 @@ photosetsphotos_cb (GFlickr *f, GList *photolist, gpointer user_data) while (photolist && od->count) { media_type = g_hash_table_lookup (photolist->data, "photo_media"); - if (strcmp (media_type, "photo") == 0) { + if (media_type == NULL) { + media = grl_media_new (); + } else if (strcmp (media_type, "photo") == 0) { media = grl_media_image_new (); } else { media = grl_media_video_new (); @@ -535,7 +547,8 @@ photosetsphotos_cb (GFlickr *f, GList *photolist, gpointer user_data) if (od->count) { od->offset = 0; od->page++; - g_flickr_photosets_getPhotos (f, od->text, od->page, photosetsphotos_cb, od); + g_flickr_photosets_getPhotos (f, od->text, od->page, + photosetsphotos_cb, od); } else { g_slice_free (OperationData, od); } @@ -549,7 +562,8 @@ gettags_cb (GFlickr *f, GList *taglist, gpointer user_data) gint count; /* Go to offset element */ - taglist = g_list_nth (taglist, grl_operation_options_get_skip (bs->options)); + taglist = g_list_nth (taglist, + grl_operation_options_get_skip (bs->options)); /* No more elements can be sent */ if (!taglist) { @@ -614,7 +628,9 @@ grl_flickr_source_public_browse (GrlSource *source, if (!container_id) { /* Get hot tags list. List is limited up to HOTLIST_MAX tags */ if (skip >= HOTLIST_MAX) { - bs->callback (bs->source, bs->operation_id, NULL, 0, bs->user_data, NULL); + bs->callback (bs->source, bs->operation_id, + NULL, 0, + bs->user_data, NULL); } else { request_size = CLAMP (skip + count, 1, HOTLIST_MAX); g_flickr_tags_getHotList (f, request_size, gettags_cb, bs); @@ -683,7 +699,8 @@ grl_flickr_source_personal_browse (GrlSource *source, od->count = count; od->operation_id = bs->operation_id; - g_flickr_photosets_getPhotos (f, container_id, od->page, photosetsphotos_cb, od); + g_flickr_photosets_getPhotos (f, container_id, od->page, + photosetsphotos_cb, od); } } @@ -705,7 +722,8 @@ grl_flickr_source_resolve (GrlSource *source, const gchar *id; if (!rs->media || (id = grl_media_get_id (rs->media)) == NULL) { - rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL); + rs->callback (rs->source, rs->operation_id, + rs->media, rs->user_data, NULL); return; } -- 1.8.1.4