From 95e2de8921230cb677c1adf3e13eb08e9c58acdb Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 7 Oct 2013 22:10:22 -0400 Subject: [PATCH] Bug 709561 - Pick up Windows Live mail from GOA This adds an "outlook-backend" module, similar to the "google-backend" and "yahoo-backend" modules. Outlook.com recently added IMAP support, and GNOME Online Accounts now exports a "Mail" interface on its "Windows Live" accounts. This module configures an E-D-S IMAP/SMTP account bound to the GOA account. --- configure.ac | 1 + modules/Makefile.am | 1 + .../module-gnome-online-accounts.c | 9 +- modules/outlook-backend/Makefile.am | 29 +++ modules/outlook-backend/module-outlook-backend.c | 290 +++++++++++++++++++++ 5 files changed, 327 insertions(+), 3 deletions(-) create mode 100644 modules/outlook-backend/Makefile.am create mode 100644 modules/outlook-backend/module-outlook-backend.c diff --git a/configure.ac b/configure.ac index e3fa22a..d788f26 100644 --- a/configure.ac +++ b/configure.ac @@ -1746,6 +1746,7 @@ modules/Makefile modules/cache-reaper/Makefile modules/gnome-online-accounts/Makefile modules/google-backend/Makefile +modules/outlook-backend/Makefile modules/owncloud-backend/Makefile modules/ubuntu-online-accounts/Makefile modules/ubuntu-online-accounts/calendar.service-type.in diff --git a/modules/Makefile.am b/modules/Makefile.am index 19d96b2..f3a719f 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -15,6 +15,7 @@ endif SUBDIRS = \ cache-reaper \ google-backend \ + outlook-backend \ owncloud-backend \ yahoo-backend \ $(TRUST_PROMPT_DIR) \ diff --git a/modules/gnome-online-accounts/module-gnome-online-accounts.c b/modules/gnome-online-accounts/module-gnome-online-accounts.c index 3058d2e..d5d1a26 100644 --- a/modules/gnome-online-accounts/module-gnome-online-accounts.c +++ b/modules/gnome-online-accounts/module-gnome-online-accounts.c @@ -100,12 +100,15 @@ gnome_online_accounts_get_backend_name (const gchar *goa_provider_type) if (g_str_equal (goa_provider_type, "imap_smtp")) eds_backend_name = "none"; - if (g_str_equal (goa_provider_type, "yahoo")) - eds_backend_name = "yahoo"; - if (g_str_equal (goa_provider_type, "owncloud")) eds_backend_name = "owncloud"; + if (g_str_equal (goa_provider_type, "windows_live")) + eds_backend_name = "outlook"; + + if (g_str_equal (goa_provider_type, "yahoo")) + eds_backend_name = "yahoo"; + return eds_backend_name; } diff --git a/modules/outlook-backend/Makefile.am b/modules/outlook-backend/Makefile.am new file mode 100644 index 0000000..21452d9 --- /dev/null +++ b/modules/outlook-backend/Makefile.am @@ -0,0 +1,29 @@ +NULL = + +module_LTLIBRARIES = module-outlook-backend.la + +module_outlook_backend_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(top_srcdir) \ + -DG_LOG_DOMAIN=\"module-outlook-backend\" \ + $(E_BACKEND_CFLAGS) \ + $(E_DATA_SERVER_CFLAGS) \ + $(NULL) + +module_outlook_backend_la_SOURCES = \ + module-outlook-backend.c \ + $(NULL) + +module_outlook_backend_la_LIBADD = \ + $(top_builddir)/libebackend/libebackend-1.2.la \ + $(top_builddir)/libedataserver/libedataserver-1.2.la \ + $(top_builddir)/camel/libcamel-1.2.la \ + $(E_BACKEND_LIBS) \ + $(E_DATA_SERVER_LIBS) \ + $(NULL) + +module_outlook_backend_la_LDFLAGS = \ + -module -avoid-version $(NO_UNDEFINED) \ + $(NULL) + +-include $(top_srcdir)/git.mk diff --git a/modules/outlook-backend/module-outlook-backend.c b/modules/outlook-backend/module-outlook-backend.c new file mode 100644 index 0000000..9cb1156 --- /dev/null +++ b/modules/outlook-backend/module-outlook-backend.c @@ -0,0 +1,290 @@ +/* + * module-outlook-backend.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +/* XXX E-D-S currently only supports email access to Outlook.com accounts. + * This is not unlike the the built-in collection backend written for + * GOA's "IMAP/SMTP" accounts, but I wrote an "outlook" module anyway + * as a placeholder with hopes that Microsoft will eventually provide + * access to calendar+contacts via CalDAV/CardDAV or even EWS. */ + +#include +#include + +#include + +/* Standard GObject macros */ +#define E_TYPE_OUTLOOK_BACKEND \ + (e_outlook_backend_get_type ()) +#define E_OUTLOOK_BACKEND(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_OUTLOOK_BACKEND, EOutlookBackend)) + +/* Just for readability... */ +#define METHOD(x) (CAMEL_NETWORK_SECURITY_METHOD_##x) + +/* IMAP Configuration Details */ +#define OUTLOOK_IMAP_BACKEND_NAME "imapx" +#define OUTLOOK_IMAP_HOST "imap-mail.outlook.com" +#define OUTLOOK_IMAP_PORT 993 +#define OUTLOOK_IMAP_SECURITY_METHOD METHOD (SSL_ON_ALTERNATE_PORT) + +/* SMTP Configuration Details */ +#define OUTLOOK_SMTP_BACKEND_NAME "smtp" +#define OUTLOOK_SMTP_HOST "smtp-mail.outlook.com" +#define OUTLOOK_SMTP_PORT 587 +#define OUTLOOK_SMTP_SECURITY_METHOD METHOD (STARTTLS_ON_STANDARD_PORT) + +typedef struct _EOutlookBackend EOutlookBackend; +typedef struct _EOutlookBackendClass EOutlookBackendClass; + +typedef struct _EOutlookBackendFactory EOutlookBackendFactory; +typedef struct _EOutlookBackendFactoryClass EOutlookBackendFactoryClass; + +struct _EOutlookBackend { + ECollectionBackend parent; +}; + +struct _EOutlookBackendClass { + ECollectionBackendClass parent_class; +}; + +struct _EOutlookBackendFactory { + ECollectionBackendFactory parent; +}; + +struct _EOutlookBackendFactoryClass { + ECollectionBackendFactoryClass parent_class; +}; + +/* Module Entry Points */ +void e_module_load (GTypeModule *type_module); +void e_module_unload (GTypeModule *type_module); + +/* Forward Declarations */ +GType e_outlook_backend_get_type (void); +GType e_outlook_backend_factory_get_type (void); + +G_DEFINE_DYNAMIC_TYPE ( + EOutlookBackend, + e_outlook_backend, + E_TYPE_COLLECTION_BACKEND) + +G_DEFINE_DYNAMIC_TYPE ( + EOutlookBackendFactory, + e_outlook_backend_factory, + E_TYPE_COLLECTION_BACKEND_FACTORY) + +static void +outlook_backend_child_added (ECollectionBackend *backend, + ESource *child_source) +{ + ESource *collection_source; + const gchar *extension_name; + gboolean is_mail = FALSE; + + collection_source = e_backend_get_source (E_BACKEND (backend)); + + extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT; + is_mail |= e_source_has_extension (child_source, extension_name); + + extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY; + is_mail |= e_source_has_extension (child_source, extension_name); + + extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT; + is_mail |= e_source_has_extension (child_source, extension_name); + + /* Synchronize mail-related user with the collection identity. */ + extension_name = E_SOURCE_EXTENSION_AUTHENTICATION; + if (is_mail && e_source_has_extension (child_source, extension_name)) { + ESourceAuthentication *auth_child_extension; + ESourceCollection *collection_extension; + const gchar *collection_identity; + const gchar *auth_child_user; + + extension_name = E_SOURCE_EXTENSION_COLLECTION; + collection_extension = e_source_get_extension ( + collection_source, extension_name); + collection_identity = e_source_collection_get_identity ( + collection_extension); + + extension_name = E_SOURCE_EXTENSION_AUTHENTICATION; + auth_child_extension = e_source_get_extension ( + child_source, extension_name); + auth_child_user = e_source_authentication_get_user ( + auth_child_extension); + + /* XXX Do not override an existing user name setting. + * The IMAP or (especially) SMTP configuration may + * have been modified to use a non-Outlook server. */ + if (auth_child_user == NULL) + e_source_authentication_set_user ( + auth_child_extension, + collection_identity); + } + + /* Chain up to parent's child_added() method. */ + E_COLLECTION_BACKEND_CLASS (e_outlook_backend_parent_class)-> + child_added (backend, child_source); +} + +static void +e_outlook_backend_class_init (EOutlookBackendClass *class) +{ + ECollectionBackendClass *backend_class; + + backend_class = E_COLLECTION_BACKEND_CLASS (class); + backend_class->child_added = outlook_backend_child_added; +} + +static void +e_outlook_backend_class_finalize (EOutlookBackendClass *class) +{ +} + +static void +e_outlook_backend_init (EOutlookBackend *backend) +{ +} + +static void +outlook_backend_prepare_mail_account_source (ESource *source) +{ + ESourceCamel *camel_extension; + ESourceExtension *extension; + CamelSettings *settings; + const gchar *backend_name; + const gchar *extension_name; + + backend_name = OUTLOOK_IMAP_BACKEND_NAME; + + extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT; + extension = e_source_get_extension (source, extension_name); + + e_source_backend_set_backend_name ( + E_SOURCE_BACKEND (extension), backend_name); + + extension_name = e_source_camel_get_extension_name (backend_name); + camel_extension = e_source_get_extension (source, extension_name); + settings = e_source_camel_get_settings (camel_extension); + + /* The "auth-mechanism" should be determined elsewhere. */ + + camel_network_settings_set_host ( + CAMEL_NETWORK_SETTINGS (settings), + OUTLOOK_IMAP_HOST); + + camel_network_settings_set_port ( + CAMEL_NETWORK_SETTINGS (settings), + OUTLOOK_IMAP_PORT); + + camel_network_settings_set_security_method ( + CAMEL_NETWORK_SETTINGS (settings), + OUTLOOK_IMAP_SECURITY_METHOD); +} + +static void +outlook_backend_prepare_mail_transport_source (ESource *source) +{ + ESourceCamel *camel_extension; + ESourceExtension *extension; + CamelSettings *settings; + const gchar *backend_name; + const gchar *extension_name; + + backend_name = OUTLOOK_SMTP_BACKEND_NAME; + + extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT; + extension = e_source_get_extension (source, extension_name); + + e_source_backend_set_backend_name ( + E_SOURCE_BACKEND (extension), backend_name); + + extension_name = e_source_camel_get_extension_name (backend_name); + camel_extension = e_source_get_extension (source, extension_name); + settings = e_source_camel_get_settings (camel_extension); + + /* The "auth-mechanism" should be determined elsewhere. */ + + camel_network_settings_set_host ( + CAMEL_NETWORK_SETTINGS (settings), + OUTLOOK_SMTP_HOST); + + camel_network_settings_set_port ( + CAMEL_NETWORK_SETTINGS (settings), + OUTLOOK_SMTP_PORT); + + camel_network_settings_set_security_method ( + CAMEL_NETWORK_SETTINGS (settings), + OUTLOOK_SMTP_SECURITY_METHOD); +} + +static void +outlook_backend_factory_prepare_mail (ECollectionBackendFactory *factory, + ESource *mail_account_source, + ESource *mail_identity_source, + ESource *mail_transport_source) +{ + ECollectionBackendFactoryClass *parent_class; + + /* Chain up to parent's prepare_mail() method. */ + parent_class = + E_COLLECTION_BACKEND_FACTORY_CLASS ( + e_outlook_backend_factory_parent_class); + parent_class->prepare_mail ( + factory, + mail_account_source, + mail_identity_source, + mail_transport_source); + + outlook_backend_prepare_mail_account_source (mail_account_source); + outlook_backend_prepare_mail_transport_source (mail_transport_source); +} + +static void +e_outlook_backend_factory_class_init (EOutlookBackendFactoryClass *class) +{ + ECollectionBackendFactoryClass *factory_class; + + factory_class = E_COLLECTION_BACKEND_FACTORY_CLASS (class); + factory_class->factory_name = "outlook"; + factory_class->backend_type = E_TYPE_OUTLOOK_BACKEND; + factory_class->prepare_mail = outlook_backend_factory_prepare_mail; +} + +static void +e_outlook_backend_factory_class_finalize (EOutlookBackendFactoryClass *class) +{ +} + +static void +e_outlook_backend_factory_init (EOutlookBackendFactory *factory) +{ +} + +G_MODULE_EXPORT void +e_module_load (GTypeModule *type_module) +{ + e_outlook_backend_register_type (type_module); + e_outlook_backend_factory_register_type (type_module); +} + +G_MODULE_EXPORT void +e_module_unload (GTypeModule *type_module) +{ +} + -- 2.7.4