Gadu-Gadu: refactoring of account registration done soc.2012.gg

Mon, 02 Jul 2012 00:58:03 +0200

author
Tomasz Wasilczyk <tomkiewicz@cpw.pidgin.im>
date
Mon, 02 Jul 2012 00:58:03 +0200
branch
soc.2012.gg
changeset 33309
bc2f2ea7b5ab
parent 33308
140aa3ad4cae
child 33310
5d38cff87be2

Gadu-Gadu: refactoring of account registration done

libpurple/protocols/gg/account.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/account.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/libgaduw.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/libgaduw.h file | annotate | diff | comparison | revisions
libpurple/protocols/gg/purplew.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/utils.c file | annotate | diff | comparison | revisions
libpurple/protocols/gg/utils.h file | annotate | diff | comparison | revisions
--- a/libpurple/protocols/gg/account.c	Sat Jun 30 19:56:46 2012 +0200
+++ b/libpurple/protocols/gg/account.c	Mon Jul 02 00:58:03 2012 +0200
@@ -18,27 +18,30 @@
 	ggp_account_token_cb callback;
 	PurpleConnection *gc;
 	void *user_data;
-
-	ggp_libgaduw_http_req *req;
 } ggp_account_token_reqdata;
 
-static void ggp_account_token_response(struct gg_http *h, gboolean success, gboolean cancelled, gpointer _reqdata);
+static void ggp_account_token_response(struct gg_http *h, gboolean success,
+	gboolean cancelled, gpointer _reqdata);
 
 /******************************************************************************/
 
 void ggp_account_token_free(ggp_account_token *token)
 {
+	if (!token)
+		return;
 	g_free(token->id);
 	g_free(token->data);
 	g_free(token);
 }
 
-void ggp_account_token_request(PurpleConnection *gc, ggp_account_token_cb callback, void *user_data)
+void ggp_account_token_request(PurpleConnection *gc,
+	ggp_account_token_cb callback, void *user_data)
 {
 	struct gg_http *h;
 	ggp_account_token_reqdata *reqdata;
 
-	purple_debug_info("gg", "ggp_account_token_request: requesting token...\n");
+	purple_debug_info("gg", "ggp_account_token_request: "
+		"requesting token...\n");
 
 	if (!ggp_deprecated_setup_proxy(gc))
 	{
@@ -58,7 +61,8 @@
 	reqdata->callback = callback;
 	reqdata->gc = gc;
 	reqdata->user_data = user_data;
-	reqdata->req = ggp_libgaduw_http_watch(gc, h, ggp_account_token_response, reqdata, TRUE);
+	ggp_libgaduw_http_watch(gc, h, ggp_account_token_response, reqdata,
+		TRUE);
 }
 
 static void ggp_account_token_response(struct gg_http *h, gboolean success,
@@ -71,10 +75,12 @@
 	g_assert(!(success && cancelled));
 	
 	if (cancelled)
-		purple_debug_info("gg", "ggp_account_token_handler: cancelled\n");
+		purple_debug_info("gg", "ggp_account_token_handler: "
+			"cancelled\n");
 	else if (success)
 	{
-		purple_debug_info("gg", "ggp_account_token_handler: got token\n");
+		purple_debug_info("gg", "ggp_account_token_handler: "
+			"got token\n");
 	
 		token = g_new(ggp_account_token, 1);
 	
@@ -82,6 +88,7 @@
 		token->id = g_strdup(token_info->tokenid);
 		token->size = h->body_size;
 		token->data = g_memdup(h->body, token->size);
+		token->length = token_info->length;
 	}
 	else
 	{
@@ -89,10 +96,9 @@
 		purple_notify_error(
 			purple_connection_get_account(reqdata->gc),
 			_("Token Error"),
-			_("Unable to fetch the token.\n"), NULL);
+			_("Unable to fetch the token."), NULL);
 	}
 	
-	gg_token_free(h);
 	reqdata->callback(reqdata->gc, token, reqdata->user_data);
 	g_free(reqdata);
 }
