ebook_backend_LTLIBRARIES = libebookbackendgoogle.la
-if HAVE_GOA
-GOA_SOURCES = \
- e-gdata-goa-authorizer.c \
- e-gdata-goa-authorizer.h
-endif
-
libebookbackendgoogle_la_CPPFLAGS = \
$(AM_CPPFLAGS) \
-DG_LOG_DOMAIN=\"libebookbackendgoogle\" \
$(EVOLUTION_ADDRESSBOOK_CFLAGS) \
$(SOUP_CFLAGS) \
$(GDATA_CFLAGS) \
- $(GOA_CFLAGS) \
$(CAMEL_CFLAGS) \
$(CODE_COVERAGE_CFLAGS) \
$(NULL)
e-book-google-utils.c \
e-book-google-utils.h \
e-gdata-oauth2-authorizer.c \
- e-gdata-oauth2-authorizer.h \
- $(GOA_SOURCES)
+ e-gdata-oauth2-authorizer.h
libebookbackendgoogle_la_LIBADD = \
$(top_builddir)/addressbook/libebook/libebook-1.2.la \
$(EVOLUTION_ADDRESSBOOK_LIBS) \
$(SOUP_LIBS) \
$(GDATA_LIBS) \
- $(GOA_LIBS) \
$(CAMEL_LIBS)
libebookbackendgoogle_la_LDFLAGS = \
#include "e-book-google-utils.h"
#include "e-gdata-oauth2-authorizer.h"
-#ifdef HAVE_GOA
-#include "e-gdata-goa-authorizer.h"
-#endif
-
#define E_BOOK_BACKEND_GOOGLE_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_BOOK_BACKEND_GOOGLE, EBookBackendGooglePrivate))
if (priv->service == NULL)
return FALSE;
-#ifdef HAVE_GOA
- /* If we're using OAuth tokens, then as far as the backend
- * is concerned it's always authorized. The GDataAuthorizer
- * will take care of everything in the background without
- * bothering clients with "auth-required" signals. */
- if (E_IS_GDATA_GOA_AUTHORIZER (priv->authorizer))
- return TRUE;
-#endif
-
return gdata_service_is_authorized (priv->service);
}
g_free (method);
}
-#ifdef HAVE_GOA
- /* If this is associated with a GNOME Online Account,
- * use OAuth 1.0a authentication instead of ClientLogin.
- *
- * XXX GNOME Online Accounts 3.8 switched its Google provider
- * from OAuth 1.0a to OAuth 2.0. Once we require GOA 3.8
- * we can drop this and keep direct GOA usage confined to
- * the "gnome-online-accounts" module. */
- if (priv->authorizer == NULL) {
- EGDataGoaAuthorizer *authorizer;
- GoaObject *goa_object;
-
- goa_object = g_object_get_data (
- G_OBJECT (backend), "GNOME Online Account");
- if (GOA_IS_OBJECT (goa_object)) {
- authorizer = e_gdata_goa_authorizer_new (goa_object);
- priv->authorizer = GDATA_AUTHORIZER (authorizer);
- }
- }
-#endif
-
if (priv->authorizer == NULL) {
GDataClientLoginAuthorizer *authorizer;
+++ /dev/null
-/*
- * e-gdata-goa-authorizer.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/>
- *
- */
-
-#include "e-gdata-goa-authorizer.h"
-
-#include <string.h>
-
-#define E_GDATA_GOA_AUTHORIZER_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_GDATA_GOA_AUTHORIZER, EGDataGoaAuthorizerPrivate))
-
-#define HMAC_SHA1_LEN 20 /* bytes, raw */
-
-struct _EGDataGoaAuthorizerPrivate {
-
- /* GoaObject is already thread-safe. */
- GoaObject *goa_object;
-
- /* These members are protected by the global mutex. */
- gchar *access_token;
- gchar *access_token_secret;
- GHashTable *authorization_domains;
-};
-
-enum {
- PROP_0,
- PROP_GOA_OBJECT
-};
-
-/* GDataAuthorizer methods must be thread-safe. */
-static GMutex mutex;
-
-/* Forward Declarations */
-static void e_gdata_goa_authorizer_interface_init
- (GDataAuthorizerInterface *interface);
-
-G_DEFINE_TYPE_WITH_CODE (
- EGDataGoaAuthorizer,
- e_gdata_goa_authorizer,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (
- GDATA_TYPE_AUTHORIZER,
- e_gdata_goa_authorizer_interface_init))
-
-static GHashTable *
-gdata_goa_authorizer_get_oauth_parameters (SoupMessage *message,
- const gchar *consumer_key,
- const gchar *consumer_secret,
- const gchar *access_token,
- const gchar *access_token_secret)
-{
- GString *query;
- GString *base_string;
- GString *signing_key;
- GHashTable *parameters;
- GHashTableIter iter;
- SoupURI *soup_uri;
- GList *keys, *i;
- GHmac *signature_hmac;
- guchar signature_digest[HMAC_SHA1_LEN];
- gsize signature_digest_len;
- gchar *string;
- gchar *request_uri;
- gpointer key;
-
- parameters = g_hash_table_new_full (
- (GHashFunc) g_str_hash,
- (GEqualFunc) g_str_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) g_free);
-
- /* soup_form_decode() uses an awkward allocation style for
- * its hash table entries, so it's easier to copy its content
- * into our own hash table than try to use the returned hash
- * table directly. */
-
- soup_uri = soup_message_get_uri (message);
- if (soup_uri->query != NULL) {
- GHashTable *hash_table;
- gpointer value;
-
- hash_table = soup_form_decode (soup_uri->query);
- g_hash_table_iter_init (&iter, hash_table);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- key = (gpointer) g_intern_string (key);
- value = g_strdup (value);
- g_hash_table_insert (parameters, key, value);
- }
- g_hash_table_destroy (hash_table);
- }
-
- /* Add OAuth parameters. */
-
- key = (gpointer) "oauth_version";
- g_hash_table_insert (parameters, key, g_strdup ("1.0"));
-
- key = (gpointer) "oauth_nonce";
- string = g_strdup_printf ("%u", g_random_int ());
- g_hash_table_insert (parameters, key, string); /* takes ownership */
-
- key = (gpointer) "oauth_timestamp";
- string = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) time (NULL));
- g_hash_table_insert (parameters, key, string); /* takes ownership */
-
- key = (gpointer) "oauth_consumer_key";
- g_hash_table_insert (parameters, key, g_strdup (consumer_key));
-
- key = (gpointer) "oauth_token";
- g_hash_table_insert (parameters, key, g_strdup (access_token));
-
- key = (gpointer) "oauth_signature_method";
- g_hash_table_insert (parameters, key, g_strdup ("HMAC-SHA1"));
-
- /* Build the query part of the signature base string. */
-
- query = g_string_sized_new (512);
- keys = g_hash_table_get_keys (parameters);
- keys = g_list_sort (keys, (GCompareFunc) g_strcmp0);
- for (i = keys; i != NULL; i = g_list_next (i)) {
- const gchar *_key = i->data;
- const gchar *val;
-
- val = g_hash_table_lookup (parameters, _key);
-
- if (i != keys)
- g_string_append_c (query, '&');
-
- g_string_append_uri_escaped (query, _key, NULL, FALSE);
- g_string_append_c (query, '=');
- g_string_append_uri_escaped (query, val, NULL, FALSE);
- }
- g_list_free (keys);
-
- /* Build the signature base string. */
-
- soup_uri = soup_uri_copy (soup_uri);
- soup_uri_set_query (soup_uri, NULL);
- soup_uri_set_fragment (soup_uri, NULL);
- request_uri = soup_uri_to_string (soup_uri, FALSE);
- soup_uri_free (soup_uri);
-
- base_string = g_string_sized_new (512);
- g_string_append_uri_escaped (base_string, message->method, NULL, FALSE);
- g_string_append_c (base_string, '&');
- g_string_append_uri_escaped (base_string, request_uri, NULL, FALSE);
- g_string_append_c (base_string, '&');
- g_string_append_uri_escaped (base_string, query->str, NULL, FALSE);
-
- /* Build the HMAC-SHA1 signing key. */
-
- signing_key = g_string_sized_new (512);
- g_string_append_uri_escaped (
- signing_key, consumer_secret, NULL, FALSE);
- g_string_append_c (signing_key, '&');
- g_string_append_uri_escaped (
- signing_key, access_token_secret, NULL, FALSE);
-
- /* Sign the request. */
-
- signature_digest_len = sizeof (signature_digest);
-
- signature_hmac = g_hmac_new (
- G_CHECKSUM_SHA1,
- (guchar *) signing_key->str,
- signing_key->len);
- g_hmac_update (
- signature_hmac,
- (guchar *) base_string->str,
- base_string->len);
- g_hmac_get_digest (
- signature_hmac,
- signature_digest,
- &signature_digest_len);
- g_hmac_unref (signature_hmac);
-
- key = (gpointer) "oauth_signature";
- string = g_base64_encode (signature_digest, signature_digest_len);
- g_hash_table_insert (parameters, key, string); /* takes ownership */
-
- g_free (request_uri);
-
- g_string_free (query, TRUE);
- g_string_free (base_string, TRUE);
- g_string_free (signing_key, TRUE);
-
- return parameters;
-}
-
-static void
-gdata_goa_authorizer_add_authorization (GDataAuthorizer *authorizer,
- SoupMessage *message)
-{
- EGDataGoaAuthorizerPrivate *priv;
- GoaOAuthBased *goa_oauth_based;
- GHashTable *parameters;
- GString *authorization;
- const gchar *consumer_key;
- const gchar *consumer_secret;
- guint ii;
-
- const gchar *oauth_keys[] = {
- "oauth_version",
- "oauth_nonce",
- "oauth_timestamp",
- "oauth_consumer_key",
- "oauth_token",
- "oauth_signature_method",
- "oauth_signature"
- };
-
- /* This MUST be called with the mutex already locked. */
-
- priv = E_GDATA_GOA_AUTHORIZER_GET_PRIVATE (authorizer);
-
- /* 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 (priv->access_token == NULL)
- return;
-
- goa_oauth_based = goa_object_get_oauth_based (priv->goa_object);
- g_return_if_fail (goa_oauth_based != NULL);
-
- consumer_key = goa_oauth_based_get_consumer_key (goa_oauth_based);
- consumer_secret = goa_oauth_based_get_consumer_secret (goa_oauth_based);
-
- parameters = gdata_goa_authorizer_get_oauth_parameters (
- message,
- consumer_key,
- consumer_secret,
- priv->access_token,
- priv->access_token_secret);
-
- authorization = g_string_new ("OAuth ");
-
- for (ii = 0; ii < G_N_ELEMENTS (oauth_keys); ii++) {
- const gchar *key;
- const gchar *val;
-
- key = oauth_keys[ii];
- val = g_hash_table_lookup (parameters, key);
-
- if (ii > 0)
- g_string_append (authorization, ", ");
-
- g_string_append (authorization, key);
- g_string_append_c (authorization, '=');
- g_string_append_c (authorization, '"');
- g_string_append_uri_escaped (authorization, val, NULL, FALSE);
- g_string_append_c (authorization, '"');
- }
-
- /* Use replace here, not append, to make sure
- * there's only one "Authorization" header. */
- soup_message_headers_replace (
- message->request_headers,
- "Authorization", authorization->str);
-
- g_string_free (authorization, TRUE);
- g_hash_table_destroy (parameters);
-
- g_object_unref (goa_oauth_based);
-}
-
-static gboolean
-gdata_goa_authorizer_is_authorized (GDataAuthorizer *authorizer,
- GDataAuthorizationDomain *domain)
-{
- EGDataGoaAuthorizerPrivate *priv;
-
- /* This MUST be called with the mutex already locked. */
-
- if (domain == NULL)
- return TRUE;
-
- priv = E_GDATA_GOA_AUTHORIZER_GET_PRIVATE (authorizer);
- domain = g_hash_table_lookup (priv->authorization_domains, domain);
-
- return (domain != NULL);
-}
-
-static void
-gdata_goa_authorizer_set_goa_object (EGDataGoaAuthorizer *authorizer,
- GoaObject *goa_object)
-{
- g_return_if_fail (GOA_IS_OBJECT (goa_object));
- g_return_if_fail (authorizer->priv->goa_object == NULL);
-
- authorizer->priv->goa_object = g_object_ref (goa_object);
-}
-
-static void
-gdata_goa_authorizer_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id) {
- case PROP_GOA_OBJECT:
- gdata_goa_authorizer_set_goa_object (
- E_GDATA_GOA_AUTHORIZER (object),
- g_value_get_object (value));
- return;
- default:
- g_assert_not_reached ();
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-gdata_goa_authorizer_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id) {
- case PROP_GOA_OBJECT:
- g_value_set_object (
- value,
- e_gdata_goa_authorizer_get_goa_object (
- E_GDATA_GOA_AUTHORIZER (object)));
- return;
- default:
- g_assert_not_reached ();
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-gdata_goa_authorizer_dispose (GObject *object)
-{
- EGDataGoaAuthorizerPrivate *priv;
-
- priv = E_GDATA_GOA_AUTHORIZER_GET_PRIVATE (object);
-
- if (priv->goa_object != NULL) {
- g_object_unref (priv->goa_object);
- priv->goa_object = NULL;
- }
-
- g_hash_table_remove_all (priv->authorization_domains);
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (e_gdata_goa_authorizer_parent_class)->dispose (object);
-}
-
-static void
-gdata_goa_authorizer_finalize (GObject *object)
-{
- EGDataGoaAuthorizerPrivate *priv;
-
- priv = E_GDATA_GOA_AUTHORIZER_GET_PRIVATE (object);
-
- g_free (priv->access_token);
- g_free (priv->access_token_secret);
- g_hash_table_destroy (priv->authorization_domains);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (e_gdata_goa_authorizer_parent_class)->finalize (object);
-}
-
-static void
-gdata_goa_authorizer_constructed (GObject *object)
-{
- EGDataGoaAuthorizerPrivate *priv;
- GType service_type;
- GList *domains;
-
- /* Chain up to parent's constructed() method. */
- G_OBJECT_CLASS (e_gdata_goa_authorizer_parent_class)->
- constructed (object);
-
- priv = E_GDATA_GOA_AUTHORIZER_GET_PRIVATE (object);
-
- /* XXX We would need to generalize this to make the class
- * reusable for other service types, probably by adding
- * a "service-type" constructor property. */
- service_type = GDATA_TYPE_CONTACTS_SERVICE;
- domains = gdata_service_get_authorization_domains (service_type);
-
- while (domains != NULL) {
- g_hash_table_insert (
- priv->authorization_domains,
- g_object_ref (domains->data),
- domains->data);
- domains = g_list_delete_link (domains, domains);
- }
-}
-
-static void
-gdata_goa_authorizer_process_request (GDataAuthorizer *authorizer,
- GDataAuthorizationDomain *domain,
- SoupMessage *message)
-{
- g_mutex_lock (&mutex);
-
- if (gdata_goa_authorizer_is_authorized (authorizer, domain))
- gdata_goa_authorizer_add_authorization (authorizer, message);
-
- g_mutex_unlock (&mutex);
-}
-
-static gboolean
-gdata_goa_authorizer_is_authorized_for_domain (GDataAuthorizer *authorizer,
- GDataAuthorizationDomain *domain)
-{
- gboolean authorized;
-
- g_mutex_lock (&mutex);
-
- authorized = gdata_goa_authorizer_is_authorized (authorizer, domain);
-
- g_mutex_unlock (&mutex);
-
- return authorized;
-}
-
-static gboolean
-gdata_goa_authorizer_refresh_authorization (GDataAuthorizer *authorizer,
- GCancellable *cancellable,
- GError **error)
-{
- EGDataGoaAuthorizerPrivate *priv;
- GoaOAuthBased *goa_oauth_based;
- gboolean success = FALSE;
-
- priv = E_GDATA_GOA_AUTHORIZER_GET_PRIVATE (authorizer);
-
- goa_oauth_based = goa_object_get_oauth_based (priv->goa_object);
- g_return_val_if_fail (goa_oauth_based != NULL, FALSE);
-
- g_mutex_lock (&mutex);
-
- g_free (priv->access_token);
- priv->access_token = NULL;
-
- g_free (priv->access_token_secret);
- priv->access_token_secret = NULL;
-
- success = goa_oauth_based_call_get_access_token_sync (
- goa_oauth_based, &priv->access_token,
- &priv->access_token_secret, NULL, cancellable, error);
-
- g_mutex_unlock (&mutex);
-
- g_object_unref (goa_oauth_based);
-
- return success;
-}
-
-static void
-e_gdata_goa_authorizer_class_init (EGDataGoaAuthorizerClass *class)
-{
- GObjectClass *object_class;
-
- g_type_class_add_private (class, sizeof (EGDataGoaAuthorizerPrivate));
-
- object_class = G_OBJECT_CLASS (class);
- object_class->set_property = gdata_goa_authorizer_set_property;
- object_class->get_property = gdata_goa_authorizer_get_property;
- object_class->dispose = gdata_goa_authorizer_dispose;
- object_class->finalize = gdata_goa_authorizer_finalize;
- object_class->constructed = gdata_goa_authorizer_constructed;
-
- g_object_class_install_property (
- object_class,
- PROP_GOA_OBJECT,
- g_param_spec_object (
- "goa-object",
- "GoaObject",
- "The GOA account to authenticate",
- GOA_TYPE_OBJECT,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-}
-
-static void
-e_gdata_goa_authorizer_interface_init (GDataAuthorizerInterface *interface)
-{
- interface->process_request =
- gdata_goa_authorizer_process_request;
- interface->is_authorized_for_domain =
- gdata_goa_authorizer_is_authorized_for_domain;
- interface->refresh_authorization =
- gdata_goa_authorizer_refresh_authorization;
-}
-
-static void
-e_gdata_goa_authorizer_init (EGDataGoaAuthorizer *authorizer)
-{
- GHashTable *authorization_domains;
-
- authorization_domains = g_hash_table_new_full (
- (GHashFunc) g_direct_hash,
- (GEqualFunc) g_direct_equal,
- (GDestroyNotify) g_object_unref,
- (GDestroyNotify) NULL);
-
- authorizer->priv = E_GDATA_GOA_AUTHORIZER_GET_PRIVATE (authorizer);
- authorizer->priv->authorization_domains = authorization_domains;
-}
-
-EGDataGoaAuthorizer *
-e_gdata_goa_authorizer_new (GoaObject *goa_object)
-{
- g_return_val_if_fail (GOA_IS_OBJECT (goa_object), NULL);
-
- return g_object_new (
- E_TYPE_GDATA_GOA_AUTHORIZER,
- "goa-object", goa_object, NULL);
-}
-
-GoaObject *
-e_gdata_goa_authorizer_get_goa_object (EGDataGoaAuthorizer *authorizer)
-{
- g_return_val_if_fail (E_IS_GDATA_GOA_AUTHORIZER (authorizer), NULL);
-
- return authorizer->priv->goa_object;
-}
+++ /dev/null
-/*
- * e-gdata-goa-authorizer.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/>
- *
- */
-
-#ifndef E_GDATA_GOA_AUTHORIZER_H
-#define E_GDATA_GOA_AUTHORIZER_H
-
-#include <gdata/gdata.h>
-
-#define GOA_API_IS_SUBJECT_TO_CHANGE
-#include <goa/goa.h>
-
-/* Standard GObject macros */
-#define E_TYPE_GDATA_GOA_AUTHORIZER \
- (e_gdata_goa_authorizer_get_type ())
-#define E_GDATA_GOA_AUTHORIZER(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), E_TYPE_GDATA_GOA_AUTHORIZER, EGDataGoaAuthorizer))
-#define E_GDATA_GOA_AUTHORIZER_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), E_TYPE_GDATA_GOA_AUTHORIZER, EGDataGoaAuthorizerClass))
-#define E_IS_GDATA_GOA_AUTHORIZER(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), E_TYPE_GDATA_GOA_AUTHORIZER))
-#define E_IS_GDATA_GOA_AUTHORIZER_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), E_TYPE_GDATA_GOA_AUTHORIZER))
-#define E_GDATA_GOA_AUTHORIZER_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), E_TYPE_GDATA_GOA_AUTHORIZER, EGDataGoaAuthorizerClass))
-
-G_BEGIN_DECLS
-
-typedef struct _EGDataGoaAuthorizer EGDataGoaAuthorizer;
-typedef struct _EGDataGoaAuthorizerClass EGDataGoaAuthorizerClass;
-typedef struct _EGDataGoaAuthorizerPrivate EGDataGoaAuthorizerPrivate;
-
-struct _EGDataGoaAuthorizer {
- GObject parent;
- EGDataGoaAuthorizerPrivate *priv;
-};
-
-struct _EGDataGoaAuthorizerClass {
- GObjectClass parent_class;
-};
-
-GType e_gdata_goa_authorizer_get_type (void);
-EGDataGoaAuthorizer *
- e_gdata_goa_authorizer_new
- (GoaObject *goa_object);
-GoaObject * e_gdata_goa_authorizer_get_goa_object
- (EGDataGoaAuthorizer *authorizer);
-
-#endif /* E_GDATA_GOA_AUTHORIZER_H */
fi
AM_CONDITIONAL(HAVE_GOA, [test x$enable_goa = xyes])
-dnl GoaPasswordBased was introduced in version 3.5.
-if `$PKG_CONFIG --atleast-version=3.5 goa-1.0`; then
- AC_DEFINE(HAVE_GOA_PASSWORD_BASED,1,[Have GoaPasswordBased in goa-1.0])
-fi
-
-dnl The "imap_smtp" provider was introduced around version 3.7.90.
-if `$PKG_CONFIG --atleast-version=3.7.90 goa-1.0`; then
- AC_DEFINE(HAVE_GOA_IMAP_SMTP,1,[Have IMAP/SMTP provider in goa-1.0])
-fi
-
dnl ********************************
dnl Check for Ubuntu Online Accounts
dnl ********************************
module_LTLIBRARIES = module-gnome-online-accounts.la
-# These aren't actually backends, but that's all
-# the installation directory has historically held.
-ecal_backend_LTLIBRARIES = module-data-cal-factory-goa.la
-ebook_backend_LTLIBRARIES = module-data-book-factory-goa.la
-
module_gnome_online_accounts_la_CPPFLAGS = \
$(AM_CPPFLAGS) \
-I$(top_srcdir) \
-module -avoid-version $(NO_UNDEFINED) \
$(NULL)
-module_data_factory_goa_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -I$(top_srcdir) \
- -DG_LOG_DOMAIN=\"module-data-factory-goa\" \
- $(E_BACKEND_CFLAGS) \
- $(CAMEL_CFLAGS) \
- $(SOUP_CFLAGS) \
- $(GOA_CFLAGS) \
- $(NULL)
-
-module_data_factory_goa_SOURCES = \
- module-data-factory-goa.c \
- $(NULL)
-
-module_data_factory_goa_LIBADD = \
- $(top_builddir)/libebackend/libebackend-1.2.la \
- $(top_builddir)/libedataserver/libedataserver-1.2.la \
- $(E_BACKEND_LIBS) \
- $(CAMEL_LIBS) \
- $(SOUP_LIBS) \
- $(GOA_LIBS) \
- $(NULL)
-
-module_data_factory_goa_LDFLAGS = \
- -module -avoid-version $(NO_UNDEFINED) \
- $(NULL)
-
-# Libtool forces us to build separate modules for the address book
-# and calendar factories, even though the modules are identical.
-
-module_data_cal_factory_goa_la_CPPFLAGS = $(module_data_factory_goa_CPPFLAGS)
-module_data_cal_factory_goa_la_SOURCES = $(module_data_factory_goa_SOURCES)
-module_data_cal_factory_goa_la_LIBADD = $(module_data_factory_goa_LIBADD)
-module_data_cal_factory_goa_la_LDFLAGS = $(module_data_factory_goa_LDFLAGS)
-
-module_data_book_factory_goa_la_CPPFLAGS = $(module_data_factory_goa_CPPFLAGS)
-module_data_book_factory_goa_la_SOURCES = $(module_data_factory_goa_SOURCES)
-module_data_book_factory_goa_la_LIBADD = $(module_data_factory_goa_LIBADD)
-module_data_book_factory_goa_la_LDFLAGS = $(module_data_factory_goa_LDFLAGS)
-
-include $(top_srcdir)/git.mk
e_goa_password_based,
E_TYPE_AUTHENTICATION_SESSION)
-#ifdef HAVE_GOA_PASSWORD_BASED
static GoaObject *
e_goa_password_based_ref_account (ESourceRegistryServer *server,
ESource *source,
return match;
}
-#endif /* HAVE_GOA_PASSWORD_BASED */
static EAuthenticationSessionResult
e_goa_password_based_execute_sync (EAuthenticationSession *session,
GCancellable *cancellable,
GError **error)
{
-#ifdef HAVE_GOA_PASSWORD_BASED
EAuthenticationSessionResult session_result;
ESourceAuthenticationResult auth_result;
ESourceAuthenticator *authenticator;
g_free (password);
return session_result;
-#else
- g_return_val_if_reached (E_AUTHENTICATION_SESSION_ERROR);
-#endif /* HAVE_GOA_PASSWORD_BASED */
}
static void
gchar *username;
} AutodiscoverAuthData;
-#ifdef HAVE_GOA_PASSWORD_BASED
static void
ews_autodiscover_data_free (AutodiscoverData *data)
{
return msg;
}
-#endif /* HAVE_GOA_PASSWORD_BASED */
void
goa_ews_autodiscover (GoaObject *goa_object,
GAsyncReadyCallback callback,
gpointer user_data)
{
- /* XXX This function is only called if HAVE_GOA_PASSWORD_BASED
- * is defined, so don't worry about a fallback behavior. */
-#ifdef HAVE_GOA_PASSWORD_BASED
GoaAccount *goa_account;
GoaExchange *goa_exchange;
GoaPasswordBased *goa_password;
g_object_unref (goa_account);
g_object_unref (goa_exchange);
g_object_unref (goa_password);
-#endif /* HAVE_GOA_PASSWORD_BASED */
}
gboolean
+++ /dev/null
-/*
- * module-data-factory-goa.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/>
- *
- */
-
-#include <libebackend/libebackend.h>
-
-#define GOA_API_IS_SUBJECT_TO_CHANGE
-#include <goa/goa.h>
-
-/* Standard GObject macros */
-#define E_TYPE_DATA_FACTORY_GOA \
- (e_data_factory_goa_get_type ())
-#define E_DATA_FACTORY_GOA(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), E_TYPE_DATA_FACTORY_GOA, EDataFactoryGoa))
-
-typedef struct _EDataFactoryGoa EDataFactoryGoa;
-typedef struct _EDataFactoryGoaClass EDataFactoryGoaClass;
-
-struct _EDataFactoryGoa {
- EExtension parent;
-
- GoaClient *goa_client;
- GHashTable *goa_accounts;
-
- gulong account_added_handler_id;
- gulong account_removed_handler_id;
-};
-
-struct _EDataFactoryGoaClass {
- EExtensionClass parent_class;
-};
-
-/* Module Entry Points */
-void e_module_load (GTypeModule *type_module);
-void e_module_unload (GTypeModule *type_module);
-
-/* Forward Declarations */
-GType e_data_factory_goa_get_type (void);
-
-G_DEFINE_DYNAMIC_TYPE (
- EDataFactoryGoa,
- e_data_factory_goa,
- E_TYPE_EXTENSION)
-
-static void
-data_factory_goa_collect_accounts (EDataFactoryGoa *extension)
-{
- GList *list, *link;
-
- g_hash_table_remove_all (extension->goa_accounts);
-
- list = goa_client_get_accounts (extension->goa_client);
-
- for (link = list; link != NULL; link = g_list_next (link)) {
- GoaObject *goa_object;
- GoaAccount *goa_account;
- const gchar *goa_account_id;
-
- goa_object = GOA_OBJECT (link->data);
-
- goa_account = goa_object_peek_account (goa_object);
- goa_account_id = goa_account_get_id (goa_account);
- g_return_if_fail (goa_account_id != NULL);
-
- g_hash_table_insert (
- extension->goa_accounts,
- g_strdup (goa_account_id),
- g_object_ref (goa_object));
- }
-
- g_list_free_full (list, (GDestroyNotify) g_object_unref);
-}
-
-static void
-data_factory_goa_account_added_cb (GoaClient *goa_client,
- GoaObject *goa_object,
- EDataFactoryGoa *extension)
-{
- GoaAccount *goa_account;
- const gchar *goa_account_id;
-
- goa_account = goa_object_peek_account (goa_object);
- goa_account_id = goa_account_get_id (goa_account);
- g_return_if_fail (goa_account_id != NULL);
-
- g_hash_table_insert (
- extension->goa_accounts,
- g_strdup (goa_account_id),
- g_object_ref (goa_object));
-}
-
-static void
-data_factory_goa_account_removed_cb (GoaClient *goa_client,
- GoaObject *goa_object,
- EDataFactoryGoa *extension)
-{
- GoaAccount *goa_account;
- const gchar *goa_account_id;
-
- goa_account = goa_object_peek_account (goa_object);
- goa_account_id = goa_account_get_id (goa_account);
- g_return_if_fail (goa_account_id != NULL);
-
- g_hash_table_remove (extension->goa_accounts, goa_account_id);
-}
-
-static void
-data_factory_goa_backend_created_cb (EDataFactory *factory,
- EBackend *backend,
- EDataFactoryGoa *extension)
-{
- ESource *source;
- GoaObject *goa_object;
- ESourceGoa *goa_extension;
- ESourceRegistry *registry = NULL;
- const gchar *extension_name;
- gchar *goa_account_id;
-
- /* Embed the corresponding GoaObject in the EBackend so the
- * backend can retrieve it by name with g_object_get_data(). */
-
- source = e_backend_get_source (backend);
- extension_name = E_SOURCE_EXTENSION_GOA;
-
- /* XXX Both EDataBookFactory and EDataCalFactory have an
- * ESourceRegistry property, so retrieve it by name. */
- g_object_get (factory, "registry", ®istry, NULL);
- g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
-
- /* Check source and its ancestors for a GOA extension. */
- source = e_source_registry_find_extension (
- registry, source, extension_name);
-
- g_object_unref (registry);
-
- if (source == NULL)
- return;
-
- goa_extension = e_source_get_extension (source, extension_name);
- goa_account_id = e_source_goa_dup_account_id (goa_extension);
- g_return_if_fail (goa_account_id != NULL);
-
- goa_object = g_hash_table_lookup (
- extension->goa_accounts, goa_account_id);
- if (goa_object != NULL) {
- g_object_set_data_full (
- G_OBJECT (backend),
- "GNOME Online Account",
- g_object_ref (goa_object),
- (GDestroyNotify) g_object_unref);
- }
-
- g_free (goa_account_id);
- g_object_unref (source);
-}
-
-static void
-data_factory_goa_dispose (GObject *object)
-{
- EDataFactoryGoa *extension;
-
- extension = E_DATA_FACTORY_GOA (object);
-
- if (extension->goa_client != NULL) {
- g_signal_handler_disconnect (
- extension->goa_client,
- extension->account_added_handler_id);
- g_signal_handler_disconnect (
- extension->goa_client,
- extension->account_removed_handler_id);
- g_object_unref (extension->goa_client);
- extension->goa_client = NULL;
- }
-
- g_hash_table_remove_all (extension->goa_accounts);
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (e_data_factory_goa_parent_class)->dispose (object);
-}
-
-static void
-data_factory_goa_finalize (GObject *object)
-{
- EDataFactoryGoa *extension;
-
- extension = E_DATA_FACTORY_GOA (object);
-
- g_hash_table_destroy (extension->goa_accounts);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (e_data_factory_goa_parent_class)->finalize (object);
-}
-
-static void
-data_factory_goa_constructed (GObject *object)
-{
- EDataFactoryGoa *extension;
- EExtensible *extensible;
- GError *error = NULL;
-
- /* Chain up to parent's constructed() method. */
- G_OBJECT_CLASS (e_data_factory_goa_parent_class)->constructed (object);
-
- extension = E_DATA_FACTORY_GOA (object);
- extensible = e_extension_get_extensible (E_EXTENSION (extension));
-
- /* XXX This blocks to make sure we don't miss any
- * "backend-created" signals from EDataFactory. */
- extension->goa_client = goa_client_new_sync (NULL, &error);
-
- if (extension->goa_client != NULL) {
- gulong handler_id;
-
- data_factory_goa_collect_accounts (extension);
-
- handler_id = g_signal_connect (
- extension->goa_client, "account-added",
- G_CALLBACK (data_factory_goa_account_added_cb),
- extension);
- extension->account_added_handler_id = handler_id;
-
- handler_id = g_signal_connect (
- extension->goa_client, "account-removed",
- G_CALLBACK (data_factory_goa_account_removed_cb),
- extension);
- extension->account_removed_handler_id = handler_id;
-
- g_signal_connect (
- extensible, "backend-created",
- G_CALLBACK (data_factory_goa_backend_created_cb),
- extension);
- } else {
- g_warning (
- "Failed to create a GoaClient: %s",
- error->message);
- g_error_free (error);
- }
-}
-
-static void
-e_data_factory_goa_class_init (EDataFactoryGoaClass *class)
-{
- GObjectClass *object_class;
- EExtensionClass *extension_class;
-
- object_class = G_OBJECT_CLASS (class);
- object_class->dispose = data_factory_goa_dispose;
- object_class->finalize = data_factory_goa_finalize;
- object_class->constructed = data_factory_goa_constructed;
-
- extension_class = E_EXTENSION_CLASS (class);
- extension_class->extensible_type = E_TYPE_DATA_FACTORY;
-}
-
-static void
-e_data_factory_goa_class_finalize (EDataFactoryGoaClass *class)
-{
-}
-
-static void
-e_data_factory_goa_init (EDataFactoryGoa *extension)
-{
- extension->goa_accounts = g_hash_table_new_full (
- (GHashFunc) g_str_hash,
- (GEqualFunc) g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) g_object_unref);
-}
-
-G_MODULE_EXPORT void
-e_module_load (GTypeModule *type_module)
-{
- e_data_factory_goa_register_type (type_module);
-}
-
-G_MODULE_EXPORT void
-e_module_unload (GTypeModule *type_module)
-{
-}
-
return source;
}
-#ifdef HAVE_GOA_PASSWORD_BASED
static void
replace_host (gchar **url,
const gchar *host)
soup_uri_free (uri);
}
-#endif /* HAVE_GOA_PASSWORD_BASED */
static void
gnome_online_accounts_config_exchange (EGnomeOnlineAccounts *extension,
ESource *source,
GoaObject *goa_object)
{
-#ifdef HAVE_GOA_PASSWORD_BASED
GoaExchange *goa_exchange;
ESourceExtension *source_extension;
const gchar *extension_name;
g_free (as_url);
g_free (oab_url);
-#endif /* HAVE_GOA_PASSWORD_BASED */
}
static void
ESource *source,
GoaObject *goa_object)
{
-#ifdef HAVE_GOA_IMAP_SMTP
GoaMail *goa_mail;
ESourceCamel *camel_extension;
ESourceBackend *backend_extension;
CAMEL_NETWORK_SECURITY_METHOD_NONE);
g_object_unref (network_address);
-#endif
}
static void
ESource *source,
GoaObject *goa_object)
{
-#ifdef HAVE_GOA_IMAP_SMTP
GoaMail *goa_mail;
ESourceCamel *camel_extension;
ESourceBackend *backend_extension;
CAMEL_NETWORK_SECURITY_METHOD_NONE);
g_object_unref (network_address);
-#endif
}
static void
GoaObject *goa_object)
{
GoaAccount *goa_account;
+ GoaCalendar *goa_calendar;
+ GoaContacts *goa_contacts;
ESourceExtension *source_extension;
const gchar *extension_name;
- const gchar *provider_type;
- const gchar *backend_name;
goa_account = goa_object_get_account (goa_object);
- provider_type = goa_account_get_provider_type (goa_account);
- backend_name = gnome_online_accounts_get_backend_name (provider_type);
+ goa_calendar = goa_object_get_calendar (goa_object);
+ goa_contacts = goa_object_get_contacts (goa_object);
g_object_bind_property (
goa_account, "presentation-identity",
source_extension, "account-id",
G_BINDING_SYNC_CREATE);
- /* Requires more properties from ownCloud, but these are not
- * available before ownCloud was introduced, thus workaround
- * it with the backend_name check. */
- if (g_strcmp0 (backend_name, "owncloud") == 0) {
- GoaCalendar *goa_calendar;
- GoaContacts *goa_contacts;
-
- goa_calendar = goa_object_get_calendar (goa_object);
- if (goa_calendar) {
- g_object_bind_property (
- goa_calendar, "uri",
- source_extension, "calendar-url",
- G_BINDING_SYNC_CREATE);
- g_object_unref (goa_calendar);
- }
+ if (goa_calendar != NULL) {
+ g_object_bind_property (
+ goa_calendar, "uri",
+ source_extension, "calendar-url",
+ G_BINDING_SYNC_CREATE);
+ }
- goa_contacts = goa_object_get_contacts (goa_object);
- if (goa_contacts) {
- g_object_bind_property (
- goa_contacts, "uri",
- source_extension, "contacts-url",
- G_BINDING_SYNC_CREATE);
- g_object_unref (goa_contacts);
- }
+ if (goa_contacts != NULL) {
+ g_object_bind_property (
+ goa_contacts, "uri",
+ source_extension, "contacts-url",
+ G_BINDING_SYNC_CREATE);
}
extension_name = E_SOURCE_EXTENSION_COLLECTION;
NULL,
NULL, (GDestroyNotify) NULL);
- g_object_unref (goa_account);
+ g_clear_object (&goa_account);
+ g_clear_object (&goa_calendar);
+ g_clear_object (&goa_contacts);
/* Handle optional GOA interfaces. */
gnome_online_accounts_config_exchange (extension, source, goa_object);
e_server_side_source_set_removable (
E_SERVER_SIDE_SOURCE (source), FALSE);
-#ifdef HAVE_GOA_PASSWORD_BASED
if (goa_object_peek_password_based (goa_object) != NULL) {
/* Obtain passwords from the OnlineAccounts service. */
e_server_side_source_set_auth_session_type (
E_SERVER_SIDE_SOURCE (source),
E_TYPE_GOA_PASSWORD_BASED);
}
-#endif /* HAVE_GOA_PASSWORD_BASED */
if (goa_object_peek_oauth2_based (goa_object) != NULL) {
/* This module provides OAuth 2.0 support to the collection.