From 297686ecdcb4b84ed840e921247a2e82addad5b0 Mon Sep 17 00:00:00 2001 From: Marek Chalupa Date: Wed, 3 Apr 2013 09:07:45 +0200 Subject: [PATCH] Grilo modified to be compatible with new flickr plugin Two new functions added to grl-config.[ch] which are used by flickr plugin - grl_config_get/set_api_token_secret() (needed by oauth authentication proccess). Also grilo-test-ui was modificated to use new flickr plugin: flickr-auth.[ch] was replaced by their oauth alternatives and main.c was rewritten to use them. Into authenticate flickr popup window was added text entry to enter the verifier given by flickr. --- configure.ac | 2 + src/data/grl-config.c | 35 ++++ src/data/grl-config.h | 21 ++- tools/grilo-test-ui/Makefile.am | 6 +- tools/grilo-test-ui/flickr-auth.c | 257 ------------------------------ tools/grilo-test-ui/flickr-auth.h | 43 ----- tools/grilo-test-ui/flickr-oauth.c | 318 +++++++++++++++++++++++++++++++++++++ tools/grilo-test-ui/flickr-oauth.h | 91 +++++++++++ tools/grilo-test-ui/main.c | 44 +++-- 9 files changed, 494 insertions(+), 323 deletions(-) delete mode 100644 tools/grilo-test-ui/flickr-auth.c delete mode 100644 tools/grilo-test-ui/flickr-auth.h create mode 100644 tools/grilo-test-ui/flickr-oauth.c create mode 100644 tools/grilo-test-ui/flickr-oauth.h diff --git a/configure.ac b/configure.ac index d19d041..cf32c78 100644 --- a/configure.ac +++ b/configure.ac @@ -120,6 +120,7 @@ PKG_CHECK_MODULES(DEPS, glib-2.0 >= 2.29.10 \ gio-2.0 \ libxml-2.0) + GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0` GLIB_MKENUMS=`pkg-config --variable=glib_mkenums glib-2.0` AC_SUBST(GLIB_GENMARSHAL) @@ -150,6 +151,7 @@ AC_ARG_ENABLE(test-ui, ]) AM_CONDITIONAL(BUILD_GRILO_TEST_UI, test "x$HAVE_GTK" = "xyes") +PKG_CHECK_MODULES(OAUTH, oauth) # ---------------------------------------------------------- # NET LIBRARY diff --git a/src/data/grl-config.c b/src/data/grl-config.c index 0d68f01..fb981af 100644 --- a/src/data/grl-config.c +++ b/src/data/grl-config.c @@ -446,6 +446,25 @@ grl_config_set_api_token (GrlConfig *config, const gchar *token) } /** + * grl_config_set_api_token_secret: + * @config: the config instance + * @secret: the API token + * + * Set the webservice API token secret in the configuration + * (Needed by OAuth) + * + * Since: 0.2.5 + */ +void +grl_config_set_api_token_secret (GrlConfig *config, const gchar *secret) +{ + grl_config_set_string (GRL_CONFIG (config), + GRL_CONFIG_KEY_APITOKEN_SECRET, + secret); +} + + +/** * grl_config_set_api_secret: * @config: the config instance * @secret: the webservice passphrase @@ -570,6 +589,22 @@ grl_config_get_api_token (GrlConfig *config) } /** + * grl_config_get_api_token_secret: + * @config: the config instance + * + * Returns: the webservice API token secret + * (Needed by OAuth) + * + * Since: 0.2.5 + */ +gchar * +grl_config_get_api_token_secret (GrlConfig *config) +{ + return grl_config_get_string (GRL_CONFIG (config), + GRL_CONFIG_KEY_APITOKEN_SECRET); +} + +/** * grl_config_get_api_secret: * @config: the config instance * diff --git a/src/data/grl-config.h b/src/data/grl-config.h index 020521c..df5536c 100644 --- a/src/data/grl-config.h +++ b/src/data/grl-config.h @@ -63,14 +63,15 @@ G_BEGIN_DECLS GRL_TYPE_CONFIG, \ GrlConfigClass)) -#define GRL_CONFIG_KEY_PLUGIN "target-plugin" -#define GRL_CONFIG_KEY_SOURCE "target-source" -#define GRL_CONFIG_KEY_APIKEY "api-key" -#define GRL_CONFIG_KEY_APIKEY_BLOB "api-key-blob" -#define GRL_CONFIG_KEY_APITOKEN "api-token" -#define GRL_CONFIG_KEY_APISECRET "api-secret" -#define GRL_CONFIG_KEY_USERNAME "username" -#define GRL_CONFIG_KEY_PASSWORD "password" +#define GRL_CONFIG_KEY_PLUGIN "target-plugin" +#define GRL_CONFIG_KEY_SOURCE "target-source" +#define GRL_CONFIG_KEY_APIKEY "api-key" +#define GRL_CONFIG_KEY_APIKEY_BLOB "api-key-blob" +#define GRL_CONFIG_KEY_APITOKEN "api-token" +#define GRL_CONFIG_KEY_APITOKEN_SECRET "api-token-secret" +#define GRL_CONFIG_KEY_APISECRET "api-secret" +#define GRL_CONFIG_KEY_USERNAME "username" +#define GRL_CONFIG_KEY_PASSWORD "password" typedef struct _GrlConfig GrlConfig; typedef struct _GrlConfigPrivate GrlConfigPrivate; @@ -109,6 +110,8 @@ void grl_config_set_api_key_blob (GrlConfig *config, const guint8 *blob, gsize s void grl_config_set_api_token (GrlConfig *config, const gchar *token); +void grl_config_set_api_token_secret (GrlConfig *config, const gchar *secret); + void grl_config_set_api_secret (GrlConfig *config, const gchar *secret); void grl_config_set_username (GrlConfig *config, const gchar *username); @@ -125,6 +128,8 @@ guint8 *grl_config_get_api_key_blob (GrlConfig *config, gsize *size); gchar *grl_config_get_api_token (GrlConfig *config); +gchar *grl_config_get_api_token_secret (GrlConfig *config); + gchar *grl_config_get_api_secret (GrlConfig *config); gchar *grl_config_get_username (GrlConfig *config); diff --git a/tools/grilo-test-ui/Makefile.am b/tools/grilo-test-ui/Makefile.am index 35ca65a..f0bd832 100644 --- a/tools/grilo-test-ui/Makefile.am +++ b/tools/grilo-test-ui/Makefile.am @@ -11,12 +11,13 @@ bin_PROGRAMS = grilo-test-ui- GRL_MAJORMINOR@ grilo_test_ui_ GRL_MAJORMINOR@_SOURCES = \ main.c \ - flickr-auth.h \ - flickr-auth.c + flickr-oauth.h \ + flickr-oauth.c grilo_test_ui_ GRL_MAJORMINOR@_CFLAGS = \ -DPREFIX=$(prefix) \ $(GTU_CFLAGS) \ + $(OAUTH_CFLAGS) \ $(GRL_FLICKR_CFLAGS) \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/data @@ -24,6 +25,7 @@ grilo_test_ui_ GRL_MAJORMINOR@_CFLAGS = \ grilo_test_ui_ GRL_MAJORMINOR@_LDADD = \ $(DEPS_LIBS) \ $(GTU_LIBS) \ + $(OAUTH_LIBS) \ $(GRL_FLICKR_LIBS) \ $(top_builddir)/src/lib GRL_NAME@.la diff --git a/tools/grilo-test-ui/flickr-auth.c b/tools/grilo-test-ui/flickr-auth.c deleted file mode 100644 index 16b8af6..0000000 --- a/tools/grilo-test-ui/flickr-auth.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (C) 2010 Igalia S.L. - * - * Contact: Iago Toral Quiroga - * - * 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 -#include -#include - -#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 deleted file mode 100644 index 0fd663e..0000000 --- a/tools/grilo-test-ui/flickr-auth.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2010 Igalia S.L. - * - * Contact: Iago Toral Quiroga - * - * 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 - -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/flickr-oauth.c b/tools/grilo-test-ui/flickr-oauth.c new file mode 100644 index 0000000..25701cf --- /dev/null +++ b/tools/grilo-test-ui/flickr-oauth.c @@ -0,0 +1,318 @@ +#include "flickr-oauth.h" + +#include +#include + +#include +#include + +/* ---------- private functions declarations ---------- */ + +static gchar * +parse_request_token (const gchar *string, gchar **secret); + +static gchar * +parse_access_token (const gchar *string, gchar **secret); + +static gchar * +parse_token (const gint parts_no, const gchar *string, gchar **secret); + +static gchar * +get_param_value (const gchar *string); + +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_get_request_token (const gchar *consumer_key, + const gchar *consumer_secret, + gchar **secret) +{ + gchar *signature; + gchar *url; + gchar *timestamp; + gchar *nonce; + gchar *params[7]; + gchar *params_string; /* one string later created from params[] */ + gchar *http_reply; + + timestamp = get_timestamp (); + nonce = oauth_gen_nonce (); + + params[0] = g_strdup_printf ("oauth_callback=%s", FLICKR_OAUTH_CALLBACK); + params[1] = g_strdup_printf ("oauth_consumer_key=%s", consumer_key); + params[2] = g_strdup_printf ("oauth_nonce=%s", nonce); + params[3] = g_strdup_printf ("oauth_signature_method=%s", + FLICKR_OAUTH_SIGNATURE_METHOD); + params[4] = g_strdup_printf ("oauth_timestamp=%s", timestamp); + params[5] = g_strdup_printf ("oauth_version=%s", FLICKR_OAUTH_VERSION); + + + g_free (timestamp); + g_free (nonce); + + signature = flickroauth_get_signature (consumer_secret, NULL, + FLICKR_OAUTH_REQUESTTOKEN_URL, + params, 6); + + params[6] = g_strdup_printf ("oauth_signature=%s", signature); + g_free (signature); + + params_string = oauth_serialize_url (7, 0, params); + + free_params (params, 7); + + url = g_strdup_printf ("%s?%s", FLICKR_OAUTH_REQUESTTOKEN_URL, params_string); + g_free (params_string); + + http_reply = oauth_http_get2 (url, NULL, NULL); + g_free (url); + + return parse_request_token (http_reply, secret); +} + +gchar * +flickroauth_get_access_token (const gchar *consumer_key, + const gchar *consumer_secret, + const gchar *oauth_token, + const gchar *oauth_token_secret, + const gchar *verifier, + gchar **secret) +{ + gchar *signature; + gchar *url; + gchar *timestamp; + gchar *nonce; + gchar *params[8]; + gchar *params_string; /* one string later created from params[] */ + gchar *http_reply; + + timestamp = get_timestamp (); + nonce = oauth_gen_nonce (); + + params[0] = g_strdup_printf ("oauth_verifier=%s", verifier); + params[1] = g_strdup_printf ("oauth_consumer_key=%s", consumer_key); + params[2] = g_strdup_printf ("oauth_nonce=%s", nonce); + params[3] = g_strdup_printf ("oauth_signature_method=%s", + FLICKR_OAUTH_SIGNATURE_METHOD); + params[4] = g_strdup_printf ("oauth_timestamp=%s", timestamp); + params[5] = g_strdup_printf ("oauth_version=%s", FLICKR_OAUTH_VERSION); + params[6] = g_strdup_printf ("oauth_token=%s", oauth_token); + + g_free (timestamp); + g_free (nonce); + + signature = flickroauth_get_signature (consumer_secret, + oauth_token_secret, + FLICKR_OAUTH_ACCESSTOKEN_URL, + params, 7); + + params[7] = g_strdup_printf ("oauth_signature=%s", signature); + g_free (signature); + + params_string = oauth_serialize_url (8, 0, params); + + free_params (params, 8); + + url = g_strdup_printf ("%s?%s", FLICKR_OAUTH_ACCESSTOKEN_URL, params_string); + g_free (params_string); + + http_reply = oauth_http_get2 (url, NULL, NULL); + g_free (url); + + return parse_access_token (http_reply, secret); +} + +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 gchar +*get_param_value (const gchar *string) +{ + gchar *eq = strchr (string, '='); + + if (eq == NULL) + return NULL; + + return g_strdup (eq + 1); +} + +static gchar * +parse_token (const gint parts_no, const gchar *string, gchar **secret) +{ + gchar **array; + gchar *token = NULL; + gint i = 0; + + array = g_strsplit (string, "&", parts_no); + + while (array[i] != NULL) { + if (g_str_has_prefix (array[i], "oauth_token_secret")) + (*secret) = get_param_value (array[i]); + else if (g_str_has_prefix (array[i], "oauth_token")) + token = get_param_value(array[i]); + + i++; + } + + g_strfreev (array); + + return token; +} + +inline static gchar * +parse_access_token (const gchar *string, gchar **secret) +{ + return parse_token(5, string, secret); +} + +inline static gchar * +parse_request_token (const gchar *string, gchar **secret) +{ + return parse_token(3, string, secret); +} + +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/tools/grilo-test-ui/flickr-oauth.h b/tools/grilo-test-ui/flickr-oauth.h new file mode 100644 index 0000000..ac04902 --- /dev/null +++ b/tools/grilo-test-ui/flickr-oauth.h @@ -0,0 +1,91 @@ +/* + * Flickr authentication library (using OAuth) + * + * 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_ACCESSTOKEN_URL "http://www.flickr.com/services/oauth/access_token" +#define FLICKR_OAUTH_REQUESTTOKEN_URL "http://www.flickr.com/services/oauth/request_token" +#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" + +/* ------------------------------------------------------------- */ +#define DEBUG +/* for debugging */ +#ifdef DEBUG + +/* +gchar *dev_consumer_key = "e6b8c86373f5e44e78fed8805e675ede"; +gchar *dev_consumer_secret = "39cea595d57bb9f5"; + +#include +#define dbg(A, ...) fprintf (stderr, "-- (DBG) %s:%d --\n" A "\n", __FUNCTION__,\ + __LINE__, __VA_ARGS__) + +*/ +#endif +/* ------------------------------------------------------------- */ + + +/* public API */ + +gchar * +flickroauth_get_signature (const gchar *consumer_secret, + const gchar *token_secret, + const gchar *url, + gchar **params, + gint params_no); + +gchar * +flickroauth_get_request_token (const gchar *consumer_key, + const gchar *consumer_secret, + gchar **secret); + +gchar * +flickroauth_get_access_token (const gchar *consumer_key, + const gchar *consumer_secret, + const gchar *oauth_token, + const gchar *oauth_token_secret, + const gchar *verifier, + gchar **secret); + +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/tools/grilo-test-ui/main.c b/tools/grilo-test-ui/main.c index 5c75319..77a8e03 100644 --- a/tools/grilo-test-ui/main.c +++ b/tools/grilo-test-ui/main.c @@ -25,12 +25,12 @@ #include +#include "flickr-oauth.h" + #include #include #include -#include "flickr-auth.h" - #define GRL_LOG_DOMAIN_DEFAULT test_ui_log_domain GRL_LOG_DOMAIN_STATIC(test_ui_log_domain); @@ -1394,7 +1394,7 @@ get_config_dir (void) } static gchar * -load_flickr_token (void) +load_flickr_token (gchar **secret) { GKeyFile *keyfile; gchar *path; @@ -1415,6 +1415,7 @@ load_flickr_token (void) goto bailout; token = g_key_file_get_value (keyfile, "flickr", "auth-token", NULL); + (*secret) = g_key_file_get_value (keyfile, "flickr", "auth-token-secret", NULL); bailout: g_free (file); @@ -1423,7 +1424,7 @@ bailout: } static void -save_flickr_token (const gchar *token) +save_flickr_token (const gchar *token, const gchar *secret) { GKeyFile *keyfile; gchar *path; @@ -1441,6 +1442,7 @@ save_flickr_token (const gchar *token) keyfile = g_key_file_new (); g_key_file_load_from_file (keyfile, file, G_KEY_FILE_NONE, NULL); g_key_file_set_value (keyfile, "flickr", "auth-token", token); + g_key_file_set_value (keyfile, "flickr", "auth-token-secret", secret); { GError *error = NULL; @@ -1494,18 +1496,24 @@ authorize_flickr (void) GtkWidget *fail_dialog; GtkWidget *label; GtkWidget *view; + GtkWidget *input; + const gchar *verifier; gchar *markup; gchar *token = NULL; gchar *login_link; GtkWidget *ok_button; - gchar *frob = flickr_get_frob (FLICKR_KEY, FLICKR_SECRET); - if (!frob) { - GRL_WARNING ("Unable to obtain a Flickr's frob"); + gchar *rt_secret; + gchar *at_secret; + + gchar *rt = flickroauth_get_request_token (FLICKR_KEY, FLICKR_SECRET, &rt_secret); + if (!rt) { + GRL_WARNING ("Unable to obtain a Flickr's Request Key"); return NULL; } - login_link = flickr_get_login_link (FLICKR_KEY, FLICKR_SECRET, frob, "read"); + login_link = flickroauth_authorization_url (rt, "read"); + view = gtk_text_view_new (); gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)), FLICKR_AUTHORIZE_MSG, @@ -1522,6 +1530,8 @@ authorize_flickr (void) gtk_label_set_markup (GTK_LABEL (label), markup); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + input = gtk_entry_new (); + dialog = gtk_dialog_new_with_buttons ("Authorize Flickr access", GTK_WINDOW (gtk_widget_get_parent_window (view)), @@ -1530,6 +1540,7 @@ authorize_flickr (void) gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), view, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), label, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), input, TRUE, TRUE, 0); ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_OK); gtk_widget_set_sensitive (ok_button, FALSE); @@ -1542,9 +1553,10 @@ authorize_flickr (void) gtk_widget_show_all (dialog); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { - token = flickr_get_token (FLICKR_KEY, FLICKR_SECRET, frob); + verifier = gtk_entry_get_text (GTK_ENTRY (input)); + token = flickroauth_get_access_token (FLICKR_KEY, FLICKR_SECRET, rt, rt_secret, verifier, &at_secret); if (token) { - save_flickr_token (token); + save_flickr_token (token, at_secret); } else { fail_dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_parent_window (view)), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, @@ -1557,7 +1569,10 @@ authorize_flickr (void) } gtk_widget_destroy (dialog); - g_free (frob); + g_free (rt); + g_free (rt_secret); + g_free (at_secret); + g_free (login_link); g_free (markup); @@ -1570,6 +1585,7 @@ set_flickr_config (void) GrlConfig *config; GrlRegistry *registry; gchar *token; + gchar *secret; registry = grl_registry_get_default (); @@ -1578,13 +1594,13 @@ set_flickr_config (void) grl_config_set_api_secret (config, FLICKR_SECRET); grl_registry_add_config (registry, config, NULL); - token = load_flickr_token (); + token = load_flickr_token (&secret); if (!token) { token = authorize_flickr (); if (!token) { /* Save empty token to avoid asking again */ - save_flickr_token (""); + save_flickr_token ("", ""); } } @@ -1593,9 +1609,11 @@ set_flickr_config (void) grl_config_set_api_key (config, FLICKR_KEY); grl_config_set_api_secret (config, FLICKR_SECRET); grl_config_set_api_token (config, token); + grl_config_set_api_token_secret (config, secret); grl_registry_add_config (registry, config, NULL); } g_free (token); + g_free (secret); } static void -- 1.8.1.4