[evolution-data-server/uoa: 4/4] Prototype a GDataAuthorizer for UOA.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/uoa: 4/4] Prototype a GDataAuthorizer for UOA.
- Date: Mon, 3 Dec 2012 20:27:37 +0000 (UTC)
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]