[gnome-online-accounts] Add Windows Live oauth2



commit 0b39d4c9c39d82084baf486d796f5fdad84cd2cc
Author: Xavier Claessens <xclaesse gmail com>
Date:   Thu Dec 15 10:48:25 2011 +0100

    Add Windows Live oauth2
    
    https://bugzilla.gnome.org/show_bug.cgi?id=661067

 configure.ac                          |   15 ++
 po/POTFILES.in                        |    1 +
 src/goabackend/Makefile.am            |    2 +
 src/goabackend/goabackendtypes.h      |    3 +
 src/goabackend/goamessengerprovider.c |  327 +++++++++++++++++++++++++++++++++
 src/goabackend/goamessengerprovider.h |   44 +++++
 src/goabackend/goaoauth2provider.c    |   17 +-
 src/goabackend/goaprovider.c          |    5 +
 8 files changed, 407 insertions(+), 7 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 6fef6be..8a474da 100644
--- a/configure.ac
+++ b/configure.ac
@@ -164,6 +164,20 @@ if test "$enable_facebook" != "no"; then
   AC_DEFINE(GOA_FACEBOOK_ENABLED, 1, [Enable Facebook data provider])
 fi
 
+# Messenger
+AC_ARG_ENABLE([messenger], [AS_HELP_STRING([--enable-messenger], [Enable Messenger provider])], [], [enable_messenger=no])
+AC_ARG_WITH(messenger-client-id,
+            [AS_HELP_STRING([--with-messenger-client-id],
+                            [Messenger OAuth 2.0 client id])],
+                            [],
+                            [])
+if test "$with_messenger_client_id" = ""; then
+  with_messenger_client_id=not_set
+fi
+AC_DEFINE_UNQUOTED(GOA_MESSENGER_CLIENT_ID, ["$with_messenger_client_id"], [Messenger OAuth 2.0 client id])
+if test "$enable_messenger" != "no"; then
+  AC_DEFINE(GOA_MESSENGER_ENABLED, 1, [Enable Messenger data provider])
+fi
 
 # Internationalization
 #
@@ -222,6 +236,7 @@ echo "
 	Twitter provider:           ${enable_twitter} (OAuth 1.0, key:${with_twitter_consumer_key} secret:${with_twitter_consumer_secret})
 	Yahoo provider:             ${enable_yahoo} (OAuth 1.0, key:${with_yahoo_consumer_key} secret:${with_yahoo_consumer_secret})
 	Facebook provider:          ${enable_facebook} (OAuth 2.0, id:${with_facebook_client_id} secret:${with_facebook_client_secret})
+	Messenger provider:         ${enable_messenger} (OAuth 2.0, id:${with_messenger_client_id})
 
         Maintainer mode:            ${USE_MAINTAINER_MODE}
         Building api docs:          ${enable_gtk_doc}
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 2ccc9d7..700f70b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,6 +4,7 @@
 src/daemon/goadaemon.c
 src/goabackend/goafacebookprovider.c
 src/goabackend/goagoogleprovider.c
+src/goabackend/goamessengerprovider.c
 src/goabackend/goaoauth2provider.c
 src/goabackend/goaoauthprovider.c
 src/goabackend/goaprovider.c
diff --git a/src/goabackend/Makefile.am b/src/goabackend/Makefile.am
index cad5dca..0aacafd 100644
--- a/src/goabackend/Makefile.am
+++ b/src/goabackend/Makefile.am
@@ -55,6 +55,7 @@ libgoa_backend_1_0_la_HEADERS =						\
 	goafacebookprovider.h						\
 	goayahooprovider.h						\
 	goatwitterprovider.h						\
+	goamessengerprovider.h						\
 	$(NULL)
 
 libgoa_backend_1_0_la_SOURCES =						\
@@ -71,6 +72,7 @@ libgoa_backend_1_0_la_SOURCES =						\
 	goafacebookprovider.h		goafacebookprovider.c		\
 	goayahooprovider.h		goayahooprovider.c		\
 	goatwitterprovider.h		goatwitterprovider.c		\
+	goamessengerprovider.h		goamessengerprovider.c		\
 	$(NULL)
 
 libgoa_backend_1_0_la_CPPFLAGS =				\
diff --git a/src/goabackend/goabackendtypes.h b/src/goabackend/goabackendtypes.h
index 9fda675..53e1171 100644
--- a/src/goabackend/goabackendtypes.h
+++ b/src/goabackend/goabackendtypes.h
@@ -57,6 +57,9 @@ typedef struct _GoaTwitterProvider GoaTwitterProvider;
 struct _GoaEditableLabel;
 typedef struct _GoaEditableLabel GoaEditableLabel;
 
+struct _GoaMessengerProvider;
+typedef struct _GoaMessengerProvider GoaMessengerProvider;
+
 G_END_DECLS
 
 #endif /* __GOA_BACKEND_TYPES_H__ */
