Bug 709561 - Pick up Windows Live mail from GOA
[platform/upstream/evolution-data-server.git] / modules / outlook-backend / module-outlook-backend.c
1 /*
2  * module-outlook-backend.c
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) version 3.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with the program; if not, see <http://www.gnu.org/licenses/>
16  *
17  */
18
19 /* XXX E-D-S currently only supports email access to Outlook.com accounts.
20  *     This is not unlike the the built-in collection backend written for
21  *     GOA's "IMAP/SMTP" accounts, but I wrote an "outlook" module anyway
22  *     as a placeholder with hopes that Microsoft will eventually provide
23  *     access to calendar+contacts via CalDAV/CardDAV or even EWS. */
24
25 #include <config.h>
26 #include <glib/gi18n-lib.h>
27
28 #include <libebackend/libebackend.h>
29
30 /* Standard GObject macros */
31 #define E_TYPE_OUTLOOK_BACKEND \
32         (e_outlook_backend_get_type ())
33 #define E_OUTLOOK_BACKEND(obj) \
34         (G_TYPE_CHECK_INSTANCE_CAST \
35         ((obj), E_TYPE_OUTLOOK_BACKEND, EOutlookBackend))
36
37 /* Just for readability... */
38 #define METHOD(x) (CAMEL_NETWORK_SECURITY_METHOD_##x)
39
40 /* IMAP Configuration Details */
41 #define OUTLOOK_IMAP_BACKEND_NAME       "imapx"
42 #define OUTLOOK_IMAP_HOST               "imap-mail.outlook.com"
43 #define OUTLOOK_IMAP_PORT               993
44 #define OUTLOOK_IMAP_SECURITY_METHOD    METHOD (SSL_ON_ALTERNATE_PORT)
45
46 /* SMTP Configuration Details */
47 #define OUTLOOK_SMTP_BACKEND_NAME       "smtp"
48 #define OUTLOOK_SMTP_HOST               "smtp-mail.outlook.com"
49 #define OUTLOOK_SMTP_PORT               587
50 #define OUTLOOK_SMTP_SECURITY_METHOD    METHOD (STARTTLS_ON_STANDARD_PORT)
51
52 typedef struct _EOutlookBackend EOutlookBackend;
53 typedef struct _EOutlookBackendClass EOutlookBackendClass;
54
55 typedef struct _EOutlookBackendFactory EOutlookBackendFactory;
56 typedef struct _EOutlookBackendFactoryClass EOutlookBackendFactoryClass;
57
58 struct _EOutlookBackend {
59         ECollectionBackend parent;
60 };
61
62 struct _EOutlookBackendClass {
63         ECollectionBackendClass parent_class;
64 };
65
66 struct _EOutlookBackendFactory {
67         ECollectionBackendFactory parent;
68 };
69
70 struct _EOutlookBackendFactoryClass {
71         ECollectionBackendFactoryClass parent_class;
72 };
73
74 /* Module Entry Points */
75 void e_module_load (GTypeModule *type_module);
76 void e_module_unload (GTypeModule *type_module);
77
78 /* Forward Declarations */
79 GType e_outlook_backend_get_type (void);
80 GType e_outlook_backend_factory_get_type (void);
81
82 G_DEFINE_DYNAMIC_TYPE (
83         EOutlookBackend,
84         e_outlook_backend,
85         E_TYPE_COLLECTION_BACKEND)
86
87 G_DEFINE_DYNAMIC_TYPE (
88         EOutlookBackendFactory,
89         e_outlook_backend_factory,
90         E_TYPE_COLLECTION_BACKEND_FACTORY)
91
92 static void
93 outlook_backend_child_added (ECollectionBackend *backend,
94                              ESource *child_source)
95 {
96         ESource *collection_source;
97         const gchar *extension_name;
98         gboolean is_mail = FALSE;
99
100         collection_source = e_backend_get_source (E_BACKEND (backend));
101
102         extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
103         is_mail |= e_source_has_extension (child_source, extension_name);
104
105         extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
106         is_mail |= e_source_has_extension (child_source, extension_name);
107
108         extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
109         is_mail |= e_source_has_extension (child_source, extension_name);
110
111         /* Synchronize mail-related user with the collection identity. */
112         extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
113         if (is_mail && e_source_has_extension (child_source, extension_name)) {
114                 ESourceAuthentication *auth_child_extension;
115                 ESourceCollection *collection_extension;
116                 const gchar *collection_identity;
117                 const gchar *auth_child_user;
118
119                 extension_name = E_SOURCE_EXTENSION_COLLECTION;
120                 collection_extension = e_source_get_extension (
121                         collection_source, extension_name);
122                 collection_identity = e_source_collection_get_identity (
123                         collection_extension);
124
125                 extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
126                 auth_child_extension = e_source_get_extension (
127                         child_source, extension_name);
128                 auth_child_user = e_source_authentication_get_user (
129                         auth_child_extension);
130
131                 /* XXX Do not override an existing user name setting.
132                  *     The IMAP or (especially) SMTP configuration may
133                  *     have been modified to use a non-Outlook server. */
134                 if (auth_child_user == NULL)
135                         e_source_authentication_set_user (
136                                 auth_child_extension,
137                                 collection_identity);
138         }
139
140         /* Chain up to parent's child_added() method. */
141         E_COLLECTION_BACKEND_CLASS (e_outlook_backend_parent_class)->
142                 child_added (backend, child_source);
143 }
144
145 static void
146 e_outlook_backend_class_init (EOutlookBackendClass *class)
147 {
148         ECollectionBackendClass *backend_class;
149
150         backend_class = E_COLLECTION_BACKEND_CLASS (class);
151         backend_class->child_added = outlook_backend_child_added;
152 }
153
154 static void
155 e_outlook_backend_class_finalize (EOutlookBackendClass *class)
156 {
157 }
158
159 static void
160 e_outlook_backend_init (EOutlookBackend *backend)
161 {
162 }
163
164 static void
165 outlook_backend_prepare_mail_account_source (ESource *source)
166 {
167         ESourceCamel *camel_extension;
168         ESourceExtension *extension;
169         CamelSettings *settings;
170         const gchar *backend_name;
171         const gchar *extension_name;
172
173         backend_name = OUTLOOK_IMAP_BACKEND_NAME;
174
175         extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
176         extension = e_source_get_extension (source, extension_name);
177
178         e_source_backend_set_backend_name (
179                 E_SOURCE_BACKEND (extension), backend_name);
180
181         extension_name = e_source_camel_get_extension_name (backend_name);
182         camel_extension = e_source_get_extension (source, extension_name);
183         settings = e_source_camel_get_settings (camel_extension);
184
185         /* The "auth-mechanism" should be determined elsewhere. */
186
187         camel_network_settings_set_host (
188                 CAMEL_NETWORK_SETTINGS (settings),
189                 OUTLOOK_IMAP_HOST);
190
191         camel_network_settings_set_port (
192                 CAMEL_NETWORK_SETTINGS (settings),
193                 OUTLOOK_IMAP_PORT);
194
195         camel_network_settings_set_security_method (
196                 CAMEL_NETWORK_SETTINGS (settings),
197                 OUTLOOK_IMAP_SECURITY_METHOD);
198 }
199
200 static void
201 outlook_backend_prepare_mail_transport_source (ESource *source)
202 {
203         ESourceCamel *camel_extension;
204         ESourceExtension *extension;
205         CamelSettings *settings;
206         const gchar *backend_name;
207         const gchar *extension_name;
208
209         backend_name = OUTLOOK_SMTP_BACKEND_NAME;
210
211         extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
212         extension = e_source_get_extension (source, extension_name);
213
214         e_source_backend_set_backend_name (
215                 E_SOURCE_BACKEND (extension), backend_name);
216
217         extension_name = e_source_camel_get_extension_name (backend_name);
218         camel_extension = e_source_get_extension (source, extension_name);
219         settings = e_source_camel_get_settings (camel_extension);
220
221         /* The "auth-mechanism" should be determined elsewhere. */
222
223         camel_network_settings_set_host (
224                 CAMEL_NETWORK_SETTINGS (settings),
225                 OUTLOOK_SMTP_HOST);
226
227         camel_network_settings_set_port (
228                 CAMEL_NETWORK_SETTINGS (settings),
229                 OUTLOOK_SMTP_PORT);
230
231         camel_network_settings_set_security_method (
232                 CAMEL_NETWORK_SETTINGS (settings),
233                 OUTLOOK_SMTP_SECURITY_METHOD);
234 }
235
236 static void
237 outlook_backend_factory_prepare_mail (ECollectionBackendFactory *factory,
238                                       ESource *mail_account_source,
239                                       ESource *mail_identity_source,
240                                       ESource *mail_transport_source)
241 {
242         ECollectionBackendFactoryClass *parent_class;
243
244         /* Chain up to parent's prepare_mail() method. */
245         parent_class =
246                 E_COLLECTION_BACKEND_FACTORY_CLASS (
247                 e_outlook_backend_factory_parent_class);
248         parent_class->prepare_mail (
249                 factory,
250                 mail_account_source,
251                 mail_identity_source,
252                 mail_transport_source);
253
254         outlook_backend_prepare_mail_account_source (mail_account_source);
255         outlook_backend_prepare_mail_transport_source (mail_transport_source);
256 }
257
258 static void
259 e_outlook_backend_factory_class_init (EOutlookBackendFactoryClass *class)
260 {
261         ECollectionBackendFactoryClass *factory_class;
262
263         factory_class = E_COLLECTION_BACKEND_FACTORY_CLASS (class);
264         factory_class->factory_name = "outlook";
265         factory_class->backend_type = E_TYPE_OUTLOOK_BACKEND;
266         factory_class->prepare_mail = outlook_backend_factory_prepare_mail;
267 }
268
269 static void
270 e_outlook_backend_factory_class_finalize (EOutlookBackendFactoryClass *class)
271 {
272 }
273
274 static void
275 e_outlook_backend_factory_init (EOutlookBackendFactory *factory)
276 {
277 }
278
279 G_MODULE_EXPORT void
280 e_module_load (GTypeModule *type_module)
281 {
282         e_outlook_backend_register_type (type_module);
283         e_outlook_backend_factory_register_type (type_module);
284 }
285
286 G_MODULE_EXPORT void
287 e_module_unload (GTypeModule *type_module)
288 {
289 }
290