@@ -105,93 +111,118 @@
 {
 	ggp_account_token *token;
 	PurpleConnection *gc;
+	
+	gchar *email;
+	gchar *password;
+	gchar *token_value;
+	gboolean password_remember;
 } ggp_account_register_data;
 
-static void ggp_account_register_dialog(PurpleConnection *gc, ggp_account_token *token, gpointer user_data);
-static void ggp_account_register_dialog_ok(ggp_account_register_data *register_data, PurpleRequestFields *fields);
-static void ggp_account_register_dialog_cancel(ggp_account_register_data *register_data, PurpleRequestFields *fields);
-static void ggp_account_register_completed(ggp_account_register_data *register_data, gboolean success);
+static void ggp_account_register_dialog(PurpleConnection *gc,
+	ggp_account_token *token, gpointer user_data);
+static void ggp_account_register_dialog_ok(
+	ggp_account_register_data *register_data, PurpleRequestFields *fields);
+static void ggp_account_register_dialog_invalid(
+	ggp_account_register_data *register_data, const gchar *message);
+static void ggp_account_register_dialog_cancel(
+	ggp_account_register_data *register_data, PurpleRequestFields *fields);
+static void ggp_account_register_response(struct gg_http *h, gboolean success,
+	gboolean cancelled, gpointer _reqdata);
+static void ggp_account_register_completed(
+	ggp_account_register_data *register_data, gboolean success);
+
+#define GGP_ACCOUNT_REGISTER_TITLE _("Register New Gadu-Gadu Account")
 
 /******************************************************************************/
 
-static void ggp_account_register_completed(ggp_account_register_data *register_data, gboolean success)
-{
-	PurpleAccount *account = purple_connection_get_account(register_data->gc);
-	
-	ggp_account_token_free(register_data->token);
-	g_free(register_data);
-	
-	purple_account_disconnect(account);
-	purple_account_register_completed(account, TRUE);
-}
-
 void ggp_account_register(PurpleAccount *account)
 {
 	PurpleConnection *gc = purple_account_get_connection(account);
+	ggp_account_register_data *register_data;
 	
 	purple_debug_info("gg", "ggp_account_register\n");
 	
-	ggp_account_token_request(gc, ggp_account_register_dialog, NULL);
+	register_data = g_new0(ggp_account_register_data, 1);
+	register_data->gc = gc;
+	register_data->password_remember = TRUE;
+	
+	ggp_account_token_request(gc, ggp_account_register_dialog,
+		register_data);
 }
 
-static void ggp_account_register_dialog(PurpleConnection *gc, ggp_account_token *token, gpointer user_data)
+static void ggp_account_register_dialog(PurpleConnection *gc,
+	ggp_account_token *token, gpointer _register_data)
 {
 	PurpleAccount *account = purple_connection_get_account(gc);
 	PurpleRequestFields *fields;
-	PurpleRequestFieldGroup *group;
+	PurpleRequestFieldGroup *main_group, *password_group, *token_group;
 	PurpleRequestField *field;
-	ggp_account_register_data *register_data;
+	ggp_account_register_data *register_data = _register_data;
 	
 	purple_debug_info("gg", "ggp_account_register_dialog(%x, %x, %x)\n",
-		(unsigned int)gc, (unsigned int)token, (unsigned int)user_data);
+		(unsigned int)gc, (unsigned int)token,
+		(unsigned int)_register_data);
 	if (!token)
 	{
-		purple_account_disconnect(account);
-		purple_account_register_completed(account, FALSE);
+		ggp_account_register_completed(register_data, FALSE);
 		return;
 	}
 	
-	// TODO: required fields
 	fields = purple_request_fields_new();
-	group = purple_request_field_group_new(NULL);
-	purple_request_fields_add_group(fields, group);
+	main_group = purple_request_field_group_new(NULL);
+	purple_request_fields_add_group(fields, main_group);
 	
