[evolution-data-server/uoa: 4/4] Prototype a GDataAuthorizer for UOA.



commit f5fafef629b6176234e09d9d502c036da8063277
Author: Matthew Barnes <mbarnes redhat com>
Date:   Mon Nov 12 08:48:36 2012 -0500

    Prototype a GDataAuthorizer for UOA.

 addressbook/backends/google/Makefile.am            |   14 +-
 .../backends/google/e-book-backend-google.c        |   59 +++-
 .../backends/google/e-gdata-uoa-authorizer.c       |  469 ++++++++++++++++++++
 .../backends/google/e-gdata-uoa-authorizer.h       |   69 +++
 4 files changed, 603 insertions(+), 8 deletions(-)
---
diff --git a/addressbook/backends/google/Makefile.am b/addressbook/backends/google/Makefile.am
index 03dc659..5ef68fe 100644
--- a/addressbook/backends/google/Makefile.am
+++ b/addressbook/backends/google/Makefile.am
@@ -8,6 +8,12 @@ GOA_SOURCES = \
 	e-gdata-goa-authorizer.h
 endif
 
+if HAVE_UOA
+UOA_SOURCES = \
+	e-gdata-uoa-authorizer.c \
+	e-gdata-uoa-authorizer.h
+endif
+
 libebookbackendgoogle_la_CPPFLAGS = \
 	$(AM_CPPFLAGS) \
 	-DG_LOG_DOMAIN=\"libebookbackendgoogle\" \
@@ -16,6 +22,8 @@ libebookbackendgoogle_la_CPPFLAGS = \
 	-I$(top_srcdir)/addressbook \
 	-I$(top_builddir)/addressbook \
 	$(EVOLUTION_ADDRESSBOOK_CFLAGS) \
+	$(LIBACCOUNTS_GLIB_CFLAGS) \
+	$(LIBSIGNON_GLIB_CFLAGS) \
 	$(SOUP_CFLAGS) \
 	$(GDATA_CFLAGS) \
 	$(GOA_CFLAGS) \
@@ -29,7 +37,9 @@ libebookbackendgoogle_la_SOURCES = \
 	e-book-backend-google.h \
 	e-book-google-utils.c \
 	e-book-google-utils.h \
-	$(GOA_SOURCES)
+	$(GOA_SOURCES) \
+	$(UOA_SOURCES) \
+	$(NULL)
 
 libebookbackendgoogle_la_LIBADD = \
 	$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \
@@ -37,6 +47,8 @@ libebookbackendgoogle_la_LIBADD = \
 	$(top_builddir)/libedataserver/libedataserver-1.2.la \
 	$(top_builddir)/libebackend/libebackend-1.2.la \
 	$(EVOLUTION_ADDRESSBOOK_LIBS) \
+	$(LIBACCOUNTS_GLIB_LIBS) \
+	$(LIBSIGNON_GLIB_LIBS) \
 	$(SOUP_LIBS) \
 	$(GDATA_LIBS) \
 	$(GOA_LIBS) \
diff --git a/addressbook/backends/google/e-book-backend-google.c b/addressbook/backends/google/e-book-backend-google.c
index e8610d3..fdc077d 100644
--- a/addressbook/backends/google/e-book-backend-google.c
+++ b/addressbook/backends/google/e-book-backend-google.c
@@ -35,6 +35,10 @@
 #include "e-gdata-goa-authorizer.h"
 #endif
 
+#ifdef HAVE_UOA
+#include "e-gdata-uoa-authorizer.h"
+#endif
+
 #define E_BOOK_BACKEND_GOOGLE_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
 	((obj), E_TYPE_BOOK_BACKEND_GOOGLE, EBookBackendGooglePrivate))
@@ -261,14 +265,17 @@ backend_is_authorized (EBookBackend *backend)
 	if (priv->service == NULL)
 		return FALSE;
 
+	/* If we're using OAuth, as both EGDataGoaAuthorizer and
+	 * EGDataUoaAuthorizer do, then as far as the backend is
+	 * concerned it's always authorized. */
 #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
+#ifdef HAVE_UOA
+	if (E_IS_GDATA_UOA_AUTHORIZER (priv->authorizer))
+		return TRUE;
+#endif
 
 	return gdata_service_is_authorized (priv->service);
 }
@@ -976,6 +983,39 @@ request_authorization (EBookBackend *backend,
 	}
 #endif
 
