diff options
author | Ross Burton <ross@linux.intel.com> | 2009-05-24 10:31:49 +0100 |
---|---|---|
committer | Ross Burton <ross@linux.intel.com> | 2009-05-24 21:25:01 +0100 |
commit | d82692abfd3770b62e79f5295797f873129811c4 (patch) | |
tree | 940af9add781ebc5af203a49f51443e87de8df7e /rest | |
parent | c4607c65656a5067be52ac505ab417aaa7afa277 (diff) | |
download | librest-d82692abfd3770b62e79f5295797f873129811c4.tar.gz |
Add initial facebook proxy
Diffstat (limited to 'rest')
-rw-r--r-- | rest/Makefile.am | 5 | ||||
-rw-r--r-- | rest/facebook-proxy-call.c | 83 | ||||
-rw-r--r-- | rest/facebook-proxy-call.h | 64 | ||||
-rw-r--r-- | rest/facebook-proxy-private.h | 33 | ||||
-rw-r--r-- | rest/facebook-proxy.c | 328 | ||||
-rw-r--r-- | rest/facebook-proxy.h | 88 |
6 files changed, 601 insertions, 0 deletions
diff --git a/rest/Makefile.am b/rest/Makefile.am index 2567822..5c6fb03 100644 --- a/rest/Makefile.am +++ b/rest/Makefile.am @@ -18,6 +18,9 @@ librest_la_SOURCES = rest-proxy.c \ flickr-proxy.c \ flickr-proxy-call.c \ flickr-proxy-private.h \ + facebook-proxy.c \ + facebook-proxy-call.c \ + facebook-proxy-private.h \ sha1.c \ sha1.h \ $(librest_la_HEADERS) @@ -27,6 +30,8 @@ librest_la_HEADERS = rest-proxy.h \ oauth-proxy-call.h \ flickr-proxy.h \ flickr-proxy-call.h \ + facebook-proxy.h \ + facebook-proxy-call.h \ rest-xml-parser.h librest_ladir = $(includedir)/rest/rest diff --git a/rest/facebook-proxy-call.c b/rest/facebook-proxy-call.c new file mode 100644 index 0000000..9116249 --- /dev/null +++ b/rest/facebook-proxy-call.c @@ -0,0 +1,83 @@ +/* + * 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 "facebook-proxy-call.h" +#include "facebook-proxy-private.h" +#include "rest-proxy-call-private.h" +#include "sha1.h" + +G_DEFINE_TYPE (FacebookProxyCall, facebook_proxy_call, REST_TYPE_PROXY_CALL) + +static gboolean +_prepare (RestProxyCall *call, GError **error) +{ + FacebookProxy *proxy = NULL; + FacebookProxyPrivate *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 Facebook puts the function in the parameters */ + call_priv->url = g_strdup ("http://api.facebook.com/restserver.php"); + + rest_proxy_call_add_params (call, + "method", call_priv->function, + "api_key", priv->api_key, + "v", "1.0", + NULL); + + if (priv->session_key) + rest_proxy_call_add_param (call, "session_key", priv->session_key); + + /* TODO call id */ + + s = facebook_proxy_sign (proxy, call_priv->params); + rest_proxy_call_add_param (call, "sig", s); + g_free (s); + + g_object_unref (proxy); + + return TRUE; +} + +static void +facebook_proxy_call_class_init (FacebookProxyCallClass *klass) +{ + RestProxyCallClass *call_class = REST_PROXY_CALL_CLASS (klass); + + call_class->prepare = _prepare; +} + +static void +facebook_proxy_call_init (FacebookProxyCall *self) +{ +} + +#if BUILD_TESTS +#warning TODO facebook signature test cases +#endif diff --git a/rest/facebook-proxy-call.h b/rest/facebook-proxy-call.h new file mode 100644 index 0000000..c81f6ff --- /dev/null +++ b/rest/facebook-proxy-call.h @@ -0,0 +1,64 @@ +/* + * 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 _FACEBOOK_PROXY_CALL +#define _FACEBOOK_PROXY_CALL + +#include <rest/rest-proxy-call.h> + +G_BEGIN_DECLS + +#define FACEBOOK_TYPE_PROXY_CALL facebook_proxy_call_get_type() + +#define FACEBOOK_PROXY_CALL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), FACEBOOK_TYPE_PROXY_CALL, FacebookProxyCall)) + +#define FACEBOOK_PROXY_CALL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), FACEBOOK_TYPE_PROXY_CALL, FacebookProxyCallClass)) + +#define FACEBOOK_IS_PROXY_CALL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FACEBOOK_TYPE_PROXY_CALL)) + +#define FACEBOOK_IS_PROXY_CALL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), FACEBOOK_TYPE_PROXY_CALL)) + +#define FACEBOOK_PROXY_CALL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), FACEBOOK_TYPE_PROXY_CALL, FacebookProxyCallClass)) + +/** + * FacebookProxyCall: + * + * #FacebookProxyCall has no publicly available members. + */ +typedef struct { + RestProxyCall parent; +} FacebookProxyCall; + +typedef struct { + RestProxyCallClass parent_class; +} FacebookProxyCallClass; + +GType facebook_proxy_call_get_type (void); + +G_END_DECLS + +#endif /* _FACEBOOK_PROXY_CALL */ diff --git a/rest/facebook-proxy-private.h b/rest/facebook-proxy-private.h new file mode 100644 index 0000000..0f652a6 --- /dev/null +++ b/rest/facebook-proxy-private.h @@ -0,0 +1,33 @@ +/* + * 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 "facebook-proxy.h" + +#define PROXY_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), FACEBOOK_TYPE_PROXY, FacebookProxyPrivate)) + +struct _FacebookProxyPrivate { + char *api_key; + char *app_secret; + char *session_key; +}; + diff --git a/rest/facebook-proxy.c b/rest/facebook-proxy.c new file mode 100644 index 0000000..55ef45f --- /dev/null +++ b/rest/facebook-proxy.c @@ -0,0 +1,328 @@ +/* + * 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 "facebook-proxy.h" +#include "facebook-proxy-private.h" +#include "facebook-proxy-call.h" + +G_DEFINE_TYPE (FacebookProxy, facebook_proxy, REST_TYPE_PROXY) + +enum { + PROP_0, + PROP_API_KEY, + PROP_APP_SECRET, + PROP_SESSION_KEY, +}; + +static RestProxyCall * +_new_call (RestProxy *proxy) +{ + RestProxyCall *call; + + call = g_object_new (FACEBOOK_TYPE_PROXY_CALL, + "proxy", proxy, + NULL); + + return call; +} + +static void +facebook_proxy_get_property (GObject *object, guint property_id, + GValue *value, GParamSpec *pspec) +{ + FacebookProxyPrivate *priv = PROXY_GET_PRIVATE (object); + + switch (property_id) { + case PROP_API_KEY: + g_value_set_string (value, priv->api_key); + break; + case PROP_APP_SECRET: + g_value_set_string (value, priv->app_secret); + break; + case PROP_SESSION_KEY: + g_value_set_string (value, priv->session_key); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +facebook_proxy_set_property (GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec) +{ + FacebookProxyPrivate *priv = PROXY_GET_PRIVATE (object); + + switch (property_id) { + case PROP_API_KEY: + if (priv->api_key) + g_free (priv->api_key); + priv->api_key = g_value_dup_string (value); + break; + case PROP_APP_SECRET: + if (priv->app_secret) + g_free (priv->app_secret); + priv->app_secret = g_value_dup_string (value); + break; + case PROP_SESSION_KEY: + if (priv->session_key); + g_free (priv->session_key); + priv->session_key = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +facebook_proxy_finalize (GObject *object) +{ + FacebookProxyPrivate *priv = PROXY_GET_PRIVATE (object); + + g_free (priv->api_key); + g_free (priv->app_secret); + g_free (priv->session_key); + + G_OBJECT_CLASS (facebook_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 +facebook_proxy_class_init (FacebookProxyClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + RestProxyClass *proxy_class = REST_PROXY_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (klass, sizeof (FacebookProxyPrivate)); + + object_class->get_property = facebook_proxy_get_property; + object_class->set_property = facebook_proxy_set_property; + object_class->finalize = facebook_proxy_finalize; + + proxy_class->new_call = _new_call; + + pspec = g_param_spec_string ("api-key", "api-key", + "The API key", NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY|G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, + PROP_API_KEY, + pspec); + + pspec = g_param_spec_string ("app-secret", "app-secret", + "The application secret", NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT|G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, + PROP_APP_SECRET, + pspec); + + pspec = g_param_spec_string ("session-key", "session-key", + "The session key", NULL, + G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, + PROP_SESSION_KEY, + pspec); +} + +static void +facebook_proxy_init (FacebookProxy *self) +{ + self->priv = PROXY_GET_PRIVATE (self); +} + +RestProxy * +facebook_proxy_new (const char *api_key, + const char *app_secret) +{ + return facebook_proxy_new_with_session (api_key, + app_secret, + NULL); +} + +RestProxy * +facebook_proxy_new_with_session (const char *api_key, + const char *app_secret, + const char *session_key) +{ + return g_object_new (FACEBOOK_TYPE_PROXY, + "api-key", api_key, + "app-secret", app_secret, + "session-key", session_key, + "url-format", "http://api.facebook.com/restserver.php", + "binding-required", FALSE, + NULL); +} + +/** + * facebook_proxy_get_api_key: + * @proxy: an #FacebookProxy + * + * Get the API key. + * + * Returns: the API key. This string is owned by #FacebookProxy and should not be + * freed. + */ +const char * +facebook_proxy_get_api_key (FacebookProxy *proxy) +{ + FacebookProxyPrivate *priv = PROXY_GET_PRIVATE (proxy); + return priv->api_key; +} + +/** + * facebook_proxy_get_app_secret: + * @proxy: an #FacebookProxy + * + * Get the application secret for authentication. + * + * Returns: the application secret. This string is owned by #FacebookProxy and should not be + * freed. + */ +const char * +facebook_proxy_get_app_secret (FacebookProxy *proxy) +{ + FacebookProxyPrivate *priv = PROXY_GET_PRIVATE (proxy); + return priv->app_secret; +} + +void +facebook_proxy_set_app_secret (FacebookProxy *proxy, const char *secret) +{ + FacebookProxyPrivate *priv; + + g_return_if_fail (FACEBOOK_IS_PROXY (proxy)); + priv = PROXY_GET_PRIVATE (proxy); + + if (priv->app_secret) + g_free (priv->app_secret); + + priv->app_secret = g_strdup (secret); +} + +/** + * facebook_proxy_get_session_key: + * @proxy: an #FacebookProxy + * + * Get the current session key + * + * Returns: the session key, or %NULL if there is no session yet. This string is owned + * by #FacebookProxy and should not be freed. + */ +const char * +facebook_proxy_get_session_key (FacebookProxy *proxy) +{ + FacebookProxyPrivate *priv = PROXY_GET_PRIVATE (proxy); + return priv->session_key; +} + +/** + * facebook_proxy_set_session_key: + * @proxy: an #FacebookProxy + * @session_key: the session key + * + * Set the token. + */ +void +facebook_proxy_set_session_key (FacebookProxy *proxy, const char *session_key) +{ + FacebookProxyPrivate *priv; + + g_return_if_fail (FACEBOOK_IS_PROXY (proxy)); + priv = PROXY_GET_PRIVATE (proxy); + + if (priv->session_key) + g_free (priv->session_key); + + priv->session_key = g_strdup (session_key); +} + +char * +facebook_proxy_sign (FacebookProxy *proxy, GHashTable *params) +{ + FacebookProxyPrivate *priv; + GString *s; + GList *keys; + char *md5; + + g_return_val_if_fail (FACEBOOK_IS_PROXY (proxy), NULL); + g_return_val_if_fail (params, NULL); + + priv = PROXY_GET_PRIVATE (proxy); + + s = g_string_new (NULL); + + 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; + } + + g_string_append (s, priv->app_secret); + + md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, s->str, s->len); + + g_string_free (s, TRUE); + + return md5; +} + +char * +facebook_proxy_build_login_url (FacebookProxy *proxy, const char *token) +{ + SoupURI *uri; + GHashTable *params; + char *s; + + g_return_val_if_fail (FACEBOOK_IS_PROXY (proxy), NULL); + g_return_val_if_fail (token, NULL); + + uri = soup_uri_new ("http://facebook.com/login.php/"); + params = g_hash_table_new (g_str_hash, g_str_equal); + + g_hash_table_insert (params, "api_key", proxy->priv->api_key); + g_hash_table_insert (params, "v", "1.0"); + g_hash_table_insert (params, "auth_token", (gpointer)token); + + soup_uri_set_query_from_form (uri, params); + + s = soup_uri_to_string (uri, FALSE); + + g_hash_table_unref (params); + soup_uri_free (uri); + return s; +} diff --git a/rest/facebook-proxy.h b/rest/facebook-proxy.h new file mode 100644 index 0000000..9ce2184 --- /dev/null +++ b/rest/facebook-proxy.h @@ -0,0 +1,88 @@ +/* + * 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 _FACEBOOK_PROXY +#define _FACEBOOK_PROXY + +#include <rest/rest-proxy.h> + +G_BEGIN_DECLS + +#define FACEBOOK_TYPE_PROXY facebook_proxy_get_type() + +#define FACEBOOK_PROXY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), FACEBOOK_TYPE_PROXY, FacebookProxy)) + +#define FACEBOOK_PROXY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), FACEBOOK_TYPE_PROXY, FacebookProxyClass)) + +#define FACEBOOK_IS_PROXY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FACEBOOK_TYPE_PROXY)) + +#define FACEBOOK_IS_PROXY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), FACEBOOK_TYPE_PROXY)) + +#define FACEBOOK_PROXY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), FACEBOOK_TYPE_PROXY, FacebookProxyClass)) + +typedef struct _FacebookProxyPrivate FacebookProxyPrivate; + +/** + * FacebookProxy: + * + * #FacebookProxy has no publicly available members. + */ +typedef struct { + RestProxy parent; + FacebookProxyPrivate *priv; +} FacebookProxy; + +typedef struct { + RestProxyClass parent_class; +} FacebookProxyClass; + +GType facebook_proxy_get_type (void); + +RestProxy* facebook_proxy_new (const char *api_key, + const char *app_secret); + +RestProxy* facebook_proxy_new_with_session (const char *api_key, + const char *app_secret, + const char *session_key); + +const char * facebook_proxy_get_api_key (FacebookProxy *proxy); + +void facebook_proxy_set_app_secret (FacebookProxy *proxy, const char *secret); + +const char * facebook_proxy_get_app_secret (FacebookProxy *proxy); + +const char * facebook_proxy_get_session_key (FacebookProxy *proxy); + +void facebook_proxy_set_session_key (FacebookProxy *proxy, const char *session_key); + +char * facebook_proxy_sign (FacebookProxy *proxy, GHashTable *params); + +char * facebook_proxy_build_login_url (FacebookProxy *proxy, const char *frob); + +G_END_DECLS + +#endif /* _FACEBOOK_PROXY */ |