[evolution-data-server] Add ESoupAuthBearer.



commit fa0d18fcf2d8084d2a41f24f50f689eed8e3e241
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Jul 9 14:23:04 2013 -0400

    Add ESoupAuthBearer.
    
    SoupAuth subclass for use with OAuth 2.0 HTTP authentication.
    
    See http://tools.ietf.org/html/rfc6750
    
    EBackends should use e_source_get_oauth2_access_token() to obtain
    the access token and token expiry for an ESource, then pass them to
    e_soup_auth_bearer_set_access_token().

 docs/reference/libebackend/libebackend-docs.xml    |    1 +
 .../reference/libebackend/libebackend-sections.txt |   18 ++
 docs/reference/libebackend/libebackend.types       |    1 +
 libebackend/Makefile.am                            |    4 +
 libebackend/e-soup-auth-bearer.c                   |  196 ++++++++++++++++++++
 libebackend/e-soup-auth-bearer.h                   |   79 ++++++++
 libebackend/libebackend.h                          |    1 +
 7 files changed, 300 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/libebackend/libebackend-docs.xml b/docs/reference/libebackend/libebackend-docs.xml
index fa9ab92..f54d3d6 100644
--- a/docs/reference/libebackend/libebackend-docs.xml
+++ b/docs/reference/libebackend/libebackend-docs.xml
@@ -34,6 +34,7 @@
     <title>Miscellaneous Utilities</title>
     <xi:include href="xml/e-file-cache.xml"/>
     <xi:include href="xml/e-db3-utils.xml"/>
+    <xi:include href="xml/e-soup-auth-bearer.xml"/>
     <xi:include href="xml/e-sqlite3-vfs.xml"/>
     <xi:include href="xml/e-user-prompter.xml"/>
     <xi:include href="xml/e-user-prompter-server.xml"/>
diff --git a/docs/reference/libebackend/libebackend-sections.txt 
b/docs/reference/libebackend/libebackend-sections.txt
index 6c604bf..189f002 100644
--- a/docs/reference/libebackend/libebackend-sections.txt
+++ b/docs/reference/libebackend/libebackend-sections.txt
@@ -397,6 +397,24 @@ EServerSideSourcePrivate
 </SECTION>
 
 <SECTION>
+<FILE>e-soup-auth-bearer</FILE>
+<TITLE>ESoupAuthBearer</TITLE>
+ESoupAuthBearer
+e_soup_auth_bearer_set_access_token
+<SUBSECTION Standard>
+E_SOUP_AUTH_BEARER
+E_IS_SOUP_AUTH_BEARER
+E_TYPE_SOUP_AUTH_BEARER
+E_SOUP_AUTH_BEARER_CLASS
+E_IS_SOUP_AUTH_BEARER_CLASS
+E_SOUP_AUTH_BEARER_GET_CLASS
+ESoupAuthBearerClass
+e_soup_auth_bearer_get_type
+<SUBSECTION Private>
+ESoupAuthBearerPrivate
+</SECTION>
+
+<SECTION>
 <FILE>e-source-registry-server</FILE>
 <TITLE>ESourceRegistryServer</TITLE>
 E_SOURCE_REGISTRY_SERVER_OBJECT_PATH
diff --git a/docs/reference/libebackend/libebackend.types b/docs/reference/libebackend/libebackend.types
index aeb38dc..1d7fe96 100644
--- a/docs/reference/libebackend/libebackend.types
+++ b/docs/reference/libebackend/libebackend.types
@@ -15,6 +15,7 @@ e_module_get_type
 e_oauth2_support_get_type
 e_offline_listener_get_type
 e_server_side_source_get_type
+e_soup_auth_bearer_get_type
 e_source_registry_server_get_type
 e_user_prompter_get_type
 e_user_prompter_server_get_type
diff --git a/libebackend/Makefile.am b/libebackend/Makefile.am
index c77b470..783732e 100644
--- a/libebackend/Makefile.am
+++ b/libebackend/Makefile.am
@@ -35,6 +35,7 @@ libebackend_1_2_la_CPPFLAGS = \
        $(E_BACKEND_CFLAGS)                                     \
        $(GCR_BASE_CFLAGS)                                      \
        $(GIO_UNIX_CFLAGS)                                      \
+       $(SOUP_CFLAGS)                                          \
        $(CODE_COVERAGE_CFLAGS)                                 \
        $(NULL)
 
@@ -56,6 +57,7 @@ libebackend_1_2_la_SOURCES =          \
        e-db3-utils.c                   \
        e-module.c                      \
        e-server-side-source.c          \
+       e-soup-auth-bearer.c            \
        e-source-registry-server.c      \
        e-sqlite3-vfs.c                 \
        e-user-prompter.c               \
@@ -71,6 +73,7 @@ libebackend_1_2_la_LIBADD =                           \
        $(SQLITE3_LIBS)                                 \
        $(GCR_BASE_LIBS)                                \
        $(GIO_UNIX_LIBS)                                \
+       $(SOUP_LIBS)                                    \
        $(DB_LIBS)
 
 libebackend_1_2_la_LDFLAGS = \
