[libsocialweb: 1/3] vimeo: Migrated OAuth for future upload functionaility.



commit 1b1601e259829ee6959ddc026acb5082b5c940ce
Author: Eitan Isaacson <eitan isaacson collabora co uk>
Date:   Mon Mar 14 12:45:51 2011 -0400

    vimeo: Migrated OAuth for future upload functionaility.

 services/vimeo/Makefile.am   |    2 +
 services/vimeo/vimeo.c       |  205 ++++++++++++++++++++++++++++++++++++------
 services/vimeo/vimeo.keys.in |   10 ++-
 3 files changed, 188 insertions(+), 29 deletions(-)
---
diff --git a/services/vimeo/Makefile.am b/services/vimeo/Makefile.am
index 37b9648..3a07b61 100644
--- a/services/vimeo/Makefile.am
+++ b/services/vimeo/Makefile.am
@@ -7,6 +7,8 @@ libvimeo_la_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/interfaces $(REST_CFLAGS) $
 		     $(DBUS_GLIB_CFLAGS) -DG_LOG_DOMAIN=\"Vimeo\" \
 		     $(GCOV_CFLAGS)
 libvimeo_la_LIBADD = $(top_builddir)/libsocialweb/libsocialweb.la $(top_builddir)/interfaces/libsocialweb-ginterfaces.la \
+		     $(top_builddir)/libsocialweb-keystore/libsocialweb-keystore.la \
+		     $(top_builddir)/libsocialweb-keyfob/libsocialweb-keyfob.la \
 		     $(REST_LIBS) $(KEYRING_LIBS) $(DBUS_GLIB_LIBS) \
 		     $(GCOV_LDFLAGS)
 libvimeo_la_LDFLAGS = -module -avoid-version
diff --git a/services/vimeo/vimeo.c b/services/vimeo/vimeo.c
index 635a121..5de1ae1 100644
--- a/services/vimeo/vimeo.c
+++ b/services/vimeo/vimeo.c
@@ -31,8 +31,10 @@
 #include <libsocialweb/sw-call-list.h>
 #include <libsocialweb/sw-debug.h>
 #include <libsocialweb/sw-client-monitor.h>
+#include <libsocialweb-keyfob/sw-keyfob.h>
+#include <libsocialweb-keystore/sw-keystore.h>
 
-#include <rest/rest-proxy.h>
+#include <rest/oauth-proxy.h>
 #include <rest/rest-xml-parser.h>
 
 #include <interfaces/sw-query-ginterface.h>
@@ -49,6 +51,12 @@ G_DEFINE_TYPE_WITH_CODE (SwServiceVimeo, sw_service_vimeo, SW_TYPE_SERVICE,
 
 struct _SwServiceVimeoPrivate {
   RestProxy *proxy;
+  RestProxy *simple_proxy;
+
+  gboolean configured;
+  gboolean inited;
+
+  gchar *username;
 };
 
 static const char *
@@ -70,31 +78,153 @@ get_static_caps (SwService *service)
   return caps;
 }
 
