Secure auth selector
[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/gtk.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-hildon-includes.h>
39 #endif
40
41 /* list my signals */
42 enum {
43         MISSING_MANDATORY_DATA_SIGNAL,
44         LAST_SIGNAL
45 };
46
47 static guint signals[LAST_SIGNAL] = {0};
48
49 void 
50 modest_security_options_view_load_settings (ModestSecurityOptionsView* self, 
51                                             ModestAccountSettings *settings)
52 {
53         ModestSecurityOptionsViewPrivate *priv;
54         ModestServerAccountSettings *server_settings;
55         ModestProtocolType server_proto, secure_protocol, secure_auth;
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         modest_security_options_view_set_server_type (self, server_proto);
75         modest_serversecurity_selector_set_active_serversecurity (priv->security_view, secure_protocol);
76
77 /*              update_incoming_server_title (dialog, dialog->incoming_protocol); */
78
79         /* Username and password */
80         if (priv->full && self->type == MODEST_SECURITY_OPTIONS_OUTGOING) {
81                 priv->initial_state.user = 
82                         modest_server_account_settings_get_username (server_settings);
83                 priv->initial_state.pwd = 
84                         modest_server_account_settings_get_password (server_settings);
85
86                 if (priv->initial_state.user)
87                         gtk_entry_set_text(GTK_ENTRY (priv->user_entry), 
88                                            priv->initial_state.user);
89                 if (priv->initial_state.pwd)
90                         gtk_entry_set_text(GTK_ENTRY (priv->pwd_entry), 
91                                            priv->initial_state.pwd);
92         }
93
94         /* Set auth */
95         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING) {
96                 /* Active the authentication checkbox */
97                 if (modest_protocol_registry_protocol_type_is_secure (modest_runtime_get_protocol_registry (), 
98                                                                       secure_auth))
99                         modest_togglable_set_active (priv->auth_view,
100                                                      TRUE);
101         } else {
102                 modest_secureauth_selector_set_active_secureauth (
103                         priv->auth_view, secure_auth);
104         }
105
106         MODEST_SECURITY_OPTIONS_VIEW_GET_CLASS (self)->load_settings (self, settings);
107
108         /* Free */
109         g_object_unref (server_settings);
110 }
111
112 void 
113 modest_security_options_view_save_settings (ModestSecurityOptionsView* self, 
114                                             ModestAccountSettings *settings)
115 {
116         ModestServerAccountSettings *server_settings;
117         ModestProtocolType security_proto, auth_protocol;
118         ModestSecurityOptionsViewPrivate *priv;
119         ModestProtocolRegistry *proto_registry;
120
121         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
122         proto_registry = modest_runtime_get_protocol_registry ();
123
124         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
125                 server_settings = modest_account_settings_get_store_settings (settings);
126         else
127                 server_settings = modest_account_settings_get_transport_settings (settings);
128
129         /* initialize */
130         security_proto = MODEST_PROTOCOLS_CONNECTION_NONE;
131         auth_protocol = MODEST_PROTOCOLS_AUTH_NONE;
132
133         /* Get data */
134         security_proto = modest_serversecurity_selector_get_active_serversecurity (priv->security_view);
135
136         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING) {
137                 if (modest_togglable_get_active (priv->auth_view)) {
138                         if (!modest_protocol_registry_protocol_type_is_secure (proto_registry,
139                                                                                security_proto)) {
140                                 /* TODO */
141                                 /*              auth_protocol = check_first_supported_auth_method (self); */
142                                 auth_protocol = MODEST_PROTOCOLS_AUTH_PASSWORD;
143                         } else {
144                                 auth_protocol = MODEST_PROTOCOLS_AUTH_PASSWORD;
145                         }
146                 }
147         } else {
148                 auth_protocol = modest_secureauth_selector_get_active_secureauth (priv->auth_view);
149         }
150
151         /* Save settings */
152         modest_server_account_settings_set_security_protocol (server_settings, 
153                                                               security_proto);
154         modest_server_account_settings_set_auth_protocol (server_settings, 
155                                                           auth_protocol);
156
157         if (priv->full && self->type == MODEST_SECURITY_OPTIONS_OUTGOING) {
158                 const gchar *username, *password;
159
160                 username = gtk_entry_get_text (GTK_ENTRY (priv->user_entry));
161                 password = gtk_entry_get_text (GTK_ENTRY (priv->pwd_entry));
162
163                 modest_server_account_settings_set_username (server_settings, username);
164                 modest_server_account_settings_set_password (server_settings, password);
165         }
166
167         MODEST_SECURITY_OPTIONS_VIEW_GET_CLASS (self)->save_settings (self, settings);
168
169
170         /* Free */
171         g_object_unref (server_settings);
172 }
173
174 void 
175 modest_security_options_view_set_server_type (ModestSecurityOptionsView* self, 
176                                               ModestProtocolType server_type)
177 {
178         ModestSecurityOptionsViewPrivate *priv;
179         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
180
181         modest_serversecurity_selector_fill (priv->security_view, server_type);
182         modest_serversecurity_selector_set_active_serversecurity (priv->security_view,
183                                                                   MODEST_PROTOCOLS_CONNECTION_NONE);
184 }
185
186 static void
187 get_current_state (ModestSecurityOptionsView* self,
188                    ModestSecurityOptionsState *state)
189 {
190         ModestSecurityOptionsViewPrivate *priv;
191         ModestProtocolRegistry *proto_registry;
192
193         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
194         proto_registry = modest_runtime_get_protocol_registry ();
195
196         /* Get security */
197         state->security =
198                 modest_serversecurity_selector_get_active_serversecurity (priv->security_view);
199         state->port =
200                 modest_serversecurity_selector_get_active_serversecurity_port (priv->security_view);
201
202         /* Get auth */
203         if (self->type == MODEST_SECURITY_OPTIONS_OUTGOING) {
204                 state->auth = modest_secureauth_selector_get_active_secureauth (priv->auth_view);
205                 if (priv->full) {
206                 }
207         } else {
208                 if (modest_togglable_get_active (priv->auth_view))
209                         state->auth = priv->initial_state.auth;
210                 else
211                         state->auth = MODEST_PROTOCOLS_AUTH_NONE;
212         }
213 }
214
215 gboolean 
216 modest_security_options_view_changed (ModestSecurityOptionsView* self,
217                                       ModestAccountSettings *settings)
218 {
219         ModestSecurityOptionsViewPrivate *priv;
220         ModestSecurityOptionsState state = {0};
221
222         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
223
224         get_current_state (self, &state);
225
226         if (state.security != priv->initial_state.security ||
227             state.auth != priv->initial_state.auth)
228                 return TRUE;
229
230         if (priv->full && self->type == MODEST_SECURITY_OPTIONS_OUTGOING) {
231                 const gchar *username, *password;
232
233                 username = gtk_entry_get_text (GTK_ENTRY (priv->user_entry));
234                 password = gtk_entry_get_text (GTK_ENTRY (priv->pwd_entry));
235
236                 if (!priv->initial_state.user && strcmp (username, ""))
237                         return TRUE;
238                 if (!priv->initial_state.pwd && strcmp (password, ""))
239                         return TRUE;
240
241                 if ((priv->initial_state.user && 
242                      strcmp (priv->initial_state.user, username)) ||
243                     (priv->initial_state.pwd &&
244                      strcmp (priv->initial_state.pwd, password)))
245                         return TRUE;
246         }
247
248         /* Check subclass */
249         return  MODEST_SECURITY_OPTIONS_VIEW_GET_CLASS (self)->changed (self, settings);
250 }
251
252 void 
253 modest_security_options_view_enable_changes (ModestSecurityOptionsView* self,
254                                              gboolean enable)
255 {
256         ModestSecurityOptionsViewPrivate *priv;
257
258         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
259         gtk_widget_set_sensitive (priv->port_view, enable);
260         gtk_widget_set_sensitive (priv->security_view, enable);
261 }
262
263 gboolean 
264 modest_security_options_view_auth_check (ModestSecurityOptionsView* self)
265 {
266         ModestSecurityOptionsViewPrivate *priv;
267         ModestProtocolType security_incoming_type; 
268         gboolean auth_active, is_secure;
269         ModestProtocolRegistry *protocol_registry;
270
271         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
272         protocol_registry = modest_runtime_get_protocol_registry ();
273
274         /* Check if the server supports secure authentication */
275         security_incoming_type = 
276                 modest_serversecurity_selector_get_active_serversecurity (priv->security_view);
277
278         auth_active = 
279                 modest_togglable_get_active (priv->auth_view);
280         is_secure = 
281                 modest_protocol_registry_protocol_type_has_tag (protocol_registry, 
282                                                                 security_incoming_type, 
283                                                                 MODEST_PROTOCOL_REGISTRY_SECURE_PROTOCOLS);
284
285         if (auth_active && !is_secure)
286                 return TRUE;
287         else
288                 return FALSE;
289 }
290
291 ModestProtocolType 
292 modest_security_options_view_get_connection_protocol (ModestSecurityOptionsView *self)
293 {
294         ModestSecurityOptionsViewPrivate *priv;
295
296         g_return_val_if_fail (MODEST_IS_SECURITY_OPTIONS_VIEW (self), MODEST_PROTOCOL_REGISTRY_TYPE_INVALID);
297         priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
298
299         return modest_serversecurity_selector_get_active_serversecurity (priv->security_view);
300 }
301
302 static void 
303 modest_security_options_view_init (ModestSecurityOptionsView *self) 
304 {
305         ModestSecurityOptionsViewPrivate *priv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
306
307         memset (&(priv->initial_state), 0, sizeof (ModestSecurityOptionsState));
308
309         priv->security_view = NULL;
310         priv->port_view = NULL;
311         priv->auth_view = NULL;
312         priv->user_entry = NULL;
313         priv->pwd_entry = NULL;
314         priv->full = FALSE;
315         priv->changed = FALSE;
316 }
317
318 static void 
319 modest_security_options_view_class_init (ModestSecurityOptionsViewClass *klass) 
320 {
321         GObjectClass *gobject_class = (GObjectClass*) klass;
322
323         g_type_class_add_private (gobject_class, sizeof (ModestSecurityOptionsViewPrivate));
324
325         /* Register signals */
326         signals[MISSING_MANDATORY_DATA_SIGNAL] =
327                 g_signal_new ("missing_mandatory_data",
328                               MODEST_TYPE_SECURITY_OPTIONS_VIEW,
329                               G_SIGNAL_RUN_FIRST,
330                               G_STRUCT_OFFSET(ModestSecurityOptionsViewClass, missing_mandatory_data),
331                               NULL, NULL,
332                               g_cclosure_marshal_VOID__BOOLEAN,
333                               G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
334 }
335
336 /* Type definition */
337 G_DEFINE_ABSTRACT_TYPE (ModestSecurityOptionsView, 
338                         modest_security_options_view,
339                         GTK_TYPE_VBOX);