diff options
author | Ross Burton <ross@linux.intel.com> | 2009-05-19 17:50:08 +0100 |
---|---|---|
committer | Ross Burton <ross@linux.intel.com> | 2009-05-19 17:51:30 +0100 |
commit | 523486b7c7c6d6461a756585e35f8e196d630182 (patch) | |
tree | c528d8cfc9e305531b3b396171e93b704cab0891 | |
parent | e49d8730bfb277af59732822e78535ef37e29b6c (diff) |
Add initial Flickr proxy
-rw-r--r-- | rest/Makefile.am | 5 | ||||
-rw-r--r-- | rest/flickr-proxy-call.c | 80 | ||||
-rw-r--r-- | rest/flickr-proxy-call.h | 65 | ||||
-rw-r--r-- | rest/flickr-proxy-private.h | 35 | ||||
-rw-r--r-- | rest/flickr-proxy.c | 286 | ||||
-rw-r--r-- | rest/flickr-proxy.h | 82 |
6 files changed, 553 insertions, 0 deletions
diff --git a/rest/Makefile.am b/rest/Makefile.am index e78c5ac..2567822 100644 --- a/rest/Makefile.am +++ b/rest/Makefile.am @@ -15,6 +15,9 @@ librest_la_SOURCES = rest-proxy.c \ oauth-proxy.c \ oauth-proxy-call.c \ oauth-proxy-private.h \ + flickr-proxy.c \ + flickr-proxy-call.c \ + flickr-proxy-private.h \ sha1.c \ sha1.h \ $(librest_la_HEADERS) @@ -22,6 +25,8 @@ librest_la_HEADERS = rest-proxy.h \ rest-proxy-call.h \ oauth-proxy.h \ oauth-proxy-call.h \ + flickr-proxy.h \ + flickr-proxy-call.h \ rest-xml-parser.h librest_ladir = $(includedir)/rest/rest diff --git a/rest/flickr-proxy-call.c b/rest/flickr-proxy-call.c new file mode 100644 index 0000000..74a2e78 --- /dev/null +++ b/rest/flickr-proxy-call.c @@ -0,0 +1,80 @@ +/* + * librest - RESTful web services access + * Copyright (c) 2008, 2009, Intel Corporation. + * + * Authors: Rob Bradford <rob@linux.intel.com> + * Ross Burton <ross@linux.intel.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <string.h> +#include <libsoup/soup.h> +#include <rest/rest-proxy-call.h> +#include "flickr-proxy-call.h" +#include "flickr-proxy-private.h" +#include "rest-proxy-call-private.h" +#include "sha1.h" + +G_DEFINE_TYPE (FlickrProxyCall, flickr_proxy_call, REST_TYPE_PROXY_CALL) + +static gboolean +_prepare (RestProxyCall *call, GError **error) +{ + FlickrProxy *proxy = NULL; + FlickrProxyPrivate *priv; + RestProxyCallPrivate *call_priv; + char *s; + + g_object_get (call, "proxy", &proxy, NULL); + priv = PROXY_GET_PRIVATE (proxy); + call_priv = call->priv; + + /* First reset the URL because Flickr puts the function in the parameters */ + call_priv->url = g_strdup ("http://api.flickr.com/services/rest/"); + + rest_proxy_call_add_params (call, + "method", call_priv->function, + "api_key", priv->consumer_key, + NULL); + + if (priv->token) + rest_proxy_call_add_param (call, "auth_token", priv->token); + + s = flickr_proxy_sign (proxy, call_priv->params); + rest_proxy_call_add_param (call, "api_sig", s); + g_free (s); + + g_object_unref (proxy); + + return TRUE; +} + +static void +flickr_proxy_call_class_init (FlickrProxyCallClass *klass) +{ + RestProxyCallClass *call_class = REST_PROXY_CALL_CLASS (klass); + + call_class->prepare = _prepare; +} + +static void +flickr_proxy_call_init (FlickrProxyCall *self) +{ +} + +#if BUILD_TESTS +#warning TODO flickr signature test cases +#endif diff --git a/rest/flickr-proxy-call.h b/rest/flickr-proxy-call.h new file mode 100644 index 0000000..be96bd1 --- /dev/null +++ b/rest/flickr-proxy-call.h @@ -0,0 +1,65 @@ +/* + * librest - RESTful web services access + * Copyright (c) 2008, 2009, Intel Corporation. + * + * Authors: Rob Bradford <rob@linux.intel.com> + * Ross Burton <ross@linux.intel.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef _FLICKR_PROXY_CALL +#define _FLICKR_PROXY_CALL + +#include <rest/rest-proxy-call.h> + +G_BEGIN_DECLS + +#define FLICKR_TYPE_PROXY_CALL flickr_proxy_call_get_type() + +#define FLICKR_PROXY_CALL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLICKR_TYPE_PROXY_CALL, FlickrProxyCall)) + +#define FLICKR_PROXY_CALL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), FLICKR_TYPE_PROXY_CALL, FlickrProxyCallClass)) + +#define FLICKR_IS_PROXY_CALL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLICKR_TYPE_PROXY_CALL)) + +#define FLICKR_IS_PROXY_CALL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), FLICKR_TYPE_PROXY_CALL)) + +#define FLICKR_PROXY_CALL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), FLICKR_TYPE_PROXY_CALL, FlickrProxyCallClass)) + +/** + * FlickrProxyCall: + * + * #FlickrProxyCall has no publicly available members. + */ +typedef struct { + RestProxyCall parent; +} FlickrProxyCall; + +typedef struct { + RestProxyCallClass parent_class; +} FlickrProxyCallClass; + +GType flickr_proxy_call_get_type (void); + +G_END_DECLS + +#endif /* _FLICKR_PROXY_CALL */ + diff --git a/rest/flickr-proxy-private.h b/rest/flickr-proxy-private.h new file mode 100644 index 0000000..f0b1c9e --- /dev/null +++ b/rest/flickr-proxy-private.h @@ -0,0 +1,35 @@ +/* + * librest - RESTful web services access + * Copyright (c) 2008, 2009, Intel Corporation. + * + * Authors: Rob Bradford <rob@linux.intel.com> + * Ross Burton <ross@linux.intel.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "flickr-proxy.h" + +#define PROXY_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), FLICKR_TYPE_PROXY, FlickrProxyPrivate)) + +struct _FlickrProxyPrivate { + /* TODO rename to api_key */ + char *consumer_key; + /* TODO: rename to shared secret */ + char *consumer_secret; + char *token; +}; + diff --git a/rest/flickr-proxy.c b/rest/flickr-proxy.c new file mode 100644 index 0000000..e251ec7 --- /dev/null +++ b/rest/flickr-proxy.c @@ -0,0 +1,286 @@ +/* + * librest - RESTful web services access + * Copyright (c) 2008, 2009, Intel Corporation. + * + * Authors: Rob Bradford <rob@linux.intel.com> + * Ross Burton <ross@linux.intel.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <config.h> +#include <string.h> +#include <rest/rest-proxy.h> +#include <libsoup/soup.h> +#include "flickr-proxy.h" +#include "flickr-proxy-private.h" +#include "flickr-proxy-call.h" + +G_DEFINE_TYPE (FlickrProxy, flickr_proxy, REST_TYPE_PROXY) + +enum { + PROP_0, + PROP_CONSUMER_KEY, + PROP_CONSUMER_SECRET, + PROP_TOKEN, +}; + +static RestProxyCall * +_new_call (RestProxy *proxy) +{ + RestProxyCall *call; + + call = g_object_new (FLICKR_TYPE_PROXY_CALL, + "proxy", proxy, + NULL); + + return call; +} + +static void +flickr_proxy_get_property (GObject *object, guint property_id, + GValue *value, GParamSpec *pspec) +{ + FlickrProxyPrivate *priv = PROXY_GET_PRIVATE (object); + + switch (property_id) { + case PROP_CONSUMER_KEY: + g_value_set_string (value, priv->consumer_key); + break; + case PROP_CONSUMER_SECRET: + g_value_set_string (value, priv->consumer_secret); + break; + case PROP_TOKEN: + g_value_set_string (value, priv->token); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +flickr_proxy_set_property (GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec) +{ + FlickrProxyPrivate *priv = PROXY_GET_PRIVATE (object); + + switch (property_id) { + case PROP_CONSUMER_KEY: + if (priv->consumer_key) + g_free (priv->consumer_key); + priv->consumer_key = g_value_dup_string (value); + break; + case PROP_CONSUMER_SECRET: + if (priv->consumer_secret) + g_free (priv->consumer_secret); + priv->consumer_secret = g_value_dup_string (value); + break; + case PROP_TOKEN: + if (priv->token) + g_free (priv->token); + priv->token = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +flickr_proxy_finalize (GObject *object) +{ + FlickrProxyPrivate *priv = PROXY_GET_PRIVATE (object); + + g_free (priv->consumer_key); + g_free (priv->consumer_secret); + g_free (priv->token); + + G_OBJECT_CLASS (flickr_proxy_parent_class)->finalize (object); +} + +#ifndef G_PARAM_STATIC_STRINGS +#define G_PARAM_STATIC_STRINGS (G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB) +#endif + +static void +flickr_proxy_class_init (FlickrProxyClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + RestProxyClass *proxy_class = REST_PROXY_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (klass, sizeof (FlickrProxyPrivate)); + + object_class->get_property = flickr_proxy_get_property; + object_class->set_property = flickr_proxy_set_property; + object_class->finalize = flickr_proxy_finalize; + + proxy_class->new_call = _new_call; + + pspec = g_param_spec_string ("consumer-key", "consumer-key", + "The consumer key", NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY|G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, + PROP_CONSUMER_KEY, + pspec); + + pspec = g_param_spec_string ("consumer-secret", "consumer-secret", + "The consumer secret", NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY|G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, + PROP_CONSUMER_SECRET, + pspec); + + pspec = g_param_spec_string ("token", "token", + "The request or access token", NULL, + G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, + PROP_TOKEN, + pspec); +} + +static void +flickr_proxy_init (FlickrProxy *self) +{ + self->priv = PROXY_GET_PRIVATE (self); +} + +RestProxy * +flickr_proxy_new (const char *consumer_key, + const char *consumer_secret) +{ + return flickr_proxy_new_with_token (consumer_key, + consumer_secret, + NULL); +} + +RestProxy * +flickr_proxy_new_with_token (const char *consumer_key, + const char *consumer_secret, + const char *token) +{ + return g_object_new (FLICKR_TYPE_PROXY, + "consumer-key", consumer_key, + "consumer-secret", consumer_secret, + "token", token, + "url-format", "http://api.flickr.com/services/rest/", + "binding-required", FALSE, + NULL); +} + +/** + * flickr_proxy_get_token: + * @proxy: an #FlickrProxy + * + * Get the current request or access token. + * + * Returns: the token, or %NULL if there is no token yet. This string is owned + * by #FlickrProxy and should not be freed. + */ +const char * +flickr_proxy_get_token (FlickrProxy *proxy) +{ + FlickrProxyPrivate *priv = PROXY_GET_PRIVATE (proxy); + return priv->token; +} + +/** + * flickr_proxy_set_token: + * @proxy: an #FlickrProxy + * @token: the access token + * + * Set the access token. + */ +void +flickr_proxy_set_token (FlickrProxy *proxy, const char *token) +{ + FlickrProxyPrivate *priv; + + g_return_if_fail (FLICKR_IS_PROXY (proxy)); + priv = PROXY_GET_PRIVATE (proxy); + + if (priv->token) + g_free (priv->token); + + priv->token = g_strdup (token); +} + +char * +flickr_proxy_sign (FlickrProxy *proxy, GHashTable *params) +{ + FlickrProxyPrivate *priv; + GString *s; + GList *keys; + char *md5; + + g_return_val_if_fail (FLICKR_IS_PROXY (proxy), NULL); + g_return_val_if_fail (params, NULL); + + priv = PROXY_GET_PRIVATE (proxy); + + s = g_string_new (priv->consumer_secret); + + keys = g_hash_table_get_keys (params); + keys = g_list_sort (keys, (GCompareFunc)strcmp); + + while (keys) { + const char *key; + const char *value; + + key = keys->data; + value = g_hash_table_lookup (params, key); + + g_string_append_printf (s, "%s%s", key, value); + + keys = keys->next; + } + + md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, s->str, s->len); + + g_string_free (s, TRUE); + + return md5; +} + +char * +flickr_proxy_build_login_url (FlickrProxy *proxy, const char *frob) +{ + SoupURI *uri; + GHashTable *params; + char *sig, *s; + + g_return_val_if_fail (FLICKR_IS_PROXY (proxy), NULL); + g_return_val_if_fail (frob, NULL); + + uri = soup_uri_new ("http://flickr.com/services/auth/"); + params = g_hash_table_new (g_str_hash, g_str_equal); + + g_hash_table_insert (params, "api_key", proxy->priv->consumer_key); + /* TODO: parameter */ + g_hash_table_insert (params, "perms", "read"); + g_hash_table_insert (params, "frob", (gpointer)frob); + + sig = flickr_proxy_sign (proxy, params); + g_hash_table_insert (params, "api_sig", sig); + + soup_uri_set_query_from_form (uri, params); + + s = soup_uri_to_string (uri, FALSE); + + g_free (sig); + g_hash_table_unref (params); + soup_uri_free (uri); + + return s; +} diff --git a/rest/flickr-proxy.h b/rest/flickr-proxy.h new file mode 100644 index 0000000..1bfba4b --- /dev/null +++ b/rest/flickr-proxy.h @@ -0,0 +1,82 @@ +/* + * librest - RESTful web services access + * Copyright (c) 2008, 2009, Intel Corporation. + * + * Authors: Rob Bradford <rob@linux.intel.com> + * Ross Burton <ross@linux.intel.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef _FLICKR_PROXY +#define _FLICKR_PROXY + +#include <rest/rest-proxy.h> + +G_BEGIN_DECLS + +#define FLICKR_TYPE_PROXY flickr_proxy_get_type() + +#define FLICKR_PROXY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLICKR_TYPE_PROXY, FlickrProxy)) + +#define FLICKR_PROXY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), FLICKR_TYPE_PROXY, FlickrProxyClass)) + +#define FLICKR_IS_PROXY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLICKR_TYPE_PROXY)) + +#define FLICKR_IS_PROXY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), FLICKR_TYPE_PROXY)) + +#define FLICKR_PROXY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), FLICKR_TYPE_PROXY, FlickrProxyClass)) + +typedef struct _FlickrProxyPrivate FlickrProxyPrivate; + +/** + * FlickrProxy: + * + * #FlickrProxy has no publicly available members. + */ +typedef struct { + RestProxy parent; + FlickrProxyPrivate *priv; +} FlickrProxy; + +typedef struct { + RestProxyClass parent_class; +} FlickrProxyClass; + +GType flickr_proxy_get_type (void); + +RestProxy* flickr_proxy_new (const char *consumer_key, + const char *consumer_secret); + +RestProxy* flickr_proxy_new_with_token (const char *consumer_key, + const char *consumer_secret, + const char *token); + +const char * flickr_proxy_get_token (FlickrProxy *proxy); + +void flickr_proxy_set_token (FlickrProxy *proxy, const char *token); + +char * flickr_proxy_sign (FlickrProxy *proxy, GHashTable *params); + +char * flickr_proxy_build_login_url (FlickrProxy *proxy, const char *frob); + +G_END_DECLS + +#endif /* _FLICKR_PROXY */ |