/soc/2012/tomkiewicz/gg: 09f740724036: Gadu-Gadu: extended OAuth...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Sun Aug 19 06:42:57 EDT 2012


Changeset: 09f740724036cf61b014447df28e782855c11a06
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2012-08-19 12:41 +0200
Branch:	 soc.2012.gg
URL: http://hg.pidgin.im/soc/2012/tomkiewicz/gg/rev/09f740724036

Description:

Gadu-Gadu: extended OAuth support, initial support for gg10.5 public directory

diffstat:

 libpurple/protocols/gg/Makefile.am          |    2 +
 libpurple/protocols/gg/avatar.c             |    2 +-
 libpurple/protocols/gg/gg.c                 |   18 ++
 libpurple/protocols/gg/oauth/oauth-purple.c |   41 ++++-
 libpurple/protocols/gg/oauth/oauth-purple.h |    2 +-
 libpurple/protocols/gg/oauth/oauth.c        |    4 +-
 libpurple/protocols/gg/pubdir-prpl.c        |  213 ++++++++++++++++++++++++++++
 libpurple/protocols/gg/pubdir-prpl.h        |   28 +++
 libpurple/protocols/gg/xml.c                |   41 ++++-
 libpurple/protocols/gg/xml.h                |    2 +
 10 files changed, 339 insertions(+), 14 deletions(-)

diffs (truncated from 515 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
@@ -88,6 +88,8 @@ GGSOURCES = \
 	status.h \
 	servconn.c \
 	servconn.h \
+	pubdir-prpl.c \
+	pubdir-prpl.h \
 	oauth/oauth.c \
 	oauth/oauth.h \
 	oauth/oauth-parameter.c \
diff --git a/libpurple/protocols/gg/avatar.c b/libpurple/protocols/gg/avatar.c
--- a/libpurple/protocols/gg/avatar.c
+++ b/libpurple/protocols/gg/avatar.c
@@ -300,7 +300,7 @@ void ggp_avatar_own_set(PurpleConnection
 	
 	own_data->img = img;
 	
-	ggp_oauth_request(gc, ggp_avatar_own_got_token, img);
+	ggp_oauth_request(gc, ggp_avatar_own_got_token, img, NULL, NULL);
 }
 
 static void ggp_avatar_own_got_token(PurpleConnection *gc, const gchar *token,
diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
--- a/libpurple/protocols/gg/gg.c
+++ b/libpurple/protocols/gg/gg.c
@@ -1670,6 +1670,21 @@ static void ggp_action_status_broadcasti
 	ggp_status_broadcasting_dialog((PurpleConnection *)action->context);
 }
 
+#include "pubdir-prpl.h"
+
+static void ggp_pubdir_debug_cb(PurpleConnection *gc, int records_count, const ggp_pubdir_record *records, void *user_data)
+{
+	purple_debug_info("gg", "ggp_action_debug_got: [%d]\n", records_count);
+}
+
+static void ggp_action_debug(PurplePluginAction *action)
+{
+	PurpleConnection *gc = action->context;
+	purple_debug_info("gg", "ggp_action_debug\n");
+	
+	ggp_pubdir_get_info(gc, 5110, ggp_pubdir_debug_cb, NULL);
+}
+
 static GList *ggp_actions(PurplePlugin *plugin, gpointer context)
 {
 	GList *m = NULL;
@@ -1697,6 +1712,9 @@ static GList *ggp_actions(PurplePlugin *
 				     ggp_action_buddylist_load);
 	m = g_list_append(m, act);
 
+	act = purple_plugin_action_new("Debug action", ggp_action_debug);
+	m = g_list_append(m, act);
+
 	return m;
 }
 
diff --git a/libpurple/protocols/gg/oauth/oauth-purple.c b/libpurple/protocols/gg/oauth/oauth-purple.c
--- a/libpurple/protocols/gg/oauth/oauth-purple.c
+++ b/libpurple/protocols/gg/oauth/oauth-purple.c
@@ -15,6 +15,8 @@ typedef struct
 	gpointer user_data;
 	gchar *token;
 	gchar *token_secret;
+	
+	gchar *sign_method, *sign_url;
 } ggp_oauth_data;
 
 static void ggp_oauth_data_free(ggp_oauth_data *data);
