[evolution-data-server] UOA: Add support for IMAP access to Windows Live accounts.



commit 8ffb92b8951b25a8f0118ec7463d3a8c249c809a
Author: Matthew Barnes <mbarnes redhat com>
Date:   Thu Nov 21 10:34:24 2013 -0500

    UOA: Add support for IMAP access to Windows Live accounts.

 configure.ac                                       |    1 +
 modules/ubuntu-online-accounts/Makefile.am         |    2 +
 .../evolution-data-server.application.in.in        |    3 +
 .../module-ubuntu-online-accounts.c                |    3 +
 modules/ubuntu-online-accounts/uoa-utils.c         |  213 ++++++++++++++++++++
 .../windows-live-mail.service.in.in                |   10 +
 6 files changed, 232 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 806761f..97702f7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1788,6 +1788,7 @@ modules/ubuntu-online-accounts/google-calendar.service.in
 modules/ubuntu-online-accounts/google-contacts.service.in
 modules/ubuntu-online-accounts/google-gmail.service.in
 modules/ubuntu-online-accounts/mail.service-type.in
+modules/ubuntu-online-accounts/windows-live-mail.service.in
 modules/ubuntu-online-accounts/yahoo-calendar.service.in
 modules/ubuntu-online-accounts/yahoo-mail.service.in
 modules/trust-prompt/Makefile
diff --git a/modules/ubuntu-online-accounts/Makefile.am b/modules/ubuntu-online-accounts/Makefile.am
index 3669c04..0a268d4 100644
--- a/modules/ubuntu-online-accounts/Makefile.am
+++ b/modules/ubuntu-online-accounts/Makefile.am
@@ -61,6 +61,7 @@ service_DATA = \
        google-gmail.service \
        google-calendar.service \
        google-contacts.service \
+       windows-live-mail.service \
        yahoo-mail.service \
        yahoo-calendar.service \
        $(NULL)
@@ -79,6 +80,7 @@ EXTRA_DIST = \
        google-gmail.service.in.in \
        google-calendar.service.in.in \
        google-contacts.service.in.in \
+       windows-live-mail.service.in.in \
        yahoo-mail.service.in.in \
        yahoo-calendar.service.in.in \
        $(desktop_DATA) \
diff --git a/modules/ubuntu-online-accounts/evolution-data-server.application.in.in 
b/modules/ubuntu-online-accounts/evolution-data-server.application.in.in
index 27bc3c9..ab3d886 100644
--- a/modules/ubuntu-online-accounts/evolution-data-server.application.in.in
+++ b/modules/ubuntu-online-accounts/evolution-data-server.application.in.in
@@ -13,6 +13,9 @@
     <service id="google-contacts">
       <_description>Access your Google Contacts</_description>
     </service>
+    <service id="windows-live-mail">
+      <_description>Access your Windows Live Mail</_description>
+    </service>
     <service id="yahoo-mail">
       <_description>Access your Yahoo! Mail</_description>
     </service>
diff --git a/modules/ubuntu-online-accounts/module-ubuntu-online-accounts.c 
b/modules/ubuntu-online-accounts/module-ubuntu-online-accounts.c
index a57fbe5..e84592d 100644
--- a/modules/ubuntu-online-accounts/module-ubuntu-online-accounts.c
+++ b/modules/ubuntu-online-accounts/module-ubuntu-online-accounts.c
@@ -106,6 +106,9 @@ ubuntu_online_accounts_get_backend_name (const gchar *uoa_provider_name)
        if (g_strcmp0 (uoa_provider_name, "google") == 0)
                eds_backend_name = "google";
 
+       if (g_strcmp0 (uoa_provider_name, "windows-live") == 0)
+               eds_backend_name = "outlook";
+
        if (g_strcmp0 (uoa_provider_name, "yahoo") == 0)
                eds_backend_name = "yahoo";
 
diff --git a/modules/ubuntu-online-accounts/uoa-utils.c b/modules/ubuntu-online-accounts/uoa-utils.c
index 2be6cc6..49120e7 100644
--- a/modules/ubuntu-online-accounts/uoa-utils.c
+++ b/modules/ubuntu-online-accounts/uoa-utils.c
@@ -27,6 +27,9 @@
 #define GOOGLE_USERINFO_URI \
        "https://www.googleapis.com/oauth2/v2/userinfo";
 
