1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
From 13afda757c4ba8d558eaa64853849f2ad00a9806 Mon Sep 17 00:00:00 2001
From: Matthew Barnes <mbarnes@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
|