Irreco for N900 (Maemo 5) update. Push for 0.8.* changes.
[irreco.git] / irreco / src / core / irreco_login_dlg.c
blobf5b4dfb85b291392dbdaac9a1755c517b8cd925a
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2008 Sami Mäki (kasmra@xob.kapsi.fi)
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "irreco_login_dlg.h"
21 #include "irreco_webdb_register_dlg.h"
23 /* Include the prototypes for GConf client functions. */
24 #include <gconf/gconf-client.h>
26 /**
27 * @addtogroup IrrecoLoginDlg
28 * @ingroup Irreco
30 * Allow user to login into Irreco WebDB.
32 * @{
35 /**
36 * @file
37 * Source file of @ref IrrecoLoginDlg.
42 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
43 /* Datatypes */
44 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
46 #define APP_NAME "irreco"
47 #define GC_ROOT "/apps/Maemo/" APP_NAME "/"
49 /** Button response codes. */
50 enum {
51 IRRECO_LOGIN_REGISTER
55 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
56 /* Prototypes */
57 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
61 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
62 /* Construction & Destruction */
63 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
65 /**
66 * @name Construction & Destruction
67 * @{
70 /* Add functions here. */
72 G_DEFINE_TYPE (IrrecoLoginDlg, irreco_login_dlg, IRRECO_TYPE_DLG)
74 static void irreco_login_dlg_dispose (GObject *object)
76 if (G_OBJECT_CLASS (irreco_login_dlg_parent_class)->dispose)
77 G_OBJECT_CLASS (
78 irreco_login_dlg_parent_class)->dispose (object);
81 static void irreco_login_dlg_finalize (GObject *object)
83 if (G_OBJECT_CLASS (irreco_login_dlg_parent_class)->finalize)
84 G_OBJECT_CLASS (
85 irreco_login_dlg_parent_class)->finalize (object);
88 static void irreco_login_dlg_class_init (IrrecoLoginDlgClass *klass)
90 GObjectClass *object_class = G_OBJECT_CLASS (klass);
92 object_class->dispose = irreco_login_dlg_dispose;
93 object_class->finalize = irreco_login_dlg_finalize;
96 static void irreco_login_dlg_init (IrrecoLoginDlg *self)
98 GtkWidget *table;
99 GtkWidget *label_user;
100 GtkWidget *label_password;
101 GtkWidget *label_empty;
102 GtkWidget *align;
103 IRRECO_ENTER
105 /* Build the dialog */
106 gtk_window_set_title(GTK_WINDOW(self), _("Login to IrrecoDB"));
107 gtk_window_set_modal(GTK_WINDOW(self), TRUE);
108 gtk_window_set_destroy_with_parent(GTK_WINDOW(self), TRUE);
109 gtk_dialog_set_has_separator(GTK_DIALOG(self), FALSE);
110 gtk_dialog_add_buttons(GTK_DIALOG(self),
111 "Register", IRRECO_LOGIN_REGISTER,
112 GTK_STOCK_OK, GTK_RESPONSE_OK,
113 NULL);
115 table = gtk_table_new(4, 2, FALSE);
117 label_user = gtk_label_new("Nickname: ");
118 label_password = gtk_label_new("Password: ");
119 label_empty = gtk_label_new("");
120 self->check_password = gtk_check_button_new_with_label(
121 "Remember password");
122 gtk_table_attach_defaults(GTK_TABLE(table), label_user, 0, 1, 0, 1);
123 gtk_table_attach_defaults(GTK_TABLE(table), label_password, 0, 1, 1, 2);
124 gtk_table_attach(GTK_TABLE(table), label_empty, 0, 2, 2, 3, GTK_EXPAND,
125 GTK_EXPAND, 0, 10);
126 gtk_table_attach(GTK_TABLE(table), self->check_password, 0, 2, 2, 3,
127 GTK_FILL, GTK_SHRINK, 0, 0);
129 gtk_misc_set_alignment(GTK_MISC(label_user), 0, 0.5);
130 gtk_misc_set_alignment(GTK_MISC(label_password), 0, 0.5);
132 self->entry_user = gtk_entry_new();
133 self->entry_password = gtk_entry_new();
134 gtk_entry_set_visibility(GTK_ENTRY(self->entry_password), FALSE);
136 /* Get data from entries */
137 self->user = gtk_entry_get_text(GTK_ENTRY(self->entry_user));
138 self->password = gtk_entry_get_text(GTK_ENTRY(self->entry_password));
140 gtk_table_attach(GTK_TABLE(table), self->entry_user, 1, 2, 0, 1,
141 GTK_FILL, GTK_FILL, 0, 0);
142 gtk_table_attach(GTK_TABLE(table), self->entry_password, 1, 2, 1, 2,
143 GTK_FILL, GTK_FILL, 0, 0);
145 align = gtk_alignment_new(0.5, 0.5, 1, 1);
146 gtk_alignment_set_padding(GTK_ALIGNMENT(align), 12, 12, 12, 12);
147 gtk_container_add(GTK_CONTAINER(align), GTK_WIDGET(table));
148 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(self)->vbox),
149 GTK_WIDGET(align));
151 g_signal_connect(G_OBJECT(GTK_TOGGLE_BUTTON(self->check_password)),
152 "toggled",
153 G_CALLBACK(irreco_login_dlg_remember_password), self);
155 g_signal_connect(G_OBJECT(GTK_ENTRY(self->entry_password)), "backspace",
156 G_CALLBACK(irreco_login_dlg_passwd_entry_messed_with),
157 self);
159 gtk_widget_show_all(GTK_WIDGET(self));
161 IRRECO_RETURN
164 void irreco_login_dlg_store_user(const gchar *default_user)
166 GConfClient* gcClient = NULL;
167 IRRECO_ENTER
169 g_assert(default_user);
171 gcClient = gconf_client_get_default();
173 g_assert(GCONF_IS_CLIENT(gcClient));
175 if (!gconf_client_set_string(gcClient, GC_ROOT "prev_user",
176 default_user, NULL)) {
177 IRRECO_PRINTF("Error.\n");
180 g_object_unref(gcClient);
181 gcClient = NULL;
183 IRRECO_RETURN
186 const gchar* irreco_login_dlg_get_stored_user()
188 GConfClient *gcClient = NULL;
189 GConfValue *val = NULL;
190 const gchar *previous_user;
191 GString *prev_user;
192 IRRECO_ENTER
194 gcClient = gconf_client_get_default();
195 g_assert(GCONF_IS_CLIENT(gcClient));
197 val = gconf_client_get_without_default(gcClient, GC_ROOT
198 "prev_user", NULL);
199 if (val == NULL) {
200 IRRECO_PRINTF("prev_user not found\n");
201 g_object_unref(gcClient);
202 gcClient = NULL;
203 IRRECO_RETURN_STR("");
206 if (val->type == GCONF_VALUE_STRING) {
207 previous_user = gconf_value_get_string(val);
208 } else {
209 IRRECO_PRINTF("prev_user is not a string\n");
210 g_object_unref(gcClient);
211 gcClient = NULL;
212 IRRECO_RETURN_STR("");
215 prev_user = g_string_new(previous_user);
217 gconf_value_free(val);
218 val = NULL;
219 g_object_unref(gcClient);
220 gcClient = NULL;
222 IRRECO_RETURN_STR(prev_user->str);
225 void irreco_login_dlg_store_password(const gchar *default_password)
227 GConfClient* gcClient = NULL;
228 IRRECO_ENTER
230 g_assert(default_password);
232 gcClient = gconf_client_get_default();
234 g_assert(GCONF_IS_CLIENT(gcClient));
236 if (!gconf_client_set_string(gcClient, GC_ROOT "prev_password",
237 default_password, NULL)) {
238 IRRECO_PRINTF("Error.\n");
241 g_object_unref(gcClient);
242 gcClient = NULL;
244 IRRECO_RETURN
247 const gchar* irreco_login_dlg_get_stored_password()
249 GConfClient *gcClient = NULL;
250 GConfValue *val = NULL;
251 const gchar *previous_password;
252 GString *prev_password;
253 IRRECO_ENTER
255 gcClient = gconf_client_get_default();
256 g_assert(GCONF_IS_CLIENT(gcClient));
258 val = gconf_client_get_without_default(gcClient, GC_ROOT
259 "prev_password", NULL);
260 if (val == NULL) {
261 IRRECO_PRINTF("prev_password not found\n");
262 g_object_unref(gcClient);
263 gcClient = NULL;
264 IRRECO_RETURN_STR("");
267 if (val->type == GCONF_VALUE_STRING) {
268 previous_password = gconf_value_get_string(val);
269 } else {
270 IRRECO_PRINTF("prev_password is not a string\n");
271 g_object_unref(gcClient);
272 gcClient = NULL;
273 IRRECO_RETURN_STR("");
276 prev_password = g_string_new(previous_password);
278 gconf_value_free(val);
279 val = NULL;
280 g_object_unref(gcClient);
281 gcClient = NULL;
283 IRRECO_RETURN_STR(prev_password->str);
286 void irreco_login_dlg_store_toggle_boolean(const gchar *default_boolean)
288 GConfClient* gcClient = NULL;
289 IRRECO_ENTER
291 g_assert(default_boolean);
293 gcClient = gconf_client_get_default();
295 g_assert(GCONF_IS_CLIENT(gcClient));
297 if (!gconf_client_set_string(gcClient, GC_ROOT "prev_boolean",
298 default_boolean, NULL)) {
299 IRRECO_PRINTF("Error.\n");
302 g_object_unref(gcClient);
303 gcClient = NULL;
305 IRRECO_RETURN
308 const gchar* irreco_login_dlg_get_stored_toggle_boolean()
310 GConfClient *gcClient = NULL;
311 GConfValue *val = NULL;
312 const gchar *previous_boolean;
313 GString *prev_boolean;
314 IRRECO_ENTER
316 gcClient = gconf_client_get_default();
317 g_assert(GCONF_IS_CLIENT(gcClient));
319 val = gconf_client_get_without_default(gcClient, GC_ROOT
320 "prev_boolean", NULL);
321 if (val == NULL) {
322 IRRECO_PRINTF("prev_boolean not found\n");
323 g_object_unref(gcClient);
324 gcClient = NULL;
325 IRRECO_RETURN_STR("");
328 if (val->type == GCONF_VALUE_STRING) {
329 previous_boolean = gconf_value_get_string(val);
330 } else {
331 IRRECO_PRINTF("prev_boolean is not a string\n");
332 g_object_unref(gcClient);
333 gcClient = NULL;
334 IRRECO_RETURN_STR("");
337 prev_boolean = g_string_new(previous_boolean);
339 gconf_value_free(val);
340 val = NULL;
341 g_object_unref(gcClient);
342 gcClient = NULL;
344 IRRECO_RETURN_STR(prev_boolean->str);
347 void irreco_login_dlg_remember_password(GtkCheckButton *toggle_button,
348 IrrecoLoginDlg *self)
350 IRRECO_ENTER
352 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle_button))) {
353 irreco_login_dlg_store_toggle_boolean("TRUE");
354 } else {
355 irreco_login_dlg_store_toggle_boolean("FALSE");
356 gtk_entry_set_text(GTK_ENTRY(self->entry_password), "");
359 IRRECO_RETURN
362 void irreco_login_dlg_passwd_entry_messed_with(GtkEntry *pw_entry,
363 IrrecoLoginDlg *login_dlg)
365 IRRECO_ENTER
367 login_dlg->is_pw_entry_messed_with = TRUE;
369 IRRECO_RETURN
372 gboolean irreco_login_dlg_login(IrrecoLoginDlg *self)
374 const gchar *pwhash;
375 const gchar *tmp_pwhash;
376 const gchar *is_toggled;
377 const gchar *stored_user;
378 const gchar *stored_pw;
379 const gchar *star_hash;
380 IRRECO_ENTER
382 /* TODO Make this horrible bit of code better FIXME */
383 star_hash = g_compute_checksum_for_string(G_CHECKSUM_SHA1, "******", -1);
385 is_toggled = irreco_login_dlg_get_stored_toggle_boolean();
387 stored_user = irreco_login_dlg_get_stored_user();
388 stored_pw = irreco_login_dlg_get_stored_password();
390 if(g_str_equal(is_toggled, "TRUE") &&
391 g_str_equal(stored_user, self->user) &&
392 !g_str_equal(stored_pw, "") &&
393 !self->is_pw_entry_messed_with &&
394 (strlen(self->password) > 1)) {
396 tmp_pwhash = g_compute_checksum_for_string(G_CHECKSUM_SHA1,
397 self->password,
398 -1);
400 if(g_str_equal(tmp_pwhash, stored_pw)) {
401 pwhash = irreco_login_dlg_get_stored_password();
403 else if(g_str_equal(tmp_pwhash, star_hash)) {
404 pwhash = irreco_login_dlg_get_stored_password();
406 else {
407 goto checkout;
409 } else {
410 checkout:
411 /* Check some things */
412 if(strlen(self->user) < 6) {
413 irreco_error_dlg(GTK_WINDOW(self),
414 "Invalid user name.");
415 IRRECO_RETURN_BOOL(FALSE);
418 if(strlen(self->password) < 6) {
419 irreco_error_dlg(GTK_WINDOW(self),
420 "Invalid password.");
421 IRRECO_RETURN_BOOL(FALSE);
422 } else {
423 pwhash = g_compute_checksum_for_string(
424 G_CHECKSUM_SHA1, self->password, -1);
428 /* Login to webdb */
429 if(irreco_login_dlg_login_cache(self, pwhash)) {
431 /* Save "default" username for the next time */
432 irreco_login_dlg_store_user(self->user);
434 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
435 self->check_password))) {
436 irreco_login_dlg_store_password(pwhash);
437 irreco_login_dlg_store_toggle_boolean("TRUE");
438 } else {
439 irreco_login_dlg_store_toggle_boolean("FALSE");
441 /* Get username and password hash */
442 self->userptr = g_strdup(self->user);
443 self->passwdptr = g_strdup(pwhash);
445 IRRECO_RETURN_BOOL(TRUE);
446 } else {
447 IRRECO_RETURN_BOOL(FALSE);
451 gboolean irreco_login_dlg_login_cache(
452 IrrecoLoginDlg *self, const gchar *pwhash)
454 IrrecoWebdbCache *webdb_cache = NULL;
455 IRRECO_ENTER
457 webdb_cache = irreco_data_get_webdb_cache(self->irreco_data, FALSE);
459 if(irreco_webdb_cache_login(webdb_cache, self->user, pwhash)) {
460 IRRECO_RETURN_BOOL(TRUE);
461 } else {
462 irreco_error_dlg(GTK_WINDOW(self),
463 irreco_webdb_cache_get_error(webdb_cache));
464 IRRECO_RETURN_BOOL(FALSE);
468 /** @} */
472 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
473 /* Private Functions */
474 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
477 * @name Private Functions
478 * @{
481 /* Add functions here. */
483 IrrecoLoginDlg* irreco_login_dlg_new (IrrecoData *irreco_data,
484 GtkWindow *parent)
486 IrrecoLoginDlg *self;
487 IRRECO_ENTER
489 self = g_object_new(IRRECO_TYPE_LOGIN_DLG, NULL);
490 irreco_dlg_set_parent(IRRECO_DLG(self), parent);
491 self->irreco_data = irreco_data;
493 IRRECO_RETURN_PTR(self);
496 /** @} */
500 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
501 /* Public Functions */
502 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
505 * @name Public Functions
506 * @{
509 /* Add functions here. */
511 gboolean irreco_show_login_dlg(IrrecoData *irreco_data, GtkWindow *parent,
512 gchar **userptr, gchar **passwdptr)
514 IrrecoLoginDlg *self;
515 gint response;
516 gboolean loop = TRUE;
517 gboolean rvalue = TRUE;
518 const gchar *temp_user;
519 const gchar *is_toggled;
521 IRRECO_ENTER
523 /* Create login dialog */
524 self = g_object_new(IRRECO_TYPE_LOGIN_DLG, NULL);
525 irreco_dlg_set_parent(IRRECO_DLG(self), parent);
526 self->irreco_data = irreco_data;
528 /* Previously used username to text entry */
529 temp_user = irreco_login_dlg_get_stored_user();
530 is_toggled = irreco_login_dlg_get_stored_toggle_boolean();
531 self->is_pw_entry_messed_with = FALSE;
533 if(g_str_equal(is_toggled, "TRUE")) {
534 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
535 self->check_password), TRUE);
536 gtk_entry_set_text(GTK_ENTRY(self->entry_password), "******");
539 if(temp_user != NULL) {
540 gtk_entry_set_text(GTK_ENTRY(self->entry_user), temp_user);
543 do {
544 /* Show login dlg */
545 response = gtk_dialog_run(GTK_DIALOG(self));
547 switch(response) {
548 case IRRECO_LOGIN_REGISTER:
549 irreco_show_webdb_register_dlg(
550 self->irreco_data, GTK_WINDOW(
551 self));
552 break;
553 case GTK_RESPONSE_DELETE_EVENT:
554 is_toggled = irreco_login_dlg_get_stored_toggle_boolean();
556 if(g_str_equal(is_toggled, "FALSE")) {
557 gtk_entry_set_text(GTK_ENTRY
558 (self->entry_password), "");
559 irreco_login_dlg_store_password("");
562 loop = FALSE;
563 rvalue = FALSE;
564 break;
565 case GTK_RESPONSE_OK:
567 if(irreco_login_dlg_login(self)) {
568 /* Get username and pw-hash */
569 *userptr = g_strdup(self->userptr);
570 *passwdptr = g_strdup(self->passwdptr);
571 is_toggled = irreco_login_dlg_get_stored_toggle_boolean();
573 if(g_str_equal(is_toggled, "FALSE")) {
574 gtk_entry_set_text(GTK_ENTRY
575 (self->entry_password), "");
576 irreco_login_dlg_store_password("");
579 irreco_info_dlg(GTK_WINDOW(self),
580 "Login successful.");
581 rvalue = TRUE;
582 } else {
583 rvalue = FALSE;
584 break;
587 loop = FALSE;
588 break;
589 default:
590 break;
592 } while(loop);
594 gtk_widget_destroy(GTK_WIDGET(self));
595 IRRECO_RETURN_BOOL(rvalue);
598 /** @} */
602 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
603 /* Events and Callbacks */
604 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
607 * @name Events and Callbacks
608 * @{
611 /* Add functions here. */
613 /** @} */
615 /** @} */