+#define WINDOWS_LIVE_ME_URI \
+       "https://apis.live.net/v5.0/me";
+
 typedef struct _AsyncContext AsyncContext;
 
 struct _AsyncContext {
@@ -245,6 +248,213 @@ e_ag_account_collect_google_userinfo (GSimpleAsyncResult *simple,
        g_object_unref (simple);
 }
 
+/*************************** Windows Live Provider ***************************/
+
+static void
+e_ag_account_windows_live_got_me_cb (RestProxyCall *call,
+                                     const GError *error,
+                                     GObject *weak_object,
+                                     gpointer user_data)
+{
+       GSimpleAsyncResult *simple;
+       AsyncContext *async_context;
+       JsonParser *json_parser;
+       JsonObject *json_object;
+       JsonNode *json_node;
+       const gchar *json_string;
+       gchar *id;
+       gchar *email;
+       GError *local_error = NULL;
+
+       simple = G_SIMPLE_ASYNC_RESULT (user_data);
+       async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+       if (error != NULL) {
+               g_simple_async_result_set_from_error (simple, error);
+               goto exit;
+       }
+
+       /* This is shamelessly stolen from goawindowsliveprovider.c */
+
+       if (rest_proxy_call_get_status_code (call) != 200) {
+               g_simple_async_result_set_error (
+                       simple, G_IO_ERROR, G_IO_ERROR_FAILED,
+                       _("Expected status 200 when requesting your "
+                       "identity, instead got status %d (%s)"),
+                       rest_proxy_call_get_status_code (call),
+                       rest_proxy_call_get_status_message (call));
+               goto exit;
+       }
+
+       json_parser = json_parser_new ();
+       json_parser_load_from_data (
+               json_parser,
+               rest_proxy_call_get_payload (call),
+               rest_proxy_call_get_payload_length (call),
+               &local_error);
+
+       if (local_error != NULL) {
+               g_prefix_error (
+                       &local_error,
+                       _("Error parsing response as JSON: "));
+               g_simple_async_result_take_error (simple, local_error);
+               g_object_unref (json_parser);
+               goto exit;
+       }
+
+       json_node = json_parser_get_root (json_parser);
+       json_object = json_node_get_object (json_node);
+       json_string = json_object_get_string_member (json_object, "id");
+       id = g_strdup (json_string);
+
+       json_object = json_object_get_object_member (json_object, "emails");
+       json_string = json_object_get_string_member (json_object, "account");
+       email = g_strdup (json_string);
+
+       if (id == NULL) {
+               g_simple_async_result_set_error (
+                       simple, G_IO_ERROR, G_IO_ERROR_FAILED,
+                       _("Didn't find 'id' in JSON data"));
+               g_free (email);
+       } else if (email == NULL) {
+               g_simple_async_result_set_error (
+                       simple, G_IO_ERROR, G_IO_ERROR_FAILED,
+                       _("Didn't find 'emails.account' in JSON data"));
+       } else {
+               async_context->user_identity = id;
+               async_context->email_address = email;
+               async_context->imap_user_name = g_strdup (email);
+               async_context->smtp_user_name = g_strdup (email);
+       }
+
+       g_object_unref (json_parser);
+
+exit:
+       g_simple_async_result_complete (simple);
+
+       g_object_unref (simple);
+}
+
+static void
+e_ag_account_windows_live_session_process_cb (GObject *source_object,
+                                              GAsyncResult *result,
+                                              gpointer user_data)
+{
+       GSimpleAsyncResult *simple;
+       GVariant *session_data;
+       GError *local_error = NULL;
+
+       simple = G_SIMPLE_ASYNC_RESULT (user_data);
+
+       session_data = signon_auth_session_process_finish (
+               SIGNON_AUTH_SESSION (source_object), result, &local_error);
+
+       /* Sanity check. */
+       g_return_if_fail (
+               ((session_data != NULL) && (local_error == NULL)) ||
+               ((session_data == NULL) && (local_error != NULL)));
+
+       /* Use the access token to obtain the user's email address. */
+
+       if (session_data != NULL) {
+               RestProxy *proxy;
+               RestProxyCall *call;
+               gchar *access_token = NULL;
+
+               g_variant_lookup (
+                       session_data, "AccessToken", "s", &access_token);
+
+               g_variant_unref (session_data);
+
+               proxy = rest_proxy_new (WINDOWS_LIVE_ME_URI, FALSE);
+               call = rest_proxy_new_call (proxy);
+               rest_proxy_call_set_method (call, "GET");
+
+               /* XXX This should never be NULL, but if it is just let
+                *     the call fail and pick up the resulting GError. */
+               if (access_token != NULL) {
+                       rest_proxy_call_add_param (
+                               call, "access_token", access_token);
+                       g_free (access_token);
+               }
+
+               /* XXX The 3rd argument is supposed to be a GObject
+                *     that RestProxyCall weakly references such that
+                *     its disposal cancels the call.  This obviously
+                *     predates GCancellable.  Too bizarre to bother. */
+               rest_proxy_call_async (
+                       call, e_ag_account_windows_live_got_me_cb,
+                       NULL, g_object_ref (simple), &local_error);
+
+               if (local_error != NULL) {
+                       /* Undo the reference added to the async call. */
+                       g_object_unref (simple);
+               }
+
+               g_object_unref (proxy);
+               g_object_unref (call);
+       }
+
+       if (local_error != NULL) {
+               g_simple_async_result_take_error (simple, local_error);
+               g_simple_async_result_complete (simple);
+       }
+
+       g_object_unref (simple);
+}
+
+static void
+e_ag_account_collect_windows_live_userinfo (GSimpleAsyncResult *simple,
+                                            AgAccount *ag_account,
+                                            GCancellable *cancellable)
+{
+       AgAccountService *ag_account_service = NULL;
+       SignonAuthSession *session;
+       AgAuthData *ag_auth_data;
+       GList *list;
+       GError *local_error = NULL;
+
+       /* First obtain an OAuth 2.0 access token. */
+
+       list = ag_account_list_services_by_type (ag_account, "mail");
+       if (list != NULL) {
+               ag_account_service = ag_account_service_new (
+                       ag_account, (AgService *) list->data);
+               ag_service_list_free (list);
+       }
+
+       g_return_if_fail (ag_account_service != NULL);
+
+       ag_auth_data = ag_account_service_get_auth_data (ag_account_service);
+
+       session = signon_auth_session_new (
+               ag_auth_data_get_credentials_id (ag_auth_data),
+               ag_auth_data_get_method (ag_auth_data), &local_error);
+
+       /* Sanity check. */
+       g_return_if_fail (
+               ((session != NULL) && (local_error == NULL)) ||
+               ((session == NULL) && (local_error != NULL)));
+
+       if (session != NULL) {
+               signon_auth_session_process_async (
+                       session,
+                       ag_auth_data_get_login_parameters (ag_auth_data, NULL),
+                       ag_auth_data_get_mechanism (ag_auth_data),
+                       cancellable,
+                       e_ag_account_windows_live_session_process_cb,
+                       g_object_ref (simple));
+       } else {
+               g_simple_async_result_take_error (simple, local_error);
+               g_simple_async_result_complete_in_idle (simple);
+       }
+
+       ag_auth_data_unref (ag_auth_data);
+
+       g_object_unref (ag_account_service);
+       g_object_unref (simple);
+}
+
 /****************************** Yahoo! Provider ******************************/
 
 static void
@@ -320,6 +530,9 @@ e_ag_account_collect_userinfo (AgAccount *ag_account,
        if (g_str_equal (provider_name, "google")) {
                e_ag_account_collect_google_userinfo (
                        g_object_ref (simple), ag_account, cancellable);
+       } else if (g_str_equal (provider_name, "windows-live")) {
+               e_ag_account_collect_windows_live_userinfo (
+                       g_object_ref (simple), ag_account, cancellable);
        } else if (g_str_equal (provider_name, "yahoo")) {
                e_ag_account_collect_yahoo_userinfo (
                        g_object_ref (simple), ag_account, cancellable);
diff --git a/modules/ubuntu-online-accounts/windows-live-mail.service.in.in 
b/modules/ubuntu-online-accounts/windows-live-mail.service.in.in
new file mode 100644
index 0000000..10db024
--- /dev/null
+++ b/modules/ubuntu-online-accounts/windows-live-mail.service.in.in
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<service id="windows-live-mail">
+  <type>mail</type>
+  <_name>Windows Live Mail</_name>
+  <provider>windows-live</provider>
+  <translations>@GETTEXT_PACKAGE@</translations>
+
+  <!-- provider's authentication settings are sufficient -->
+</service>
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]