-	field = purple_request_field_string_new("email", _("Email"), "", FALSE);
-	purple_request_field_group_add_field(group, field);
-	
-	field = purple_request_field_string_new("password1", _("Password"), "",
-		FALSE);
+	field = purple_request_field_string_new("email", _("Email"),
+		register_data->email, FALSE);
+	purple_request_field_set_required(field, TRUE);
+	purple_request_field_group_add_field(main_group, field);
+
+	password_group = purple_request_field_group_new(_("Password"));
+	purple_request_fields_add_group(fields, password_group);
+
+	field = purple_request_field_string_new("password1", _("Password"),
+		register_data->password, FALSE);
+	purple_request_field_set_required(field, TRUE);
 	purple_request_field_string_set_masked(field, TRUE);
-	purple_request_field_group_add_field(group, field);
+	purple_request_field_group_add_field(password_group, field);
 	
-	field = purple_request_field_string_new("password2", _("Password (again)"), "",
-		FALSE);
+	field = purple_request_field_string_new("password2",
+		_("Password (again)"), register_data->password, FALSE);
+	purple_request_field_set_required(field, TRUE);
 	purple_request_field_string_set_masked(field, TRUE);
-	purple_request_field_group_add_field(group, field);
+	purple_request_field_group_add_field(password_group, field);
+	
+	field = purple_request_field_bool_new("password_remember",
+		_("Remember password"), register_data->password_remember);
+	purple_request_field_group_add_field(password_group, field);
 	
-	//TODO: move it into a new group?
+	token_group = purple_request_field_group_new(_("Captcha"));
+	purple_request_fields_add_group(fields, token_group);
+	
 	field = purple_request_field_string_new("token_value",
-		_("Enter captcha text"), "", FALSE);
-	purple_request_field_group_add_field(group, field);
+		_("Enter text from image below"), register_data->token_value,
+		FALSE);
+	purple_request_field_set_required(field, TRUE);
+	purple_request_field_group_add_field(token_group, field);
 	
 	field = purple_request_field_image_new("token_image", _("Captcha"),
 		token->data, token->size);
-	purple_request_field_group_add_field(group, field);
+	purple_request_field_group_add_field(token_group, field);
 	
-	register_data = g_new(ggp_account_register_data, 1);
-	register_data->gc = gc;
 	register_data->token = token;
+	register_data->password = NULL;
 	
 	purple_request_fields(gc,
-		_("Register New Gadu-Gadu Account"),
-		_("Register New Gadu-Gadu Account"),
+		GGP_ACCOUNT_REGISTER_TITLE,
+		GGP_ACCOUNT_REGISTER_TITLE,
 		_("Please, fill in the following fields"), fields,
 		_("OK"), G_CALLBACK(ggp_account_register_dialog_ok),
 		_("Cancel"), G_CALLBACK(ggp_account_register_dialog_cancel),
 		account, NULL, NULL, register_data);
 }
 
-static void ggp_account_register_dialog_cancel(ggp_account_register_data *register_data, PurpleRequestFields *fields)
+static void ggp_account_register_dialog_cancel(
+	ggp_account_register_data *register_data, PurpleRequestFields *fields)
 {
 	purple_debug_info("gg", "ggp_account_register_dialog_cancel(%x, %x)\n",
 		(unsigned int)register_data, (unsigned int)fields);
@@ -199,60 +230,150 @@
 	ggp_account_register_completed(register_data, FALSE);
 }
 
