/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