Bug 699024 - [google/yahoo] Don't override username
[platform/upstream/evolution-data-server.git] / modules / yahoo-backend / module-yahoo-backend.c
1 /*
2  * module-yahoo-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 #include <config.h>
20 #include <glib/gi18n-lib.h>
21
22 #include <libebackend/libebackend.h>
23
24 /* Standard GObject macros */
25 #define E_TYPE_YAHOO_BACKEND \
26         (e_yahoo_backend_get_type ())
27 #define E_YAHOO_BACKEND(obj) \
28         (G_TYPE_CHECK_INSTANCE_CAST \
29         ((obj), E_TYPE_YAHOO_BACKEND, EYahooBackend))
30
31 /* Just for readability... */
32 #define METHOD(x) (CAMEL_NETWORK_SECURITY_METHOD_##x)
33
34 /* IMAP Configuration Details */
35 #define YAHOO_IMAP_BACKEND_NAME         "imapx"
36 #define YAHOO_IMAP_HOST                 "imap.mail.yahoo.com"
37 #define YAHOO_IMAP_PORT                 993
38 #define YAHOO_IMAP_SECURITY_METHOD      METHOD (SSL_ON_ALTERNATE_PORT)
39
40 /* SMTP Configuration Details */
41 #define YAHOO_SMTP_BACKEND_NAME         "smtp"
42 #define YAHOO_SMTP_HOST                 "smtp.mail.yahoo.com"
43 #define YAHOO_SMTP_PORT                 465
44 #define YAHOO_SMTP_SECURITY_METHOD      METHOD (SSL_ON_ALTERNATE_PORT)
45
46 /* Calendar Configuration Details */
47 #define YAHOO_CALENDAR_BACKEND_NAME     "caldav"
48 #define YAHOO_CALENDAR_HOST             "caldav.calendar.yahoo.com"
49 #define YAHOO_CALENDAR_CALDAV_PATH      "/dav/%s/Calendar/%s"
50 #define YAHOO_CALENDAR_RESOURCE_ID      "Calendar"
51
52 /* Tasks Configuration Details
53  * (mostly the same as calendar) */
54 #define YAHOO_TASKS_RESOURCE_ID         "Tasks"
55
56 typedef struct _EYahooBackend EYahooBackend;
57 typedef struct _EYahooBackendClass EYahooBackendClass;
58
59 typedef struct _EYahooBackendFactory EYahooBackendFactory;
60 typedef struct _EYahooBackendFactoryClass EYahooBackendFactoryClass;
61
62 struct _EYahooBackend {
63         ECollectionBackend parent;
64         GWeakRef mail_identity_source;
65 };
66
67 struct _EYahooBackendClass {
68         ECollectionBackendClass parent_class;
69 };
70
71 struct _EYahooBackendFactory {
72         ECollectionBackendFactory parent;
73 };
74
75 struct _EYahooBackendFactoryClass {
76         ECollectionBackendFactoryClass parent_class;
77 };
78
79 /* Module Entry Points */
80 void e_module_load (GTypeModule *type_module);
81 void e_module_unload (GTypeModule *type_module);
82
83 /* Forward Declarations */
84 GType e_yahoo_backend_get_type (void);
85 GType e_yahoo_backend_factory_get_type (void);
86
87 G_DEFINE_DYNAMIC_TYPE (
88         EYahooBackend,
89         e_yahoo_backend,
90         E_TYPE_COLLECTION_BACKEND)
91
92 G_DEFINE_DYNAMIC_TYPE (
93         EYahooBackendFactory,
94         e_yahoo_backend_factory,
95         E_TYPE_COLLECTION_BACKEND_FACTORY)
96
97 static void
98 yahoo_backend_config_calendar_child (ECollectionBackend *backend,
99                                      ESource *source)
100 {
101         EYahooBackend *yahoo_backend;
102         ESource *collection_source;
103         ESource *mail_identity_source;
104         ESourceExtension *extension;
105         ESourceCollection *collection_extension;
106         const gchar *extension_name;
107         const gchar *identity;
108         gchar *display_name = NULL;
109
110         /* FIXME As a future enhancement, we should query Yahoo!
111          *       for a list of user calendars and add them to the
112          *       collection with matching display names and colors. */
113
114         yahoo_backend = E_YAHOO_BACKEND (backend);
115
116         collection_source = e_backend_get_source (E_BACKEND (backend));
117
118         collection_extension = e_source_get_extension (
119                 collection_source, E_SOURCE_EXTENSION_COLLECTION);
120
121         identity = e_source_collection_get_identity (collection_extension);
122
123         /* XXX Assume the calendar's display name can be derived from
124          *     the user's mail identity.  As mentioned above, we should
125          *     really just query Yahoo! for a list of user calendars. */
126         mail_identity_source =
127                 g_weak_ref_get (&yahoo_backend->mail_identity_source);
128         if (mail_identity_source != NULL) {
129                 extension = e_source_get_extension (
130                         mail_identity_source,
131                         E_SOURCE_EXTENSION_MAIL_IDENTITY);
132                 display_name = e_source_mail_identity_dup_name (
133                         E_SOURCE_MAIL_IDENTITY (extension));
134                 if (display_name != NULL)
135                         g_strdelimit (display_name, " ", '_');
136                 g_object_unref (mail_identity_source);
137         }
138
139         extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
140         extension = e_source_get_extension (source, extension_name);
141
142         e_source_authentication_set_host (
143                 E_SOURCE_AUTHENTICATION (extension),
144                 YAHOO_CALENDAR_HOST);
145
146         g_object_bind_property (
147                 collection_extension, "identity",
148                 extension, "user",
149                 G_BINDING_SYNC_CREATE);
150
151         extension_name = E_SOURCE_EXTENSION_SECURITY;
152         extension = e_source_get_extension (source, extension_name);
153
154         e_source_security_set_secure (
155                 E_SOURCE_SECURITY (extension), TRUE);
156
157         extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
158         extension = e_source_get_extension (source, extension_name);
159
160         e_source_webdav_set_display_name (
161                 E_SOURCE_WEBDAV (extension), display_name);
162
163         if (identity != NULL && display_name != NULL) {
164                 gchar *resource_path;
165
166                 resource_path = g_strdup_printf (
167                         YAHOO_CALENDAR_CALDAV_PATH, identity, display_name);
168                 e_source_webdav_set_resource_path (
169                         E_SOURCE_WEBDAV (extension), resource_path);
170                 g_free (resource_path);
171         }
172
173         g_free (display_name);
174 }
175
176 static void
177 yahoo_backend_add_calendar (ECollectionBackend *backend)
178 {
179         ESource *source;
180         ESourceBackend *extension;
181         ESourceRegistryServer *server;
182         const gchar *backend_name;
183         const gchar *extension_name;
184         const gchar *resource_id;
185
186         /* XXX We could just stick a [Calendar] and [Task List] extension
187          *     into the same ESource since all other settings are exactly
188          *     the same.  But it might be confusing if tweaking a setting
189          *     in your Yahoo! Calendar also gets applied to your Yahoo!
190          *     Task List in Evolution. */
191
192         backend_name = YAHOO_CALENDAR_BACKEND_NAME;
193
194         server = e_collection_backend_ref_server (backend);
195
196         /* Add Yahoo! Calendar */
197
198         resource_id = YAHOO_CALENDAR_RESOURCE_ID;
199         source = e_collection_backend_new_child (backend, resource_id);
200         e_source_set_display_name (source, _("Calendar"));
201
202         extension_name = E_SOURCE_EXTENSION_CALENDAR;
203         extension = e_source_get_extension (source, extension_name);
204         e_source_backend_set_backend_name (extension, backend_name);
205
206         extension_name = E_SOURCE_EXTENSION_ALARMS;
207         extension = e_source_get_extension (source, extension_name);
208         if (!e_source_alarms_get_last_notified (E_SOURCE_ALARMS (extension))) {
209                 GTimeVal today_tv;
210                 gchar *today;
211
212                 g_get_current_time (&today_tv);
213                 today = g_time_val_to_iso8601 (&today_tv);
214                 e_source_alarms_set_last_notified (E_SOURCE_ALARMS (extension), today);
215                 g_free (today);
216         }
217
218         yahoo_backend_config_calendar_child (backend, source);
219         e_source_registry_server_add_source (server, source);
220
221         g_object_unref (source);
222
223         /* Add Yahoo! Tasks */
224
225         resource_id = YAHOO_TASKS_RESOURCE_ID;
226         source = e_collection_backend_new_child (backend, resource_id);
227         e_source_set_display_name (source, _("Tasks"));
228
229         extension_name = E_SOURCE_EXTENSION_TASK_LIST;
230         extension = e_source_get_extension (source, extension_name);
231         e_source_backend_set_backend_name (extension, backend_name);
232
233         yahoo_backend_config_calendar_child (backend, source);
234         e_source_registry_server_add_source (server, source);
235
236         g_object_unref (source);
237
238         g_object_unref (server);
239 }
240
241 static void
242 yahoo_backend_populate (ECollectionBackend *backend)
243 {
244         GList *list;
245
246         /* Chain up to parent's populate() method. */
247         E_COLLECTION_BACKEND_CLASS (e_yahoo_backend_parent_class)->
248                 populate (backend);
249
250         /* Chain up first so we pick up the mail identity source. */
251         list = e_collection_backend_list_calendar_sources (backend);
252         if (list == NULL)
253                 yahoo_backend_add_calendar (backend);
254         g_list_free_full (list, (GDestroyNotify) g_object_unref);
255 }
256
257 static gchar *
258 yahoo_backend_dup_resource_id (ECollectionBackend *backend,
259                                ESource *child_source)
260 {
261         const gchar *extension_name;
262
263         /* XXX This is trival for now since we only
264          *     add one calendar and one task list. */
265
266         extension_name = E_SOURCE_EXTENSION_CALENDAR;
267         if (e_source_has_extension (child_source, extension_name))
268                 return g_strdup (YAHOO_CALENDAR_RESOURCE_ID);
269
270         extension_name = E_SOURCE_EXTENSION_TASK_LIST;
271         if (e_source_has_extension (child_source, extension_name))
272                 return g_strdup (YAHOO_TASKS_RESOURCE_ID);
273
274         return NULL;
275 }
276
277 static void
278 yahoo_backend_child_added (ECollectionBackend *backend,
279                            ESource *child_source)
280 {
281         EYahooBackend *yahoo_backend;
282         ESource *collection_source;
283         const gchar *extension_name;
284         gboolean is_mail = FALSE;
285
286         yahoo_backend = E_YAHOO_BACKEND (backend);
287         collection_source = e_backend_get_source (E_BACKEND (backend));
288
289         extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
290         is_mail |= e_source_has_extension (child_source, extension_name);
291
292         /* Take special note of the mail identity source.
293          * We need it to build the calendar CalDAV path. */
294         extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
295         if (e_source_has_extension (child_source, extension_name)) {
296                 GWeakRef *weak_ref;
297
298                 weak_ref = &yahoo_backend->mail_identity_source;
299                 g_weak_ref_set (weak_ref, child_source);
300                 is_mail = TRUE;
301         }
302
303         extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
304         is_mail |= e_source_has_extension (child_source, extension_name);
305
306         /* Synchronize mail-related user with the collection identity. */
307         extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
308         if (is_mail && e_source_has_extension (child_source, extension_name)) {
309                 ESourceAuthentication *auth_child_extension;
310                 ESourceCollection *collection_extension;
311                 const gchar *collection_identity;
312                 const gchar *auth_child_user;
313
314                 extension_name = E_SOURCE_EXTENSION_COLLECTION;
315                 collection_extension = e_source_get_extension (
316                         collection_source, extension_name);
317                 collection_identity = e_source_collection_get_identity (
318                         collection_extension);
319
320                 extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
321                 auth_child_extension = e_source_get_extension (
322                         child_source, extension_name);
323                 auth_child_user = e_source_authentication_get_user (
324                         auth_child_extension);
325
326                 /* XXX Do not override an existing user name setting.
327                  *     The IMAP or (especially) SMTP configuration may
328                  *     have been modified to use a non-Yahoo! server. */
329                 if (auth_child_user == NULL)
330                         e_source_authentication_set_user (
331                                 auth_child_extension,
332                                 collection_identity);
333         }
334
335         /* Chain up to parent's child_added() method. */
336         E_COLLECTION_BACKEND_CLASS (e_yahoo_backend_parent_class)->
337                 child_added (backend, child_source);
338 }
339
340 static void
341 e_yahoo_backend_class_init (EYahooBackendClass *class)
342 {
343         ECollectionBackendClass *backend_class;
344
345         backend_class = E_COLLECTION_BACKEND_CLASS (class);
346         backend_class->populate = yahoo_backend_populate;
347         backend_class->dup_resource_id = yahoo_backend_dup_resource_id;
348         backend_class->child_added = yahoo_backend_child_added;
349 }
350
351 static void
352 e_yahoo_backend_class_finalize (EYahooBackendClass *class)
353 {
354 }
355
356 static void
357 e_yahoo_backend_init (EYahooBackend *backend)
358 {
359 }
360
361 static void
362 yahoo_backend_prepare_mail_account_source (ESource *source)
363 {
364         ESourceCamel *camel_extension;
365         ESourceExtension *extension;
366         CamelSettings *settings;
367         const gchar *backend_name;
368         const gchar *extension_name;
369
370         backend_name = YAHOO_IMAP_BACKEND_NAME;
371
372         extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
373         extension = e_source_get_extension (source, extension_name);
374
375         e_source_backend_set_backend_name (
376                 E_SOURCE_BACKEND (extension), backend_name);
377
378         extension_name = e_source_camel_get_extension_name (backend_name);
379         camel_extension = e_source_get_extension (source, extension_name);
380         settings = e_source_camel_get_settings (camel_extension);
381
382         /* The "auth-mechanism" should be determined elsewhere. */
383
384         camel_network_settings_set_host (
385                 CAMEL_NETWORK_SETTINGS (settings),
386                 YAHOO_IMAP_HOST);
387
388         camel_network_settings_set_port (
389                 CAMEL_NETWORK_SETTINGS (settings),
390                 YAHOO_IMAP_PORT);
391
392         camel_network_settings_set_security_method (
393                 CAMEL_NETWORK_SETTINGS (settings),
394                 YAHOO_IMAP_SECURITY_METHOD);
395 }
396
397 static void
398 yahoo_backend_prepare_mail_transport_source (ESource *source)
399 {
400         ESourceCamel *camel_extension;
401         ESourceExtension *extension;
402         CamelSettings *settings;
403         const gchar *backend_name;
404         const gchar *extension_name;
405
406         /* Configure the mail transport source. */
407
408         backend_name = YAHOO_SMTP_BACKEND_NAME;
409
410         extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
411         extension = e_source_get_extension (source, extension_name);
412
413         e_source_backend_set_backend_name (
414                 E_SOURCE_BACKEND (extension), backend_name);
415
416         extension_name = e_source_camel_get_extension_name (backend_name);
417         camel_extension = e_source_get_extension (source, extension_name);
418         settings = e_source_camel_get_settings (camel_extension);
419
420         /* The "auth-mechanism" should be determined elsewhere. */
421
422         camel_network_settings_set_host (
423                 CAMEL_NETWORK_SETTINGS (settings),
424                 YAHOO_SMTP_HOST);
425
426         camel_network_settings_set_port (
427                 CAMEL_NETWORK_SETTINGS (settings),
428                 YAHOO_SMTP_PORT);
429
430         camel_network_settings_set_security_method (
431                 CAMEL_NETWORK_SETTINGS (settings),
432                 YAHOO_SMTP_SECURITY_METHOD);
433 }
434
435 static void
436 yahoo_backend_factory_prepare_mail (ECollectionBackendFactory *factory,
437                                     ESource *mail_account_source,
438                                     ESource *mail_identity_source,
439                                     ESource *mail_transport_source)
440 {
441         ECollectionBackendFactoryClass *parent_class;
442
443         /* Chain up to parent's prepare_mail() method. */
444         parent_class =
445                 E_COLLECTION_BACKEND_FACTORY_CLASS (
446                 e_yahoo_backend_factory_parent_class);
447         parent_class->prepare_mail (
448                 factory,
449                 mail_account_source,
450                 mail_identity_source,
451                 mail_transport_source);
452
453         yahoo_backend_prepare_mail_account_source (mail_account_source);
454         yahoo_backend_prepare_mail_transport_source (mail_transport_source);
455 }
456
457 static void
458 e_yahoo_backend_factory_class_init (EYahooBackendFactoryClass *class)
459 {
460         ECollectionBackendFactoryClass *factory_class;
461
462         factory_class = E_COLLECTION_BACKEND_FACTORY_CLASS (class);
463         factory_class->factory_name = "yahoo";
464         factory_class->backend_type = E_TYPE_YAHOO_BACKEND;
465         factory_class->prepare_mail = yahoo_backend_factory_prepare_mail;
466 }
467
468 static void
469 e_yahoo_backend_factory_class_finalize (EYahooBackendFactoryClass *class)
470 {
471 }
472
473 static void
474 e_yahoo_backend_factory_init (EYahooBackendFactory *factory)
475 {
476 }
477
478 G_MODULE_EXPORT void
479 e_module_load (GTypeModule *type_module)
480 {
481         e_yahoo_backend_register_type (type_module);
482         e_yahoo_backend_factory_register_type (type_module);
483 }
484
485 G_MODULE_EXPORT void
486 e_module_unload (GTypeModule *type_module)
487 {
488 }
489