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