From 13afda757c4ba8d558eaa64853849f2ad00a9806 Mon Sep 17 00:00:00 2001 From: Matthew Barnes 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