-/*
- * Callback from the keyring lookup in refresh_credentials.
- */
-static void
-found_password_cb (GnomeKeyringResult  result,
-                   GList              *list,
-                   gpointer            user_data)
+static const char **
+get_dynamic_caps (SwService *service)
+{
+  SwServiceVimeoPrivate *priv = SW_SERVICE_VIMEO (service)->priv;
+
+  static const char *configured_caps[] = {
+    IS_CONFIGURED,
+    NULL
+  };
+
+  static const char *authorized_caps[] = {
+    IS_CONFIGURED,
+    CREDENTIALS_VALID,
+    NULL
+  };
+
+  static const char *no_caps[] = { NULL };
+
+  if (priv->username != NULL)
+    return authorized_caps;
+  else if (priv->configured)
+    return configured_caps;
+  else
+    return no_caps;
+}
+
+static RestXmlNode *
+node_from_call (RestProxyCall *call, GError **error)
 {
-  SwService *service = SW_SERVICE (user_data);
-  SwServiceVimeo *vimeo = SW_SERVICE_VIMEO (service);
-  SwServiceVimeoPrivate *priv = vimeo->priv;
+  static RestXmlParser *parser = NULL;
+  RestXmlNode *node;
+
+  if (call == NULL)
+    return NULL;
+
+  if (parser == NULL)
+    parser = rest_xml_parser_new ();
+
+  if (!SOUP_STATUS_IS_SUCCESSFUL (rest_proxy_call_get_status_code (call))) {
+    g_set_error (error, SW_SERVICE_ERROR, SW_SERVICE_ERROR_REMOTE_ERROR,
+                 "HTTP error: %s (%d)",
+                 rest_proxy_call_get_status_message (call),
+                 rest_proxy_call_get_status_code (call));
+    return NULL;
+  }
+
+  node = rest_xml_parser_parse_from_data (parser,
+                                          rest_proxy_call_get_payload (call),
+                                          rest_proxy_call_get_payload_length (call));
+
+  /* Invalid XML, or incorrect root */
+  if (node == NULL || !g_str_equal (node->name, "rsp")) {
+    g_set_error (error, SW_SERVICE_ERROR, SW_SERVICE_ERROR_REMOTE_ERROR,
+                 "malformed remote response: %s",
+                 rest_proxy_call_get_payload (call));
+    if (node)
+      rest_xml_node_unref (node);
+    return NULL;
+  }
 
-  if (result == GNOME_KEYRING_RESULT_OK && list != NULL) {
-    GnomeKeyringNetworkPasswordData *data = list->data;
-    rest_proxy_bind (priv->proxy, data->user);
+  if (g_strcmp0 (rest_xml_node_get_attr (node, "stat"), "ok") != 0) {
+    RestXmlNode *err;
+    err = rest_xml_node_find (node, "err");
+    g_set_error (error, SW_SERVICE_ERROR, SW_SERVICE_ERROR_REMOTE_ERROR,
+                 "remote Vimeo error: %s", err ?
+                 rest_xml_node_get_attr (err, "msg") : "unknown");
+    rest_xml_node_unref (node);
+    return NULL;
+  }
+
+  return node;
+}
+
+static void
+_check_access_token_cb (RestProxyCall *call,
+                        const GError  *error,
+                        GObject       *weak_object,
+                        gpointer       user_data)
+{
+  RestXmlNode *root;
+  GError *err = NULL;
+  SwServiceVimeo *self = SW_SERVICE_VIMEO (weak_object);
+  SwService *service = SW_SERVICE (self);
+  SwServiceVimeoPrivate *priv = self->priv;
+
+  root = node_from_call (call, &err);
+
+  if (root == NULL) {
+    g_assert (err != NULL);
+    SW_DEBUG (VIMEO, "Invalid access token: %s", err->message);
+    g_error_free (err);
   } else {
-    rest_proxy_bind (priv->proxy, "");
+    RestXmlNode *username = rest_xml_node_find (root, "username");
+    priv->username = g_strdup (username->content);
+    rest_proxy_bind (priv->simple_proxy, priv->username);
 
-    if (result != GNOME_KEYRING_RESULT_NO_MATCH) {
-      g_warning (G_STRLOC ": Error getting password: %s", gnome_keyring_result_to_message (result));
-    }
+    rest_xml_node_unref (root);
   }
 
-  sw_service_emit_user_changed (service);
-  /* TODO: dynamic caps */
+  sw_service_emit_capabilities_changed (service, get_dynamic_caps (service));
+}
+
+static void
+got_tokens_cb (RestProxy *proxy, gboolean got_tokens, gpointer user_data)
+{
+  SwServiceVimeo *self = (SwServiceVimeo *) user_data;
+  SwService *service = SW_SERVICE (self);
+  SwServiceVimeoPrivate *priv = self->priv;
+
+  priv->configured = got_tokens;
+
+  SW_DEBUG (VIMEO, "Got tokens: %s", got_tokens ? "yes" : "no");
+
+  if (got_tokens) {
+    RestProxyCall *call;
+
+    call = rest_proxy_new_call (priv->proxy);
+    rest_proxy_call_set_function(call, "api/rest/v2");
+
+    rest_proxy_call_add_param (call, "method", "vimeo.test.login");
+
+    rest_proxy_call_async (call,
+                           _check_access_token_cb,
+                           G_OBJECT (self),
+                           NULL,
+                           NULL);
+
+    g_object_unref (call);
+  }
+
+  sw_service_emit_capabilities_changed (service, get_dynamic_caps (service));
+}
+
+static void
+online_notify (gboolean online, gpointer user_data)
+{
+  SwServiceVimeo *self = (SwServiceVimeo *) user_data;
+  SwService *service = SW_SERVICE (self);
+  SwServiceVimeoPrivate *priv = self->priv;
+
+  if (online) {
+    sw_keyfob_oauth ((OAuthProxy *) priv->proxy, got_tokens_cb, self);
+  } else {
+    g_free (priv->username);
+    priv->username = NULL;
+    sw_service_emit_capabilities_changed (service, get_dynamic_caps (service));
+  }
 }
 
 /*
@@ -102,14 +232,19 @@ found_password_cb (GnomeKeyringResult  result,
  * the keyring.
  */
 static void
-refresh_credentials (SwServiceVimeo *vimeo)
+refresh_credentials (SwServiceVimeo *self)
 {
+  SwService *service = SW_SERVICE (self);
+  SwServiceVimeoPrivate *priv = self->priv;
+
   SW_DEBUG (VIMEO, "Credentials updated");
 
-  gnome_keyring_find_network_password (NULL, NULL,
-                                       "vimeo.com",
-                                       NULL, NULL, NULL, 0,
-                                       found_password_cb, vimeo, NULL);
+  priv->configured = FALSE;
+
+  sw_service_emit_user_changed (service);
+
+  online_notify (FALSE, service);
+  online_notify (TRUE, service);
 }
 
 /*
@@ -131,6 +266,13 @@ sw_service_vimeo_dispose (GObject *object)
     priv->proxy = NULL;
   }
 
+  if (priv->simple_proxy) {
+    g_object_unref (priv->simple_proxy);
+    priv->simple_proxy = NULL;
+  }
+
+  g_free (priv->username);
+
   G_OBJECT_CLASS (sw_service_vimeo_parent_class)->dispose (object);
 }
 
@@ -173,7 +315,7 @@ _vimeo_query_open_view (SwQueryIface          *self,
   }
 
   item_view = g_object_new (SW_TYPE_VIMEO_ITEM_VIEW,
-                            "proxy", priv->proxy,
+                            "proxy", priv->simple_proxy,
                             "service", self,
                             "query", query,
                             "params", params,
@@ -210,6 +352,7 @@ sw_service_vimeo_class_init (SwServiceVimeoClass *klass)
 
   service_class->get_name = get_name;
   service_class->get_static_caps = get_static_caps;
+  service_class->get_dynamic_caps = get_dynamic_caps;
   service_class->credentials_updated = credentials_updated;
 }
 
@@ -217,10 +360,18 @@ static void
 sw_service_vimeo_init (SwServiceVimeo *self)
 {
   SwServiceVimeoPrivate *priv;
+  const gchar *api_key;
+  const gchar *api_secret;
 
   priv = self->priv = GET_PRIVATE (self);
 
-  priv->proxy = rest_proxy_new ("http://vimeo.com/api/v2/%s/";, TRUE);
+  sw_keystore_get_key_secret ("vimeo", &api_key, &api_secret);
+  if (api_key == NULL || api_secret == NULL) {
+    g_warning ("Could not get API key or secret");
+  }
+
+  priv->proxy = oauth_proxy_new (api_key, api_secret, "http://vimeo.com/";, FALSE);
+  priv->simple_proxy = rest_proxy_new ("http://vimeo.com/api/v2/%s/";, TRUE);
 
   refresh_credentials (self);
 }
diff --git a/services/vimeo/vimeo.keys.in b/services/vimeo/vimeo.keys.in
index 2e81632..2c1e4ca 100644
--- a/services/vimeo/vimeo.keys.in
+++ b/services/vimeo/vimeo.keys.in
@@ -2,5 +2,11 @@
 _Name=Vimeo
 _Description=From the beginning, Vimeo was created by filmmakers and video creators who wanted to share their creative work, along with intimate personal moments of their everyday life. As time went on, like-minded people came to the site and built a community of positive, encouraging individuals with a wide range of video interests. We hope that you feel inspired to show us both your creative side as well as your friendly side.
 Link=http://www.vimeo.com/
-AuthType=username
-AuthPasswordServer=vimeo.com
+AuthType=oauth
+
+[OAuth]
+BaseURL=http://vimeo.com/
+RequestTokenFunction=oauth/request_token
+AuthoriseFunction=oauth/authorize
+AccessTokenFunction=oauth/access_token
+Callback=oob



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