+#ifdef HAVE_UOA
+	/* If this is associated with an Ubuntu Online Account,
+	 * use OAuth authentication instead of ClientLogin. */
+	if (priv->authorizer == NULL) {
+		EGDataUoaAuthorizer *authorizer;
+		AgAccount *ag_account;
+
+		ag_account = g_object_get_data (
+			G_OBJECT (backend), "Ubuntu Online Account");
+		if (AG_IS_ACCOUNT (ag_account)) {
+			GList *service_list;
+
+			service_list = ag_account_list_services_by_type (
+				ag_account, "contacts");
+			if (service_list != NULL) {
+				AgAccountService *ag_account_service;
+				AgService *ag_service;
+
+				ag_service = (AgService *) service_list->data;
+				ag_account_service = ag_account_service_new (
+					ag_account, ag_service);
+				authorizer = e_gdata_uoa_authorizer_new (
+					ag_account_service);
+				priv->authorizer =
+					GDATA_AUTHORIZER (authorizer);
+				g_object_unref (ag_account_service);
+
+				ag_service_list_free (service_list);
+			}
+		}
+	}
+#endif
+
 	if (priv->authorizer == NULL) {
 		GDataClientLoginAuthorizer *authorizer;
 
@@ -993,13 +1033,18 @@ request_authorization (EBookBackend *backend,
 		proxy_settings_changed (priv->proxy, backend);
 	}
 
-#ifdef HAVE_GOA
-	/* If we're using OAuth tokens, then as far as the backend
-	 * is concerned it's always authorized.  The GDataAuthorizer
+	/* If we're using OAuth, as both EGDataGoaAuthorizer and
+	 * EGDataUoaAuthorizer do, then as far as the backend is
+	 * concerned it's always authorized.  The GDataAuthorizer
 	 * will take care of everything in the background. */
+#ifdef HAVE_GOA
 	if (E_IS_GDATA_GOA_AUTHORIZER (priv->authorizer))
 		return TRUE;
 #endif
+#ifdef HAVE_UOA
+	if (E_IS_GDATA_UOA_AUTHORIZER (priv->authorizer))
+		return TRUE;
+#endif
 
 	/* Otherwise it's up to us to obtain a login secret. */
 	return e_backend_authenticate_sync (
diff --git a/addressbook/backends/google/e-gdata-uoa-authorizer.c b/addressbook/backends/google/e-gdata-uoa-authorizer.c
new file mode 100644
index 0000000..e8019f2
--- /dev/null
+++ b/addressbook/backends/google/e-gdata-uoa-authorizer.c
@@ -0,0 +1,469 @@
+/*
+ * e-gdata-uoa-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-uoa-authorizer.h"
+
+/* XXX Missing from <libaccounts-glib/accounts-glib.h> */
+#include <libaccounts-glib/ag-auth-data.h>
+
+#include <libsignon-glib/signon-glib.h>
+#include <libedataserver/libedataserver.h>
+
+#define E_GDATA_UOA_AUTHORIZER_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_GDATA_UOA_AUTHORIZER, EGDataUoaAuthorizerPrivate))
+
+struct _EGDataUoaAuthorizerPrivate {
+
+	/* XXX Assuming AgAccountService is thread-safe (?). */
+	AgAccountService *ag_account_service;
+
+	/* These members are protected by the global mutex. */
+	gchar *access_token;
+	GHashTable *authorization_domains;
+};
+
+enum {
+	PROP_0,
+	PROP_AG_ACCOUNT_SERVICE
+};
+
+/* GDataAuthorizer methods must be thread-safe. */
+static GMutex mutex;
+
+/* Forward Declarations */
+static void	e_gdata_uoa_authorizer_interface_init
+					(GDataAuthorizerInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+	EGDataUoaAuthorizer,
+	e_gdata_uoa_authorizer,
+	G_TYPE_OBJECT,
+	G_IMPLEMENT_INTERFACE (
+		GDATA_TYPE_AUTHORIZER,
+		e_gdata_uoa_authorizer_interface_init))
+
+static void
+gdata_uoa_authorizer_add_authorization (GDataAuthorizer *authorizer,
+                                        SoupMessage *message)
+{
+	EGDataUoaAuthorizerPrivate *priv;
+	GString *authorization;
+
+	/* This MUST be called with the mutex already locked. */
+
+	priv = E_GDATA_UOA_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;
+
+	authorization = g_string_new ("OAuth ");
+	g_string_append (authorization, 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->str);
+
+	g_string_free (authorization, TRUE);
+}
+
+static gboolean
+gdata_uoa_authorizer_is_authorized (GDataAuthorizer *authorizer,
+                                    GDataAuthorizationDomain *domain)
+{
+	EGDataUoaAuthorizerPrivate *priv;
+
+	/* This MUST be called with the mutex already locked. */
+
+	if (domain == NULL)
+		return TRUE;
+
+	priv = E_GDATA_UOA_AUTHORIZER_GET_PRIVATE (authorizer);
+	domain = g_hash_table_lookup (priv->authorization_domains, domain);
+
+	return (domain != NULL);
+}
+
+static void
+gdata_uoa_authorizer_session_process_cb (SignonAuthSession *session,
+                                         GHashTable *session_data,
+                                         const GError *error,
+                                         gpointer user_data)
+{
+	EGDataUoaAuthorizerPrivate *priv;
+	GSimpleAsyncResult *simple = user_data;
+	GAsyncResult *result;
+	GObject *source_object;
+
+	result = G_ASYNC_RESULT (simple);
+
+	/* This returns a new reference. */
+	source_object = g_async_result_get_source_object (result);
+	priv = E_GDATA_UOA_AUTHORIZER_GET_PRIVATE (source_object);
+
+	g_mutex_lock (&mutex);
+
+	g_free (priv->access_token);
+	priv->access_token = NULL;
+
+	if (error == NULL) {
+		GHashTableIter iter;
+		gpointer key, value;
+
+		g_print ("Auth Data:\n");
+
+		/* The hash table values are GValues. */
+		g_hash_table_iter_init (&iter, session_data);
+		while (g_hash_table_iter_next (&iter, &key, &value)) {
+			gchar *str = g_strdup_value_contents (value);
+			g_print ("%s=%s\n", (gchar *) key, str);
+			g_free (str);
+		}
+
+		key = (gpointer) "AccessToken";
+		value = g_hash_table_lookup (session_data, key);
+		priv->access_token = g_value_dup_string (value);
+	} else {
+		g_simple_async_result_set_from_error (simple, error);
+	}
+
+	g_mutex_unlock (&mutex);
+
+	/* Complete with the mutex unlocked. */
+	g_simple_async_result_complete (simple);
+
+	g_object_unref (source_object);
+	g_object_unref (simple);
+
+	/* XXX Apparently we have to unreference this ourselves. */
+	g_object_unref (session);
+}
+
+static void
+gdata_uoa_authorizer_set_ag_account_service (EGDataUoaAuthorizer *authorizer,
+                                             AgAccountService *ag_account_service)
+{
+	g_return_if_fail (AG_IS_ACCOUNT_SERVICE (ag_account_service));
+	g_return_if_fail (authorizer->priv->ag_account_service == NULL);
+
+	authorizer->priv->ag_account_service =
+		g_object_ref (ag_account_service);
+}
+
+static void
+gdata_uoa_authorizer_set_property (GObject *object,
+                                   guint property_id,
+                                   const GValue *value,
+                                   GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_AG_ACCOUNT_SERVICE:
+			gdata_uoa_authorizer_set_ag_account_service (
+				E_GDATA_UOA_AUTHORIZER (object),
+				g_value_get_object (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+gdata_uoa_authorizer_get_property (GObject *object,
+                                   guint property_id,
+                                   GValue *value,
+                                   GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_AG_ACCOUNT_SERVICE:
+			g_value_set_object (
+				value,
+				e_gdata_uoa_authorizer_get_ag_account_service (
+				E_GDATA_UOA_AUTHORIZER (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+gdata_uoa_authorizer_dispose (GObject *object)
+{
+	EGDataUoaAuthorizerPrivate *priv;
+
+	priv = E_GDATA_UOA_AUTHORIZER_GET_PRIVATE (object);
+
+	if (priv->ag_account_service != NULL) {
+		g_object_unref (priv->ag_account_service);
+		priv->ag_account_service = NULL;
+	}
+
+	g_hash_table_remove_all (priv->authorization_domains);
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (e_gdata_uoa_authorizer_parent_class)->dispose (object);
+}
+
+static void
+gdata_uoa_authorizer_finalize (GObject *object)
+{
+	EGDataUoaAuthorizerPrivate *priv;
+
+	priv = E_GDATA_UOA_AUTHORIZER_GET_PRIVATE (object);
+
+	g_free (priv->access_token);
+	g_hash_table_destroy (priv->authorization_domains);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (e_gdata_uoa_authorizer_parent_class)->finalize (object);
+}
+
+static void
+gdata_uoa_authorizer_constructed (GObject *object)
+{
+	EGDataUoaAuthorizerPrivate *priv;
+	GType service_type;
+	GList *domains;
+
+	/* Chain up to parent's constructed() method. */
+	G_OBJECT_CLASS (e_gdata_uoa_authorizer_parent_class)->
+		constructed (object);
+
+	priv = E_GDATA_UOA_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_uoa_authorizer_process_request (GDataAuthorizer *authorizer,
+                                      GDataAuthorizationDomain *domain,
+                                      SoupMessage *message)
+{
+	g_mutex_lock (&mutex);
+
+	if (gdata_uoa_authorizer_is_authorized (authorizer, domain))
+		gdata_uoa_authorizer_add_authorization (authorizer, message);
+
+	g_mutex_unlock (&mutex);
+}
+
+static gboolean
+gdata_uoa_authorizer_is_authorized_for_domain (GDataAuthorizer *authorizer,
+                                               GDataAuthorizationDomain *domain)
+{
+	gboolean authorized;
+
+	g_mutex_lock (&mutex);
+
+	authorized = gdata_uoa_authorizer_is_authorized (authorizer, domain);
+
+	g_mutex_unlock (&mutex);
+
+	return authorized;
+}
+
+static gboolean
+gdata_uoa_authorizer_refresh_authorization (GDataAuthorizer *authorizer,
+                                            GCancellable *cancellable,
+                                            GError **error)
+{
+	EAsyncClosure *closure;
+	GAsyncResult *result;
+	gboolean success;
+
+	closure = e_async_closure_new ();
+
+	gdata_authorizer_refresh_authorization_async (
+		authorizer, cancellable, e_async_closure_callback, closure);
+
+	result = e_async_closure_wait (closure);
+
+	success = gdata_authorizer_refresh_authorization_finish (
+		authorizer, result, error);
+
+	e_async_closure_free (closure);
+
+	return success;
+}
+
+static void
+gdata_uoa_authorizer_refresh_authorization_async (GDataAuthorizer *authorizer,
+                                                  GCancellable *cancellable,
+                                                  GAsyncReadyCallback callback,
+                                                  gpointer user_data)
+{
+	EGDataUoaAuthorizerPrivate *priv;
+	GSimpleAsyncResult *simple;
+	SignonAuthSession *session;
+	AgAuthData *ag_auth_data;
+	GHashTable *parameters;
+	guint credentials_id;
+	const gchar *method;
+	const gchar *mechanism;
+	GError *error = NULL;
+
+	priv = E_GDATA_UOA_AUTHORIZER_GET_PRIVATE (authorizer);
+
+	simple = g_simple_async_result_new (
+		G_OBJECT (authorizer), callback, user_data,
+		gdata_uoa_authorizer_refresh_authorization_async);
+
+	ag_auth_data = ag_account_service_get_auth_data (
+		priv->ag_account_service);
+
+	credentials_id = ag_auth_data_get_credentials_id (ag_auth_data);
+	method = ag_auth_data_get_method (ag_auth_data);
+	mechanism = ag_auth_data_get_mechanism (ag_auth_data);
+	parameters = ag_auth_data_get_parameters (ag_auth_data);
+
+	session = signon_auth_session_new (credentials_id, method, &error);
+
+	/* Sanity check. */
+	g_return_if_fail (
+		((session != NULL) && (error == NULL)) ||
+		((session == NULL) && (error != NULL)));
+
+	if (session != NULL) {
+		/* XXX Bizarre calling semantics.  The async call does
+		 *     not hold its own reference on SignonAuthSession
+		 *     so we have to unreference it from the callback. */
+		signon_auth_session_process (
+			session, parameters, mechanism,
+			gdata_uoa_authorizer_session_process_cb,
+			g_object_ref (simple));
+	} else {
+		g_simple_async_result_take_error (simple, error);
+		g_simple_async_result_complete_in_idle (simple);
+	}
+
+	ag_auth_data_unref (ag_auth_data);
+
+	g_object_unref (simple);
+}
+
+static gboolean
+gdata_uoa_authorizer_refresh_authorization_finish (GDataAuthorizer *authorizer,
+                                                   GAsyncResult *result,
+                                                   GError **error)
+{
+	GSimpleAsyncResult *simple;
+
+	g_return_val_if_fail (
+		g_simple_async_result_is_valid (
+		result, G_OBJECT (authorizer),
+		gdata_uoa_authorizer_refresh_authorization_async), FALSE);
+
+	simple = G_SIMPLE_ASYNC_RESULT (result);
+
+	/* Assume success unless a GError is set. */
+	return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
+e_gdata_uoa_authorizer_class_init (EGDataUoaAuthorizerClass *class)
+{
+	GObjectClass *object_class;
+
+	g_type_class_add_private (class, sizeof (EGDataUoaAuthorizerPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = gdata_uoa_authorizer_set_property;
+	object_class->get_property = gdata_uoa_authorizer_get_property;
+	object_class->dispose = gdata_uoa_authorizer_dispose;
+	object_class->finalize = gdata_uoa_authorizer_finalize;
+	object_class->constructed = gdata_uoa_authorizer_constructed;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_AG_ACCOUNT_SERVICE,
+		g_param_spec_object (
+			"ag-account-service",
+			"AgAccountService",
+			"The UOA account service to authenticate",
+			AG_TYPE_ACCOUNT_SERVICE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT_ONLY |
+			G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_gdata_uoa_authorizer_interface_init (GDataAuthorizerInterface *interface)
+{
+	interface->process_request =
+		gdata_uoa_authorizer_process_request;
+	interface->is_authorized_for_domain =
+		gdata_uoa_authorizer_is_authorized_for_domain;
+	interface->refresh_authorization =
+		gdata_uoa_authorizer_refresh_authorization;
+	interface->refresh_authorization_async =
+		gdata_uoa_authorizer_refresh_authorization_async;
+	interface->refresh_authorization_finish =
+		gdata_uoa_authorizer_refresh_authorization_finish;
+}
+
+static void
+e_gdata_uoa_authorizer_init (EGDataUoaAuthorizer *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_UOA_AUTHORIZER_GET_PRIVATE (authorizer);
+	authorizer->priv->authorization_domains = authorization_domains;
+}
+
+EGDataUoaAuthorizer *
+e_gdata_uoa_authorizer_new (AgAccountService *ag_account_service)
+{
+	g_return_val_if_fail (
+		AG_IS_ACCOUNT_SERVICE (ag_account_service), NULL);
+
+	return g_object_new (
+		E_TYPE_GDATA_UOA_AUTHORIZER,
+		"ag-account-service", ag_account_service, NULL);
+}
+
+AgAccountService *
+e_gdata_uoa_authorizer_get_ag_account_service (EGDataUoaAuthorizer *authorizer)
+{
+	g_return_val_if_fail (E_IS_GDATA_UOA_AUTHORIZER (authorizer), NULL);
+
+	return authorizer->priv->ag_account_service;
+}
+
diff --git a/addressbook/backends/google/e-gdata-uoa-authorizer.h b/addressbook/backends/google/e-gdata-uoa-authorizer.h
new file mode 100644
index 0000000..9118f14
--- /dev/null
+++ b/addressbook/backends/google/e-gdata-uoa-authorizer.h
@@ -0,0 +1,69 @@
+/*
+ * e-gdata-uoa-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_UOA_AUTHORIZER_H
+#define E_GDATA_UOA_AUTHORIZER_H
+
+#include <gdata/gdata.h>
+#include <libaccounts-glib/accounts-glib.h>
+
+/* Standard GObject macros */
+#define E_TYPE_GDATA_UOA_AUTHORIZER \
+	(e_gdata_uoa_authorizer_get_type ())
+#define E_GDATA_UOA_AUTHORIZER(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_GDATA_UOA_AUTHORIZER, EGDataUoaAuthorizer))
+#define E_GDATA_UOA_AUTHORIZER_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_GDATA_UOA_AUTHORIZER, EGDataUoaAuthorizerClass))
+#define E_IS_GDATA_UOA_AUTHORIZER(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_GDATA_UOA_AUTHORIZER))
+#define E_IS_GDATA_UOA_AUTHORIZER_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_GDATA_UOA_AUTHORIZER))
+#define E_GDATA_UOA_AUTHORIZER_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_GDATA_UOA_AUTHORIZER, EGDataUoaAuthorizerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EGDataUoaAuthorizer EGDataUoaAuthorizer;
+typedef struct _EGDataUoaAuthorizerClass EGDataUoaAuthorizerClass;
+typedef struct _EGDataUoaAuthorizerPrivate EGDataUoaAuthorizerPrivate;
+
+struct _EGDataUoaAuthorizer {
+	GObject parent;
+	EGDataUoaAuthorizerPrivate *priv;
+};
+
+struct _EGDataUoaAuthorizerClass {
+	GObjectClass parent_class;
+};
+
+GType		e_gdata_uoa_authorizer_get_type (void);
+EGDataUoaAuthorizer *
+		e_gdata_uoa_authorizer_new
+					(AgAccountService *ag_account_service);
+AgAccountService *
+		e_gdata_uoa_authorizer_get_ag_account_service
+					(EGDataUoaAuthorizer *authorizer);
+
+G_END_DECLS
+
+#endif /* E_GDATA_UOA_AUTHORIZER_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]