* Implemented a new replacement for secureauth combobox called
[modest] / src / widgets / modest-security-options-view.c
1 /* Copyright (c) 2008, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <string.h>
31 #include <gtk/gtkvbox.h>
32 #include "modest-utils.h"
33 #include "modest-runtime.h"
34 #include "modest-platform.h"
35 #include "modest-security-options-view.h"
36 #include "modest-security-options-view-priv.h"
37 #ifdef MODEST_TOOLKIT_HILDON2
38 #include "modest-serversecurity-picker.h"
39 #include "modest-secureauth-picker.h"
40 #else
41 #include "widgets/modest-serversecurity-combo-box.h"
42 #include "widgets/modest-secureauth-combo-box.h"
43 #endif
44
45 /* list my signals */
46 enum {
47         MISSING_MANDATORY_DATA_SIGNAL,
48         LAST_SIGNAL
49 };
50
51 static guint signals[LAST_SIGNAL] = {0};
52
53 void 
54 modest_security_options_view_load_settings (ModestSecurityOptionsView* self, 
55                                             ModestAccountSettings *settings)
56 {
57         ModestSecurityOptionsViewPrivate *priv;
58         ModestServerAccountSettings *server_settings;
59         ModestProtocolType server_proto, secure_protocol, secure_auth;
60
61         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
62
63         /* Save initial settings */
64         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
65                 server_settings = modest_account_settings_get_store_settings (settings);
66         else
67                 server_settings = modest_account_settings_get_transport_settings (settings);
68
69         server_proto = modest_server_account_settings_get_protocol (server_settings);
70         secure_protocol = modest_server_account_settings_get_security_protocol (server_settings);
71         secure_auth = modest_server_account_settings_get_auth_protocol (server_settings);
72
73         priv->initial_state.security = secure_protocol;
74         priv->initial_state.auth = secure_auth;
75         priv->initial_state.port = modest_server_account_settings_get_port (server_settings);
76
77         /* Update UI */
78         modest_security_options_view_set_server_type (self, server_proto);
79 #ifdef MODEST_TOOLKIT_HILDON2
80         modest_serversecurity_picker_set_active_serversecurity (MODEST_SERVERSECURITY_PICKER (priv->security_view), secure_protocol);
81 #else
82         modest_serversecurity_combo_box_set_active_serversecurity (MODEST_SERVERSECURITY_COMBO_BOX (priv->security_view), secure_protocol);
83 #endif
84
85 /*              update_incoming_server_title (dialog, dialog->incoming_protocol); */
86
87         /* Username and password */
88         if (priv->full && self->type == MODEST_SECURITY_OPTIONS_OUTGOING) {
89                 priv->initial_state.user = 
90                         modest_server_account_settings_get_username (server_settings);
91                 priv->initial_state.pwd = 
92                         modest_server_account_settings_get_password (server_settings);
93
94                 if (priv->initial_state.user)
95                         gtk_entry_set_text(GTK_ENTRY (priv->user_entry), 
96                                            priv->initial_state.user);
97                 if (priv->initial_state.pwd)
98                         gtk_entry_set_text(GTK_ENTRY (priv->pwd_entry), 
99                                            priv->initial_state.pwd);
100         }
101
102         /* Set auth */
103         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING) {
104                 /* Active the authentication checkbox */
105                 if (modest_protocol_registry_protocol_type_is_secure (modest_runtime_get_protocol_registry (), 
106                                                                       secure_auth))
107                         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->auth_view),
108                                                       TRUE);
109         } else {
110 #ifdef MODEST_TOOLKIT_HILDON2
111                 modest_secureauth_picker_set_active_secureauth (
112                    MODEST_SECUREAUTH_PICKER (priv->auth_view), secure_auth);
113 #else
114                 modest_secureauth_combo_box_set_active_secureauth (
115                    MODEST_SECUREAUTH_COMBO_BOX (priv->auth_view), secure_auth);
116 #endif
117         }
118
119         MODEST_SECURITY_OPTIONS_VIEW_GET_CLASS (self)->load_settings (self, settings);
120
121         /* Free */
122         g_object_unref (server_settings);
123 }
124
125 void 
126 modest_security_options_view_save_settings (ModestSecurityOptionsView* self, 
127                                             ModestAccountSettings *settings)
128 {
129         ModestServerAccountSettings *server_settings;
130         ModestProtocolType security_proto, auth_protocol;
131         ModestSecurityOptionsViewPrivate *priv;
132         ModestProtocolRegistry *proto_registry;
133
134         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
135         proto_registry = modest_runtime_get_protocol_registry ();
136
137         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
138                 server_settings = modest_account_settings_get_store_settings (settings);
139         else
140                 server_settings = modest_account_settings_get_transport_settings (settings);
141
142         /* initialize */
143         security_proto = MODEST_PROTOCOLS_CONNECTION_NONE;
144         auth_protocol = MODEST_PROTOCOLS_AUTH_NONE;
145
146         /* Get data */
147 #ifdef MODEST_TOOLKIT_HILDON2
148         security_proto = modest_serversecurity_picker_get_active_serversecurity (MODEST_SERVERSECURITY_PICKER (priv->security_view));
149 #else
150         security_proto = modest_serversecurity_combo_box_get_active_serversecurity (MODEST_SERVERSECURITY_COMBO_BOX (priv->security_view));
151 #endif
152
153         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING) {
154                 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->auth_view))) {
155                         if (!modest_protocol_registry_protocol_type_is_secure (proto_registry,
156                                                                                security_proto)) {
157                                 /* TODO */
158                                 /*              auth_protocol = check_first_supported_auth_method (self); */
159                                 auth_protocol = MODEST_PROTOCOLS_AUTH_PASSWORD;
160                         } else {
161                                 auth_protocol = MODEST_PROTOCOLS_AUTH_PASSWORD;
162                         }
163                 }
164         } else {
165 #ifdef MODEST_TOOLKIT_HILDON2
166                 auth_protocol = modest_secureauth_picker_get_active_secureauth (
167                         MODEST_SECUREAUTH_PICKER (priv->auth_view));
168 #else
169                 auth_protocol = modest_secureauth_combo_box_get_active_secureauth (
170                         MODEST_SECUREAUTH_COMBO_BOX (priv->auth_view));
171 #endif
172         }
173
174         /* Save settings */
175         modest_server_account_settings_set_security_protocol (server_settings, 
176                                                               security_proto);
177         modest_server_account_settings_set_auth_protocol (server_settings, 
178                                                           auth_protocol);
179
180         if (priv->full && self->type == MODEST_SECURITY_OPTIONS_OUTGOING) {
181                 const gchar *username, *password;
182
183                 username = gtk_entry_get_text (GTK_ENTRY (priv->user_entry));
184                 password = gtk_entry_get_text (GTK_ENTRY (priv->pwd_entry));
185
186                 modest_server_account_settings_set_username (server_settings, username);
187                 modest_server_account_settings_set_password (server_settings, password);
188         }
189
190         MODEST_SECURITY_OPTIONS_VIEW_GET_CLASS (self)->save_settings (self, settings);
191
192
193         /* Free */
194         g_object_unref (server_settings);
195 }
196
197 void 
198 modest_security_options_view_set_server_type (ModestSecurityOptionsView* self, 
199                                               ModestProtocolType server_type)
200 {
201         ModestSecurityOptionsViewPrivate *priv;
202         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
203
204 #ifdef MODEST_TOOLKIT_HILDON2           
205         modest_serversecurity_picker_fill (MODEST_SERVERSECURITY_PICKER (priv->security_view), server_type);
206         modest_serversecurity_picker_set_active_serversecurity (MODEST_SERVERSECURITY_PICKER (priv->security_view),
207                                                                 MODEST_PROTOCOLS_CONNECTION_NONE);
208 #else
209         modest_serversecurity_combo_box_fill (MODEST_SERVERSECURITY_COMBO_BOX (priv->security_view), server_type);
210         modest_serversecurity_combo_box_set_active_serversecurity (MODEST_SERVERSECURITY_COMBO_BOX (priv->security_view),
211                                                                    MODEST_PROTOCOLS_CONNECTION_NONE);
212 #endif
213 }
214
215 static void
216 get_current_state (ModestSecurityOptionsView* self,
217                    ModestSecurityOptionsState *state)
218 {
219         ModestSecurityOptionsViewPrivate *priv;
220         ModestProtocolRegistry *proto_registry;
221
222         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
223         proto_registry = modest_runtime_get_protocol_registry ();
224
225         /* Get security */
226 #ifdef MODEST_TOOLKIT_HILDON2
227         state->security = 
228                 modest_serversecurity_picker_get_active_serversecurity (MODEST_SERVERSECURITY_PICKER (priv->security_view));
229 #else
230         state->security = 
231                 modest_serversecurity_combo_box_get_active_serversecurity (MODEST_SERVERSECURITY_COMBO_BOX (priv->security_view));
232 #endif
233
234         /* Get auth */
235         if (self->type == MODEST_SECURITY_OPTIONS_OUTGOING) {
236 #ifdef MODEST_TOOLKIT_HILDON2
237                 state->auth = modest_secureauth_picker_get_active_secureauth (MODEST_SECUREAUTH_PICKER (priv->auth_view));
238 #else
239                 state->auth = modest_secureauth_combo_box_get_active_secureauth (MODEST_SECUREAUTH_COMBO_BOX (priv->auth_view));
240 #endif
241                 if (priv->full) {
242                 }
243         } else {
244                 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->auth_view)))
245                         state->auth = priv->initial_state.auth;
246                 else
247                         state->auth = MODEST_PROTOCOLS_AUTH_NONE;
248         }
249 }
250
251 gboolean 
252 modest_security_options_view_changed (ModestSecurityOptionsView* self,
253                                       ModestAccountSettings *settings)
254 {
255         ModestSecurityOptionsViewPrivate *priv;
256         ModestSecurityOptionsState state = {0};
257
258         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
259
260         get_current_state (self, &state);
261
262         if (state.security != priv->initial_state.security ||
263             state.auth != priv->initial_state.auth)
264                 return TRUE;
265
266         if (priv->full && self->type == MODEST_SECURITY_OPTIONS_OUTGOING) {
267                 const gchar *username, *password;
268
269                 username = gtk_entry_get_text (GTK_ENTRY (priv->user_entry));
270                 password = gtk_entry_get_text (GTK_ENTRY (priv->pwd_entry));
271
272                 if (!priv->initial_state.user && strcmp (username, ""))
273                         return TRUE;
274                 if (!priv->initial_state.pwd && strcmp (password, ""))
275                         return TRUE;
276
277                 if ((priv->initial_state.user && 
278                      strcmp (priv->initial_state.user, username)) ||
279                     (priv->initial_state.pwd &&
280                      strcmp (priv->initial_state.pwd, password)))
281                         return TRUE;
282         }
283
284         /* Check subclass */
285         return  MODEST_SECURITY_OPTIONS_VIEW_GET_CLASS (self)->changed (self, settings);
286 }
287
288 void 
289 modest_security_options_view_enable_changes (ModestSecurityOptionsView* self,
290                                              gboolean enable)
291 {
292         ModestSecurityOptionsViewPrivate *priv;
293
294         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
295         gtk_widget_set_sensitive (priv->port_view, enable);
296         gtk_widget_set_sensitive (priv->security_view, enable);
297 }
298
299 gboolean 
300 modest_security_options_view_auth_check (ModestSecurityOptionsView* self)
301 {
302         ModestSecurityOptionsViewPrivate *priv;
303         ModestProtocolType security_incoming_type; 
304         gboolean auth_active, is_secure;
305         ModestProtocolRegistry *protocol_registry;
306
307         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
308         protocol_registry = modest_runtime_get_protocol_registry ();
309
310         /* Check if the server supports secure authentication */
311 #ifdef MODEST_TOOLKIT_HILDON2
312         security_incoming_type = 
313                 modest_serversecurity_picker_get_active_serversecurity (MODEST_SERVERSECURITY_PICKER (priv->security_view));
314 #else
315         security_incoming_type = 
316                 modest_serversecurity_combo_box_get_active_serversecurity (MODEST_SERVERSECURITY_COMBO_BOX (priv->security_view));
317 #endif
318
319         auth_active = 
320                 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->auth_view));
321         is_secure = 
322                 modest_protocol_registry_protocol_type_has_tag (protocol_registry, 
323                                                                 security_incoming_type, 
324                                                                 MODEST_PROTOCOL_REGISTRY_SECURE_PROTOCOLS);
325
326         if (auth_active && !is_secure)
327                 return TRUE;
328         else
329                 return FALSE;
330 }
331
332 GList* 
333 modest_security_options_view_get_supported_auth_methods (ModestSecurityOptionsView *self,
334                                                          const gchar *hostname,
335                                                          const gchar *username,
336                                                          ModestProtocolType server_type)
337 {
338         GtkWindow *window;
339         GError *error = NULL;
340         GList *list_auth_methods, *retval = NULL;
341         ModestSecurityOptionsViewPrivate *priv;
342         ModestAccountSettings current_settings;
343         ModestServerAccountSettings *server_settings;
344         
345         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
346
347         window = GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_WINDOW));
348
349         /* Get current settings */
350         modest_security_options_view_save_settings (self, &current_settings);
351
352         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
353                 server_settings = modest_account_settings_get_store_settings (&current_settings);
354         else
355                 server_settings = modest_account_settings_get_transport_settings (&current_settings);
356
357         list_auth_methods =
358                 modest_utils_get_supported_secure_authentication_methods (server_type,
359                                                                           hostname,
360                                                                           modest_server_account_settings_get_port (server_settings),
361                                                                           username,
362                                                                           window,
363                                                                           &error);
364
365         if (list_auth_methods) {
366                 GList *list = NULL, *method = NULL;
367                 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
368
369                 for (method = list_auth_methods; method != NULL; method = g_list_next(method)) {
370                         ModestProtocolType auth_protocol_type = 
371                                 (ModestProtocolType) (GPOINTER_TO_INT(method->data));
372                         if (modest_protocol_registry_protocol_type_is_secure (registry, 
373                                                                               auth_protocol_type)) {
374                                 list = g_list_append(list, GINT_TO_POINTER(auth_protocol_type));
375                         }
376                 }
377                 g_list_free(list_auth_methods);
378                 if (list) {
379                         retval = list;
380                         goto end;
381                 }
382         }
383
384         if(error == NULL || 
385            error->domain != modest_utils_get_supported_secure_authentication_error_quark() ||
386            error->code != MODEST_UTILS_GET_SUPPORTED_SECURE_AUTHENTICATION_ERROR_CANCELED) {
387                 modest_platform_information_banner (GTK_WIDGET(self),
388                                                     NULL,
389                                                     _("mcen_ib_unableto_discover_auth_methods"));
390         }
391
392         if(error != NULL)
393                 g_error_free(error);
394
395  end:
396         /* Frees */
397         g_object_unref (server_settings);
398
399         return retval;
400 }
401
402 static void 
403 modest_security_options_view_init (ModestSecurityOptionsView *self) 
404 {
405         ModestSecurityOptionsViewPrivate *priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
406
407         memset (&(priv->initial_state), 0, sizeof (ModestSecurityOptionsState));
408
409         priv->security_view = NULL;
410         priv->port_view = NULL;
411         priv->auth_view = NULL;
412         priv->user_entry = NULL;
413         priv->pwd_entry = NULL;
414 }
415
416 static void 
417 modest_security_options_view_class_init (ModestSecurityOptionsViewClass *klass) 
418 {
419         GObjectClass *gobject_class = (GObjectClass*) klass;
420
421         g_type_class_add_private (gobject_class, sizeof (ModestSecurityOptionsViewPrivate));
422
423         /* Register signals */
424         signals[MISSING_MANDATORY_DATA_SIGNAL] =
425                 g_signal_new ("missing_mandatory_data",
426                               MODEST_TYPE_SECURITY_OPTIONS_VIEW,
427                               G_SIGNAL_RUN_FIRST,
428                               G_STRUCT_OFFSET(ModestSecurityOptionsViewClass, missing_mandatory_data),
429                               NULL, NULL,
430                               g_cclosure_marshal_VOID__BOOLEAN,
431                               G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
432 }
433
434 /* Type definition */
435 G_DEFINE_ABSTRACT_TYPE (ModestSecurityOptionsView, 
436                         modest_security_options_view,
437                         GTK_TYPE_VBOX);