/soc/2012/tomkiewicz/gg: cf23e0f1861a: Gadu-Gadu: OAuth support

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Mon Aug 6 07:16:50 EDT 2012


Changeset: cf23e0f1861ae8a4ab8ca83e3a13f0f9e32b9771
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2012-08-06 13:16 +0200
Branch:	 soc.2012.gg
URL: http://hg.pidgin.im/soc/2012/tomkiewicz/gg/rev/cf23e0f1861a

Description:

Gadu-Gadu: OAuth support

diffstat:

 libpurple/protocols/gg/Makefile.am             |    8 +-
 libpurple/protocols/gg/oauth/oauth-parameter.c |  154 +++++++++++++++++
 libpurple/protocols/gg/oauth/oauth-parameter.h |   14 +
 libpurple/protocols/gg/oauth/oauth-purple.c    |  225 +++++++++++++++++++++++++
 libpurple/protocols/gg/oauth/oauth-purple.h    |   13 +
 libpurple/protocols/gg/oauth/oauth.c           |  139 +++++++++++++++
 libpurple/protocols/gg/oauth/oauth.h           |   11 +
 7 files changed, 563 insertions(+), 1 deletions(-)

diffs (truncated from 604 to 300 lines):

diff --git a/libpurple/protocols/gg/Makefile.am b/libpurple/protocols/gg/Makefile.am
--- a/libpurple/protocols/gg/Makefile.am
+++ b/libpurple/protocols/gg/Makefile.am
@@ -79,7 +79,13 @@ GGSOURCES = \
 	roster.c \
 	roster.h \
 	xml.c \
-	xml.h
+	xml.h \
+	oauth/oauth.c \
+	oauth/oauth.h \
+	oauth/oauth-parameter.c \
+	oauth/oauth-parameter.h \
+	oauth/oauth-purple.c \
+	oauth/oauth-purple.h
 
 AM_CFLAGS = $(st)
 