@@ -100,6 +103,7 @@ libebackendinclude_HEADERS =                \
        e-dbhash.h                      \
        e-module.h                      \
        e-server-side-source.h          \
+       e-soup-auth-bearer.h            \
        e-source-registry-server.h      \
        e-sqlite3-vfs.h                 \
        e-user-prompter.h               \
diff --git a/libebackend/e-soup-auth-bearer.c b/libebackend/e-soup-auth-bearer.c
new file mode 100644
index 0000000..1d5f804
--- /dev/null
+++ b/libebackend/e-soup-auth-bearer.c
@@ -0,0 +1,196 @@
+/*
+ * e-soup-auth-bearer.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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * SECTION: e-soup-auth-bearer
+ * @include: libebackend/libebackend.h
+ * @short_description: OAuth 2.0 support for libsoup
+ *
+ * #ESoupAuthBearer adds libsoup support for the use of bearer tokens in
+ * HTTP requests to access OAuth 2.0 protected resources, as defined in
+ * <ulink url="http://tools.ietf.org/html/rfc6750";>RFC 6750</ulink>.
+ *
+ * An #EBackend should integrate #ESoupAuthBearer first by adding it as a
+ * feature to a #SoupSession's #SoupAuthManager, then from a #SoupSession
+ * #SoupSession::authenticate handler call e_source_get_oauth2_access_token()
+ * and pass the results to e_soup_auth_bearer_set_access_token().
+ **/
+
+#include "e-soup-auth-bearer.h"
+
+#include <time.h>
+
+#define E_SOUP_AUTH_BEARER_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE \
+       ((obj), E_TYPE_SOUP_AUTH_BEARER, ESoupAuthBearerPrivate))
+
+#define AUTH_STRENGTH 1
+
+#define EXPIRY_INVALID ((time_t) -1)
+
+struct _ESoupAuthBearerPrivate {
+       gchar *access_token;
+       time_t expiry;
+};
+
+G_DEFINE_TYPE (
+       ESoupAuthBearer,
+       e_soup_auth_bearer,
+       SOUP_TYPE_AUTH)
+
+static gboolean
+e_soup_auth_bearer_is_expired (ESoupAuthBearer *bearer)
+{
+       gboolean expired = FALSE;
+
+       if (bearer->priv->expiry != EXPIRY_INVALID)
+               expired = (bearer->priv->expiry < time (NULL));
+
+       return expired;
+}
+
+static void
+e_soup_auth_bearer_finalize (GObject *object)
+{
+       ESoupAuthBearerPrivate *priv;
+
+       priv = E_SOUP_AUTH_BEARER_GET_PRIVATE (object);
+
+       g_free (priv->access_token);
+
+       /* Chain up to parent's finalize() method. */
+       G_OBJECT_CLASS (e_soup_auth_bearer_parent_class)->finalize (object);
+}
+
+static gboolean
+e_soup_auth_bearer_update (SoupAuth *auth,
+                           SoupMessage *message,
+                           GHashTable *auth_header)
+{
+       /* XXX Not sure what to do here.  Discard the access token? */
+
+       return TRUE;
+}
+
+static GSList *
+e_soup_auth_bearer_get_protection_space (SoupAuth *auth,
+                                         SoupURI *source_uri)
+{
+       /* XXX Not sure what to do here.  Need to return something. */
+
+       return g_slist_prepend (NULL, g_strdup (""));
+}
+
+static gboolean
+e_soup_auth_bearer_is_authenticated (SoupAuth *auth)
+{
+       ESoupAuthBearer *bearer;
+       gboolean authenticated = FALSE;
+
+       bearer = E_SOUP_AUTH_BEARER (auth);
+
+       if (!e_soup_auth_bearer_is_expired (bearer))
+               authenticated = (bearer->priv->access_token != NULL);
+
+       return authenticated;
+}
+
+static gchar *
+e_soup_auth_bearer_get_authorization (SoupAuth *auth,
+                                      SoupMessage *message)
+{
+       ESoupAuthBearer *bearer;
+
+       bearer = E_SOUP_AUTH_BEARER (auth);
+
+       return g_strdup_printf ("Bearer %s", bearer->priv->access_token);
+}
+
+static void
+e_soup_auth_bearer_class_init (ESoupAuthBearerClass *class)
+{
+       GObjectClass *object_class;
+       SoupAuthClass *auth_class;
+
+       g_type_class_add_private (class, sizeof (ESoupAuthBearerPrivate));
+
+       /* Keep the "e" prefix on private methods
+        * so we don't step on libsoup's namespace. */
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->finalize = e_soup_auth_bearer_finalize;
+
+       auth_class = SOUP_AUTH_CLASS (class);
+       auth_class->scheme_name = "Bearer";
+       auth_class->strength = AUTH_STRENGTH;
+       auth_class->update = e_soup_auth_bearer_update;
+       auth_class->get_protection_space = e_soup_auth_bearer_get_protection_space;
+       auth_class->is_authenticated = e_soup_auth_bearer_is_authenticated;
+       auth_class->get_authorization = e_soup_auth_bearer_get_authorization;
+}
+
+static void
+e_soup_auth_bearer_init (ESoupAuthBearer *bearer)
+{
+       bearer->priv = E_SOUP_AUTH_BEARER_GET_PRIVATE (bearer);
+       bearer->priv->expiry = EXPIRY_INVALID;
+}
+
+/**
+ * e_soup_auth_bearer_set_access_token:
+ * @bearer: an #ESoupAuthBearer
+ * @access_token: an OAuth 2.0 access token
+ * @expires_in_seconds: expiry for @access_token, or 0 if unknown
+ *
+ * This function is analogous to soup_auth_authenticate() for "Basic" HTTP
+ * authentication, except it takes an OAuth 2.0 access token instead of a
+ * username and password.
+ *
+ * If @expires_in_seconds is greater than zero, soup_auth_is_authenticated()
+ * will return %FALSE after the given number of seconds have elapsed.
+ *
+ * Since: 3.10
+ **/
+void
+e_soup_auth_bearer_set_access_token (ESoupAuthBearer *bearer,
+                                     const gchar *access_token,
+                                     gint expires_in_seconds)
+{
+       gboolean was_authenticated;
+       gboolean now_authenticated;
+
+       g_return_if_fail (E_IS_SOUP_AUTH_BEARER (bearer));
+
+       was_authenticated = soup_auth_is_authenticated (SOUP_AUTH (bearer));
+
+       g_free (bearer->priv->access_token);
+       bearer->priv->access_token = g_strdup (access_token);
+
+       if (expires_in_seconds > 0)
+               bearer->priv->expiry = time (NULL) + expires_in_seconds;
+       else
+               bearer->priv->expiry = EXPIRY_INVALID;
+
+       now_authenticated = soup_auth_is_authenticated (SOUP_AUTH (bearer));
+
+       if (was_authenticated != now_authenticated)
+               g_object_notify (
+                       G_OBJECT (bearer),
+                       SOUP_AUTH_IS_AUTHENTICATED);
+}
+
diff --git a/libebackend/e-soup-auth-bearer.h b/libebackend/e-soup-auth-bearer.h
new file mode 100644
index 0000000..83746a4
--- /dev/null
+++ b/libebackend/e-soup-auth-bearer.h
@@ -0,0 +1,79 @@
+/*
+ * e-soup-auth-bearer.h
+ *
+ * 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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#if !defined (__LIBEBACKEND_H_INSIDE__) && !defined (LIBEBACKEND_COMPILATION)
+#error "Only <libebackend/libebackend.h> should be included directly."
+#endif
+
+#ifndef E_SOUP_AUTH_BEARER_H
+#define E_SOUP_AUTH_BEARER_H
+
+#include <libsoup/soup.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SOUP_AUTH_BEARER \
+       (e_soup_auth_bearer_get_type ())
+#define E_SOUP_AUTH_BEARER(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), E_TYPE_SOUP_AUTH_BEARER, ESoupAuthBearer))
+#define E_SOUP_AUTH_BEARER_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), E_TYPE_SOUP_AUTH_BEARER, ESoupAuthBearerClass))
+#define E_IS_SOUP_AUTH_BEARER(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), E_TYPE_SOUP_AUTH_BEARER))
+#define E_IS_SOUP_AUTH_BEARER_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), E_TYPE_SOUP_AUTH_BEARER))
+#define E_SOUP_AUTH_BEARER_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), E_TYPE_SOUP_AUTH_BEARER, ESoupAuthBearerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ESoupAuthBearer ESoupAuthBearer;
+typedef struct _ESoupAuthBearerClass ESoupAuthBearerClass;
+typedef struct _ESoupAuthBearerPrivate ESoupAuthBearerPrivate;
+
+/**
+ * ESoupAuthBearer:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ *
+ * Since: 3.10
+ **/
+struct _ESoupAuthBearer {
+       SoupAuth parent;
+       ESoupAuthBearerPrivate *priv;
+};
+
+struct _ESoupAuthBearerClass {
+       SoupAuthClass parent_class;
+};
+
+GType          e_soup_auth_bearer_get_type     (void) G_GNUC_CONST;
+void           e_soup_auth_bearer_set_access_token
+                                               (ESoupAuthBearer *bearer,
+                                                const gchar *access_token,
+                                                gint expires_in_seconds);
+
+G_END_DECLS
+
+#endif /* E_SOUP_AUTH_BEARER_H */
+
diff --git a/libebackend/libebackend.h b/libebackend/libebackend.h
index f7f0157..0aac5d4 100644
--- a/libebackend/libebackend.h
+++ b/libebackend/libebackend.h
@@ -42,6 +42,7 @@
 #include <libebackend/e-oauth2-support.h>
 #include <libebackend/e-offline-listener.h>
 #include <libebackend/e-server-side-source.h>
+#include <libebackend/e-soup-auth-bearer.h>
 #include <libebackend/e-source-registry-server.h>
 #include <libebackend/e-sqlite3-vfs.h>
 #include <libebackend/e-user-prompter.h>


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