@@ -35,11 +37,13 @@ static void ggp_oauth_data_free(ggp_oaut
 {
 	g_free(data->token);
 	g_free(data->token_secret);
+	g_free(data->sign_method);
+	g_free(data->sign_url);
 	g_free(data);
 }
 
 void ggp_oauth_request(PurpleConnection *gc, ggp_oauth_request_cb callback,
-	gpointer user_data)
+	gpointer user_data, const gchar *sign_method, const gchar *sign_url)
 {
 	PurpleAccount *account = purple_connection_get_account(gc);
 	char *auth;
@@ -48,6 +52,8 @@ void ggp_oauth_request(PurpleConnection 
 	gchar *request;
 	ggp_oauth_data *data;
 
+	g_return_if_fail((method == NULL) == (url == NULL));
+
 	purple_debug_misc("gg", "ggp_oauth_request: requesting token...\n");
 
 	auth = gg_oauth_generate_header(method, url,
@@ -66,6 +72,8 @@ void ggp_oauth_request(PurpleConnection 
 	data->gc = gc;
 	data->callback = callback;
 	data->user_data = user_data;
+	data->sign_method = g_strdup(sign_method);
+	data->sign_url = g_strdup(sign_url);
 
 	purple_util_fetch_url_request(account, url, FALSE, NULL, TRUE, request,
 		FALSE, GGP_OAUTH_RESPONSE_MAX, ggp_oauth_request_token_got,
@@ -192,7 +200,7 @@ static void ggp_oauth_access_token_got(P
 	const gchar *error_message)
 {
 	ggp_oauth_data *data = user_data;
-	gchar *token;
+	gchar *token, *token_secret;
 	xmlnode *xml;
 	gboolean succ = TRUE;
 
@@ -206,6 +214,8 @@ static void ggp_oauth_access_token_got(P
 	}
 
 	succ &= ggp_xml_get_string(xml, "oauth_token", &token);
+	succ &= ggp_xml_get_string(xml, "oauth_token_secret",
+		&token_secret);
 	xmlnode_free(xml);
 	if (!succ || strlen(token) < 10)
 	{
@@ -215,11 +225,30 @@ static void ggp_oauth_access_token_got(P
 		return;
 	}
 
-	purple_debug_misc("gg", "ggp_oauth_access_token_got: "
-		"got access token\n");
-
-	data->callback(data->gc, token, data->user_data);
+	if (data->sign_url)
+	{
+		PurpleAccount *account;
+		gchar *auth;
+		
+		purple_debug_misc("gg", "ggp_oauth_access_token_got: "
+			"got access token, returning signed url\n");
+		
+		account = purple_connection_get_account(data->gc);
+		auth = gg_oauth_generate_header(
+			data->sign_method, data->sign_url,
+			purple_account_get_username(account),
+			purple_account_get_password(account),
+			token, token_secret);
+		data->callback(data->gc, auth, data->user_data);
+	}
+	else
+	{
+		purple_debug_misc("gg", "ggp_oauth_access_token_got: "
+			"got access token, returning it\n");
+		data->callback(data->gc, token, data->user_data);
+	}
 
 	g_free(token);
+	g_free(token_secret);
 	ggp_oauth_data_free(data);
 }
diff --git a/libpurple/protocols/gg/oauth/oauth-purple.h b/libpurple/protocols/gg/oauth/oauth-purple.h
--- a/libpurple/protocols/gg/oauth/oauth-purple.h
+++ b/libpurple/protocols/gg/oauth/oauth-purple.h
@@ -8,6 +8,6 @@ typedef void (*ggp_oauth_request_cb)(Pur
 	gpointer user_data);
 
 void ggp_oauth_request(PurpleConnection *gc, ggp_oauth_request_cb callback,
-	gpointer user_data);
+	gpointer user_data, const gchar *sign_method, const gchar *sign_url);
 
 #endif /* _GGP_OAUTH_PURPLE_H */
diff --git a/libpurple/protocols/gg/oauth/oauth.c b/libpurple/protocols/gg/oauth/oauth.c
--- a/libpurple/protocols/gg/oauth/oauth.c
+++ b/libpurple/protocols/gg/oauth/oauth.c
@@ -68,8 +68,8 @@ static char *gg_oauth_generate_signature
 	g_free(request_e);
 
 	consumer_secret_e = g_uri_escape_string(consumer_secret, NULL, FALSE);
-	token_secret_e = g_uri_escape_string(token_secret, NULL, FALSE);
-	key = g_strdup_printf("%s&%s", consumer_secret, token_secret ? token_secret : "");
+	token_secret_e = token_secret ? g_uri_escape_string(token_secret, NULL, FALSE) : NULL;
+	key = g_strdup_printf("%s&%s", consumer_secret_e, token_secret ? token_secret_e : "");
 	g_free(consumer_secret_e);
 	g_free(token_secret_e);
 
diff --git a/libpurple/protocols/gg/pubdir-prpl.c b/libpurple/protocols/gg/pubdir-prpl.c
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/gg/pubdir-prpl.c
@@ -0,0 +1,213 @@
+#include "pubdir-prpl.h"
+
+#include <debug.h>
+
+#include "oauth/oauth-purple.h"
+#include "xml.h"
+#include "utils.h"
+
+typedef struct
+{
+	PurpleConnection *gc;
+	ggp_pubdir_request_cb cb;
+	void *user_data;
+	union
+	{
+		struct
+		{
+			uin_t uin;
+		} user_info;
+	} params;
+} ggp_pubdir_request;
+
+void ggp_pubdir_request_free(ggp_pubdir_request *request);
+void ggp_pubdir_record_free(ggp_pubdir_record *records, int count);
+
+static void ggp_pubdir_get_info_got_token(PurpleConnection *gc,
+	const gchar *token, gpointer _request);
+static void ggp_pubdir_get_info_got_data(PurpleUtilFetchUrlData *url_data,
+	gpointer user_data, const gchar *url_text, gsize len,
+	const gchar *error_message);
+
+/******************************************************************************/
+
+void ggp_pubdir_record_free(ggp_pubdir_record *records, int count)
+{
+	int i;
+	for (i = 0; i < count; i++)
+	{
+		g_free(records[i].label);
+		g_free(records[i].city);
+	}
+	g_free(records);
+}
+
+void ggp_pubdir_request_free(ggp_pubdir_request *request)
+{
+	g_free(request);
+}
+
+void ggp_pubdir_get_info(PurpleConnection *gc, uin_t uin,
+	ggp_pubdir_request_cb cb, void *user_data)
+{
+	ggp_pubdir_request *request = g_new0(ggp_pubdir_request, 1);
+	gchar *url;
+
+	request->gc = gc;
+	request->cb = cb;
+	request->user_data = user_data;
+	request->params.user_info.uin = uin;
+
+	url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u", uin);
+	ggp_oauth_request(gc, ggp_pubdir_get_info_got_token, request,
+		"GET", url);
+	g_free(url);
+}
+
+static void ggp_pubdir_get_info_got_token(PurpleConnection *gc,
+	const gchar *token, gpointer _request)
+{
+	gchar *http_request;
+	ggp_pubdir_request *request = _request;
+	gchar *url;
+
+	if (!token || !PURPLE_CONNECTION_IS_VALID(gc))
+	{
+		request->cb(gc, -1, NULL, request->user_data);
+		ggp_pubdir_request_free(request);
+		return;
+	}
+
+	url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u",
+		request->params.user_info.uin);
+	http_request = g_strdup_printf(
+		"GET /users/%u HTTP/1.1\r\n"
+		"Host: api.gadu-gadu.pl\r\n"
+		"%s\r\n"
+		"\r\n",
+		request->params.user_info.uin,
+		token);
+	
+	purple_util_fetch_url_request(purple_connection_get_account(gc), url,
+		FALSE, NULL, TRUE, http_request, FALSE, -1,
+		ggp_pubdir_get_info_got_data, request);
+	
+	g_free(url);
+	g_free(http_request);
+}
+
+static void ggp_pubdir_get_info_got_data(PurpleUtilFetchUrlData *url_data,
+	gpointer _request, const gchar *url_text, gsize len,
+	const gchar *error_message)
+{
+	ggp_pubdir_request *request = _request;
+	PurpleConnection *gc = request->gc;
+	gboolean succ = TRUE;
+	xmlnode *xml;
+	unsigned int status, nextOffset;
+	int record_count, i;
+	ggp_pubdir_record *records;
+
+	purple_debug_misc("gg", "ggp_pubdir_get_info_got_data: [%s]\n", url_text);
+
+	xml = xmlnode_from_str(url_text, -1);



More information about the Commits mailing list