diff --git a/libpurple/protocols/gg/oauth/oauth-parameter.c b/libpurple/protocols/gg/oauth/oauth-parameter.c
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/gg/oauth/oauth-parameter.c
@@ -0,0 +1,154 @@
+/*
+ *  (C) Copyright 2008 Wojtek Kaniewski <wojtekka at irc.pl>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License Version
+ *  2.1 as published by the Free Software Foundation.
+ *
+ *  This program 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 program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
+ *  USA.
+ */
+
+// source: http://toxygen.net/libgadu/
+
+#include "oauth-parameter.h"
+
+struct gg_oauth_parameter {
+	char *key;
+	char *value;
+	struct gg_oauth_parameter *next;
+};
+
+int gg_oauth_parameter_set(gg_oauth_parameter_t **list, const char *key, const char *value)
+{
+	gg_oauth_parameter_t *p, *new_p;
+	char *new_key;
+	char *new_value;
+
+	if (value == NULL)
+		return 0;
+
+	if (list == NULL)
+		return -1;
+
+	new_key = strdup(key);
+
+	if (new_key == NULL)
+		return -1;
+
+	new_value = strdup(value);
+
+	if (new_value == NULL) {
+		free(new_key);
+		return -1;
+	}
+
+	new_p = malloc(sizeof(gg_oauth_parameter_t));
+
+	if (new_p == NULL) {
+		free(new_key);
+		free(new_value);
+		return -1;
+	}
+
+	memset(new_p, 0, sizeof(gg_oauth_parameter_t));
+	new_p->key = new_key;
+	new_p->value = new_value;
+
+	if (*list != NULL) {
+		p = *list;
+
+		while (p != NULL && p->next != NULL)
+			p = p->next;
+
+		p->next = new_p;
+	} else {
+		*list = new_p;
+	}
+
+	return 0;
+}
+
+char *gg_oauth_parameter_join(gg_oauth_parameter_t *list, int header)
+{
+	gg_oauth_parameter_t *p;
+	int len = 0;
+	char *res, *out;
+
+	if (header)
+		len += strlen("Authorization: OAuth ");
+
+	for (p = list; p; p = p->next) {
+		gchar *escaped;
+		len += strlen(p->key);
+
+		len += (header) ? 3 : 1;
+
+		escaped = g_uri_escape_string(p->value, NULL, FALSE);
+		len += strlen(escaped);
+		g_free(escaped);
+
+		if (p->next)
+			len += 1;
+	}
+
+	res = malloc(len + 1);
+
+	if (res == NULL)
+		return NULL;
+
+	out = res;
+
+	*out = 0;
+
+	if (header) {
+		strcpy(out, "Authorization: OAuth ");
+		out += strlen(out);
+	}
+
+	for (p = list; p; p = p->next) {
+		gchar *escaped;
+		strcpy(out, p->key);
+		out += strlen(p->key);
+
+		strcpy(out++, "=");
+
+		if (header)
+			strcpy(out++, "\"");
+
+		escaped = g_uri_escape_string(p->value, NULL, FALSE);
+		strcpy(out, escaped);
+		out += strlen(escaped);
+		g_free(escaped);
+
+		if (header)
+			strcpy(out++, "\"");
+
+		if (p->next != NULL)
+			strcpy(out++, (header) ? "," : "&");
+	}
+
+	return res;
+}
+
+void gg_oauth_parameter_free(gg_oauth_parameter_t *list)
+{
+	while (list != NULL) {
+		gg_oauth_parameter_t *next;
+
+		next = list->next;
+
+		free(list->key);
+		free(list->value);
+		free(list);
+
+		list = next;
+	}
+}
diff --git a/libpurple/protocols/gg/oauth/oauth-parameter.h b/libpurple/protocols/gg/oauth/oauth-parameter.h
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/gg/oauth/oauth-parameter.h
@@ -0,0 +1,14 @@
+// source: http://toxygen.net/libgadu/
+
+#ifndef _GGP_OAUTH_PARAMETER_H
+#define _GGP_OAUTH_PARAMETER_H
+
+#include <internal.h>
+
+typedef struct gg_oauth_parameter gg_oauth_parameter_t;
+
+int gg_oauth_parameter_set(gg_oauth_parameter_t **list, const char *key, const char *value);
+char *gg_oauth_parameter_join(gg_oauth_parameter_t *list, int header);
+void gg_oauth_parameter_free(gg_oauth_parameter_t *list);
+
+#endif /* _GGP_OAUTH_PARAMETER_H */
diff --git a/libpurple/protocols/gg/oauth/oauth-purple.c b/libpurple/protocols/gg/oauth/oauth-purple.c
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/gg/oauth/oauth-purple.c
@@ -0,0 +1,225 @@
+#include "oauth-purple.h"
+
+#include "oauth.h"
+#include "../utils.h"
+#include "../xml.h"
+
+#include <debug.h>
+
+#define GGP_OAUTH_RESPONSE_MAX 10240
+
+typedef struct
+{
+	PurpleConnection *gc;
+	ggp_oauth_request_cb callback;
+	gpointer user_data;
+	gchar *token;
+	gchar *token_secret;
+} ggp_oauth_data;
+
+static void ggp_oauth_data_free(ggp_oauth_data *data);
+
+static void ggp_oauth_request_token_got(PurpleUtilFetchUrlData *url_data,
+	gpointer user_data, const gchar *url_text, gsize len,
+	const gchar *error_message);
+
+static void ggp_oauth_authorization_done(PurpleUtilFetchUrlData *url_data,
+	gpointer user_data, const gchar *url_text, gsize len,
+	const gchar *error_message);
+
+static void ggp_oauth_access_token_got(PurpleUtilFetchUrlData *url_data,
+	gpointer user_data, const gchar *url_text, gsize len,
+	const gchar *error_message);
+
+static void ggp_oauth_data_free(ggp_oauth_data *data)
+{
+	g_free(data->token);
+	g_free(data->token_secret);
+	g_free(data);
+}
+
+void ggp_oauth_request(PurpleConnection *gc, ggp_oauth_request_cb callback,
+	gpointer user_data)
+{
+	PurpleAccount *account = purple_connection_get_account(gc);
+	char *auth;
+	const char *method = "POST";
+	const char *url = "http://api.gadu-gadu.pl/request_token";
+	gchar *request;
+	ggp_oauth_data *data;
+
+	purple_debug_misc("gg", "ggp_oauth_request: requesting token...\n");
+
+	auth = gg_oauth_generate_header(method, url,
+		purple_account_get_username(account),
+		purple_account_get_password(account), NULL, NULL);
+	request = g_strdup_printf(
+		"POST /request_token HTTP/1.1\r\n"
+		"Host: api.gadu-gadu.pl\r\n"
+		"%s\r\n"
+		"Content-Length: 0\r\n"
+		"\r\n",
+		auth);
+	free(auth);
+
+	data = g_new0(ggp_oauth_data, 1);
+	data->gc = gc;
+	data->callback = callback;
+	data->user_data = user_data;
+
+	purple_util_fetch_url_request(account, url, FALSE, NULL, TRUE, request,
+		FALSE, GGP_OAUTH_RESPONSE_MAX, ggp_oauth_request_token_got,
+		data);
+
+	g_free(request);
+}
+
+static void ggp_oauth_request_token_got(PurpleUtilFetchUrlData *url_data,
+	gpointer user_data, const gchar *url_text, gsize len,
+	const gchar *error_message)
+{
+	ggp_oauth_data *data = user_data;
+	PurpleAccount *account;
+	xmlnode *xml;
+	gchar *request, *request_data;
+	gboolean succ = TRUE;
+
+	if (!PURPLE_CONNECTION_IS_VALID(data->gc))
+	{
+		ggp_oauth_data_free(data);
+		return;
+	}
+	account = purple_connection_get_account(data->gc);
+
+	if (len == 0)
+	{
+		purple_debug_error("gg", "ggp_oauth_request_token_got: "
+			"requested token not received\n");
+		ggp_oauth_data_free(data);
+		return;



More information about the Commits mailing list