-static void ggp_account_register_dialog_ok(ggp_account_register_data *register_data, PurpleRequestFields *fields)
+static void ggp_account_register_dialog_ok(
+	ggp_account_register_data *register_data, PurpleRequestFields *fields)
 {
-	PurpleAccount *account = purple_connection_get_account(register_data->gc);
-	const gchar *email, *password1, *password2, *token_value;
+	const gchar *password2;
 	struct gg_http *h;
-	struct gg_pubdir *register_result;
-	uin_t uin;
 
-	purple_debug_info("gg", "ggp_account_register_dialog_ok(%x, %x)\n",
+	purple_debug_misc("gg", "ggp_account_register_dialog_ok(%x, %x)\n",
 		(unsigned int)register_data, (unsigned int)fields);
 
-	email = purple_request_fields_get_string(fields, "email");
-	password1 = purple_request_fields_get_string(fields, "password1");
+	g_free(register_data->email);
+	g_free(register_data->password);
+	g_free(register_data->token_value);
+	
+	register_data->email = g_strdup(
+		purple_request_fields_get_string(fields, "email"));
+	register_data->password = g_strdup(
+		purple_request_fields_get_string(fields, "password1"));
 	password2 = purple_request_fields_get_string(fields, "password2");
-	token_value = purple_request_fields_get_string(fields, "token_value");
+	register_data->password_remember =
+		purple_request_fields_get_bool(fields, "password_remember");
+	register_data->token_value = g_strdup(
+		purple_request_fields_get_string(fields, "token_value"));
 
-	g_assert(email != NULL);
-	g_assert(password1 != NULL);
+	g_assert(register_data->email != NULL);
+	g_assert(register_data->password != NULL);
 	g_assert(password2 != NULL);
-	g_assert(token_value != NULL);
+	g_assert(register_data->token_value != NULL);
 
-	if (g_utf8_collate(password1, password2) != 0)
+	if (g_utf8_collate(register_data->password, password2) != 0)
+	{
+		g_free(register_data->password);
+		register_data->password = NULL;
+		ggp_account_register_dialog_invalid(register_data,
+			_("Passwords do not match"));
+		return;
+	}
+	if (!ggp_password_validate(register_data->password))
+	{
+		g_free(register_data->password);
+		register_data->password = NULL;
+		ggp_account_register_dialog_invalid(register_data,
+			_("Password can contain 6-15 alphanumeric characters"));
+		return;
+	}
+	if (!purple_email_is_valid(register_data->email))
+	{
+		ggp_account_register_dialog_invalid(register_data,
+			_("Invalid email address"));
+		return;
+	}
+	if (strlen(register_data->token_value) != register_data->token->length
+		|| !g_regex_match_simple("^[a-zA-Z0-9]+$",
+			register_data->token_value, 0, 0))
 	{
-		purple_debug_warning("gg", "ggp_account_register_dialog_ok: validation failed - passwords does not match\n");
-		purple_notify_error(purple_connection_get_account(register_data->gc),
-			_("TODO: title"),
-			_("Passwords do not match"), NULL);
+		ggp_account_register_dialog_invalid(register_data,
+			_("Captcha validation failed"));
+		return;
+	}
+
+	purple_debug_info("gg", "ggp_account_register_dialog_ok: validation ok "
+		"[token id=%s, value=%s]\n",
+		register_data->token->id, register_data->token_value);
+	h = gg_register3(register_data->email, register_data->password,
+		register_data->token->id, register_data->token_value, TRUE);
+	
+	ggp_libgaduw_http_watch(register_data->gc, h,
+		ggp_account_register_response, register_data, TRUE);
+}
+
+static void ggp_account_register_dialog_invalid(
+	ggp_account_register_data *register_data, const gchar *message)
+{
+	purple_debug_warning("gg", "ggp_account_register_dialog_invalid: %s\n",
+		message);
+	ggp_account_register_dialog(register_data->gc, register_data->token,
+		register_data);
+	purple_notify_error(purple_connection_get_account(register_data->gc),
+		GGP_ACCOUNT_REGISTER_TITLE, message, NULL);
+}
+
+static void ggp_account_register_response(struct gg_http *h, gboolean success,
+	gboolean cancelled, gpointer _register_data)
+{
+	ggp_account_register_data *register_data = _register_data;
+	PurpleAccount *account =
+		purple_connection_get_account(register_data->gc);
+	struct gg_pubdir *register_result = h->data;
+	uin_t uin;
+	gchar *tmp;
+	
+	g_assert(!(success && cancelled));
+	
+	if (cancelled)
+	{
+		purple_debug_info("gg", "ggp_account_register_response: "
+			"cancelled\n");
+		ggp_account_register_completed(register_data, FALSE);
+		return;
+	}
+	if (!success || !register_result->success)
+	{
+		//TODO (libgadu 1.12.x): check register_result->error
+		purple_debug_error("gg", "ggp_account_register_response: "
+			"error\n");
+		purple_notify_error(NULL,
+			GGP_ACCOUNT_REGISTER_TITLE,
+			_("Unable to register new account. "
+			"An unknown error occurred."), NULL);
 		ggp_account_register_completed(register_data, FALSE);
 		return;
 	}
 
-	purple_debug_info("gg", "ggp_account_register_dialog_ok: validation ok [token id=%s, value=%s]\n",
-		register_data->token->id, token_value);
-	h = gg_register3(email, password1, register_data->token->id, token_value, 0); // TODO: async (use code from ggp_account_token_handler)
-	if (h == NULL || !(register_result = h->data) || !register_result->success)
-	{
-		purple_debug_warning("gg", "ggp_account_register_dialog_ok: registration failed\n");
-		purple_notify_error(purple_connection_get_account(register_data->gc),
-			_("TODO: title"),
-			_("Unable to register new account.  An unknown error occurred."), NULL);
-		ggp_account_register_completed(register_data, FALSE);
-		return;
-	}
 	uin = register_result->uin;
-	
-	purple_debug_info("gg", "ggp_account_register_dialog_ok: registered uin %u\n", uin);
-	gg_register_free(h);
+	purple_debug_info("gg", "ggp_account_register_dialog_ok: "
+		"registered uin %u\n", uin);
 	
 	purple_account_set_username(account, ggp_uin_to_str(uin));
-	purple_account_set_remember_password(account, TRUE); //TODO: option
-	purple_account_set_password(account, password1);
+	purple_account_set_remember_password(account,
+		register_data->password_remember);
+	purple_account_set_password(account, register_data->password);
 	
-	purple_notify_info(NULL, _("New Gadu-Gadu Account Registered"),
-		_("Registration completed successfully!"), NULL); //TODO: show new UIN
+	tmp = g_strdup_printf(_("Your new GG number: %u."), uin);
+	purple_notify_info(NULL, GGP_ACCOUNT_REGISTER_TITLE,
+		_("Registration completed successfully!"), tmp);
+	g_free(tmp);
 	
 	ggp_account_register_completed(register_data, TRUE);
 }
+
+static void ggp_account_register_completed(
+	ggp_account_register_data *register_data, gboolean success)
+{
+	PurpleAccount *account =
+		purple_connection_get_account(register_data->gc);
+
+	purple_debug_misc("gg", "ggp_account_register_completed: %d\n",
+		success);
+	
+	g_free(register_data->email);
+	g_free(register_data->password);
+	g_free(register_data->token_value);
+	ggp_account_token_free(register_data->token);
+	g_free(register_data);
+	
+	purple_account_disconnect(account);
+	purple_account_register_completed(account, success);
+}
--- a/libpurple/protocols/gg/account.h	Sat Jun 30 19:56:46 2012 +0200
+++ b/libpurple/protocols/gg/account.h	Mon Jul 02 00:58:03 2012 +0200
@@ -8,14 +8,17 @@
 	gchar *id;
 	gpointer data;
 	size_t size;
+	int length;
 } ggp_account_token;
 
 /**
  * token must be free'd with ggp_account_token_free
  */
