[arch-commits] Commit in evolution-data-server/trunk (5 files)

Jan de Groot jgc at nymeria.archlinux.org
Mon Aug 5 10:37:35 UTC 2013


    Date: Monday, August 5, 2013 @ 12:37:35
  Author: jgc
Revision: 192046

upgpkg: evolution-data-server 3.8.4-2

Support Google 2 factor auth

Added:
  evolution-data-server/trunk/fix-google-2fa-1.patch
  evolution-data-server/trunk/fix-google-2fa-2.patch
  evolution-data-server/trunk/fix-google-2fa-3.patch
  evolution-data-server/trunk/fix-google-2fa-4.patch
Modified:
  evolution-data-server/trunk/PKGBUILD

------------------------+
 PKGBUILD               |   26 ++-
 fix-google-2fa-1.patch |  402 +++++++++++++++++++++++++++++++++++++++++++++++
 fix-google-2fa-2.patch |   86 ++++++++++
 fix-google-2fa-3.patch |   48 +++++
 fix-google-2fa-4.patch |  159 ++++++++++++++++++
 5 files changed, 717 insertions(+), 4 deletions(-)

Modified: PKGBUILD
===================================================================
--- PKGBUILD	2013-08-05 10:07:57 UTC (rev 192045)
+++ PKGBUILD	2013-08-05 10:37:35 UTC (rev 192046)
@@ -3,20 +3,38 @@
 
 pkgname=evolution-data-server
 pkgver=3.8.4
-pkgrel=1
+pkgrel=2
 pkgdesc="Centralized access to appointments and contacts"
 arch=(i686 x86_64)
 depends=(gnome-online-accounts nss krb5 libgweather libical db libgdata)
-makedepends=(intltool gperf gobject-introspection vala python2)
+makedepends=(intltool gperf gobject-introspection vala python2 gnome-common)
 options=('!libtool')
 install=$pkgname.install
 url="http://www.gnome.org"
 license=(GPL)
