3 * Purple is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * Rewritten from scratch during Google Summer of Code 2012
8 * by Tomek Wasilczyk (http://www.wasilczyk.pl).
10 * Previously implemented by:
11 * - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
12 * - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
13 * - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
38 #include "validator.h"
40 /*******************************************************************************
42 ******************************************************************************/
46 ggp_account_token_cb callback
;
49 } ggp_account_token_reqdata
;
51 static void ggp_account_token_response(struct gg_http
*h
, gboolean success
,
52 gboolean cancelled
, gpointer _reqdata
);
54 /******************************************************************************/
56 void ggp_account_token_free(ggp_account_token
*token
)
65 void ggp_account_token_request(PurpleConnection
*gc
,
66 ggp_account_token_cb callback
, void *user_data
)
69 ggp_account_token_reqdata
*reqdata
;
71 purple_debug_info("gg", "ggp_account_token_request: "
72 "requesting token...\n");
77 callback(gc
, NULL
, user_data
);
81 reqdata
= g_new(ggp_account_token_reqdata
, 1);
82 reqdata
->callback
= callback
;
84 reqdata
->user_data
= user_data
;
85 ggp_libgaduw_http_watch(gc
, h
, ggp_account_token_response
, reqdata
,
89 static void ggp_account_token_response(struct gg_http
*h
, gboolean success
,
90 gboolean cancelled
, gpointer _reqdata
)
92 ggp_account_token_reqdata
*reqdata
= _reqdata
;
93 struct gg_token
*token_info
;
94 ggp_account_token
*token
= NULL
;
96 g_assert(!(success
&& cancelled
));
99 purple_debug_info("gg", "ggp_account_token_handler: "
102 purple_debug_info("gg", "ggp_account_token_handler: "
105 token
= g_new(ggp_account_token
, 1);
107 token_info
= h
->data
;
108 token
->id
= g_strdup(token_info
->tokenid
);
109 token
->size
= h
->body_size
;
110 token
->data
= g_memdup(h
->body
, token
->size
);
111 token
->length
= token_info
->length
;
113 purple_debug_error("gg", "ggp_account_token_handler: error\n");
115 purple_connection_get_account(reqdata
->gc
),
117 _("Unable to fetch the token."), NULL
,
118 purple_request_cpar_from_connection(reqdata
->gc
));
121 reqdata
->callback(reqdata
->gc
, token
, reqdata
->user_data
);
125 gboolean
ggp_account_token_validate(ggp_account_token
*token
,
128 if (strlen(value
) != token
->length
)
130 return g_regex_match_simple("^[a-zA-Z0-9]+$", value
, 0, 0);
133 /*******************************************************************************
134 * New account registration.
135 ******************************************************************************/
139 ggp_account_token
*token
;
140 PurpleConnection
*gc
;
145 gboolean password_remember
;
146 } ggp_account_register_data
;
148 static void ggp_account_register_dialog(PurpleConnection
*gc
,
149 ggp_account_token
*token
, gpointer _register_data
);
150 static void ggp_account_register_dialog_ok(
151 ggp_account_register_data
*register_data
, PurpleRequestFields
*fields
);
152 static void ggp_account_register_dialog_cancel(
153 ggp_account_register_data
*register_data
, PurpleRequestFields
*fields
);
154 static void ggp_account_register_response(struct gg_http
*h
, gboolean success
,
155 gboolean cancelled
, gpointer _reqdata
);
156 static void ggp_account_register_completed(
157 ggp_account_register_data
*register_data
, gboolean success
);
159 #define GGP_ACCOUNT_REGISTER_TITLE _("Register New Gadu-Gadu Account")
161 /******************************************************************************/
163 void ggp_account_register(PurpleAccount
*account
)
165 PurpleConnection
*gc
= purple_account_get_connection(account
);
166 ggp_account_register_data
*register_data
;
168 purple_debug_info("gg", "ggp_account_register\n");
170 register_data
= g_new0(ggp_account_register_data
, 1);
171 register_data
->gc
= gc
;
172 register_data
->password_remember
= TRUE
;
174 ggp_account_token_request(gc
, ggp_account_register_dialog
,
178 static void ggp_account_register_dialog(PurpleConnection
*gc
,
179 ggp_account_token
*token
, gpointer _register_data
)
181 PurpleRequestFields
*fields
;
182 PurpleRequestFieldGroup
*main_group
, *password_group
, *token_group
;
183 PurpleRequestField
*field
, *field_password
;
184 ggp_account_register_data
*register_data
= _register_data
;
186 purple_debug_info("gg", "ggp_account_register_dialog(%p, %p, %p)\n",
187 gc
, token
, _register_data
);
189 ggp_account_register_completed(register_data
, FALSE
);
193 fields
= purple_request_fields_new();
194 main_group
= purple_request_field_group_new(NULL
);
195 purple_request_fields_add_group(fields
, main_group
);
197 field
= purple_request_field_string_new("email", _("Email"),
198 register_data
->email
, FALSE
);
199 purple_request_field_set_required(field
, TRUE
);
200 purple_request_field_set_validator(field
,
201 purple_request_field_email_validator
, NULL
);
202 purple_request_field_group_add_field(main_group
, field
);
204 password_group
= purple_request_field_group_new(_("Password"));
205 purple_request_fields_add_group(fields
, password_group
);
207 field
= purple_request_field_string_new("password1", _("Password"),
208 register_data
->password
, FALSE
);
209 purple_request_field_set_required(field
, TRUE
);
210 purple_request_field_string_set_masked(field
, TRUE
);
211 purple_request_field_set_validator(field
, ggp_validator_password
, NULL
);
212 purple_request_field_group_add_field(password_group
, field
);
213 field_password
= field
;
215 field
= purple_request_field_string_new("password2",
216 _("Password (again)"), register_data
->password
, FALSE
);
217 purple_request_field_set_required(field
, TRUE
);
218 purple_request_field_string_set_masked(field
, TRUE
);
219 purple_request_field_set_validator(field
, ggp_validator_password_equal
,
221 purple_request_field_group_add_field(password_group
, field
);
223 field
= purple_request_field_bool_new("password_remember",
224 _("Remember password"), register_data
->password_remember
);
225 purple_request_field_group_add_field(password_group
, field
);
227 token_group
= purple_request_field_group_new(_("CAPTCHA"));
228 purple_request_fields_add_group(fields
, token_group
);
230 field
= purple_request_field_string_new("token_value",
231 _("Enter text from image below"), register_data
->token_value
,
233 purple_request_field_set_required(field
, TRUE
);
234 purple_request_field_set_validator(field
, ggp_validator_token
, token
);
235 purple_request_field_group_add_field(token_group
, field
);
236 purple_debug_info("gg", "token set %p\n", register_data
->token
);
238 field
= purple_request_field_image_new("token_image", _("CAPTCHA"),
239 token
->data
, token
->size
);
240 purple_request_field_group_add_field(token_group
, field
);
242 register_data
->token
= token
;
244 purple_request_fields(gc
,
245 GGP_ACCOUNT_REGISTER_TITLE
,
246 GGP_ACCOUNT_REGISTER_TITLE
,
247 _("Please, fill in the following fields"), fields
,
248 _("OK"), G_CALLBACK(ggp_account_register_dialog_ok
),
249 _("Cancel"), G_CALLBACK(ggp_account_register_dialog_cancel
),
250 purple_request_cpar_from_connection(gc
), register_data
);
253 static void ggp_account_register_dialog_cancel(
254 ggp_account_register_data
*register_data
, PurpleRequestFields
*fields
)
256 purple_debug_info("gg", "ggp_account_register_dialog_cancel(%p, %p)\n",
257 register_data
, fields
);
259 ggp_account_register_completed(register_data
, FALSE
);
262 static void ggp_account_register_dialog_ok(
263 ggp_account_register_data
*register_data
, PurpleRequestFields
*fields
)
267 purple_debug_misc("gg", "ggp_account_register_dialog_ok(%p, %p)\n",
268 register_data
, fields
);
270 g_free(register_data
->email
);
271 g_free(register_data
->password
);
272 g_free(register_data
->token_value
);
274 register_data
->email
= g_strdup(
275 purple_request_fields_get_string(fields
, "email"));
276 register_data
->password
= g_strdup(
277 purple_request_fields_get_string(fields
, "password1"));
278 register_data
->password_remember
=
279 purple_request_fields_get_bool(fields
, "password_remember");
280 register_data
->token_value
= g_strdup(
281 purple_request_fields_get_string(fields
, "token_value"));
283 g_assert(register_data
->email
!= NULL
);
284 g_assert(register_data
->password
!= NULL
);
285 g_assert(register_data
->token_value
!= NULL
);
287 h
= gg_register3(register_data
->email
, register_data
->password
,
288 register_data
->token
->id
, register_data
->token_value
, TRUE
);
290 ggp_libgaduw_http_watch(register_data
->gc
, h
,
291 ggp_account_register_response
, register_data
, TRUE
);
294 static void ggp_account_register_response(struct gg_http
*h
, gboolean success
,
295 gboolean cancelled
, gpointer _register_data
)
297 ggp_account_register_data
*register_data
= _register_data
;
298 PurpleAccount
*account
=
299 purple_connection_get_account(register_data
->gc
);
300 struct gg_pubdir
*register_result
= h
->data
;
304 g_assert(!(success
&& cancelled
));
307 purple_debug_info("gg", "ggp_account_register_response: "
309 ggp_account_register_completed(register_data
, FALSE
);
312 if (!success
|| !register_result
->success
) {
313 /* TODO (libgadu 1.12.x): check register_result->error */
314 purple_debug_error("gg", "ggp_account_register_response: "
316 purple_notify_error(NULL
,
317 GGP_ACCOUNT_REGISTER_TITLE
,
318 _("Unable to register new account. "
319 "An unknown error occurred."), NULL
,
320 purple_request_cpar_from_account(account
));
321 ggp_account_register_completed(register_data
, FALSE
);
325 uin
= register_result
->uin
;
326 purple_debug_info("gg", "ggp_account_register_response: "
327 "registered uin %u\n", uin
);
329 purple_account_set_username(account
, ggp_uin_to_str(uin
));
330 purple_account_set_remember_password(account
,
331 register_data
->password_remember
);
332 purple_account_set_password(account
, register_data
->password
,
335 tmp
= g_strdup_printf(_("Your new GG number: %u."), uin
);
336 purple_notify_info(account
, GGP_ACCOUNT_REGISTER_TITLE
,
337 _("Registration completed successfully!"), tmp
,
338 purple_request_cpar_from_account(account
));
341 ggp_account_register_completed(register_data
, TRUE
);
344 static void ggp_account_register_completed(
345 ggp_account_register_data
*register_data
, gboolean success
)
347 PurpleAccount
*account
=
348 purple_connection_get_account(register_data
->gc
);
350 purple_debug_misc("gg", "ggp_account_register_completed: %d\n",
353 g_free(register_data
->email
);
354 g_free(register_data
->password
);
355 g_free(register_data
->token_value
);
356 ggp_account_token_free(register_data
->token
);
357 g_free(register_data
);
359 purple_account_disconnect(account
);
360 purple_account_register_completed(account
, success
);
363 /*******************************************************************************
365 ******************************************************************************/
369 ggp_account_token
*token
;
370 PurpleConnection
*gc
;
373 gchar
*password_current
;
376 } ggp_account_chpass_data
;
378 static void ggp_account_chpass_data_free(ggp_account_chpass_data
*chpass_data
);
379 static void ggp_account_chpass_dialog(PurpleConnection
*gc
,
380 ggp_account_token
*token
, gpointer _chpass_data
);
381 static void ggp_account_chpass_dialog_ok(
382 ggp_account_chpass_data
*chpass_data
, PurpleRequestFields
*fields
);
383 static void ggp_account_chpass_dialog_invalid(
384 ggp_account_chpass_data
*chpass_data
, const gchar
*message
);
385 static void ggp_account_chpass_dialog_cancel(
386 ggp_account_chpass_data
*chpass_data
, PurpleRequestFields
*fields
);
387 static void ggp_account_chpass_response(struct gg_http
*h
, gboolean success
,
388 gboolean cancelled
, gpointer _chpass_data
);
390 #define GGP_ACCOUNT_CHPASS_TITLE _("Password change")
392 /******************************************************************************/
394 static void ggp_account_chpass_data_free(ggp_account_chpass_data
*chpass_data
)
396 g_free(chpass_data
->email
);
397 g_free(chpass_data
->password_current
);
398 g_free(chpass_data
->password_new
);
399 g_free(chpass_data
->token_value
);
400 ggp_account_token_free(chpass_data
->token
);
404 void ggp_account_chpass(PurpleConnection
*gc
)
406 ggp_account_chpass_data
*chpass_data
;
408 purple_debug_info("gg", "ggp_account_chpass\n");
410 chpass_data
= g_new0(ggp_account_chpass_data
, 1);
411 chpass_data
->gc
= gc
;
413 ggp_account_token_request(gc
, ggp_account_chpass_dialog
, chpass_data
);
416 static void ggp_account_chpass_dialog(PurpleConnection
*gc
,
417 ggp_account_token
*token
, gpointer _chpass_data
)
419 ggp_account_chpass_data
*chpass_data
= _chpass_data
;
420 PurpleAccount
*account
= purple_connection_get_account(chpass_data
->gc
);
421 PurpleRequestFields
*fields
;
422 PurpleRequestFieldGroup
*main_group
, *password_group
, *token_group
;
423 PurpleRequestField
*field
, *field_password
;
426 purple_debug_info("gg", "ggp_account_chpass_dialog(%p, %p, %p)\n",
427 gc
, token
, _chpass_data
);
429 ggp_account_chpass_data_free(chpass_data
);
433 fields
= purple_request_fields_new();
434 main_group
= purple_request_field_group_new(NULL
);
435 purple_request_fields_add_group(fields
, main_group
);
437 field
= purple_request_field_string_new("email",
438 _("New email address"), chpass_data
->email
, FALSE
);
439 purple_request_field_set_required(field
, TRUE
);
440 purple_request_field_set_validator(field
,
441 purple_request_field_email_validator
, NULL
);
442 purple_request_field_group_add_field(main_group
, field
);
444 password_group
= purple_request_field_group_new(_("Password"));
445 purple_request_fields_add_group(fields
, password_group
);
447 field
= purple_request_field_string_new("password_current",
448 _("Current password"), chpass_data
->password_current
, FALSE
);
449 purple_request_field_set_required(field
, TRUE
);
450 purple_request_field_string_set_masked(field
, TRUE
);
451 purple_request_field_group_add_field(password_group
, field
);
453 field
= purple_request_field_string_new("password_new1",
454 _("Password"), chpass_data
->password_new
, FALSE
);
455 purple_request_field_set_required(field
, TRUE
);
456 purple_request_field_string_set_masked(field
, TRUE
);
457 purple_request_field_set_validator(field
, ggp_validator_password
, NULL
);
458 purple_request_field_group_add_field(password_group
, field
);
459 field_password
= field
;
461 field
= purple_request_field_string_new("password_new2",
462 _("Password (retype)"), chpass_data
->password_new
, FALSE
);
463 purple_request_field_set_required(field
, TRUE
);
464 purple_request_field_string_set_masked(field
, TRUE
);
465 purple_request_field_set_validator(field
, ggp_validator_password_equal
,
467 purple_request_field_group_add_field(password_group
, field
);
469 token_group
= purple_request_field_group_new(_("CAPTCHA"));
470 purple_request_fields_add_group(fields
, token_group
);
472 field
= purple_request_field_string_new("token_value",
473 _("Enter text from image below"), chpass_data
->token_value
,
475 purple_request_field_set_required(field
, TRUE
);
476 purple_request_field_set_validator(field
, ggp_validator_token
, token
);
477 purple_request_field_group_add_field(token_group
, field
);
479 field
= purple_request_field_image_new("token_image", _("CAPTCHA"),
480 token
->data
, token
->size
);
481 purple_request_field_group_add_field(token_group
, field
);
483 chpass_data
->token
= token
;
485 primary
= g_strdup_printf(_("Change password for %s"),
486 purple_account_get_username(account
));
488 purple_request_fields(gc
, GGP_ACCOUNT_CHPASS_TITLE
, primary
,
489 _("Please enter your current password and your new password."),
491 _("OK"), G_CALLBACK(ggp_account_chpass_dialog_ok
),
492 _("Cancel"), G_CALLBACK(ggp_account_chpass_dialog_cancel
),
493 purple_request_cpar_from_connection(gc
), chpass_data
);
498 static void ggp_account_chpass_dialog_ok(
499 ggp_account_chpass_data
*chpass_data
, PurpleRequestFields
*fields
)
501 PurpleAccount
*account
= purple_connection_get_account(chpass_data
->gc
);
505 purple_debug_misc("gg", "ggp_account_chpass_dialog_ok(%p, %p)\n",
506 chpass_data
, fields
);
508 g_free(chpass_data
->email
);
509 g_free(chpass_data
->password_current
);
510 g_free(chpass_data
->password_new
);
511 g_free(chpass_data
->token_value
);
513 chpass_data
->email
= g_strdup(
514 purple_request_fields_get_string(fields
, "email"));
515 chpass_data
->password_current
= g_strdup(
516 purple_request_fields_get_string(fields
, "password_current"));
517 chpass_data
->password_new
= g_strdup(
518 purple_request_fields_get_string(fields
, "password_new1"));
519 chpass_data
->token_value
= g_strdup(
520 purple_request_fields_get_string(fields
, "token_value"));
522 g_assert(chpass_data
->email
!= NULL
);
523 g_assert(chpass_data
->password_current
!= NULL
);
524 g_assert(chpass_data
->password_new
!= NULL
);
525 g_assert(chpass_data
->token_value
!= NULL
);
527 if (g_utf8_collate(chpass_data
->password_current
,
528 purple_connection_get_password(chpass_data
->gc
)) != 0)
530 g_free(chpass_data
->password_current
);
531 chpass_data
->password_current
= NULL
;
532 ggp_account_chpass_dialog_invalid(chpass_data
,
533 _("Your current password is different from the one that"
537 if (g_utf8_collate(chpass_data
->password_current
,
538 chpass_data
->password_new
) == 0)
540 g_free(chpass_data
->password_new
);
541 chpass_data
->password_new
= NULL
;
542 ggp_account_chpass_dialog_invalid(chpass_data
,
543 _("New password have to be different from the current "
548 uin
= ggp_str_to_uin(purple_account_get_username(account
));
549 purple_debug_info("gg", "ggp_account_chpass_dialog_ok: validation ok "
550 "[token id=%s, value=%s]\n",
551 chpass_data
->token
->id
, chpass_data
->token_value
);
552 h
= gg_change_passwd4(uin
, chpass_data
->email
,
553 chpass_data
->password_current
, chpass_data
->password_new
,
554 chpass_data
->token
->id
, chpass_data
->token_value
, TRUE
);
556 ggp_libgaduw_http_watch(chpass_data
->gc
, h
,
557 ggp_account_chpass_response
, chpass_data
, TRUE
);
560 static void ggp_account_chpass_dialog_invalid(
561 ggp_account_chpass_data
*chpass_data
, const gchar
*message
)
563 purple_debug_warning("gg", "ggp_account_chpass_dialog_invalid: %s\n",
565 ggp_account_chpass_dialog(chpass_data
->gc
, chpass_data
->token
,
567 purple_notify_error(purple_connection_get_account(chpass_data
->gc
),
568 GGP_ACCOUNT_CHPASS_TITLE
, message
, NULL
,
569 purple_request_cpar_from_connection(chpass_data
->gc
));
572 static void ggp_account_chpass_dialog_cancel(
573 ggp_account_chpass_data
*chpass_data
, PurpleRequestFields
*fields
)
575 ggp_account_chpass_data_free(chpass_data
);
578 static void ggp_account_chpass_response(struct gg_http
*h
, gboolean success
,
579 gboolean cancelled
, gpointer _chpass_data
)
581 ggp_account_chpass_data
*chpass_data
= _chpass_data
;
582 PurpleAccount
*account
=
583 purple_connection_get_account(chpass_data
->gc
);
584 struct gg_pubdir
*chpass_result
= h
->data
;
586 g_assert(!(success
&& cancelled
));
589 purple_debug_info("gg", "ggp_account_chpass_response: "
591 ggp_account_chpass_data_free(chpass_data
);
594 if (!success
|| !chpass_result
->success
) {
595 /* TODO (libgadu 1.12.x): check chpass_result->error */
596 purple_debug_error("gg", "ggp_account_chpass_response: "
598 purple_notify_error(NULL
,
599 GGP_ACCOUNT_CHPASS_TITLE
,
600 _("Unable to change password. "
601 "An unknown error occurred."), NULL
,
602 purple_request_cpar_from_connection(chpass_data
->gc
));
603 ggp_account_chpass_data_free(chpass_data
);
607 purple_debug_info("gg", "ggp_account_chpass_response: "
608 "password changed\n");
610 purple_account_set_password(account
, chpass_data
->password_new
,
613 purple_notify_info(account
, GGP_ACCOUNT_CHPASS_TITLE
,
614 _("Your password has been changed."), NULL
,
615 purple_request_cpar_from_connection(chpass_data
->gc
));
617 ggp_account_chpass_data_free(chpass_data
);
619 /* TODO: reconnect / check how it is done in original client */
620 purple_account_disconnect(account
);