-typedef void (*ggp_account_token_cb)(PurpleConnection *gc, ggp_account_token *token, gpointer user_data);
+typedef void (*ggp_account_token_cb)(PurpleConnection *gc,
+	ggp_account_token *token, gpointer user_data);
 
-void ggp_account_token_request(PurpleConnection *gc, ggp_account_token_cb callback, void *user_data);
+void ggp_account_token_request(PurpleConnection *gc,
+	ggp_account_token_cb callback, void *user_data);
 void ggp_account_token_free(ggp_account_token *token);
 
 
--- a/libpurple/protocols/gg/libgaduw.c	Sat Jun 30 19:56:46 2012 +0200
+++ b/libpurple/protocols/gg/libgaduw.c	Mon Jul 02 00:58:03 2012 +0200
@@ -24,8 +24,8 @@
 	gpointer user_data, gboolean show_processing)
 {
 	ggp_libgaduw_http_req *req;
-	purple_debug_misc("gg", "ggp_libgaduw_http_watch(h=%x, show_processing=%d)\n",
-		(unsigned int)h, show_processing);
+	purple_debug_misc("gg", "ggp_libgaduw_http_watch(h=%x, "
+		"show_processing=%d)\n", (unsigned int)h, show_processing);
 	
 	req = g_new(ggp_libgaduw_http_req, 1);
 	req->user_data = user_data;
@@ -55,7 +55,7 @@
 {
 	ggp_libgaduw_http_req *req = _req;
 	
-	if (gg_token_watch_fd(req->h) == -1 || req->h->state == GG_STATE_ERROR)
+	if (req->h->callback(req->h) == -1 || req->h->state == GG_STATE_ERROR)
 	{
 		purple_debug_error("gg", "ggp_libgaduw_http_handler: failed to "
 			"make http request: %d\n", req->h->error);
@@ -107,5 +107,6 @@
 	}
 	purple_input_remove(req->inpa);
 	req->cb(req->h, success, req->cancelled, req->user_data);
+	req->h->destroy(req->h);
 	g_free(req);
 }
--- a/libpurple/protocols/gg/libgaduw.h	Sat Jun 30 19:56:46 2012 +0200
+++ b/libpurple/protocols/gg/libgaduw.h	Mon Jul 02 00:58:03 2012 +0200
@@ -21,7 +21,8 @@
 } ggp_libgaduw_http_req;
 
 ggp_libgaduw_http_req * ggp_libgaduw_http_watch(PurpleConnection *gc,
-	struct gg_http *h, ggp_libgaduw_http_cb cb, gpointer user_data, gboolean show_processing);
+	struct gg_http *h, ggp_libgaduw_http_cb cb, gpointer user_data,
+	gboolean show_processing);
 void ggp_libgaduw_http_cancel(ggp_libgaduw_http_req *req);
 
 