-source=(http://ftp.gnome.org/pub/gnome/sources/$pkgname/${pkgver%.*}/$pkgname-$pkgver.tar.xz)
-sha256sums=('0b9e725d36a4c63ccb15b4e0f92932764c9a335e84af2ebeeb4c182760ef3f6e')
+source=(http://ftp.gnome.org/pub/gnome/sources/$pkgname/${pkgver%.*}/$pkgname-$pkgver.tar.xz
+fix-google-2fa-1.patch
+fix-google-2fa-2.patch
+fix-google-2fa-3.patch
+fix-google-2fa-4.patch)
+sha256sums=('0b9e725d36a4c63ccb15b4e0f92932764c9a335e84af2ebeeb4c182760ef3f6e'
+            'c1de9fe146f0512cf6c0219341c8409a9e4d955c3eb6a85f7d07183972b9328e'
+            '3e1c83dd00f01dfa0f9d67d2327de110b3e232a5f9a882ccce09a02392df7de6'
+            '9da8cccf504f40b8ee9e068b465cdf0a1a858999dd88d8e8e96f1e4cdffbf1e2'
+            '27022d00575ba1b9283d9420aa231c2770ff403b0b6c0442b6d679faefdbe00e')
 
+
+prepare() {
+  cd "$pkgname-$pkgver"
+  patch -Np1 -i ../fix-google-2fa-1.patch
+  patch -Np1 -i ../fix-google-2fa-2.patch
+  patch -Np1 -i ../fix-google-2fa-3.patch
+  patch -Np1 -i ../fix-google-2fa-4.patch
+}
+
 build() {
   cd "$pkgname-$pkgver"
+  autoreconf -fi
   ./configure --prefix=/usr --sysconfdir=/etc \
       --localstatedir=/var --with-openldap=yes \
       --libexecdir=/usr/lib/evolution-data-server \

Added: fix-google-2fa-1.patch
===================================================================
--- fix-google-2fa-1.patch	                        (rev 0)
+++ fix-google-2fa-1.patch	2013-08-05 10:37:35 UTC (rev 192046)
@@ -0,0 +1,402 @@
+From fa0d18fcf2d8084d2a41f24f50f689eed8e3e241 Mon Sep 17 00:00:00 2001
+From: Matthew Barnes <mbarnes at redhat.com>
+Date: Tue, 09 Jul 2013 18:23:04 +0000
+Subject: 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().
+---
+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>
+

Added: fix-google-2fa-2.patch
===================================================================
--- fix-google-2fa-2.patch	                        (rev 0)
+++ fix-google-2fa-2.patch	2013-08-05 10:37:35 UTC (rev 192046)
@@ -0,0 +1,86 @@
+From 54e876d3fc25ec59c58beda915a8c9d1f8d5f101 Mon Sep 17 00:00:00 2001
+From: Matthew Barnes <mbarnes at redhat.com>
+Date: Tue, 09 Jul 2013 21:06:16 +0000
+Subject: CalDAV: Add support for OAuth 2.0 authentication.
+
+---
+diff --git a/calendar/backends/caldav/e-cal-backend-caldav.c b/calendar/backends/caldav/e-cal-backend-caldav.c
+index 58c70b6..58f0654 100644
+--- a/calendar/backends/caldav/e-cal-backend-caldav.c
++++ b/calendar/backends/caldav/e-cal-backend-caldav.c
+@@ -968,6 +968,32 @@ parse_propfind_response (SoupMessage *message,
+ /* Authentication helpers for libsoup */
+ 
+ static void
++soup_authenticate_bearer (SoupSession *session,
++                          SoupMessage *message,
++                          SoupAuth *auth,
++                          ESource *source)
++{
++	gchar *access_token = NULL;
++	gint expires_in_seconds = -1;
++	GError *local_error = NULL;
++
++	e_source_get_oauth2_access_token_sync (
++		source, NULL, &access_token,
++		&expires_in_seconds, &local_error);
++
++	e_soup_auth_bearer_set_access_token (
++		E_SOUP_AUTH_BEARER (auth),
++		access_token, expires_in_seconds);
++
++	if (local_error != NULL) {
++		g_warning ("%s: %s", G_STRFUNC, local_error->message);
++		g_error_free (local_error);
++	}
++
++	g_free (access_token);
++}
++
++static void
+ soup_authenticate (SoupSession *session,
+                    SoupMessage *msg,
+                    SoupAuth *auth,
+@@ -985,8 +1011,14 @@ soup_authenticate (SoupSession *session,
+ 	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+ 	auth_extension = e_source_get_extension (source, extension_name);
+ 
++	if (retrying)
++		return;
++
++	if (E_IS_SOUP_AUTH_BEARER (auth)) {
++		soup_authenticate_bearer (session, msg, auth, source);
++
+ 	/* do not send same password twice, but keep it for later use */
+-	if (!retrying && cbdav->priv->password != NULL) {
++	} else if (cbdav->priv->password != NULL) {
+ 		gchar *user;
+ 
+ 		user = e_source_authentication_dup_user (auth_extension);
+@@ -5194,6 +5226,8 @@ cal_backend_caldav_constructed (GObject *object)
+ static void
+ e_cal_backend_caldav_init (ECalBackendCalDAV *cbdav)
+ {
++	SoupSessionFeature *feature;
++
+ 	cbdav->priv = E_CAL_BACKEND_CALDAV_GET_PRIVATE (cbdav);
+ 	cbdav->priv->session = soup_session_sync_new ();
+ 	g_object_set (
+@@ -5203,6 +5237,16 @@ e_cal_backend_caldav_init (ECalBackendCalDAV *cbdav)
+ 		SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE,
+ 		NULL);
+ 
++	/* XXX SoupAuthManager is public API as of libsoup 2.42, but
++	 *     this isn't worth bumping our libsoup requirement over.
++	 *     So get the SoupAuthManager GType by its type name. */
++	feature = soup_session_get_feature (
++		cbdav->priv->session,
++		g_type_from_name ("SoupAuthManager"));
++
++	/* Add the "Bearer" auth type to support OAuth 2.0. */
++	soup_session_feature_add_feature (feature, E_TYPE_SOUP_AUTH_BEARER);
++
+ 	cbdav->priv->proxy = e_proxy_new ();
+ 	e_proxy_setup_proxy (cbdav->priv->proxy);
+ 	g_signal_connect (cbdav->priv->proxy, "changed", G_CALLBACK (proxy_settings_changed), cbdav->priv);
+

Added: fix-google-2fa-3.patch
===================================================================
--- fix-google-2fa-3.patch	                        (rev 0)
+++ fix-google-2fa-3.patch	2013-08-05 10:37:35 UTC (rev 192046)
@@ -0,0 +1,48 @@
+From cc9fb7d15ce3983fc36487d2856e5fd14b341725 Mon Sep 17 00:00:00 2001
+From: Matthew Barnes <mbarnes at redhat.com>
+Date: Tue, 09 Jul 2013 15:49:09 +0000
+Subject: google: Minor module cleanups.
+
+---
+diff --git a/modules/google-backend/module-google-backend.c b/modules/google-backend/module-google-backend.c
+index d5684bb..cbd7bd2 100644
+--- a/modules/google-backend/module-google-backend.c
++++ b/modules/google-backend/module-google-backend.c
+@@ -100,19 +100,17 @@ google_backend_contacts_update_auth_method (ESource *source)
+ 	EOAuth2Support *oauth2_support;
+ 	ESourceAuthentication *extension;
+ 	const gchar *extension_name;
+-
+-	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+-	extension = e_source_get_extension (source, extension_name);
++	const gchar *method;
+ 
+ 	oauth2_support = e_server_side_source_ref_oauth2_support (
+ 		E_SERVER_SIDE_SOURCE (source));
+-	if (oauth2_support != NULL) {
+-		e_source_authentication_set_method (extension, "OAuth2");
+-		g_object_unref (oauth2_support);
+-		return;
+-	}
+ 
+-	e_source_authentication_set_method (extension, "ClientLogin");
++	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
++	extension = e_source_get_extension (source, extension_name);
++	method = (oauth2_support != NULL) ? "OAuth2" : "ClientLogin";
++	e_source_authentication_set_method (extension, method);
++
++	g_clear_object (&oauth2_support);
+ }
+ 
+ static void
+@@ -178,7 +176,8 @@ google_backend_add_calendar (ECollectionBackend *backend)
+ 
+ 		g_get_current_time (&today_tv);
+ 		today = g_time_val_to_iso8601 (&today_tv);
+-		e_source_alarms_set_last_notified (E_SOURCE_ALARMS (extension), today);
++		e_source_alarms_set_last_notified (
++			E_SOURCE_ALARMS (extension), today);
+ 		g_free (today);
+ 	}
+ 
+

Added: fix-google-2fa-4.patch
===================================================================
--- fix-google-2fa-4.patch	                        (rev 0)
+++ fix-google-2fa-4.patch	2013-08-05 10:37:35 UTC (rev 192046)
@@ -0,0 +1,159 @@
+From 13afda757c4ba8d558eaa64853849f2ad00a9806 Mon Sep 17 00:00:00 2001
+From: Matthew Barnes <mbarnes at redhat.com>
+Date: Tue, 09 Jul 2013 15:42:17 +0000
+Subject: google: Use CalDAV v2 if OAuth 2.0 support is available.
+
+---
+diff --git a/modules/google-backend/module-google-backend.c b/modules/google-backend/module-google-backend.c
+index cbd7bd2..4ded74d 100644
+--- a/modules/google-backend/module-google-backend.c
++++ b/modules/google-backend/module-google-backend.c
+@@ -45,10 +45,16 @@
+ 
+ /* Calendar Configuration Details */
+ #define GOOGLE_CALENDAR_BACKEND_NAME	"caldav"
+-#define GOOGLE_CALENDAR_HOST		"www.google.com"
+-#define GOOGLE_CALENDAR_CALDAV_PATH	"/calendar/dav/%s/events"
+ #define GOOGLE_CALENDAR_RESOURCE_ID	"Calendar"
+ 
++/* CalDAV v1 Configuration Details */
++#define GOOGLE_CALDAV_V1_HOST		"www.google.com"
++#define GOOGLE_CALDAV_V1_PATH		"/calendar/dav/%s/events"
++
++/* CalDAV v2 Configuration Details */
++#define GOOGLE_CALDAV_V2_HOST		"apidata.googleusercontent.com"
++#define GOOGLE_CALDAV_V2_PATH		"/caldav/v2/%s/events"
++
+ /* Contacts Configuration Details */
+ #define GOOGLE_CONTACTS_BACKEND_NAME	"google"
+ #define GOOGLE_CONTACTS_HOST		"www.google.com"
+@@ -95,6 +101,52 @@ G_DEFINE_DYNAMIC_TYPE (
+ 	E_TYPE_COLLECTION_BACKEND_FACTORY)
+ 
+ static void
++google_backend_calendar_update_auth_method (ESource *source)
++{
++	EOAuth2Support *oauth2_support;
++	ESourceAuthentication *auth_extension;
++	ESourceWebdav *webdav_extension;
++	const gchar *extension_name;
++	const gchar *host;
++	const gchar *method;
++	const gchar *path_format;
++	gchar *path;
++	gchar *user;
++
++	oauth2_support = e_server_side_source_ref_oauth2_support (
++		E_SERVER_SIDE_SOURCE (source));
++
++	/* The host name and WebDAV resource path depend on the
++	 * authentication method used, so update those here too. */
++
++	if (oauth2_support != NULL) {
++		method = "OAuth2";
++		host = GOOGLE_CALDAV_V2_HOST;
++		path_format = GOOGLE_CALDAV_V2_PATH;
++	} else {
++		method = "plain/password";
++		host = GOOGLE_CALDAV_V1_HOST;
++		path_format = GOOGLE_CALDAV_V1_PATH;
++	}
++
++	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
++	auth_extension = e_source_get_extension (source, extension_name);
++	e_source_authentication_set_host (auth_extension, host);
++	e_source_authentication_set_method (auth_extension, method);
++
++	extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
++	webdav_extension = e_source_get_extension (source, extension_name);
++
++	user = e_source_authentication_dup_user (auth_extension);
++	path = g_strdup_printf (path_format, (user != NULL) ? user : "");
++	e_source_webdav_set_resource_path (webdav_extension, path);
++	g_free (path);
++	g_free (user);
++
++	g_clear_object (&oauth2_support);
++}
++
++static void
+ google_backend_contacts_update_auth_method (ESource *source)
+ {
+ 	EOAuth2Support *oauth2_support;
+@@ -123,14 +175,16 @@ google_backend_add_calendar (ECollectionBackend *backend)
+ 	ESourceCollection *collection_extension;
+ 	const gchar *backend_name;
+ 	const gchar *extension_name;
+-	const gchar *identity;
+ 	const gchar *resource_id;
+-	gchar *path;
+ 
+ 	/* FIXME As a future enhancement, we should query Google
+ 	 *       for a list of user calendars and add them to the
+ 	 *       collection with matching display names and colors. */
+ 
++	/* NOTE: Host name and WebDAV resource path are set in
++	 *       google_backend_calendar_update_auth_method(),
++	 *       since they depend on the auth method used. */
++
+ 	collection_source = e_backend_get_source (E_BACKEND (backend));
+ 
+ 	resource_id = GOOGLE_CALENDAR_RESOURCE_ID;
+@@ -153,15 +207,15 @@ google_backend_add_calendar (ECollectionBackend *backend)
+ 	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+ 	extension = e_source_get_extension (source, extension_name);
+ 
+-	e_source_authentication_set_host (
+-		E_SOURCE_AUTHENTICATION (extension),
+-		GOOGLE_CALENDAR_HOST);
+-
+ 	g_object_bind_property (
+ 		collection_extension, "identity",
+ 		extension, "user",
+ 		G_BINDING_SYNC_CREATE);
+ 
++	/* Make sure the WebDAV resource path is up-to-date, since
++	 * it's built from the "user" property that we just set. */
++	google_backend_calendar_update_auth_method (source);
++
+ 	extension_name = E_SOURCE_EXTENSION_SECURITY;
+ 	extension = e_source_get_extension (source, extension_name);
+ 
+@@ -181,15 +235,6 @@ google_backend_add_calendar (ECollectionBackend *backend)
+ 		g_free (today);
+ 	}
+ 
+-	extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
+-	extension = e_source_get_extension (source, extension_name);
+-
+-	identity = e_source_collection_get_identity (collection_extension);
+-	path = g_strdup_printf (GOOGLE_CALENDAR_CALDAV_PATH, identity);
+-	e_source_webdav_set_resource_path (
+-		E_SOURCE_WEBDAV (extension), path);
+-	g_free (path);
+-
+ 	server = e_collection_backend_ref_server (backend);
+ 	e_source_registry_server_add_source (server, source);
+ 	g_object_unref (server);
+@@ -336,6 +381,20 @@ google_backend_child_added (ECollectionBackend *backend,
+ 				collection_identity);
+ 	}
+ 
++	/* Keep the calendar authentication method up-to-date.
++	 *
++	 * XXX Not using a property binding here in case I end up adding
++	 *     other "support" interfaces which influence authentication.
++	 *     Many-to-one property bindinds tend not to work so well. */
++	extension_name = E_SOURCE_EXTENSION_CALENDAR;
++	if (e_source_has_extension (child_source, extension_name)) {
++		google_backend_calendar_update_auth_method (child_source);
++		g_signal_connect (
++			child_source, "notify::oauth2-support",
++			G_CALLBACK (google_backend_calendar_update_auth_method),
++			NULL);
++	}
++
+ 	/* Keep the contacts authentication method up-to-date.
+ 	 *
+ 	 * XXX Not using a property binding here in case I end up adding
+




More information about the arch-commits mailing list