[evolution-data-server] Merge duplicated code around EGDataOAuth2Authorizer
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Merge duplicated code around EGDataOAuth2Authorizer
- Date: Tue, 21 Nov 2017 12:48:02 +0000 (UTC)
commit 34514d58d5387030c073c6c35efcb353204553a0
Author: Milan Crha <mcrha redhat com>
Date: Tue Nov 21 13:47:14 2017 +0100
Merge duplicated code around EGDataOAuth2Authorizer
.../evolution-data-server-docs.sgml.in | 1 +
src/addressbook/backends/google/CMakeLists.txt | 2 -
.../backends/google/e-book-backend-google.c | 6 +-
.../backends/google/e-gdata-oauth2-authorizer.c | 394 ---------------
src/calendar/backends/gtasks/CMakeLists.txt | 2 -
.../backends/gtasks/e-cal-backend-gtasks.c | 5 +-
.../backends/gtasks/e-gdata-oauth2-authorizer.c | 394 ---------------
.../backends/gtasks/e-gdata-oauth2-authorizer.h | 75 ---
src/libedataserver/CMakeLists.txt | 5 +
src/libedataserver/e-data-server-util.c | 2 +-
src/libedataserver/e-gdata-oauth2-authorizer.c | 527 ++++++++++++++++++++
.../e-gdata-oauth2-authorizer.h | 29 +-
src/libedataserver/libedataserver.h | 1 +
src/modules/google-backend/CMakeLists.txt | 2 -
.../google-backend/e-gdata-oauth2-authorizer.c | 394 ---------------
.../google-backend/e-gdata-oauth2-authorizer.h | 74 ---
src/modules/google-backend/module-google-backend.c | 23 +-
17 files changed, 565 insertions(+), 1371 deletions(-)
---
diff --git a/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
b/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
index 37517ce..9f7861a 100644
--- a/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
+++ b/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
@@ -227,6 +227,7 @@
<xi:include href="xml/e-error.xml"/>
<xi:include href="xml/e-flag.xml"/>
<xi:include href="xml/e-free-form-exp.xml"/>
+ <xi:include href="xml/e-gdata-oauth2-authorizer.xml"/>
<xi:include href="xml/e-gdbus-templates.xml"/>
<xi:include href="xml/e-memory.xml"/>
<xi:include href="xml/e-network-monitor.xml"/>
diff --git a/src/addressbook/backends/google/CMakeLists.txt b/src/addressbook/backends/google/CMakeLists.txt
index e4d930d..09e2bee 100644
--- a/src/addressbook/backends/google/CMakeLists.txt
+++ b/src/addressbook/backends/google/CMakeLists.txt
@@ -12,8 +12,6 @@ add_library(ebookbackendgoogle MODULE
e-book-backend-google.h
e-book-google-utils.c
e-book-google-utils.h
- e-gdata-oauth2-authorizer.c
- e-gdata-oauth2-authorizer.h
)
add_dependencies(ebookbackendgoogle
diff --git a/src/addressbook/backends/google/e-book-backend-google.c
b/src/addressbook/backends/google/e-book-backend-google.c
index 645cbb1..2ec0d24 100644
--- a/src/addressbook/backends/google/e-book-backend-google.c
+++ b/src/addressbook/backends/google/e-book-backend-google.c
@@ -28,9 +28,10 @@
#include <glib/gi18n-lib.h>
#include <gdata/gdata.h>
+#include "libedataserver/libedataserver.h"
+
#include "e-book-backend-google.h"
#include "e-book-google-utils.h"
-#include "e-gdata-oauth2-authorizer.h"
#define URI_GET_CONTACTS "https://www.google.com/m8/feeds/contacts/default/full"
@@ -168,8 +169,7 @@ ebb_google_request_authorization (EBookBackendGoogle *bbgoogle,
source = e_backend_get_source (E_BACKEND (bbgoogle));
- /* Only OAuth2 is supported with Google Tasks */
- authorizer = e_gdata_oauth2_authorizer_new (source);
+ authorizer = e_gdata_oauth2_authorizer_new (source, GDATA_TYPE_CONTACTS_SERVICE);
bbgoogle->priv->authorizer = GDATA_AUTHORIZER (authorizer);
}
diff --git a/src/calendar/backends/gtasks/CMakeLists.txt b/src/calendar/backends/gtasks/CMakeLists.txt
index 38ee19a..4664980 100644
--- a/src/calendar/backends/gtasks/CMakeLists.txt
+++ b/src/calendar/backends/gtasks/CMakeLists.txt
@@ -9,8 +9,6 @@ set(SOURCES
e-cal-backend-gtasks-factory.c
e-cal-backend-gtasks.c
e-cal-backend-gtasks.h
- e-gdata-oauth2-authorizer.c
- e-gdata-oauth2-authorizer.h
)
add_library(ecalbackendgtasks MODULE
diff --git a/src/calendar/backends/gtasks/e-cal-backend-gtasks.c
b/src/calendar/backends/gtasks/e-cal-backend-gtasks.c
index f8c4d2c..9815242 100644
--- a/src/calendar/backends/gtasks/e-cal-backend-gtasks.c
+++ b/src/calendar/backends/gtasks/e-cal-backend-gtasks.c
@@ -21,7 +21,8 @@
#include <glib/gi18n-lib.h>
#include <gdata/gdata.h>
-#include "e-gdata-oauth2-authorizer.h"
+#include "libedataserver/libedataserver.h"
+
#include "e-cal-backend-gtasks.h"
#define d(x)
@@ -281,7 +282,7 @@ ecb_gtasks_request_authorization (ECalBackendGTasks *cbgtasks,
source = e_backend_get_source (E_BACKEND (cbgtasks));
/* Only OAuth2 is supported with Google Tasks */
- authorizer = e_gdata_oauth2_authorizer_new (source);
+ authorizer = e_gdata_oauth2_authorizer_new (source, GDATA_TYPE_TASKS_SERVICE);
cbgtasks->priv->authorizer = GDATA_AUTHORIZER (authorizer);
}
diff --git a/src/libedataserver/CMakeLists.txt b/src/libedataserver/CMakeLists.txt
index d562e84..3a16a57 100644
--- a/src/libedataserver/CMakeLists.txt
+++ b/src/libedataserver/CMakeLists.txt
@@ -57,6 +57,7 @@ set(SOURCES
e-extension.c
e-flag.c
e-free-form-exp.c
+ e-gdata-oauth2-authorizer.c
e-gdbus-templates.c
e-iterator.c
e-list.c
@@ -140,6 +141,7 @@ set(HEADERS
e-extension.h
e-flag.h
e-free-form-exp.h
+ e-gdata-oauth2-authorizer.h
e-gdbus-templates.h
e-iterator.h
e-list.h
@@ -242,6 +244,7 @@ target_compile_options(edataserver PUBLIC
${GIO_UNIX_CFLAGS}
${ICU_CFLAGS}
${GOOGLE_AUTH_CFLAGS}
+ ${LIBGDATA_CFLAGS}
)
target_include_directories(edataserver PUBLIC
@@ -256,6 +259,7 @@ target_include_directories(edataserver PUBLIC
${GIO_UNIX_INCLUDE_DIRS}
${ICU_INCLUDE_DIRS}
${GOOGLE_AUTH_INCLUDE_DIRS}
+ ${LIBGDATA_INCLUDE_DIRS}
)
target_link_libraries(edataserver
@@ -265,6 +269,7 @@ target_link_libraries(edataserver
${GIO_UNIX_LDFLAGS}
${ICU_LDFLAGS}
${GOOGLE_AUTH_LDFLAGS}
+ ${LIBGDATA_LDFLAGS}
)
install(TARGETS edataserver
diff --git a/src/libedataserver/e-data-server-util.c b/src/libedataserver/e-data-server-util.c
index 505ab36..750e18f 100644
--- a/src/libedataserver/e-data-server-util.c
+++ b/src/libedataserver/e-data-server-util.c
@@ -2247,7 +2247,7 @@ e_named_parameters_new_clone (const ENamedParameters *parameters)
/**
* e_named_parameters_free:
- * @parameters: an #ENamedParameters
+ * @parameters: (nullable): an #ENamedParameters
*
* Frees an instance of #ENamedParameters, previously allocated
* with e_named_parameters_new(). Function does nothing, if
diff --git a/src/libedataserver/e-gdata-oauth2-authorizer.c b/src/libedataserver/e-gdata-oauth2-authorizer.c
new file mode 100644
index 0000000..79ef743
--- /dev/null
+++ b/src/libedataserver/e-gdata-oauth2-authorizer.c
@@ -0,0 +1,527 @@
+/*
+ * e-gdata-oauth2-authorizer.c
+ *
+ * This library 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.
+ *
+ * This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "evolution-data-server-config.h"
+
+#include <time.h>
+
+#include "e-gdata-oauth2-authorizer.h"
+
+#ifdef HAVE_LIBGDATA
+
+#include <gdata/gdata.h>
+
+#define EXPIRY_INVALID ((time_t) -1)
+
+struct _EGDataOAuth2AuthorizerPrivate {
+ GWeakRef source;
+ GType service_type;
+
+ /* These members are protected by the global mutex. */
+ gchar *access_token;
+ time_t expiry;
+ GHashTable *authorization_domains;
+ ENamedParameters *credentials;
+};
+
+enum {
+ PROP_0,
+ PROP_SERVICE_TYPE,
+ PROP_SOURCE
+};
+
+/* GDataAuthorizer methods must be thread-safe. */
+static GMutex mutex;
+
+/* Forward Declarations */
+static void e_gdata_oauth2_authorizer_interface_init (GDataAuthorizerInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (EGDataOAuth2Authorizer, e_gdata_oauth2_authorizer, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GDATA_TYPE_AUTHORIZER, e_gdata_oauth2_authorizer_interface_init))
+
+static gboolean
+e_gdata_oauth2_authorizer_is_authorized (GDataAuthorizer *authorizer,
+ GDataAuthorizationDomain *domain)
+{
+ EGDataOAuth2Authorizer *oauth2_authorizer;
+
+ /* This MUST be called with the mutex already locked. */
+
+ if (!domain)
+ return TRUE;
+
+ oauth2_authorizer = E_GDATA_OAUTH2_AUTHORIZER (authorizer);
+
+ return g_hash_table_contains (oauth2_authorizer->priv->authorization_domains, domain);
+}
+
+static void
+e_gdata_oauth2_authorizer_set_service_type (EGDataOAuth2Authorizer *authorizer,
+ GType service_type)
+{
+ g_return_if_fail (service_type != 0);
+
+ authorizer->priv->service_type = service_type;
+}
+
+static void
+e_gdata_oauth2_authorizer_set_source (EGDataOAuth2Authorizer *authorizer,
+ ESource *source)
+{
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ g_weak_ref_set (&authorizer->priv->source, source);
+}
+
+static void
+e_gdata_oauth2_authorizer_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SERVICE_TYPE:
+ e_gdata_oauth2_authorizer_set_service_type (
+ E_GDATA_OAUTH2_AUTHORIZER (object),
+ g_value_get_gtype (value));
+ return;
+
+ case PROP_SOURCE:
+ e_gdata_oauth2_authorizer_set_source (
+ E_GDATA_OAUTH2_AUTHORIZER (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+e_gdata_oauth2_authorizer_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SERVICE_TYPE:
+ g_value_set_gtype (
+ value,
+ e_gdata_oauth2_authorizer_get_service_type (
+ E_GDATA_OAUTH2_AUTHORIZER (object)));
+ return;
+
+ case PROP_SOURCE:
+ g_value_take_object (
+ value,
+ e_gdata_oauth2_authorizer_ref_source (
+ E_GDATA_OAUTH2_AUTHORIZER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+e_gdata_oauth2_authorizer_dispose (GObject *object)
+{
+ EGDataOAuth2Authorizer *oauth2_authorizer;
+
+ oauth2_authorizer = E_GDATA_OAUTH2_AUTHORIZER (object);
+
+ g_weak_ref_set (&oauth2_authorizer->priv->source, NULL);
+
+ g_hash_table_remove_all (oauth2_authorizer->priv->authorization_domains);
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (e_gdata_oauth2_authorizer_parent_class)->dispose (object);
+}
+
+static void
+e_gdata_oauth2_authorizer_finalize (GObject *object)
+{
+ EGDataOAuth2Authorizer *oauth2_authorizer;
+
+ oauth2_authorizer = E_GDATA_OAUTH2_AUTHORIZER (object);
+
+ g_free (oauth2_authorizer->priv->access_token);
+
+ g_hash_table_destroy (oauth2_authorizer->priv->authorization_domains);
+ g_weak_ref_clear (&oauth2_authorizer->priv->source);
+
+ e_named_parameters_free (oauth2_authorizer->priv->credentials);
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (e_gdata_oauth2_authorizer_parent_class)->finalize (object);
+}
+
+static void
+e_gdata_oauth2_authorizer_constructed (GObject *object)
+{
+ EGDataOAuth2Authorizer *oauth2_authorizer;
+ GList *domains, *link;
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (e_gdata_oauth2_authorizer_parent_class)->constructed (object);
+
+ oauth2_authorizer = E_GDATA_OAUTH2_AUTHORIZER (object);
+
+ domains = gdata_service_get_authorization_domains (oauth2_authorizer->priv->service_type);
+ for (link = domains; link; link = g_list_next (link)) {
+ g_hash_table_add (
+ oauth2_authorizer->priv->authorization_domains,
+ g_object_ref (domains->data));
+ }
+
+ g_list_free (domains);
+}
+
+static void
+e_gdata_oauth2_authorizer_process_request (GDataAuthorizer *authorizer,
+ GDataAuthorizationDomain *domain,
+ SoupMessage *message)
+{
+ EGDataOAuth2Authorizer *oauth2_authorizer;
+ gchar *authorization;
+
+ oauth2_authorizer = E_GDATA_OAUTH2_AUTHORIZER (authorizer);
+
+ g_mutex_lock (&mutex);
+
+ if (!e_gdata_oauth2_authorizer_is_authorized (authorizer, domain) ||
+ e_gdata_oauth2_authorizer_is_expired (oauth2_authorizer))
+ goto exit;
+
+ /* We can't add an Authorization header without an access token.
+ * Let the request fail. GData should refresh us if it gets back
+ * a "401 Authorization required" response from Google, and then
+ * automatically retry the request. */
+ if (!oauth2_authorizer->priv->access_token)
+ goto exit;
+
+ authorization = g_strdup_printf ("OAuth %s", oauth2_authorizer->priv->access_token);
+
+ /* Use replace here, not append, to make sure
+ * there's only one "Authorization" header. */
+ soup_message_headers_replace (
+ message->request_headers,
+ "Authorization", authorization);
+
+ g_free (authorization);
+
+exit:
+ g_mutex_unlock (&mutex);
+}
+
+static gboolean
+e_gdata_oauth2_authorizer_is_authorized_for_domain (GDataAuthorizer *authorizer,
+ GDataAuthorizationDomain *domain)
+{
+ gboolean authorized;
+
+ g_mutex_lock (&mutex);
+
+ authorized = e_gdata_oauth2_authorizer_is_authorized (authorizer, domain);
+
+ g_mutex_unlock (&mutex);
+
+ return authorized;
+}
+
+static gboolean
+e_gdata_oauth2_authorizer_refresh_authorization (GDataAuthorizer *authorizer,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EGDataOAuth2Authorizer *oauth2_authorizer;
+ ESource *source;
+ gchar *access_token = NULL;
+ gint expires_in_seconds = -1;
+ gboolean success = FALSE;
+
+ oauth2_authorizer = E_GDATA_OAUTH2_AUTHORIZER (authorizer);
+ source = e_gdata_oauth2_authorizer_ref_source (oauth2_authorizer);
+ g_return_val_if_fail (source != NULL, FALSE);
+
+ g_mutex_lock (&mutex);
+
+ success = e_util_get_source_oauth2_access_token_sync (source, oauth2_authorizer->priv->credentials,
+ &access_token, &expires_in_seconds, cancellable, error);
+
+ /* Returned token is the same, thus no refresh happened, thus rather fail. */
+ if (access_token && g_strcmp0 (access_token, oauth2_authorizer->priv->access_token) == 0) {
+ g_free (access_token);
+ access_token = NULL;
+ success = FALSE;
+ }
+
+ g_free (oauth2_authorizer->priv->access_token);
+ oauth2_authorizer->priv->access_token = access_token;
+
+ if (success && expires_in_seconds > 0)
+ oauth2_authorizer->priv->expiry = time (NULL) + expires_in_seconds - 1;
+ else
+ oauth2_authorizer->priv->expiry = EXPIRY_INVALID;
+
+ g_mutex_unlock (&mutex);
+
+ g_object_unref (source);
+
+ return success && access_token;
+}
+
+static void
+e_gdata_oauth2_authorizer_class_init (EGDataOAuth2AuthorizerClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EGDataOAuth2AuthorizerPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = e_gdata_oauth2_authorizer_set_property;
+ object_class->get_property = e_gdata_oauth2_authorizer_get_property;
+ object_class->dispose = e_gdata_oauth2_authorizer_dispose;
+ object_class->finalize = e_gdata_oauth2_authorizer_finalize;
+ object_class->constructed = e_gdata_oauth2_authorizer_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SERVICE_TYPE,
+ g_param_spec_gtype (
+ "service-type",
+ "Service Type",
+ "The service type for which this authorization will be used",
+ GDATA_TYPE_SERVICE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SOURCE,
+ g_param_spec_object (
+ "source",
+ "Source",
+ "The data source to authenticate",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_gdata_oauth2_authorizer_interface_init (GDataAuthorizerInterface *iface)
+{
+ iface->process_request = e_gdata_oauth2_authorizer_process_request;
+ iface->is_authorized_for_domain = e_gdata_oauth2_authorizer_is_authorized_for_domain;
+ iface->refresh_authorization = e_gdata_oauth2_authorizer_refresh_authorization;
+}
+
+static void
+e_gdata_oauth2_authorizer_init (EGDataOAuth2Authorizer *oauth2_authorizer)
+{
+ oauth2_authorizer->priv = G_TYPE_INSTANCE_GET_PRIVATE (oauth2_authorizer,
E_TYPE_GDATA_OAUTH2_AUTHORIZER, EGDataOAuth2AuthorizerPrivate);
+ oauth2_authorizer->priv->authorization_domains = g_hash_table_new_full (g_direct_hash,
g_direct_equal, g_object_unref, NULL);
+ oauth2_authorizer->priv->expiry = EXPIRY_INVALID;
+ g_weak_ref_init (&oauth2_authorizer->priv->source, NULL);
+}
+
+#endif /* HAVE_LIBGDATA */
+
+/**
+ * e_gdata_oauth2_authorizer_supported:
+ *
+ * Returns: Whether the #EGDataOAuth2Authorizer is supported, which
+ * means whether evolution-data-server had been compiled with libgdata.
+ *
+ * Since: 3.28
+ **/
+gboolean
+e_gdata_oauth2_authorizer_supported (void)
+{
+#ifdef HAVE_LIBGDATA
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+/**
+ * e_gdata_oauth2_authorizer_new:
+ * @source: an #ESource
+ * @service_type: a #GDataService type descendant
+ *
+ * Creates a new #EGDataOAuth2Authorizer for the given @source
+ * and @service_type. The function always returns %NULL when
+ * e_gdata_oauth2_authorizer_supported() returns %FALSE.
+ *
+ * Returns: (transfer full): a new #EGDataOAuth2Authorizer, or %NULL when
+ * the #EGDataOAuth2Authorizer is not supported.
+ *
+ * Since: 3.28
+ **/
+EGDataOAuth2Authorizer *
+e_gdata_oauth2_authorizer_new (ESource *source,
+ GType service_type)
+{
+ g_return_val_if_fail (E_IS_SOURCE (source), NULL);
+
+#ifdef HAVE_LIBGDATA
+ return g_object_new (E_TYPE_GDATA_OAUTH2_AUTHORIZER,
+ "service-type", service_type,
+ "source", source,
+ NULL);
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * e_gdata_oauth2_authorizer_ref_source:
+ * @oauth2_authorizer: an #EGDataOAuth2Authorizer
+ *
+ * Returns: (transfer full): an #ESource, for which the @oauth2_authorizer
+ * had been created, or %NULL. Free returned non-NULL object with g_object_unref(),
+ * when done with it.
+ *
+ * See: e_gdata_oauth2_authorizer_supported()
+ *
+ * Since: 3.28
+ **/
+ESource *
+e_gdata_oauth2_authorizer_ref_source (EGDataOAuth2Authorizer *oauth2_authorizer)
+{
+#ifdef HAVE_LIBGDATA
+ g_return_val_if_fail (E_IS_GDATA_OAUTH2_AUTHORIZER (oauth2_authorizer), NULL);
+
+ return g_weak_ref_get (&oauth2_authorizer->priv->source);
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * e_gdata_oauth2_authorizer_get_service_type:
+ * @oauth2_authorizer: an #EGDataOAuth2Authorizer
+ *
+ * Returns: a service %GType, for which the @oauth2_authorizer had been created.
+ *
+ * See: e_gdata_oauth2_authorizer_supported()
+ *
+ * Since: 3.28
+ **/
+GType
+e_gdata_oauth2_authorizer_get_service_type (EGDataOAuth2Authorizer *oauth2_authorizer)
+{
+#ifdef HAVE_LIBGDATA
+ g_return_val_if_fail (E_IS_GDATA_OAUTH2_AUTHORIZER (oauth2_authorizer), (GType) 0);
+
+ return oauth2_authorizer->priv->service_type;
+#else
+ return (GType) 0;
+#endif
+}
+
+/**
+ * e_gdata_oauth2_authorizer_set_credentials:
+ * @oauth2_authorizer: an #EGDataOAuth2Authorizer
+ * @credentials: (nullable): credentials to set, or %NULL
+ *
+ * Updates internally stored credentials, used to get access token.
+ *
+ * See: e_gdata_oauth2_authorizer_supported()
+ *
+ * Since: 3.28
+ **/
+void
+e_gdata_oauth2_authorizer_set_credentials (EGDataOAuth2Authorizer *oauth2_authorizer,
+ const ENamedParameters *credentials)
+{
+#ifdef HAVE_LIBGDATA
+ g_return_if_fail (E_IS_GDATA_OAUTH2_AUTHORIZER (oauth2_authorizer));
+
+ g_mutex_lock (&mutex);
+
+ e_named_parameters_free (oauth2_authorizer->priv->credentials);
+ if (credentials)
+ oauth2_authorizer->priv->credentials = e_named_parameters_new_clone (credentials);
+ else
+ oauth2_authorizer->priv->credentials = NULL;
+
+ g_free (oauth2_authorizer->priv->access_token);
+ oauth2_authorizer->priv->access_token = NULL;
+
+ oauth2_authorizer->priv->expiry = EXPIRY_INVALID;
+
+ g_mutex_unlock (&mutex);
+#endif
+}
+
+/**
+ * e_gdata_oauth2_authorizer_clone_credentials:
+ * @oauth2_authorizer: an #EGDataOAuth2Authorizer
+ *
+ * Returns: (transfer full) (nullable): A copy of currently stored credentials,
+ * or %NULL, when none are set. Free the returned structure with
+ * e_named_parameters_free(), when no longer needed.
+ *
+ * See: e_gdata_oauth2_authorizer_supported()
+ *
+ * Since: 3.28
+ **/
+ENamedParameters *
+e_gdata_oauth2_authorizer_clone_credentials (EGDataOAuth2Authorizer *oauth2_authorizer)
+{
+#ifdef HAVE_LIBGDATA
+ ENamedParameters *credentials = NULL;
+
+ g_return_val_if_fail (E_IS_GDATA_OAUTH2_AUTHORIZER (oauth2_authorizer), NULL);
+
+ g_mutex_lock (&mutex);
+
+ if (oauth2_authorizer->priv->credentials)
+ credentials = e_named_parameters_new_clone (oauth2_authorizer->priv->credentials);
+
+ g_mutex_unlock (&mutex);
+
+ return credentials;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * e_gdata_oauth2_authorizer_is_expired:
+ * @oauth2_authorizer: an #EGDataOAuth2Authorizer
+ *
+ * Returns: Whether the internally stored token is expired.
+ *
+ * See: e_gdata_oauth2_authorizer_supported()
+ *
+ * Since: 3.28
+ **/
+gboolean
+e_gdata_oauth2_authorizer_is_expired (EGDataOAuth2Authorizer *oauth2_authorizer)
+{
+#ifdef HAVE_LIBGDATA
+ g_return_val_if_fail (E_IS_GDATA_OAUTH2_AUTHORIZER (oauth2_authorizer), TRUE);
+
+ return oauth2_authorizer->priv->expiry == EXPIRY_INVALID ||
+ oauth2_authorizer->priv->expiry <= time (NULL);
+#else
+ return TRUE;
+#endif
+}
diff --git a/src/addressbook/backends/google/e-gdata-oauth2-authorizer.h
b/src/libedataserver/e-gdata-oauth2-authorizer.h
similarity index 70%
rename from src/addressbook/backends/google/e-gdata-oauth2-authorizer.h
rename to src/libedataserver/e-gdata-oauth2-authorizer.h
index 0dfc582..eef8078 100644
--- a/src/addressbook/backends/google/e-gdata-oauth2-authorizer.h
+++ b/src/libedataserver/e-gdata-oauth2-authorizer.h
@@ -15,11 +15,15 @@
*
*/
+#if !defined (__LIBEDATASERVER_H_INSIDE__) && !defined (LIBEDATASERVER_COMPILATION)
+#error "Only <libedataserver/libedataserver.h> should be included directly."
+#endif
+
#ifndef E_GDATA_OAUTH2_AUTHORIZER_H
#define E_GDATA_OAUTH2_AUTHORIZER_H
-#include <gdata/gdata.h>
-#include <libedataserver/libedataserver.h>
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-data-server-util.h>
/* Standard GObject macros */
#define E_TYPE_GDATA_OAUTH2_AUTHORIZER \
@@ -55,21 +59,22 @@ struct _EGDataOAuth2AuthorizerClass {
GObjectClass parent_class;
};
-GType e_gdata_oauth2_authorizer_get_type
- (void) G_GNUC_CONST;
+gboolean e_gdata_oauth2_authorizer_supported (void);
+GType e_gdata_oauth2_authorizer_get_type (void) G_GNUC_CONST;
EGDataOAuth2Authorizer *
- e_gdata_oauth2_authorizer_new
- (ESource *source);
-ESource * e_gdata_oauth2_authorizer_ref_source
- (EGDataOAuth2Authorizer *authorizer);
+ e_gdata_oauth2_authorizer_new (ESource *source,
+ GType service_type);
+ESource * e_gdata_oauth2_authorizer_ref_source (EGDataOAuth2Authorizer *oauth2_authorizer);
+GType e_gdata_oauth2_authorizer_get_service_type
+ (EGDataOAuth2Authorizer *oauth2_authorizer);
void e_gdata_oauth2_authorizer_set_credentials
- (EGDataOAuth2Authorizer *authorizer,
- const ENamedParameters *credentials);
+ (EGDataOAuth2Authorizer *oauth2_authorizer,
+ const ENamedParameters *credentials);
ENamedParameters *
e_gdata_oauth2_authorizer_clone_credentials
- (EGDataOAuth2Authorizer *authorizer);
+ (EGDataOAuth2Authorizer *oauth2_authorizer);
+gboolean e_gdata_oauth2_authorizer_is_expired (EGDataOAuth2Authorizer *oauth2_authorizer);
G_END_DECLS
#endif /* E_GDATA_OAUTH2_AUTHORIZER_H */
-
diff --git a/src/libedataserver/libedataserver.h b/src/libedataserver/libedataserver.h
index fd95ddd..f3df296 100644
--- a/src/libedataserver/libedataserver.h
+++ b/src/libedataserver/libedataserver.h
@@ -31,6 +31,7 @@
#include <libedataserver/e-extension.h>
#include <libedataserver/e-flag.h>
#include <libedataserver/e-free-form-exp.h>
+#include <libedataserver/e-gdata-oauth2-authorizer.h>
#include <libedataserver/e-gdbus-templates.h>
#include <libedataserver/e-iterator.h>
#include <libedataserver/e-list-iterator.h>
diff --git a/src/modules/google-backend/CMakeLists.txt b/src/modules/google-backend/CMakeLists.txt
index c6b9e7b..7f62505 100644
--- a/src/modules/google-backend/CMakeLists.txt
+++ b/src/modules/google-backend/CMakeLists.txt
@@ -1,8 +1,6 @@
set(extra_deps)
if(HAVE_LIBGDATA)
set(sources
- e-gdata-oauth2-authorizer.c
- e-gdata-oauth2-authorizer.h
module-google-backend.c
)
else(HAVE_LIBGDATA)
diff --git a/src/modules/google-backend/module-google-backend.c
b/src/modules/google-backend/module-google-backend.c
index 2663355..4efa245 100644
--- a/src/modules/google-backend/module-google-backend.c
+++ b/src/modules/google-backend/module-google-backend.c
@@ -20,21 +20,12 @@
#include <glib/gi18n-lib.h>
#include <libebackend/libebackend.h>
+#include <libedataserver/libedataserver.h>
#ifdef HAVE_LIBGDATA
#include <gdata/gdata.h>
#endif
-/* This macro was introduced in libgdata 0.11,
- * but we currently only require libgdata 0.10. */
-#ifndef GDATA_CHECK_VERSION
-#define GDATA_CHECK_VERSION(major,minor,micro) 0
-#endif
-
-#if GDATA_CHECK_VERSION(0,15,1)
-#include "e-gdata-oauth2-authorizer.h"
-#endif
-
/* Standard GObject macros */
#define E_TYPE_GOOGLE_BACKEND \
(e_google_backend_get_type ())
@@ -340,7 +331,7 @@ google_remove_unknown_sources_cb (gpointer resource_id,
}
}
-#if GDATA_CHECK_VERSION(0,15,1)
+#ifdef HAVE_LIBGDATA
static void
google_add_task_list (ECollectionBackend *collection,
const gchar *resource_id,
@@ -419,7 +410,7 @@ google_add_task_list (ECollectionBackend *collection,
g_object_unref (server);
g_free (identity);
}
-#endif /* GDATA_CHECK_VERSION(0,15,1) */
+#endif /* HAVE_LIBGDATA */
static ESourceAuthenticationResult
google_backend_authenticate_sync (EBackend *backend,
@@ -439,7 +430,6 @@ google_backend_authenticate_sync (EBackend *backend,
GList *sources;
ENamedParameters *credentials_copy = NULL;
const gchar *calendar_url;
- GError *local_error = NULL;
g_return_val_if_fail (collection != NULL, E_SOURCE_AUTHENTICATION_ERROR);
@@ -494,14 +484,15 @@ google_backend_authenticate_sync (EBackend *backend,
result = E_SOURCE_AUTHENTICATION_ACCEPTED;
}
-#if GDATA_CHECK_VERSION(0,15,1)
+#ifdef HAVE_LIBGDATA
if (result == E_SOURCE_AUTHENTICATION_ACCEPTED &&
e_source_collection_get_calendar_enabled (collection_extension) &&
(goa_extension || e_source_credentials_google_is_supported ())) {
EGDataOAuth2Authorizer *authorizer;
GDataTasksService *tasks_service;
+ GError *local_error = NULL;
- authorizer = e_gdata_oauth2_authorizer_new (e_backend_get_source (backend));
+ authorizer = e_gdata_oauth2_authorizer_new (e_backend_get_source (backend),
GDATA_TYPE_TASKS_SERVICE);
e_gdata_oauth2_authorizer_set_credentials (authorizer, credentials);
tasks_service = gdata_tasks_service_new (GDATA_AUTHORIZER (authorizer));
@@ -543,7 +534,7 @@ google_backend_authenticate_sync (EBackend *backend,
g_clear_object (&authorizer);
g_clear_error (&local_error);
}
-#endif /* GDATA_CHECK_VERSION(0,15,1) */
+#endif /* HAVE_LIBGDATA */
if (result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
ESourceRegistryServer *server;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]