* Added new server security picker for hildon2, and replaced
[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 #else
40 #include "widgets/modest-serversecurity-combo-box.h"
41 #endif
42 #include "widgets/modest-secureauth-combo-box.h"
43
44 /* list my signals */
45 enum {
46         MISSING_MANDATORY_DATA_SIGNAL,
47         LAST_SIGNAL
48 };
49
50 static guint signals[LAST_SIGNAL] = {0};
51
52 void 
53 modest_security_options_view_load_settings (ModestSecurityOptionsView* self, 
54                                             ModestAccountSettings *settings)
55 {
56         ModestSecurityOptionsViewPrivate *priv;
57         ModestServerAccountSettings *server_settings;
58         ModestProtocolType server_proto, secure_protocol, secure_auth;
59
60         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
61
62         /* Save initial settings */
63         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
64                 server_settings = modest_account_settings_get_store_settings (settings);
65         else
66                 server_settings = modest_account_settings_get_transport_settings (settings);
67
68         server_proto = modest_server_account_settings_get_protocol (server_settings);
69         secure_protocol = modest_server_account_settings_get_security_protocol (server_settings);
70         secure_auth = modest_server_account_settings_get_auth_protocol (server_settings);
71
72         priv->initial_state.security = secure_protocol;
73         priv->initial_state.auth = secure_auth;
74         priv->initial_state.port = modest_server_account_settings_get_port (server_settings);
75
76         /* Update UI */
77         modest_security_options_view_set_server_type (self, server_proto);
78 #ifdef MODEST_TOOLKIT_HILDON2
79         modest_serversecurity_picker_set_active_serversecurity (MODEST_SERVERSECURITY_PICKER (priv->security_view), secure_protocol);
80 #else
81         modest_serversecurity_combo_box_set_active_serversecurity (MODEST_SERVERSECURITY_COMBO_BOX (priv->security_view), secure_protocol);
82 #endif
83
84 /*              update_incoming_server_title (dialog, dialog->incoming_protocol); */
85
86         /* Username and password */
87         if (priv->full && self->type == MODEST_SECURITY_OPTIONS_OUTGOING) {
88                 priv->initial_state.user = 
89                         modest_server_account_settings_get_username (server_settings);
90                 priv->initial_state.pwd = 
91                         modest_server_account_settings_get_password (server_settings);
92
93                 if (priv->initial_state.user)
94                         gtk_entry_set_text(GTK_ENTRY (priv->user_entry), 
95                                            priv->initial_state.user);
96                 if (priv->initial_state.pwd)
97                         gtk_entry_set_text(GTK_ENTRY (priv->pwd_entry), 
98                                            priv->initial_state.pwd);
99         }
100
101         /* Set auth */
102         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING) {
103                 /* Active the authentication checkbox */
104                 if (modest_protocol_registry_protocol_type_is_secure (modest_runtime_get_protocol_registry (), 
105                                                                       secure_auth))
106                         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->auth_view),
107                                                       TRUE);
108         } else {
109                 modest_secureauth_combo_box_set_active_secureauth (
110                    MODEST_SECUREAUTH_COMBO_BOX (priv->auth_view), secure_auth);
111         }
112
113         MODEST_SECURITY_OPTIONS_VIEW_GET_CLASS (self)->load_settings (self, settings);
114
115         /* Free */
116         g_object_unref (server_settings);
117 }
118
119 void 
120 modest_security_options_view_save_settings (ModestSecurityOptionsView* self, 
121                                             ModestAccountSettings *settings)
122 {
123         ModestServerAccountSettings *server_settings;
124         ModestProtocolType security_proto, auth_protocol;
125         ModestSecurityOptionsViewPrivate *priv;
126         ModestProtocolRegistry *proto_registry;
127
128         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
129         proto_registry = modest_runtime_get_protocol_registry ();
130
131         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
132                 server_settings = modest_account_settings_get_store_settings (settings);
133         else
134                 server_settings = modest_account_settings_get_transport_settings (settings);
135
136         /* initialize */
137         security_proto = MODEST_PROTOCOLS_CONNECTION_NONE;
138         auth_protocol = MODEST_PROTOCOLS_AUTH_NONE;
139
140         /* Get data */
141 #ifdef MODEST_TOOLKIT_HILDON2
142         security_proto = modest_serversecurity_picker_get_active_serversecurity (MODEST_SERVERSECURITY_PICKER (priv->security_view));
143 #else
144         security_proto = modest_serversecurity_combo_box_get_active_serversecurity (MODEST_SERVERSECURITY_COMBO_BOX (priv->security_view));
145 #endif
146
147         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING) {
148                 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->auth_view))) {
149                         if (!modest_protocol_registry_protocol_type_is_secure (proto_registry,
150                                                                                security_proto)) {
151                                 /* TODO */
152                                 /*              auth_protocol = check_first_supported_auth_method (self); */
153                                 auth_protocol = MODEST_PROTOCOLS_AUTH_PASSWORD;
154                         } else {
155                                 auth_protocol = MODEST_PROTOCOLS_AUTH_PASSWORD;
156                         }
157                 }
158         } else {
159                 auth_protocol = modest_secureauth_combo_box_get_active_secureauth (
160                            MODEST_SECUREAUTH_COMBO_BOX (priv->auth_view));
161         }
162
163         /* Save settings */
164         modest_server_account_settings_set_security_protocol (server_settings, 
165                                                               security_proto);
166         modest_server_account_settings_set_auth_protocol (server_settings, 
167                                                           auth_protocol);
168
169         if (priv->full && self->type == MODEST_SECURITY_OPTIONS_OUTGOING) {
170                 const gchar *username, *password;
171
172                 username = gtk_entry_get_text (GTK_ENTRY (priv->user_entry));
173                 password = gtk_entry_get_text (GTK_ENTRY (priv->pwd_entry));
174
175                 modest_server_account_settings_set_username (server_settings, username);
176                 modest_server_account_settings_set_password (server_settings, password);
177         }
178
179         MODEST_SECURITY_OPTIONS_VIEW_GET_CLASS (self)->save_settings (self, settings);
180
181
182         /* Free */
183         g_object_unref (server_settings);
184 }
185
186 void 
187 modest_security_options_view_set_server_type (ModestSecurityOptionsView* self, 
188                                               ModestProtocolType server_type)
189 {
190         ModestSecurityOptionsViewPrivate *priv;
191         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
192
193 #ifdef MODEST_TOOLKIT_HILDON2           
194         modest_serversecurity_picker_fill (MODEST_SERVERSECURITY_PICKER (priv->security_view), server_type);
195         modest_serversecurity_picker_set_active_serversecurity (MODEST_SERVERSECURITY_PICKER (priv->security_view),
196                                                                 MODEST_PROTOCOLS_CONNECTION_NONE);
197 #else
198         modest_serversecurity_combo_box_fill (MODEST_SERVERSECURITY_COMBO_BOX (priv->security_view), server_type);
199         modest_serversecurity_combo_box_set_active_serversecurity (MODEST_SERVERSECURITY_COMBO_BOX (priv->security_view),
200                                                                    MODEST_PROTOCOLS_CONNECTION_NONE);
201 #endif
202 }
203
204 static void
205 get_current_state (ModestSecurityOptionsView* self,
206                    ModestSecurityOptionsState *state)
207 {
208         ModestSecurityOptionsViewPrivate *priv;
209         ModestProtocolRegistry *proto_registry;
210
211         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
212         proto_registry = modest_runtime_get_protocol_registry ();
213
214         /* Get security */
215 #ifdef MODEST_TOOLKIT_HILDON2
216         state->security = 
217                 modest_serversecurity_picker_get_active_serversecurity (MODEST_SERVERSECURITY_PICKER (priv->security_view));
218 #else
219         state->security = 
220                 modest_serversecurity_combo_box_get_active_serversecurity (MODEST_SERVERSECURITY_COMBO_BOX (priv->security_view));
221 #endif
222
223         /* Get auth */
224         if (self->type == MODEST_SECURITY_OPTIONS_OUTGOING) {
225                 state->auth = modest_secureauth_combo_box_get_active_secureauth (MODEST_SECUREAUTH_COMBO_BOX (priv->auth_view));
226                 if (priv->full) {
227                 }
228         } else {
229                 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->auth_view)))
230                         state->auth = priv->initial_state.auth;
231                 else
232                         state->auth = MODEST_PROTOCOLS_AUTH_NONE;
233         }
234 }
235
236 gboolean 
237 modest_security_options_view_changed (ModestSecurityOptionsView* self,
238                                       ModestAccountSettings *settings)
239 {
240         ModestSecurityOptionsViewPrivate *priv;
241         ModestSecurityOptionsState state = {0};
242
243         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
244
245         get_current_state (self, &state);
246
247         if (state.security != priv->initial_state.security ||
248             state.auth != priv->initial_state.auth)
249                 return TRUE;
250
251         if (priv->full && self->type == MODEST_SECURITY_OPTIONS_OUTGOING) {
252                 const gchar *username, *password;
253
254                 username = gtk_entry_get_text (GTK_ENTRY (priv->user_entry));
255                 password = gtk_entry_get_text (GTK_ENTRY (priv->pwd_entry));
256
257                 if (!priv->initial_state.user && strcmp (username, ""))
258                         return TRUE;
259                 if (!priv->initial_state.pwd && strcmp (password, ""))
260                         return TRUE;
261
262                 if ((priv->initial_state.user && 
263                      strcmp (priv->initial_state.user, username)) ||
264                     (priv->initial_state.pwd &&
265                      strcmp (priv->initial_state.pwd, password)))
266                         return TRUE;
267         }
268
269         /* Check subclass */
270         return  MODEST_SECURITY_OPTIONS_VIEW_GET_CLASS (self)->changed (self, settings);
271 }
272
273 void 
274 modest_security_options_view_enable_changes (ModestSecurityOptionsView* self,
275                                              gboolean enable)
276 {
277         ModestSecurityOptionsViewPrivate *priv;
278
279         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
280         gtk_widget_set_sensitive (priv->port_view, enable);
281         gtk_widget_set_sensitive (priv->security_view, enable);
282 }
283
284 gboolean 
285 modest_security_options_view_auth_check (ModestSecurityOptionsView* self)
286 {
287         ModestSecurityOptionsViewPrivate *priv;
288         ModestProtocolType security_incoming_type; 
289         gboolean auth_active, is_secure;
290         ModestProtocolRegistry *protocol_registry;
291
292         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
293         protocol_registry = modest_runtime_get_protocol_registry ();
294
295         /* Check if the server supports secure authentication */
296 #ifdef MODEST_TOOLKIT_HILDON2
297         security_incoming_type = 
298                 modest_serversecurity_picker_get_active_serversecurity (MODEST_SERVERSECURITY_PICKER (priv->security_view));
299 #else
300         security_incoming_type = 
301                 modest_serversecurity_combo_box_get_active_serversecurity (MODEST_SERVERSECURITY_COMBO_BOX (priv->security_view));
302 #endif
303
304         auth_active = 
305                 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->auth_view));
306         is_secure = 
307                 modest_protocol_registry_protocol_type_has_tag (protocol_registry, 
308                                                                 security_incoming_type, 
309                                                                 MODEST_PROTOCOL_REGISTRY_SECURE_PROTOCOLS);
310
311         if (auth_active && !is_secure)
312                 return TRUE;
313         else
314                 return FALSE;
315 }
316
317 GList* 
318 modest_security_options_view_get_supported_auth_methods (ModestSecurityOptionsView *self,
319                                                          const gchar *hostname,
320                                                          const gchar *username,
321                                                          ModestProtocolType server_type)
322 {
323         GtkWindow *window;
324         GError *error = NULL;
325         GList *list_auth_methods, *retval = NULL;
326         ModestSecurityOptionsViewPrivate *priv;
327         ModestAccountSettings current_settings;
328         ModestServerAccountSettings *server_settings;
329         
330         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
331
332         window = GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_WINDOW));
333
334         /* Get current settings */
335         modest_security_options_view_save_settings (self, &current_settings);
336
337         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
338                 server_settings = modest_account_settings_get_store_settings (&current_settings);
339         else
340                 server_settings = modest_account_settings_get_transport_settings (&current_settings);
341
342         list_auth_methods =
343                 modest_utils_get_supported_secure_authentication_methods (server_type,
344                                                                           hostname,
345                                                                           modest_server_account_settings_get_port (server_settings),
346                                                                           username,
347                                                                           window,
348                                                                           &error);
349
350         if (list_auth_methods) {
351                 GList *list = NULL, *method = NULL;
352                 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
353
354                 for (method = list_auth_methods; method != NULL; method = g_list_next(method)) {
355                         ModestProtocolType auth_protocol_type = 
356                                 (ModestProtocolType) (GPOINTER_TO_INT(method->data));
357                         if (modest_protocol_registry_protocol_type_is_secure (registry, 
358                                                                               auth_protocol_type)) {
359                                 list = g_list_append(list, GINT_TO_POINTER(auth_protocol_type));
360                         }
361                 }
362                 g_list_free(list_auth_methods);
363                 if (list) {
364                         retval = list;
365                         goto end;
366                 }
367         }
368
369         if(error == NULL || 
370            error->domain != modest_utils_get_supported_secure_authentication_error_quark() ||
371            error->code != MODEST_UTILS_GET_SUPPORTED_SECURE_AUTHENTICATION_ERROR_CANCELED) {
372                 modest_platform_information_banner (GTK_WIDGET(self),
373                                                     NULL,
374                                                     _("mcen_ib_unableto_discover_auth_methods"));
375         }
376
377         if(error != NULL)
378                 g_error_free(error);
379
380  end:
381         /* Frees */
382         g_object_unref (server_settings);
383
384         return retval;
385 }
386
387 static void 
388 modest_security_options_view_init (ModestSecurityOptionsView *self) 
389 {
390         ModestSecurityOptionsViewPrivate *priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
391
392         memset (&(priv->initial_state), 0, sizeof (ModestSecurityOptionsState));
393
394         priv->security_view = NULL;
395         priv->port_view = NULL;
396         priv->auth_view = NULL;
397         priv->user_entry = NULL;
398         priv->pwd_entry = NULL;
399 }
400
401 static void 
402 modest_security_options_view_class_init (ModestSecurityOptionsViewClass *klass) 
403 {
404         GObjectClass *gobject_class = (GObjectClass*) klass;
405
406         g_type_class_add_private (gobject_class, sizeof (ModestSecurityOptionsViewPrivate));
407
408         /* Register signals */
409         signals[MISSING_MANDATORY_DATA_SIGNAL] =
410                 g_signal_new ("missing_mandatory_data",
411                               MODEST_TYPE_SECURITY_OPTIONS_VIEW,
412                               G_SIGNAL_RUN_FIRST,
413                               G_STRUCT_OFFSET(ModestSecurityOptionsViewClass, missing_mandatory_data),
414                               NULL, NULL,
415                               g_cclosure_marshal_VOID__BOOLEAN,
416                               G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
417 }
418
419 /* Type definition */
420 G_DEFINE_ABSTRACT_TYPE (ModestSecurityOptionsView, 
421                         modest_security_options_view,
422                         GTK_TYPE_VBOX);