--- a/libpurple/protocols/gg/purplew.c	Sat Jun 30 19:56:46 2012 +0200
+++ b/libpurple/protocols/gg/purplew.c	Mon Jul 02 00:58:03 2012 +0200
@@ -1,6 +1,7 @@
 #include "purplew.h"
 
 #include <request.h>
+#include <debug.h>
 
 guint ggp_purplew_http_input_add(struct gg_http *http_req,
 	PurpleInputFunction func, gpointer user_data)
@@ -13,6 +14,10 @@
 	if (check & GG_CHECK_WRITE)
 		cond |= PURPLE_INPUT_WRITE;
 
+	//TODO: verbose mode
+	//purple_debug_misc("gg", "ggp_purplew_http_input_add: "
+	//	"[req=%x, fd=%d, cond=%d]\n",
+	//	(unsigned int)http_req, http_req->fd, cond);
 	return purple_input_add(http_req->fd, cond, func, user_data);
 }
 
--- a/libpurple/protocols/gg/utils.c	Sat Jun 30 19:56:46 2012 +0200
+++ b/libpurple/protocols/gg/utils.c	Mon Jul 02 00:58:03 2012 +0200
@@ -85,3 +85,12 @@
 {
 	return ggp_convert(src, "CP1250", "UTF-8");
 }
+
+gboolean ggp_password_validate(const gchar *password)
+{
+	const int len = strlen(password);
+	if (len < 6 || len > 15)
+		return FALSE;
+	return g_regex_match_simple("^[ a-zA-Z0-9~`!@#$%^&*()_+=[\\]{};':\",./?"
+		"<>\\\\|-]+$", password, 0, 0);
+}
--- a/libpurple/protocols/gg/utils.h	Sat Jun 30 19:56:46 2012 +0200
+++ b/libpurple/protocols/gg/utils.h	Mon Jul 02 00:58:03 2012 +0200
@@ -64,4 +64,6 @@
  */
 gchar * ggp_convert_from_cp1250(const gchar *src);
 
+gboolean ggp_password_validate(const gchar *password);
+
 #endif /* _GGP_UTILS_H */

mercurial