diff --git a/src/goabackend/goamessengerprovider.c b/src/goabackend/goamessengerprovider.c
new file mode 100644
index 0000000..13d6996
--- /dev/null
+++ b/src/goabackend/goamessengerprovider.c
@@ -0,0 +1,327 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (C) 2011 Red Hat, Inc.
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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) any later version.
+ *
+ * This library 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 this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: David Zeuthen <davidz redhat com>
+ *          Xavier Claessens <xclaesse gmail com>
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+#include <rest/rest-proxy.h>
+#include <json-glib/json-glib.h>
+#include <libsoup/soup-gnome.h>
+#include <webkit/webkit.h>
+
+#include "goaprovider.h"
+#include "goaoauth2provider.h"
+#include "goamessengerprovider.h"
+
+/**
+ * GoaMessengerProvider:
+ *
+ * The #GoaMessengerProvider structure contains only private data and should
+ * only be accessed using the provided API.
+ */
+struct _GoaMessengerProvider
+{
+  /*< private >*/
+  GoaOAuth2Provider parent_instance;
+};
+
+typedef struct _GoaMessengerProviderClass GoaMessengerProviderClass;
+
+struct _GoaMessengerProviderClass
+{
+  GoaOAuth2ProviderClass parent_class;
+};
+
+/**
+ * SECTION:goamessengerprovider
+ * @title: GoaMessengerProvider
+ * @short_description: A provider for Messenger
+ *
+ * #GoaMessengerProvider is used for handling Messenger accounts.
+ */
+
+G_DEFINE_TYPE_WITH_CODE (GoaMessengerProvider, goa_messenger_provider, GOA_TYPE_OAUTH2_PROVIDER,
+                         g_io_extension_point_implement (GOA_PROVIDER_EXTENSION_POINT_NAME,
+							 g_define_type_id,
+							 "windows_live",
+							 0));
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static const gchar *
+get_provider_type (GoaProvider *_provider)
+{
+  return "windows_live";
+}
+
+static gchar *
+get_provider_name (GoaProvider *_provider,
+                   GoaObject   *object)
+{
+  return g_strdup (_("Windows Live"));
+}
+
+static const gchar *
+get_authorization_uri (GoaOAuth2Provider *provider)
+{
+  return "https://oauth.live.com/authorize";;
+}
+
+
+static const gchar *
+get_token_uri (GoaOAuth2Provider *provider)
+{
+  return "https://oauth.live.com/token";;
+}
+
+
+static const gchar *
+get_redirect_uri (GoaOAuth2Provider *provider)
+{
+  return "https://oauth.live.com/desktop";;
+}
+
+static const gchar *
+get_scope (GoaOAuth2Provider *provider)
+{
+  return "wl.messenger,"
+         "wl.offline_access,"
+         "wl.emails";
+}
+
+static const gchar *
+get_client_id (GoaOAuth2Provider *provider)
+{
+  return GOA_MESSENGER_CLIENT_ID;
+}
+
+static const gchar *
+get_client_secret (GoaOAuth2Provider *provider)
+{
+  return NULL;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gchar *
+get_identity_sync (GoaOAuth2Provider  *provider,
+                   const gchar        *access_token,
+                   gchar             **out_presentation_identity,
+                   GCancellable       *cancellable,
+                   GError            **error)
+{
+  RestProxy *proxy;
+  RestProxyCall *call;
+  JsonParser *parser;
+  JsonObject *json_object;
+  gchar *ret;
+  gchar *id;
+  gchar *presentation_identity;
+
+  ret = NULL;
+  proxy = NULL;
+  call = NULL;
+  parser = NULL;
+  id = NULL;
+  presentation_identity = NULL;
+
+  /* TODO: cancellable */
+
+  proxy = rest_proxy_new ("https://apis.live.net/v5.0/me";, FALSE);
+  call = rest_proxy_new_call (proxy);
+  rest_proxy_call_set_method (call, "GET");
+  rest_proxy_call_add_param (call, "access_token", access_token);
+
+  if (!rest_proxy_call_sync (call, error))
+    goto out;
+  if (rest_proxy_call_get_status_code (call) != 200)
+    {
+      g_set_error (error,
+                   GOA_ERROR,
+                   GOA_ERROR_FAILED,
+                   _("Expected status 200 when requesting guid, instead got status %d (%s)"),
+                   rest_proxy_call_get_status_code (call),
+                   rest_proxy_call_get_status_message (call));
+      goto out;
+    }
+
+  parser = json_parser_new ();
+  if (!json_parser_load_from_data (parser,
+                                   rest_proxy_call_get_payload (call),
+                                   rest_proxy_call_get_payload_length (call),
+                                   error))
+    {
+      g_prefix_error (error, _("Error parsing response as JSON: "));
+      goto out;
+    }
+
+  json_object = json_node_get_object (json_parser_get_root (parser));
+  id = g_strdup (json_object_get_string_member (json_object, "id"));
+  if (id == NULL)
+    {
+      g_set_error (error,
+                   GOA_ERROR,
+                   GOA_ERROR_FAILED,
+                   _("Didn't find id member in JSON data"));
+      goto out;
+    }
+
+  json_object = json_object_get_object_member (json_object, "emails");
+  presentation_identity = g_strdup (json_object_get_string_member (json_object, "account"));
+  if (presentation_identity == NULL)
+    {
+      g_set_error (error,
+                   GOA_ERROR,
+                   GOA_ERROR_FAILED,
+                   _("Didn't find account email member in JSON data"));
+      goto out;
+    }
+
+  ret = id;
+  id = NULL;
+  if (out_presentation_identity != NULL)
+    {
+      *out_presentation_identity = presentation_identity;
+      presentation_identity = NULL;
+    }
+
+ out:
+  g_free (id);
+  g_free (presentation_identity);
+  if (call != NULL)
+    g_object_unref (call);
+  if (proxy != NULL)
+    g_object_unref (proxy);
+  return ret;
+}
+
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+build_object (GoaProvider         *provider,
+              GoaObjectSkeleton   *object,
+              GKeyFile            *key_file,
+              const gchar         *group,
+              GError             **error)
+{
+  GoaChat *chat = NULL;
+  gboolean chat_enabled;
+  gboolean ret = FALSE;
+
+  /* Chain up */
+  if (!GOA_PROVIDER_CLASS (goa_messenger_provider_parent_class)->build_object (provider,
+                                                                              object,
+                                                                              key_file,
+                                                                              group,
+                                                                              error))
+    goto out;
+
+  /* Chat */
+  chat = goa_object_get_chat (GOA_OBJECT (object));
+  chat_enabled = g_key_file_get_boolean (key_file, group, "ChatEnabled", NULL);
+  if (chat_enabled)
+    {
+      if (chat == NULL)
+        {
+          chat = goa_chat_skeleton_new ();
+          goa_object_skeleton_set_chat (object, chat);
+        }
+    }
+  else
+    {
+      if (chat != NULL)
+        goa_object_skeleton_set_chat (object, NULL);
+    }
+
+  ret = TRUE;
+
+ out:
+  if (chat != NULL)
+    g_object_unref (chat);
+
+  return ret;
+}
+
+static gboolean
+get_use_external_browser (GoaOAuth2Provider *provider)
+{
+  return FALSE;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+show_account (GoaProvider         *provider,
+              GoaClient           *client,
+              GoaObject           *object,
+              GtkBox              *vbox,
+              GtkTable            *table)
+{
+  /* Chain up */
+  GOA_PROVIDER_CLASS (goa_messenger_provider_parent_class)->show_account (provider, client, object, vbox, table);
+
+  goa_util_add_row_editable_label_from_keyfile (table, object, _("User Name"), "PresentationIdentity", FALSE);
+  goa_util_add_row_switch_from_keyfile (table, object, _("Chat"), "ChatEnabled");
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+add_account_key_values (GoaOAuth2Provider *provider,
+                        GVariantBuilder   *builder)
+{
+  g_variant_builder_add (builder, "{ss}", "ChatEnabled", "true");
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+goa_messenger_provider_init (GoaMessengerProvider *client)
+{
+}
+
+static void
+goa_messenger_provider_class_init (GoaMessengerProviderClass *klass)
+{
+  GoaProviderClass *provider_class;
+  GoaOAuth2ProviderClass *oauth2_class;
+
+  provider_class = GOA_PROVIDER_CLASS (klass);
+  provider_class->get_provider_type          = get_provider_type;
+  provider_class->get_provider_name          = get_provider_name;
+  provider_class->build_object               = build_object;
+  provider_class->show_account               = show_account;
+
+  oauth2_class = GOA_OAUTH2_PROVIDER_CLASS (klass);
+  oauth2_class->get_authorization_uri    = get_authorization_uri;
+  oauth2_class->get_token_uri            = get_token_uri;
+  oauth2_class->get_redirect_uri         = get_redirect_uri;
+  oauth2_class->get_scope                = get_scope;
+  oauth2_class->get_client_id            = get_client_id;
+  oauth2_class->get_client_secret        = get_client_secret;
+  oauth2_class->get_identity_sync        = get_identity_sync;
+  oauth2_class->get_use_external_browser = get_use_external_browser;
+  oauth2_class->add_account_key_values   = add_account_key_values;
+}
diff --git a/src/goabackend/goamessengerprovider.h b/src/goabackend/goamessengerprovider.h
new file mode 100644
index 0000000..4aa1503
--- /dev/null
+++ b/src/goabackend/goamessengerprovider.h
@@ -0,0 +1,44 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (C) 2011 Red Hat, Inc.
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library 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) any later version.
+ *
+ * This library 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 this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: David Zeuthen <davidz redhat com>
+ *          Xavier Claessens <xclaesse gmail com>
+ */
+
+#if !defined (__GOA_BACKEND_INSIDE_GOA_BACKEND_H__) && !defined (GOA_BACKEND_COMPILATION)
+#error "Only <goabackend/goabackend.h> can be included directly."
+#endif
+
+#ifndef __GOA_MESSENGER_PROVIDER_H__
+#define __GOA_MESSENGER_PROVIDER_H__
+
+#include <goabackend/goabackendtypes.h>
+
+G_BEGIN_DECLS
+
+#define GOA_TYPE_MESSENGER_PROVIDER   (goa_messenger_provider_get_type ())
+#define GOA_MESSENGER_PROVIDER(o)     (G_TYPE_CHECK_INSTANCE_CAST ((o), GOA_TYPE_MESSENGER_PROVIDER, GoaFacebookProvider))
+#define GOA_IS_MESSENGER_PROVIDER(o)  (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOA_TYPE_MESSENGER_PROVIDER))
+
+GType goa_messenger_provider_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GOA_MESSENGER_PROVIDER_H__ */
diff --git a/src/goabackend/goaoauth2provider.c b/src/goabackend/goaoauth2provider.c
index 3af0a4b..62ab2dd 100644
--- a/src/goabackend/goaoauth2provider.c
+++ b/src/goabackend/goaoauth2provider.c
@@ -391,6 +391,7 @@ get_tokens_sync (GoaOAuth2Provider  *provider,
   gchar *ret_refresh_token;
   const gchar *payload;
   gsize payload_length;
+  const gchar *client_secret;
 
   ret = NULL;
   ret_access_token = NULL;
@@ -399,24 +400,26 @@ get_tokens_sync (GoaOAuth2Provider  *provider,
 
   proxy = rest_proxy_new (goa_oauth2_provider_get_token_uri (provider), FALSE);
   call = rest_proxy_new_call (proxy);
-  rest_proxy_call_set_method (call, "POST");
-  rest_proxy_call_add_header (call, "Content-Type", "application/x-www-form-urlencoded");
+
+  rest_proxy_call_set_method (call, "GET");
+  rest_proxy_call_add_param (call, "client_id", goa_oauth2_provider_get_client_id (provider));
+  rest_proxy_call_add_param (call, "redirect_uri", goa_oauth2_provider_get_redirect_uri (provider));
+
+  client_secret = goa_oauth2_provider_get_client_secret (provider);
+  if (client_secret != NULL)
+    rest_proxy_call_add_param (call, "client_secret", client_secret);
+
   if (refresh_token != NULL)
     {
       /* Swell, we have a refresh code - just use that */
-      rest_proxy_call_add_param (call, "client_id", goa_oauth2_provider_get_client_id (provider));
-      rest_proxy_call_add_param (call, "client_secret", goa_oauth2_provider_get_client_secret (provider));
       rest_proxy_call_add_param (call, "grant_type", "refresh_token");
       rest_proxy_call_add_param (call, "refresh_token", refresh_token);
     }
   else
     {
       /* No refresh code.. request an access token using the authorization code instead */
-      rest_proxy_call_add_param (call, "client_id", goa_oauth2_provider_get_client_id (provider));
-      rest_proxy_call_add_param (call, "client_secret", goa_oauth2_provider_get_client_secret (provider));
       rest_proxy_call_add_param (call, "grant_type", "authorization_code");
       rest_proxy_call_add_param (call, "code", authorization_code);
-      rest_proxy_call_add_param (call, "redirect_uri", goa_oauth2_provider_get_redirect_uri (provider));
     }
 
   /* TODO: cancellable support? */
diff --git a/src/goabackend/goaprovider.c b/src/goabackend/goaprovider.c
index 678d6b5..468984d 100644
--- a/src/goabackend/goaprovider.c
+++ b/src/goabackend/goaprovider.c
@@ -30,6 +30,7 @@
 #include "goafacebookprovider.h"
 #include "goayahooprovider.h"
 #include "goatwitterprovider.h"
+#include "goamessengerprovider.h"
 
 #include "goaeditablelabel.h"
 
@@ -597,6 +598,10 @@ ensure_ep_and_builtins (void)
       type = GOA_TYPE_FACEBOOK_PROVIDER;
 #endif
 
+#ifdef GOA_MESSENGER_ENABLED
+      type = GOA_TYPE_MESSENGER_PROVIDER;
+#endif
+
       type = type; /* silence -Wunused-but-set-variable */
 
       g_once_init_leave (&once_init_value, 1);



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