From: Alberto Mardegan Date: Thu, 2 Aug 2012 09:55:37 +0000 (+0300) Subject: Use GDBus X-Git-Tag: 1.5~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=293ed4e769fd58a9e78f9da721f3340e0635cd99;p=platform%2Fupstream%2Flibgsignon-glib.git Use GDBus This commit contains a minimal set of changes needed to switch from dbus-glib to GDBus. None of the other issues (such as the code being a mess) are addressed by this commit, in order to make the review simpler. A later commit will completely remove all traces of dbus-glib. --- diff --git a/.gitignore b/.gitignore index 5023561..cb976b2 100644 --- a/.gitignore +++ b/.gitignore @@ -16,8 +16,10 @@ depcomp /docs/reference/xml/ gtk-doc.make install-sh +/libsignon-glib/signon-errors-map.c /libsignon-glib/signon-marshal.c /libsignon-glib/signon-marshal.h +/libsignon-glib/sso-*-gen.* libtool ltmain.sh m4/gtk-doc.m4 @@ -25,6 +27,7 @@ m4/libtool.m4 m4/lt*.m4 missing patches/ +/py-compile stamp-h1 *~ *.cache diff --git a/configure.ac b/configure.ac index 4cb8fba..c513e5e 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,9 @@ GOBJECT_INTROSPECTION_CHECK([1.30.0]) PKG_CHECK_MODULES( DEPS, - glib-2.0 + gio-2.0 >= 2.30 + gio-unix-2.0 + glib-2.0 >= 2.32 gobject-2.0 dbus-1 dbus-glib-1 diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am index 3974b45..e74ba98 100644 --- a/docs/reference/Makefile.am +++ b/docs/reference/Makefile.am @@ -38,8 +38,8 @@ FIXXREF_OPTIONS= # Used for dependencies. The docs will be rebuilt if any of these change. # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c -HFILE_GLOB=$(top_srcdir)/libsignon-glib/*.h -CFILE_GLOB=$(top_srcdir)/libsignon-glib/*.c +HFILE_GLOB=$(top_srcdir)/libsignon-glib/signon-*.h +CFILE_GLOB=$(top_srcdir)/libsignon-glib/signon-*.c # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h @@ -51,7 +51,11 @@ IGNORE_HFILES= \ signon-internals.h \ signon-proxy.h \ signon-utils.h \ - so-marshal.h + so-marshal.h \ + sso-auth-service-gen.h \ + sso-auth-service.h \ + sso-auth-session-gen.h \ + sso-identity-gen.h # Images to copy into HTML directory. # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png diff --git a/libsignon-glib/Makefile.am b/libsignon-glib/Makefile.am index 4136590..5483b21 100644 --- a/libsignon-glib/Makefile.am +++ b/libsignon-glib/Makefile.am @@ -21,6 +21,12 @@ BUILT_SOURCES = \ signon-enum-types.h \ signon-enum-types.c \ signon-errors-enum.c \ + sso-auth-service-gen.c \ + sso-auth-service-gen.h \ + sso-auth-session-gen.c \ + sso-auth-session-gen.h \ + sso-identity-gen.c \ + sso-identity-gen.h \ stamp-signon-enum-types.h CLEANFILES = $(BUILT_SOURCES) @@ -42,7 +48,9 @@ libsignon_glib_la_SOURCES = \ signon-proxy.h \ signon-proxy.c \ signon-utils.h \ - signon-utils.c + signon-utils.c \ + sso-auth-service.c \ + sso-auth-service.h nodist_libsignon_glib_la_SOURCES = \ $(BUILT_SOURCES) @@ -70,6 +78,18 @@ signon-client-glib-gen.h: $(DBUS_INTERFACES_DIR)/com.google.code.AccountsSSO.Sin dbus-binding-tool --prefix=signon-client-glib --mode=glib-client $< \ | sed s/com_google_code_AccountsSSO_SingleSignOn/SSO/g > $@ +sso-auth-service-gen.h sso-auth-service-gen.c: $(DBUS_INTERFACES_DIR)/com.google.code.AccountsSSO.SingleSignOn.AuthService.xml + gdbus-codegen --generate-c-code sso-auth-service-gen \ + --annotate "com.google.code.AccountsSSO.SingleSignOn.AuthService" org.gtk.GDBus.C.Name SsoAuthService $< + +sso-auth-session-gen.h sso-auth-session-gen.c: $(DBUS_INTERFACES_DIR)/com.google.code.AccountsSSO.SingleSignOn.AuthSession.xml + gdbus-codegen --generate-c-code sso-auth-session-gen \ + --annotate "com.google.code.AccountsSSO.SingleSignOn.AuthSession" org.gtk.GDBus.C.Name SsoAuthSession $< + +sso-identity-gen.h sso-identity-gen.c: $(DBUS_INTERFACES_DIR)/com.google.code.AccountsSSO.SingleSignOn.Identity.xml + gdbus-codegen --generate-c-code sso-identity-gen \ + --annotate "com.google.code.AccountsSSO.SingleSignOn.Identity" org.gtk.GDBus.C.Name SsoIdentity $< + signon-auth-session-client-glib-gen.h: $(DBUS_INTERFACES_DIR)/com.google.code.AccountsSSO.SingleSignOn.AuthSession.xml dbus-binding-tool --prefix=signon-auth-session-client-glib --mode=glib-client $< \ | sed s/com_google_code_AccountsSSO_SingleSignOn/SSO/g > $@ @@ -128,6 +148,16 @@ signon-errors-enum.c: Makefile signon-errors.h && cp xgen-getc signon-errors-enum.c \ && rm -f xgen-getc +signon-errors-map.c: Makefile signon-errors.h + ( cd $(srcdir) && \ + echo "static const GDBusErrorEntry signon_error_entries[] = {" && \ + grep "^ *SIGNON_ERROR_" signon-errors.h | \ + sed -e 's/SIGNON_ERROR_\([A-Z_0-9]*\).*/{ SIGNON_ERROR_\1, SIGNOND_\1_ERR_NAME },/' && \ + echo -e "};\n" ) > signon-errors-map.c + +CLEANFILES += signon-errors-map.c +signon-errors.$(OBJEXT): signon-errors-map.c + EXTRA_DIST = signon-marshal.list \ stamp-signon-enum-types.h diff --git a/libsignon-glib/signon-auth-service.c b/libsignon-glib/signon-auth-service.c index 6645375..444227b 100644 --- a/libsignon-glib/signon-auth-service.c +++ b/libsignon-glib/signon-auth-service.c @@ -4,8 +4,9 @@ * This file is part of libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. + * Copyright (C) 2012 Canonical Ltd. * - * Contact: Alberto Mardegan + * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -31,17 +32,18 @@ */ #include "signon-auth-service.h" -#include "signon-client-glib-gen.h" -#include "signon-internals.h" #include "signon-errors.h" -#include "signon-proxy.h" +#include "signon-internals.h" +#include "sso-auth-service.h" +#include #include G_DEFINE_TYPE (SignonAuthService, signon_auth_service, G_TYPE_OBJECT); struct _SignonAuthServicePrivate { - SignonProxy *signon_proxy; + SsoAuthService *proxy; + GCancellable *cancellable; }; typedef struct _MethodCbData @@ -70,21 +72,9 @@ signon_auth_service_init (SignonAuthService *auth_service) SignonAuthServicePrivate); auth_service->priv = priv; - priv->signon_proxy = signon_proxy_new (); -} - -static GObject * -signon_auth_service_constructor (GType type, guint n_params, - GObjectConstructParam *params) -{ - GObjectClass *object_class = - (GObjectClass *)signon_auth_service_parent_class; - GObject *object; - - object = object_class->constructor (type, n_params, params); - g_return_val_if_fail (SIGNON_IS_AUTH_SERVICE (object), NULL); - - return object; + /* Create the proxy */ + priv->cancellable = g_cancellable_new (); + priv->proxy = sso_auth_service_get_instance (); } static void @@ -93,10 +83,16 @@ signon_auth_service_dispose (GObject *object) SignonAuthService *auth_service = SIGNON_AUTH_SERVICE (object); SignonAuthServicePrivate *priv = auth_service->priv; - if (priv->signon_proxy) + if (priv->cancellable) + { + g_cancellable_cancel (priv->cancellable); + priv->cancellable = NULL; + } + + if (priv->proxy) { - g_object_unref (priv->signon_proxy); - priv->signon_proxy = NULL; + g_object_unref (priv->proxy); + priv->proxy = NULL; } G_OBJECT_CLASS (signon_auth_service_parent_class)->dispose (object); @@ -116,7 +112,6 @@ signon_auth_service_class_init (SignonAuthServiceClass *klass) g_type_class_add_private (object_class, sizeof (SignonAuthServicePrivate)); object_class->dispose = signon_auth_service_dispose; - object_class->constructor = signon_auth_service_constructor; object_class->finalize = signon_auth_service_finalize; } @@ -134,46 +129,46 @@ signon_auth_service_new () } static void -auth_query_methods_cb (DBusGProxy *proxy, char **value, - GError *error, gpointer user_data) +auth_query_methods_cb (GObject *object, GAsyncResult *res, + gpointer user_data) { + SsoAuthService *proxy = SSO_AUTH_SERVICE (object); MethodCbData *data = (MethodCbData*)user_data; - GError *new_error = NULL; - g_return_if_fail (data != NULL); + gchar **value = NULL; + GError *error = NULL; - if (error) - { - new_error = _signon_errors_get_error_from_dbus (error); - value = NULL; - } + g_return_if_fail (data != NULL); + sso_auth_service_call_query_methods_finish (proxy, &value, + res, &error); (data->cb) - (data->service, value, new_error, data->userdata); + (data->service, value, error, data->userdata); - if (new_error) - g_error_free (new_error); + g_free (value); + if (error) + g_error_free (error); g_slice_free (MethodCbData, data); } static void -auth_query_mechanisms_cb (DBusGProxy *proxy, char **value, - GError *error, gpointer user_data) +auth_query_mechanisms_cb (GObject *object, GAsyncResult *res, + gpointer user_data) { + SsoAuthService *proxy = SSO_AUTH_SERVICE (object); MechanismCbData *data = (MechanismCbData*) user_data; - GError *new_error = NULL; - g_return_if_fail (data != NULL); + gchar **value = NULL; + GError *error = NULL; - if (error) - { - new_error = _signon_errors_get_error_from_dbus (error); - value = NULL; - } + g_return_if_fail (data != NULL); + sso_auth_service_call_query_mechanisms_finish (proxy, &value, + res, &error); (data->cb) - (data->service, data->method, value, new_error, data->userdata); + (data->service, data->method, value, error, data->userdata); - if (new_error) - g_error_free (new_error); + g_free (value); + if (error) + g_error_free (error); g_free (data->method); g_slice_free (MechanismCbData, data); } @@ -201,10 +196,10 @@ signon_auth_service_query_methods (SignonAuthService *auth_service, SignonQueryMethodsCb cb, gpointer user_data) { + SignonAuthServicePrivate *priv; + g_return_if_fail (SIGNON_IS_AUTH_SERVICE (auth_service)); g_return_if_fail (cb != NULL); - - SignonAuthServicePrivate *priv; priv = SIGNON_AUTH_SERVICE_PRIV (auth_service); MethodCbData *cb_data; @@ -213,7 +208,8 @@ signon_auth_service_query_methods (SignonAuthService *auth_service, cb_data->cb = cb; cb_data->userdata = user_data; - SSO_AuthService_query_methods_async (DBUS_G_PROXY(priv->signon_proxy), + sso_auth_service_call_query_methods (priv->proxy, + priv->cancellable, auth_query_methods_cb, cb_data); } @@ -245,8 +241,11 @@ signon_auth_service_query_mechanisms (SignonAuthService *auth_service, SignonQueryMechanismCb cb, gpointer user_data) { + SignonAuthServicePrivate *priv; + g_return_if_fail (SIGNON_IS_AUTH_SERVICE (auth_service)); g_return_if_fail (cb != NULL); + priv = SIGNON_AUTH_SERVICE_PRIV (auth_service); MechanismCbData *cb_data; cb_data = g_slice_new (MechanismCbData); @@ -255,11 +254,9 @@ signon_auth_service_query_mechanisms (SignonAuthService *auth_service, cb_data->userdata = user_data; cb_data->method = g_strdup (method); - SignonAuthServicePrivate *priv; - priv = SIGNON_AUTH_SERVICE_PRIV (auth_service); - - SSO_AuthService_query_mechanisms_async (DBUS_G_PROXY(priv->signon_proxy), + sso_auth_service_call_query_mechanisms (priv->proxy, method, + priv->cancellable, auth_query_mechanisms_cb, cb_data); } diff --git a/libsignon-glib/signon-auth-session.c b/libsignon-glib/signon-auth-session.c index 837be06..f54072b 100644 --- a/libsignon-glib/signon-auth-session.c +++ b/libsignon-glib/signon-auth-session.c @@ -4,6 +4,7 @@ * This file is part of libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. + * Copyright (C) 2012 Canonical Ltd. * * Contact: Alberto Mardegan * @@ -40,12 +41,11 @@ #include "signon-internals.h" #include "signon-auth-session.h" #include "signon-dbus-queue.h" -#include "signon-client-glib-gen.h" -#include "signon-auth-session-client-glib-gen.h" #include "signon-errors.h" #include "signon-marshal.h" -#include "signon-proxy.h" #include "signon-utils.h" +#include "sso-auth-service.h" +#include "sso-auth-session-gen.h" /* SignonAuthSessionState is defined in signoncommon.h */ #include @@ -65,17 +65,20 @@ static gchar auth_session_process_pending_message[] = "The request is added to q struct _SignonAuthSessionPrivate { - DBusGProxy *proxy; - SignonProxy *signon_proxy; + SsoAuthSession *proxy; + SsoAuthService *auth_service_proxy; + GCancellable *cancellable; gint id; gchar *method_name; - DBusGProxyCall *pending_call_get_path; - + gboolean registering; gboolean busy; gboolean canceled; gboolean dispose_has_run; + + guint signal_state_changed; + guint signal_unregistered; }; typedef struct _AuthSessionQueryAvailableMechanismsData @@ -86,7 +89,7 @@ typedef struct _AuthSessionQueryAvailableMechanismsData typedef struct _AuthSessionProcessData { - GHashTable *session_data; + GVariant *session_data; gchar *mechanism; gpointer cb_data; } AuthSessionProcessData; @@ -109,42 +112,18 @@ typedef struct _AuthSessionProcessCbData #define SIGNON_AUTH_SESSION_GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SIGNON_TYPE_AUTH_SESSION, SignonAuthSessionPrivate)) -static void auth_session_state_changed_cb (DBusGProxy *proxy, gint state, gchar *message, gpointer user_data); -static void auth_session_remote_object_destroyed_cb (DBusGProxy *proxy, gpointer user_data); +static void auth_session_state_changed_cb (GDBusProxy *proxy, gint state, gchar *message, gpointer user_data); +static void auth_session_remote_object_destroyed_cb (GDBusProxy *proxy, gpointer user_data); static gboolean auth_session_priv_init (SignonAuthSession *self, guint id, const gchar *method_name, GError **err); -static void auth_session_get_object_path_reply (DBusGProxy *proxy, char *object_path, GError *error, gpointer userdata); static void auth_session_set_id_ready_cb (gpointer object, const GError *error, gpointer user_data); static void auth_session_query_available_mechanisms_ready_cb (gpointer object, const GError *error, gpointer user_data); static void auth_session_process_ready_cb (gpointer object, const GError *error, gpointer user_data); static void auth_session_cancel_ready_cb (gpointer object, const GError *error, gpointer user_data); -static void auth_session_query_mechanisms_reply (DBusGProxy *proxy, char **object_path, GError *error, gpointer userdata); -static void auth_session_process_reply (DBusGProxy *proxy, GHashTable *session_data, GError *error, gpointer userdata); - static void auth_session_check_remote_object(SignonAuthSession *self); -DBusGProxyCall* -_SSO_AuthSession_process_async_timeout (DBusGProxy *proxy, - const GHashTable* IN_sessionDataVa, - const char * IN_mechanism, - SSO_AuthSession_process_reply callback, - gpointer userdata, - int timeout) - -{ - DBusGAsyncData *stuff; - stuff = g_slice_new (DBusGAsyncData); - stuff->cb = G_CALLBACK (callback); - stuff->userdata = userdata; - return dbus_g_proxy_begin_call_with_timeout (proxy, "process", - SSO_AuthSession_process_async_callback, stuff, - _dbus_glib_async_data_free, timeout, - dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), - IN_sessionDataVa, G_TYPE_STRING, IN_mechanism, G_TYPE_INVALID); -} - static GQuark auth_session_object_quark () { @@ -160,7 +139,8 @@ static void signon_auth_session_init (SignonAuthSession *self) { self->priv = SIGNON_AUTH_SESSION_GET_PRIV (self); - self->priv->signon_proxy = signon_proxy_new (); + self->priv->auth_service_proxy = sso_auth_service_get_instance (); + self->priv->cancellable = g_cancellable_new (); } static void @@ -174,29 +154,25 @@ signon_auth_session_dispose (GObject *object) if (priv->dispose_has_run) return; - GError *err = NULL; + if (priv->cancellable) + { + g_cancellable_cancel (priv->cancellable); + priv->cancellable = NULL; + } if (priv->proxy) { - dbus_g_proxy_disconnect_signal (priv->proxy, - "stateChanged", - G_CALLBACK (auth_session_state_changed_cb), - self); - dbus_g_proxy_disconnect_signal (priv->proxy, - "unregistered", - G_CALLBACK (auth_session_remote_object_destroyed_cb), - self); - - SSO_AuthSession_object_unref (priv->proxy, &err); + g_signal_handler_disconnect (priv->proxy, priv->signal_state_changed); + g_signal_handler_disconnect (priv->proxy, priv->signal_unregistered); g_object_unref (priv->proxy); priv->proxy = NULL; } - if (priv->signon_proxy) + if (priv->auth_service_proxy) { - g_object_unref (priv->signon_proxy); - priv->signon_proxy = NULL; + g_object_unref (priv->auth_service_proxy); + priv->auth_service_proxy = NULL; } G_OBJECT_CLASS (signon_auth_session_parent_class)->dispose (object); @@ -298,7 +274,10 @@ auth_session_set_id_ready_cb (gpointer object, gint id = GPOINTER_TO_INT(user_data); GError *err = NULL; - SSO_AuthSession_set_id (priv->proxy, id, &err); + sso_auth_session_call_set_id_sync (priv->proxy, + id, + priv->cancellable, + &err); priv->id = id; if (err) @@ -438,7 +417,8 @@ signon_auth_session_process (SignonAuthSession *self, AuthSessionProcessData *operation_data = g_slice_new0 (AuthSessionProcessData); - operation_data->session_data = signon_copy_variant_map (session_data); + operation_data->session_data = + signon_hash_table_to_variant (session_data); operation_data->mechanism = g_strdup (mechanism); operation_data->cb_data = cb_data; @@ -478,15 +458,25 @@ signon_auth_session_cancel (SignonAuthSession *self) } static void -auth_session_get_object_path_reply (DBusGProxy *proxy, char *object_path, - GError *error, gpointer userdata) +auth_session_get_object_path_reply (GObject *object, GAsyncResult *res, + gpointer userdata) { + SsoAuthService *proxy = SSO_AUTH_SERVICE (object); + gchar *object_path = NULL; + GError *error = NULL; + + sso_auth_service_call_get_auth_session_object_path_finish (proxy, + &object_path, + res, + &error); + SIGNON_RETURN_IF_CANCELLED (error); + g_return_if_fail (SIGNON_IS_AUTH_SESSION (userdata)); SignonAuthSession *self = SIGNON_AUTH_SESSION (userdata); SignonAuthSessionPrivate *priv = self->priv; g_return_if_fail (priv != NULL); - priv->pending_call_get_path = NULL; + priv->registering = FALSE; if (!g_strcmp0(object_path, "") || error) { if (error) @@ -498,41 +488,41 @@ auth_session_get_object_path_reply (DBusGProxy *proxy, char *object_path, } else { - priv->proxy = dbus_g_proxy_new_from_proxy (DBUS_G_PROXY (priv->signon_proxy), - SIGNOND_AUTH_SESSION_INTERFACE, - object_path); - - dbus_g_object_register_marshaller (_signon_marshal_VOID__INT_STRING, - G_TYPE_NONE, - G_TYPE_INT, - G_TYPE_STRING, - G_TYPE_INVALID); - - dbus_g_proxy_add_signal (priv->proxy, - "stateChanged", - G_TYPE_INT, - G_TYPE_STRING, - G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (priv->proxy, - "stateChanged", - G_CALLBACK (auth_session_state_changed_cb), - self, - NULL); - - dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - G_TYPE_INVALID); - - dbus_g_proxy_add_signal (priv->proxy, - "unregistered", - G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (priv->proxy, - "unregistered", - G_CALLBACK (auth_session_remote_object_destroyed_cb), - self, - NULL); + GDBusConnection *connection; + const gchar *bus_name; + GError *proxy_error = NULL; + + connection = g_dbus_proxy_get_connection ((GDBusProxy *)proxy); + bus_name = g_dbus_proxy_get_name ((GDBusProxy *)proxy); + + priv->proxy = + sso_auth_session_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + bus_name, + object_path, + priv->cancellable, + &proxy_error); + if (G_UNLIKELY (proxy_error != NULL)) + { + g_warning ("Failed to initialize AuthSession proxy: %s", + proxy_error->message); + g_clear_error (&proxy_error); + } + + g_dbus_proxy_set_default_timeout ((GDBusProxy *)priv->proxy, + G_MAXINT); + + priv->signal_state_changed = + g_signal_connect (priv->proxy, + "state-changed", + G_CALLBACK (auth_session_state_changed_cb), + self); + + priv->signal_unregistered = + g_signal_connect (priv->proxy, + "unregistered", + G_CALLBACK (auth_session_remote_object_destroyed_cb), + self); } DEBUG ("Object path received: %s", object_path); @@ -541,7 +531,7 @@ auth_session_get_object_path_reply (DBusGProxy *proxy, char *object_path, } static void -auth_session_state_changed_cb (DBusGProxy *proxy, +auth_session_state_changed_cb (GDBusProxy *proxy, gint state, gchar *message, gpointer user_data) @@ -556,7 +546,7 @@ auth_session_state_changed_cb (DBusGProxy *proxy, message); } -static void auth_session_remote_object_destroyed_cb (DBusGProxy *proxy, +static void auth_session_remote_object_destroyed_cb (GDBusProxy *proxy, gpointer user_data) { g_return_if_fail (SIGNON_IS_AUTH_SESSION (user_data)); @@ -593,67 +583,78 @@ auth_session_priv_init (SignonAuthSession *self, guint id, priv->id = id; priv->method_name = g_strdup (method_name); - priv->pending_call_get_path = - SSO_AuthService_get_auth_session_object_path_async ( - DBUS_G_PROXY (priv->signon_proxy), - (const guint)id, - method_name, - auth_session_get_object_path_reply, - self); + priv->registering = TRUE; + sso_auth_service_call_get_auth_session_object_path ( + priv->auth_service_proxy, + id, + method_name, + priv->cancellable, + auth_session_get_object_path_reply, + self); priv->busy = FALSE; priv->canceled = FALSE; return TRUE; } static void -auth_session_query_mechanisms_reply (DBusGProxy *proxy, gchar **mechanisms, - GError *error, gpointer userdata) +auth_session_query_mechanisms_reply (GObject *object, GAsyncResult *res, + gpointer userdata) { - GError *new_error = NULL; + SsoAuthSession *proxy = SSO_AUTH_SESSION (object); + gchar **mechanisms = NULL; + GError *error = NULL; AuthSessionQueryAvailableMechanismsCbData *cb_data = (AuthSessionQueryAvailableMechanismsCbData *)userdata; g_return_if_fail (cb_data != NULL); - if (error) - { - new_error = _signon_errors_get_error_from_dbus (error); - mechanisms = NULL; - } + sso_auth_session_call_query_available_mechanisms_finish (proxy, + &mechanisms, + res, + &error); + SIGNON_RETURN_IF_CANCELLED (error); + (cb_data->cb) (cb_data->self, mechanisms, error, cb_data->user_data); - (cb_data->cb) - (cb_data->self, mechanisms, new_error, cb_data->user_data); - - if (new_error) - g_error_free (new_error); + if (error) + g_error_free (error); g_slice_free (AuthSessionQueryAvailableMechanismsCbData, cb_data); } static void -auth_session_process_reply (DBusGProxy *proxy, GHashTable *session_data, - GError *error, gpointer userdata) +auth_session_process_reply (GObject *object, GAsyncResult *res, + gpointer userdata) { - GError *new_error = NULL; + SsoAuthSession *proxy = SSO_AUTH_SESSION (object); + GVariant *session_data_variant; + GHashTable *session_data = NULL; + GError *error = NULL; AuthSessionProcessCbData *cb_data = (AuthSessionProcessCbData *)userdata; g_return_if_fail (cb_data != NULL); g_return_if_fail (cb_data->self != NULL); g_return_if_fail (cb_data->self->priv != NULL); - if (error) + sso_auth_session_call_process_finish (proxy, + &session_data_variant, + res, + &error); + SIGNON_RETURN_IF_CANCELLED (error); + + if (!error) { - new_error = _signon_errors_get_error_from_dbus (error); - session_data = NULL; + session_data = signon_hash_table_from_variant (session_data_variant); } /* Keep a reference on the SignonAuthSession, because the callback * code might unreference it, while we still need it. */ g_object_ref (cb_data->self); - (cb_data->cb) - (cb_data->self, session_data, new_error, cb_data->user_data); + (cb_data->cb) (cb_data->self, session_data, error, cb_data->user_data); cb_data->self->priv->busy = FALSE; - if (new_error) - g_error_free (new_error); + if (error) + g_error_free (error); + + if (session_data != NULL) + g_hash_table_unref (session_data); g_object_unref (cb_data->self); g_slice_free (AuthSessionProcessCbData, cb_data); @@ -685,9 +686,10 @@ auth_session_query_available_mechanisms_ready_cb (gpointer object, const GError else { g_return_if_fail (priv->proxy != NULL); - SSO_AuthSession_query_available_mechanisms_async ( + sso_auth_session_call_query_available_mechanisms ( priv->proxy, (const char **)operation_data->wanted_mechanisms, + priv->cancellable, auth_session_query_mechanisms_reply, cb_data); @@ -741,14 +743,12 @@ auth_session_process_ready_cb (gpointer object, const GError *error, gpointer us { g_return_if_fail (priv->proxy != NULL); - _SSO_AuthSession_process_async_timeout (priv->proxy, + sso_auth_session_call_process (priv->proxy, operation_data->session_data, operation_data->mechanism, + priv->cancellable, auth_session_process_reply, - cb_data, - 0x7FFFFFFF); - - g_hash_table_destroy (operation_data->session_data); + cb_data); g_signal_emit (self, auth_session_signals[STATE_CHANGED], @@ -778,7 +778,9 @@ auth_session_cancel_ready_cb (gpointer object, const GError *error, gpointer use DEBUG("error during initialization"); } else if (priv->proxy && priv->busy) - SSO_AuthSession_cancel (priv->proxy, NULL); + sso_auth_session_call_cancel_sync (priv->proxy, + priv->cancellable, + NULL); priv->busy = FALSE; priv->canceled = FALSE; @@ -794,16 +796,18 @@ auth_session_check_remote_object(SignonAuthSession *self) if (priv->proxy != NULL) return; - g_return_if_fail (priv->signon_proxy != NULL); + g_return_if_fail (priv->auth_service_proxy != NULL); - if (priv->pending_call_get_path == NULL) + if (!priv->registering) { - priv->pending_call_get_path = - SSO_AuthService_get_auth_session_object_path_async (DBUS_G_PROXY (priv->signon_proxy), - (const guint)priv->id, - priv->method_name, - auth_session_get_object_path_reply, - self); + priv->registering = TRUE; + sso_auth_service_call_get_auth_session_object_path ( + priv->auth_service_proxy, + priv->id, + priv->method_name, + priv->cancellable, + auth_session_get_object_path_reply, + self); } } diff --git a/libsignon-glib/signon-errors.c b/libsignon-glib/signon-errors.c index bc5e4ae..622e2d6 100644 --- a/libsignon-glib/signon-errors.c +++ b/libsignon-glib/signon-errors.c @@ -4,8 +4,9 @@ * This file is part of libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. + * Copyright (C) 2012 Canonical Ltd. * - * Contact: Alberto Mardegan + * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -25,7 +26,9 @@ #include "signon-errors.h" #include "signon-enum-types.h" #include "signon-internals.h" +#include "signoncommon.h" #include +#include /** * SECTION:signon-errors @@ -36,20 +39,16 @@ */ #define SIGNON_ERROR_PREFIX SIGNOND_SERVICE_PREFIX ".Error" +#include "signon-errors-map.c" + GQuark signon_error_quark (void) { - static gsize quark = 0; - - if (g_once_init_enter (&quark)) - { - GQuark domain = g_quark_from_static_string ("signon-errors"); - - g_assert (sizeof (GQuark) <= sizeof (gsize)); + static volatile gsize quark = 0; - g_type_init (); - dbus_g_error_domain_register (domain, SIGNON_ERROR_PREFIX, SIGNON_TYPE_ERROR); - g_once_init_leave (&quark, domain); - } + g_dbus_error_register_error_domain ("signon-errors", + &quark, + signon_error_entries, + G_N_ELEMENTS (signon_error_entries)); return (GQuark) quark; } diff --git a/libsignon-glib/signon-identity-info.c b/libsignon-glib/signon-identity-info.c index 2a16381..e0f5d76 100644 --- a/libsignon-glib/signon-identity-info.c +++ b/libsignon-glib/signon-identity-info.c @@ -4,7 +4,7 @@ * This file is part of libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. - * Copyright (C) 2011 Canonical Ltd. + * Copyright (C) 2011-2012 Canonical Ltd. * * Contact: Alberto Mardegan * @@ -41,6 +41,12 @@ G_DEFINE_BOXED_TYPE (SignonIdentityInfo, signon_identity_info, (GBoxedFreeFunc)signon_identity_info_free); +static GVariant * +signon_variant_new_string (const gchar *string) +{ + return g_variant_new_string (string != NULL ? string : ""); +} + static const gchar *identity_info_get_secret (const SignonIdentityInfo *info) { g_return_val_if_fail (info != NULL, NULL); @@ -238,6 +244,153 @@ signon_identity_info_to_hash_table (const SignonIdentityInfo *self) return map; } +SignonIdentityInfo * +signon_identity_info_new_from_variant (GVariant *variant) +{ + GVariant *method_map; + + if (!variant) + return NULL; + + SignonIdentityInfo *info = signon_identity_info_new (); + + DEBUG("%s: ", G_STRFUNC); + + g_variant_lookup (variant, + SIGNOND_IDENTITY_INFO_ID, + "u", + &info->id); + + g_variant_lookup (variant, + SIGNOND_IDENTITY_INFO_USERNAME, + "s", + &info->username); + + if (g_variant_lookup (variant, + SIGNOND_IDENTITY_INFO_SECRET, + "s", + &info->secret)) + { + g_variant_lookup (variant, + SIGNOND_IDENTITY_INFO_STORESECRET, + "b", + &info->store_secret); + } + + g_variant_lookup (variant, + SIGNOND_IDENTITY_INFO_CAPTION, + "s", + &info->caption); + + g_variant_lookup (variant, + SIGNOND_IDENTITY_INFO_REALMS, + "^as", + &info->realms); + + /* get the methods */ + if (g_variant_lookup (variant, + SIGNOND_IDENTITY_INFO_AUTHMETHODS, + "@a{sas}", + &method_map)) + { + GVariantIter iter; + gchar *method; + gchar **mechanisms; + + g_variant_iter_init (&iter, method_map); + while (g_variant_iter_next (&iter, "{s^as}", &method, &mechanisms)) + { + g_hash_table_insert (info->methods, method, mechanisms); + } + } + + g_variant_lookup (variant, + SIGNOND_IDENTITY_INFO_ACL, + "^as", + &info->access_control_list); + + g_variant_lookup (variant, + SIGNOND_IDENTITY_INFO_TYPE, + "u", + &info->type); + + return info; +} + +GVariant * +signon_identity_info_to_variant (const SignonIdentityInfo *self) +{ + GVariantBuilder builder; + GVariantBuilder method_builder; + GVariant *method_map; + GHashTableIter iter; + const gchar *method; + const gchar **mechanisms; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + + g_variant_builder_add (&builder, "{sv}", + SIGNOND_IDENTITY_INFO_ID, + g_variant_new_uint32 (self->id)); + + g_variant_builder_add (&builder, "{sv}", + SIGNOND_IDENTITY_INFO_USERNAME, + signon_variant_new_string (self->username)); + + g_variant_builder_add (&builder, "{sv}", + SIGNOND_IDENTITY_INFO_SECRET, + signon_variant_new_string (self->secret)); + + g_variant_builder_add (&builder, "{sv}", + SIGNOND_IDENTITY_INFO_CAPTION, + signon_variant_new_string (self->caption)); + + g_variant_builder_add (&builder, "{sv}", + SIGNOND_IDENTITY_INFO_STORESECRET, + g_variant_new_boolean (self->store_secret)); + + g_variant_builder_init (&method_builder, + (const GVariantType *)"a{sas}"); + g_hash_table_iter_init (&iter, self->methods); + while (g_hash_table_iter_next (&iter, + (gpointer)&method, + (gpointer)&mechanisms)) + { + g_variant_builder_add (&method_builder, "{s^as}", + method, + mechanisms); + } + method_map = g_variant_builder_end (&method_builder); + + g_variant_builder_add (&builder, "{sv}", + SIGNOND_IDENTITY_INFO_AUTHMETHODS, + method_map); + + if (self->realms != NULL) + { + g_variant_builder_add (&builder, "{sv}", + SIGNOND_IDENTITY_INFO_REALMS, + g_variant_new_strv ((const gchar * const *) + self->realms, + -1)); + } + + if (self->access_control_list != NULL) + { + g_variant_builder_add (&builder, "{sv}", + SIGNOND_IDENTITY_INFO_ACL, + g_variant_new_strv ((const gchar * const *) + self->access_control_list, + -1)); + } + + g_variant_builder_add (&builder, "{sv}", + SIGNOND_IDENTITY_INFO_TYPE, + g_variant_new_int32 (self->type)); + + return g_variant_builder_end (&builder); +} + /* * Public methods: */ diff --git a/libsignon-glib/signon-identity.c b/libsignon-glib/signon-identity.c index 0a39dc2..b30ca12 100644 --- a/libsignon-glib/signon-identity.c +++ b/libsignon-glib/signon-identity.c @@ -4,8 +4,9 @@ * This file is part of libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. + * Copyright (C) 2012 Canonical Ltd. * - * Contact: Alberto Mardegan + * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -33,12 +34,11 @@ #include "signon-identity.h" #include "signon-auth-session.h" #include "signon-internals.h" -#include "signon-proxy.h" -#include "signon-identity-glib-gen.h" -#include "signon-client-glib-gen.h" #include "signon-dbus-queue.h" #include "signon-utils.h" #include "signon-errors.h" +#include "sso-auth-service.h" +#include "sso-identity-gen.h" G_DEFINE_TYPE (SignonIdentity, signon_identity, G_TYPE_OBJECT); @@ -62,8 +62,9 @@ typedef enum { struct _SignonIdentityPrivate { - DBusGProxy *proxy; - SignonProxy *signon_proxy; + SsoIdentity *proxy; + SsoAuthService *auth_service_proxy; + GCancellable *cancellable; SignonIdentityInfo *identity_info; @@ -75,6 +76,9 @@ struct _SignonIdentityPrivate gboolean updated; guint id; + + guint signal_info_updated; + guint signal_unregistered; }; enum { @@ -95,7 +99,7 @@ typedef struct _IdentityStoreCredentialsCbData typedef struct _IdentityStoreCredentialsData { - GHashTable *info_map; + GVariant *info_variant; gpointer cb_data; } IdentityStoreCredentialsData; @@ -142,30 +146,19 @@ typedef struct _IdentityVoidData gpointer cb_data; } IdentityVoidData; -static void identity_registered (SignonIdentity *identity, DBusGProxy *proxy, char *object_path, - GHashTable *identity_data, GError *error); static void identity_check_remote_registration (SignonIdentity *self); -static void identity_new_cb (DBusGProxy *proxy, char *objectPath, GError *error, gpointer userdata); -static void identity_new_from_db_cb (DBusGProxy *proxy, char *objectPath, GHashTable *identityData, - GError *error, gpointer userdata); static void identity_store_credentials_ready_cb (gpointer object, const GError *error, gpointer user_data); -static void identity_store_credentials_reply (DBusGProxy *proxy, guint id, GError *error, gpointer userdata); +static void identity_store_credentials_reply (GObject *object, + GAsyncResult *res, + gpointer userdata); static void identity_session_object_destroyed_cb (gpointer data, GObject *where_the_session_was); static void identity_verify_data (SignonIdentity *self, const gchar *data_to_send, gint operation, SignonIdentityVerifyCb cb, gpointer user_data); static void identity_verify_ready_cb (gpointer object, const GError *error, gpointer user_data); -static void identity_verify_reply (DBusGProxy *proxy, gboolean valid, GError *error, gpointer userdata); -static void identity_signout_reply (DBusGProxy *proxy, gboolean result, GError *error, gpointer userdata); -static void identity_removed_reply (DBusGProxy *proxy, GError *error, gpointer userdata); -static void identity_info_reply(DBusGProxy *proxy, - GHashTable *identity_data, - GError *error, gpointer userdata); static void identity_remove_ready_cb (gpointer object, const GError *error, gpointer user_data); static void identity_signout_ready_cb (gpointer object, const GError *error, gpointer user_data); static void identity_info_ready_cb (gpointer object, const GError *error, gpointer user_data); -static void identity_state_changed_cb (DBusGProxy *proxy, gint state, gpointer user_data); -static void identity_remote_object_destroyed_cb(DBusGProxy *proxy, gpointer user_data); static void identity_process_signout (SignonIdentity *self); static void identity_process_updated (SignonIdentity *self); @@ -223,16 +216,20 @@ signon_identity_get_property (GObject *object, static void signon_identity_init (SignonIdentity *identity) { + SignonIdentityPrivate *priv; + identity->priv = G_TYPE_INSTANCE_GET_PRIVATE (identity, SIGNON_TYPE_IDENTITY, SignonIdentityPrivate); - identity->priv->signon_proxy = signon_proxy_new(); - identity->priv->registration_state = NOT_REGISTERED; + priv = identity->priv; + priv->auth_service_proxy = sso_auth_service_get_instance(); + priv->cancellable = g_cancellable_new (); + priv->registration_state = NOT_REGISTERED; - identity->priv->removed = FALSE; - identity->priv->signed_out = FALSE; - identity->priv->updated = FALSE; + priv->removed = FALSE; + priv->signed_out = FALSE; + priv->updated = FALSE; } static void @@ -241,28 +238,24 @@ signon_identity_dispose (GObject *object) SignonIdentity *identity = SIGNON_IDENTITY (object); SignonIdentityPrivate *priv = identity->priv; + if (priv->cancellable) + { + g_cancellable_cancel (priv->cancellable); + priv->cancellable = NULL; + } + if (priv->identity_info) { signon_identity_info_free (priv->identity_info); priv->identity_info = NULL; } - if (priv->signon_proxy) - { - g_object_unref (priv->signon_proxy); - priv->signon_proxy = NULL; - } + g_clear_object (&priv->auth_service_proxy); if (priv->proxy) { - dbus_g_proxy_disconnect_signal (priv->proxy, - "infoUpdated", - G_CALLBACK (identity_state_changed_cb), - identity); - dbus_g_proxy_disconnect_signal (priv->proxy, - "unregistered", - G_CALLBACK (identity_remote_object_destroyed_cb), - identity); + g_signal_handler_disconnect (priv->proxy, priv->signal_info_updated); + g_signal_handler_disconnect (priv->proxy, priv->signal_unregistered); g_object_unref (priv->proxy); priv->proxy = NULL; } @@ -322,7 +315,7 @@ signon_identity_class_init (SignonIdentityClass *klass) } static void -identity_state_changed_cb (DBusGProxy *proxy, +identity_state_changed_cb (GDBusProxy *proxy, gint state, gpointer user_data) { @@ -348,7 +341,7 @@ identity_state_changed_cb (DBusGProxy *proxy, } static void -identity_remote_object_destroyed_cb(DBusGProxy *proxy, +identity_remote_object_destroyed_cb(GDBusProxy *proxy, gpointer user_data) { g_return_if_fail (SIGNON_IS_IDENTITY (user_data)); @@ -378,8 +371,8 @@ identity_remote_object_destroyed_cb(DBusGProxy *proxy, } static void -identity_registered (SignonIdentity *identity, DBusGProxy *proxy, - char *object_path, GHashTable *identity_data, +identity_registered (SignonIdentity *identity, + char *object_path, GVariant *identity_data, GError *error) { g_return_if_fail (SIGNON_IS_IDENTITY (identity)); @@ -391,6 +384,11 @@ identity_registered (SignonIdentity *identity, DBusGProxy *proxy, if (!error) { + GDBusConnection *connection; + GDBusProxy *auth_service_proxy; + const gchar *bus_name; + GError *proxy_error = NULL; + DEBUG("%s: %s", G_STRFUNC, object_path); /* * TODO: as Aurel will finalize the code polishing so we will @@ -398,46 +396,42 @@ identity_registered (SignonIdentity *identity, DBusGProxy *proxy, * */ g_return_if_fail (priv->proxy == NULL); - priv->proxy = dbus_g_proxy_new_from_proxy (DBUS_G_PROXY (priv->signon_proxy), - SIGNOND_IDENTITY_INTERFACE, - object_path); - - dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, - G_TYPE_INT, - G_TYPE_INVALID); - - dbus_g_proxy_add_signal (priv->proxy, - "infoUpdated", - G_TYPE_INT, - G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (priv->proxy, - "infoUpdated", - G_CALLBACK (identity_state_changed_cb), - identity, - NULL); - - dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - G_TYPE_INVALID); + auth_service_proxy = (GDBusProxy *)priv->auth_service_proxy; + connection = g_dbus_proxy_get_connection (auth_service_proxy); + bus_name = g_dbus_proxy_get_name (auth_service_proxy); + + priv->proxy = + sso_identity_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + bus_name, + object_path, + priv->cancellable, + &proxy_error); + if (G_UNLIKELY (proxy_error != NULL)) + { + g_warning ("Failed to initialize Identity proxy: %s", + proxy_error->message); + g_clear_error (&proxy_error); + } - dbus_g_proxy_add_signal (priv->proxy, - "unregistered", - G_TYPE_INVALID); + priv->signal_info_updated = + g_signal_connect (priv->proxy, + "info-updated", + G_CALLBACK (identity_state_changed_cb), + identity); - dbus_g_proxy_connect_signal (priv->proxy, - "unregistered", - G_CALLBACK (identity_remote_object_destroyed_cb), - identity, - NULL); + priv->signal_unregistered = + g_signal_connect (priv->proxy, + "unregistered", + G_CALLBACK (identity_remote_object_destroyed_cb), + identity); if (identity_data) { DEBUG("%s: ", G_STRFUNC); priv->identity_info = - signon_identity_info_new_from_hash_table (identity_data); - g_hash_table_unref (identity_data); + signon_identity_info_new_from_variant (identity_data); + g_variant_unref (identity_data); } priv->updated = TRUE; @@ -479,30 +473,45 @@ signon_identity_get_last_error (SignonIdentity *identity) } static void -identity_new_cb (DBusGProxy *proxy, - char *object_path, - GError *error, +identity_new_cb (GObject *object, GAsyncResult *res, gpointer userdata) { SignonIdentity *identity = (SignonIdentity*)userdata; + SsoAuthService *proxy = SSO_AUTH_SERVICE (object); + gchar *object_path; + GError *error = NULL; + g_return_if_fail (identity != NULL); - DEBUG ("%s %d", G_STRFUNC, __LINE__); - GError *new_error = _signon_errors_get_error_from_dbus (error); - identity_registered (identity, proxy, object_path, NULL, new_error); + DEBUG ("%s", G_STRFUNC); + + sso_auth_service_call_register_new_identity_finish (proxy, + &object_path, + res, + &error); + SIGNON_RETURN_IF_CANCELLED (error); + identity_registered (identity, object_path, NULL, error); } static void -identity_new_from_db_cb (DBusGProxy *proxy, - char *objectPath, - GHashTable *identityData, - GError *error, +identity_new_from_db_cb (GObject *object, GAsyncResult *res, gpointer userdata) { SignonIdentity *identity = (SignonIdentity*)userdata; + SsoAuthService *proxy = SSO_AUTH_SERVICE (object); + gchar *object_path; + GVariant *identity_data; + GError *error = NULL; + g_return_if_fail (identity != NULL); - DEBUG ("%s %d", G_STRFUNC, __LINE__); - GError *new_error = _signon_errors_get_error_from_dbus (error); - identity_registered (identity, proxy, objectPath, identityData, new_error); + DEBUG ("%s", G_STRFUNC); + + sso_auth_service_call_get_identity_finish (proxy, + &object_path, + &identity_data, + res, + &error); + SIGNON_RETURN_IF_CANCELLED (error); + identity_registered (identity, object_path, identity_data, error); } static void @@ -517,11 +526,16 @@ identity_check_remote_registration (SignonIdentity *self) return; if (priv->id != 0) - SSO_AuthService_get_identity_async - (DBUS_G_PROXY (priv->signon_proxy), priv->id, identity_new_from_db_cb, self); + sso_auth_service_call_get_identity (priv->auth_service_proxy, + priv->id, + priv->cancellable, + identity_new_from_db_cb, + self); else - SSO_AuthService_register_new_identity_async - (DBUS_G_PROXY (priv->signon_proxy), identity_new_cb, self); + sso_auth_service_call_register_new_identity (priv->auth_service_proxy, + priv->cancellable, + identity_new_cb, + self); priv->registration_state = PENDING_REGISTRATION; } @@ -533,7 +547,7 @@ identity_check_remote_registration (SignonIdentity *self) * Construct an identity object associated with an existing identity * record. * - * Returns: an instance of an #SignonIdentity. + * Returns: an instance of a #SignonIdentity. */ SignonIdentity* signon_identity_new_from_db (guint32 id) @@ -687,7 +701,7 @@ signon_identity_store_credentials_with_info(SignonIdentity *self, cb_data->user_data = user_data; operation_data = g_slice_new0 (IdentityStoreCredentialsData); - operation_data->info_map = signon_identity_info_to_hash_table (info); + operation_data->info_variant = signon_identity_info_to_variant (info); operation_data->cb_data = cb_data; identity_check_remote_registration (self); @@ -775,25 +789,24 @@ identity_store_credentials_ready_cb (gpointer object, const GError *error, gpoin { g_return_if_fail (priv->proxy != NULL); - SSO_Identity_store_async( - priv->proxy, - operation_data->info_map, - identity_store_credentials_reply, - cb_data); + sso_identity_call_store (priv->proxy, + operation_data->info_variant, + priv->cancellable, + identity_store_credentials_reply, + cb_data); } - g_hash_table_unref (operation_data->info_map); g_slice_free (IdentityStoreCredentialsData, operation_data); } static void -identity_store_credentials_reply (DBusGProxy *proxy, - guint id, - GError *error, +identity_store_credentials_reply (GObject *object, GAsyncResult *res, gpointer userdata) { - GError *new_error = NULL; IdentityStoreCredentialsCbData *cb_data = (IdentityStoreCredentialsCbData *)userdata; + SsoIdentity *proxy = SSO_IDENTITY (object); + guint id; + GError *error = NULL; g_return_if_fail (cb_data != NULL); g_return_if_fail (cb_data->self != NULL); @@ -801,11 +814,12 @@ identity_store_credentials_reply (DBusGProxy *proxy, SignonIdentityPrivate *priv = cb_data->self->priv; - new_error = _signon_errors_get_error_from_dbus (error); + sso_identity_call_store_finish (proxy, &id, res, &error); + SIGNON_RETURN_IF_CANCELLED (error); if (cb_data->cb) { - (cb_data->cb) (cb_data->self, id, new_error, cb_data->user_data); + (cb_data->cb) (cb_data->self, id, error, cb_data->user_data); } if (error == NULL) @@ -831,30 +845,31 @@ identity_store_credentials_reply (DBusGProxy *proxy, priv->removed = FALSE; } - g_clear_error(&new_error); + g_clear_error(&error); g_slice_free (IdentityStoreCredentialsCbData, cb_data); } static void -identity_verify_reply (DBusGProxy *proxy, - gboolean valid, - GError *error, +identity_verify_reply (GObject *object, GAsyncResult *res, gpointer userdata) { - GError *new_error = NULL; + SsoIdentity *proxy = SSO_IDENTITY (object); + gboolean valid; + GError *error = NULL; IdentityVerifyCbData *cb_data = (IdentityVerifyCbData *)userdata; g_return_if_fail (cb_data != NULL); g_return_if_fail (cb_data->self != NULL); - new_error = _signon_errors_get_error_from_dbus (error); + sso_identity_call_verify_secret_finish (proxy, &valid, res, &error); + SIGNON_RETURN_IF_CANCELLED (error); if (cb_data->cb) { - (cb_data->cb) (cb_data->self, valid, new_error, cb_data->user_data); + (cb_data->cb) (cb_data->self, valid, error, cb_data->user_data); } - g_clear_error(&new_error); + g_clear_error(&error); g_slice_free (IdentityVerifyCbData, cb_data); } @@ -908,10 +923,11 @@ identity_verify_ready_cb (gpointer object, const GError *error, gpointer user_da switch (operation_data->operation) { case SIGNON_VERIFY_SECRET: - SSO_Identity_verify_secret_async (priv->proxy, - operation_data->data_to_send, - identity_verify_reply, - cb_data); + sso_identity_call_verify_secret (priv->proxy, + operation_data->data_to_send, + priv->cancellable, + identity_verify_reply, + cb_data); break; default: g_critical ("Wrong operation code"); }; @@ -1042,59 +1058,63 @@ identity_process_signout(SignonIdentity *self) * in ANY CASE * */ static void -identity_signout_reply (DBusGProxy *proxy, - gboolean result, - GError *error, +identity_signout_reply (GObject *object, GAsyncResult *res, gpointer userdata) { - GError *new_error = NULL; + SsoIdentity *proxy = SSO_IDENTITY (object); + gboolean result; + GError *error = NULL; IdentityVoidCbData *cb_data = (IdentityVoidCbData *)userdata; g_return_if_fail (cb_data != NULL); g_return_if_fail (cb_data->self != NULL); g_return_if_fail (cb_data->self->priv != NULL); - new_error = _signon_errors_get_error_from_dbus (error); + sso_identity_call_sign_out_finish (proxy, &result, res, &error); + SIGNON_RETURN_IF_CANCELLED (error); if (cb_data->cb) { - (cb_data->cb) (cb_data->self, new_error, cb_data->user_data); + (cb_data->cb) (cb_data->self, error, cb_data->user_data); } - g_clear_error(&new_error); + g_clear_error(&error); g_slice_free (IdentityVoidCbData, cb_data); } static void -identity_removed_reply (DBusGProxy *proxy, - GError *error, +identity_removed_reply (GObject *object, GAsyncResult *res, gpointer userdata) { - GError *new_error = NULL; + SsoIdentity *proxy = SSO_IDENTITY (object); + GError *error = NULL; IdentityVoidCbData *cb_data = (IdentityVoidCbData *)userdata; g_return_if_fail (cb_data != NULL); g_return_if_fail (cb_data->self != NULL); g_return_if_fail (cb_data->self->priv != NULL); - new_error = _signon_errors_get_error_from_dbus (error); + sso_identity_call_remove_finish (proxy, res, &error); + SIGNON_RETURN_IF_CANCELLED (error); if (cb_data->cb) { - (cb_data->cb) (cb_data->self, new_error, cb_data->user_data); + (cb_data->cb) (cb_data->self, error, cb_data->user_data); } - g_clear_error(&new_error); + g_clear_error(&error); g_slice_free (IdentityVoidCbData, cb_data); } static void -identity_info_reply(DBusGProxy *proxy, GHashTable *identity_data, - GError *error, gpointer userdata) +identity_info_reply(GObject *object, GAsyncResult *res, + gpointer userdata) { + SsoIdentity *proxy = SSO_IDENTITY (object); + GVariant *identity_data = NULL; DEBUG ("%d %s", __LINE__, __func__); - GError *new_error = NULL; + GError *error = NULL; IdentityInfoCbData *cb_data = (IdentityInfoCbData *)userdata; g_return_if_fail (cb_data != NULL); @@ -1103,17 +1123,19 @@ identity_info_reply(DBusGProxy *proxy, GHashTable *identity_data, SignonIdentityPrivate *priv = cb_data->self->priv; - new_error = _signon_errors_get_error_from_dbus (error); + sso_identity_call_get_info_finish (proxy, &identity_data, res, &error); + SIGNON_RETURN_IF_CANCELLED (error); priv->identity_info = - signon_identity_info_new_from_hash_table (identity_data); - g_hash_table_unref (identity_data); + signon_identity_info_new_from_variant (identity_data); + if (identity_data != NULL) + g_variant_unref (identity_data); if (cb_data->cb) { - (cb_data->cb) (cb_data->self, priv->identity_info, new_error, cb_data->user_data); + (cb_data->cb) (cb_data->self, priv->identity_info, error, cb_data->user_data); } - g_clear_error(&new_error); + g_clear_error(&error); g_slice_free (IdentityInfoCbData, cb_data); priv->updated = TRUE; @@ -1164,9 +1186,10 @@ identity_info_ready_cb(gpointer object, const GError *error, gpointer user_data) else if (priv->updated == FALSE) { g_return_if_fail (priv->proxy != NULL); - SSO_Identity_get_info_async (priv->proxy, - identity_info_reply, - cb_data); + sso_identity_call_get_info (priv->proxy, + priv->cancellable, + identity_info_reply, + cb_data); } else { @@ -1222,10 +1245,10 @@ identity_signout_ready_cb(gpointer object, const GError *error, gpointer user_da else { g_return_if_fail (priv->proxy != NULL); - SSO_Identity_sign_out_async( - priv->proxy, - identity_signout_reply, - cb_data); + sso_identity_call_sign_out (priv->proxy, + priv->cancellable, + identity_signout_reply, + cb_data); } } @@ -1268,10 +1291,10 @@ identity_remove_ready_cb(gpointer object, const GError *error, gpointer user_dat else { g_return_if_fail (priv->proxy != NULL); - SSO_Identity_remove_async( - priv->proxy, - identity_removed_reply, - cb_data); + sso_identity_call_remove (priv->proxy, + priv->cancellable, + identity_removed_reply, + cb_data); } } diff --git a/libsignon-glib/signon-internals.h b/libsignon-glib/signon-internals.h index ba4b650..8fefbce 100644 --- a/libsignon-glib/signon-internals.h +++ b/libsignon-glib/signon-internals.h @@ -4,8 +4,9 @@ * This file is part of libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. + * Copyright (C) 2012 Canonical Ltd. * - * Contact: Alberto Mardegan + * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -60,6 +61,14 @@ G_GNUC_INTERNAL SignonIdentityInfo * signon_identity_info_new_from_hash_table (GHashTable *map); +G_GNUC_INTERNAL +SignonIdentityInfo * +signon_identity_info_new_from_variant (GVariant *variant); + +G_GNUC_INTERNAL +GVariant * +signon_identity_info_to_variant (const SignonIdentityInfo *self); + G_GNUC_INTERNAL GHashTable * signon_identity_info_to_hash_table (const SignonIdentityInfo *self); diff --git a/libsignon-glib/signon-utils.c b/libsignon-glib/signon-utils.c index ba09001..4321af2 100644 --- a/libsignon-glib/signon-utils.c +++ b/libsignon-glib/signon-utils.c @@ -4,8 +4,9 @@ * This file is part of libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. + * Copyright (C) 2012 Canonical Ltd. * - * Contact: Alberto Mardegan + * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -22,6 +23,28 @@ * 02110-1301 USA */ #include "signon-utils.h" +#include + +static const GVariantType * +signon_gtype_to_variant_type (GType type) +{ + switch (type) + { + case G_TYPE_STRING: return G_VARIANT_TYPE_STRING; + case G_TYPE_BOOLEAN: return G_VARIANT_TYPE_BOOLEAN; + case G_TYPE_UCHAR: return G_VARIANT_TYPE_BYTE; + case G_TYPE_INT: return G_VARIANT_TYPE_INT32; + case G_TYPE_UINT: return G_VARIANT_TYPE_UINT32; + case G_TYPE_INT64: return G_VARIANT_TYPE_INT64; + case G_TYPE_UINT64: return G_VARIANT_TYPE_UINT64; + case G_TYPE_DOUBLE: return G_VARIANT_TYPE_DOUBLE; + default: + if (type == G_TYPE_STRV) return G_VARIANT_TYPE_STRING_ARRAY; + + g_critical ("Unsupported type %s", g_type_name (type)); + return NULL; + } +} GValue * signon_gvalue_new (GType type) @@ -31,17 +54,6 @@ signon_gvalue_new (GType type) return value; } -static void signon_gvalue_copy (gchar *key, - GValue *value, - GHashTable *dest) -{ - GValue *copy_value = g_slice_new0 (GValue); - g_value_init (copy_value, value->g_type); - g_value_copy (value, copy_value); - - g_hash_table_insert (dest, g_strdup(key), copy_value); -} - void signon_gvalue_free (gpointer val) { g_return_if_fail (G_IS_VALUE(val)); @@ -51,19 +63,50 @@ void signon_gvalue_free (gpointer val) g_slice_free (GValue, value); } -GHashTable *signon_copy_variant_map (const GHashTable *old_map) +GHashTable *signon_hash_table_from_variant (GVariant *variant) { - if (old_map == NULL) - return NULL; + GHashTable *hash_table; + GVariantIter iter; + GVariant *value; + gchar *key; + + if (variant == NULL) return NULL; + + hash_table = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + signon_gvalue_free); + g_variant_iter_init (&iter, variant); + while (g_variant_iter_next (&iter, "{sv}", &key, &value)) + { + GValue *val = g_slice_new0 (GValue); + g_dbus_gvariant_to_gvalue (value, val); + g_variant_unref (value); + + g_hash_table_insert (hash_table, key, val); + } + return hash_table; +} + +GVariant *signon_hash_table_to_variant (const GHashTable *hash_table) +{ + GVariantBuilder builder; + GHashTableIter iter; + const gchar *key; + const GValue *value; - GHashTable *new_map = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - signon_gvalue_free); + if (hash_table == NULL) return NULL; - g_hash_table_foreach ((GHashTable*)old_map, - (GHFunc)signon_gvalue_copy, - (gpointer)new_map); + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); - return new_map; + g_hash_table_iter_init (&iter, (GHashTable *)hash_table); + while (g_hash_table_iter_next (&iter, (gpointer)&key, (gpointer)&value)) + { + GVariant *val; + const GVariantType *type; + type = signon_gtype_to_variant_type (G_VALUE_TYPE (value)); + val = g_dbus_gvalue_to_gvariant (value, type); + g_variant_builder_add (&builder, "{sv}", key, val); + } + return g_variant_builder_end (&builder); } diff --git a/libsignon-glib/signon-utils.h b/libsignon-glib/signon-utils.h index d73f633..b3cf092 100644 --- a/libsignon-glib/signon-utils.h +++ b/libsignon-glib/signon-utils.h @@ -4,8 +4,9 @@ * This file is part of libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. + * Copyright (C) 2012 Canonical Ltd. * - * Contact: Alberto Mardegan + * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -26,12 +27,23 @@ #include -G_GNUC_INTERNAL -GHashTable *signon_copy_variant_map (const GHashTable *old_map); +#define SIGNON_RETURN_IF_CANCELLED(error) \ + if (error != NULL && \ + error->domain == G_IO_ERROR && \ + error->code == G_IO_ERROR_CANCELLED) \ + { \ + g_error_free (error); \ + return; \ + } G_GNUC_INTERNAL GValue *signon_gvalue_new (GType type); G_GNUC_INTERNAL void signon_gvalue_free (gpointer val); +G_GNUC_INTERNAL +GHashTable *signon_hash_table_from_variant (GVariant *variant); +G_GNUC_INTERNAL +GVariant *signon_hash_table_to_variant (const GHashTable *hash_table); + #endif //_SIGNON_UTILS_H_ diff --git a/libsignon-glib/sso-auth-service.c b/libsignon-glib/sso-auth-service.c new file mode 100644 index 0000000..2a70798 --- /dev/null +++ b/libsignon-glib/sso-auth-service.c @@ -0,0 +1,105 @@ +/* vi: set et sw=4 ts=4 cino=t0,(0: */ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of libsignon-glib + * + * Copyright (C) 2012 Canonical Ltd. + * + * Contact: Alberto Mardegan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include "signon-errors.h" +#include "signon-internals.h" +#include "sso-auth-service.h" + +static GHashTable *thread_objects = NULL; +static GMutex map_mutex; + +static SsoAuthService * +get_singleton () +{ + SsoAuthService *object = NULL; + + g_mutex_lock (&map_mutex); + + if (thread_objects != NULL) + { + GWeakRef *ref; + ref = g_hash_table_lookup (thread_objects, g_thread_self ()); + if (ref != NULL) + { + object = g_weak_ref_get (ref); + } + } + + g_mutex_unlock (&map_mutex); + return object; +} + +static void +set_singleton (SsoAuthService *object) +{ + g_return_if_fail (IS_SSO_AUTH_SERVICE (object)); + + g_mutex_lock (&map_mutex); + + if (thread_objects == NULL) + { + thread_objects = g_hash_table_new (g_direct_hash, g_direct_equal); + } + + if (object != NULL) + { + GWeakRef *ref = g_slice_new (GWeakRef); + g_weak_ref_init (ref, object); + g_hash_table_insert (thread_objects, g_thread_self (), ref); + } + + g_mutex_unlock (&map_mutex); +} + +SsoAuthService * +sso_auth_service_get_instance () +{ + SsoAuthService *sso_auth_service; + GError *error = NULL; + + sso_auth_service = get_singleton (); + if (sso_auth_service != NULL) return sso_auth_service; + + /* Create the object */ + sso_auth_service = + sso_auth_service_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + SIGNOND_SERVICE, + SIGNOND_DAEMON_OBJECTPATH, + NULL, + &error); + if (G_LIKELY (error == NULL)) { + set_singleton (sso_auth_service); + } + else + { + g_warning ("Couldn't activate signond: %s", error->message); + g_clear_error (&error); + } + + /* While at it, register the error mapping with GDBus */ + signon_error_quark (); + + return sso_auth_service; +} diff --git a/libsignon-glib/sso-auth-service.h b/libsignon-glib/sso-auth-service.h new file mode 100644 index 0000000..69f83d5 --- /dev/null +++ b/libsignon-glib/sso-auth-service.h @@ -0,0 +1,37 @@ +/* vi: set et sw=4 ts=4 cino=t0,(0: */ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of libsignon-glib + * + * Copyright (C) 2012 Canonical Ltd. + * + * Contact: Alberto Mardegan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef _SSO_AUTH_SERVICE_H_ +#define _SSO_AUTH_SERVICE_H_ + +#include "sso-auth-service-gen.h" + +G_BEGIN_DECLS + +G_GNUC_INTERNAL +SsoAuthService *sso_auth_service_get_instance (); + +G_END_DECLS + +#endif /* _SSO_AUTH_SERVICE_H_ */ diff --git a/tests/check_signon.c b/tests/check_signon.c index b5a483b..485e742 100644 --- a/tests/check_signon.c +++ b/tests/check_signon.c @@ -171,6 +171,19 @@ signon_query_mechanisms_cb (SignonAuthService *auth_service, gchar *method, g_main_loop_quit (main_loop); } +static void +signon_query_mechanisms_cb_fail (SignonAuthService *auth_service, + gchar *method, + gchar **mechanisms, + GError *error, gpointer user_data) +{ + fail_unless (error != NULL); + fail_unless (mechanisms == NULL); + fail_unless (error->domain == SIGNON_ERROR); + fail_unless (error->code == SIGNON_ERROR_METHOD_NOT_KNOWN); + g_main_loop_quit (main_loop); +} + START_TEST(test_query_mechanisms) { g_type_init (); @@ -189,6 +202,13 @@ START_TEST(test_query_mechanisms) main_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (main_loop); + + /* Test a non existing method */ + signon_auth_service_query_mechanisms (auth_service, + "non-existing", + (SignonQueryMechanismCb)signon_query_mechanisms_cb_fail, + "Hello"); + g_main_loop_run (main_loop); end_test (); } END_TEST @@ -626,11 +646,7 @@ START_TEST(test_get_nonexisting_identity) fail_unless (error != NULL); fail_unless (error->domain == SIGNON_ERROR); - - //TODO: as the error management will - //became stable we will need to change - //the expected value of error code - fail_unless (error->code == SIGNON_ERROR_UNKNOWN); + fail_unless (error->code == SIGNON_ERROR_IDENTITY_NOT_FOUND); end_test (); } @@ -658,7 +674,10 @@ static void store_credentials_identity_cb(SignonIdentity *self, (*last_id) += 1; } - g_main_loop_quit (main_loop); + /* Wait some time to ensure that the info-updated signals are + * processed + */ + g_timeout_add_seconds (2, test_quit_main_loop_cb, main_loop); } START_TEST(test_store_credentials_identity) @@ -984,6 +1003,7 @@ START_TEST(test_info_identity) g_main_loop_run (main_loop); gint id = signon_identity_info_get_id (info); + fail_unless (id != 0); SignonIdentity *idty2 = signon_identity_new_from_db (id); signon_identity_query_info (idty2, identity_info_cb, &info); @@ -1068,6 +1088,10 @@ START_TEST(test_signout_identity) gint id = signon_identity_info_get_id (info); SignonIdentity *idty2 = signon_identity_new_from_db (id); + /* wait some more time to ensure that the object gets registered */ + g_timeout_add_seconds (2, test_quit_main_loop_cb, main_loop); + g_main_loop_run (main_loop); + signon_identity_info_free (info); GError *err = NULL; @@ -1128,7 +1152,7 @@ START_TEST(test_unregistered_identity) /* * give time to handle unregistered signal * */ - g_timeout_add_seconds (5, (GSourceFunc)g_main_loop_quit, main_loop); + g_timeout_add_seconds (5, test_quit_main_loop_cb, main_loop); signon_identity_query_info (idty, identity_info_cb, &info); g_main_loop_run (main_loop); @@ -1153,6 +1177,10 @@ START_TEST(test_unregistered_auth_session) SignonAuthSession *as = signon_identity_create_session(idty, "ssotest", &err); + /* give time to register the objects */ + g_timeout_add_seconds (2, test_quit_main_loop_cb, main_loop); + g_main_loop_run (main_loop); + /* * give the time for identity to became idle * */ @@ -1162,7 +1190,9 @@ START_TEST(test_unregistered_auth_session) /* * give time to handle unregistered signal * */ - g_timeout_add_seconds (5, (GSourceFunc)g_main_loop_quit, main_loop); + g_timeout_add_seconds (5, test_quit_main_loop_cb, main_loop); + g_main_loop_run (main_loop); + gchar* patterns[4]; patterns[0] = g_strdup("mech1"); @@ -1176,6 +1206,7 @@ START_TEST(test_unregistered_auth_session) (gpointer)patterns); g_main_loop_run (main_loop); + g_object_unref (as); g_object_unref (idty); g_object_unref (idty2); @@ -1224,6 +1255,8 @@ START_TEST(test_regression_unref) GError *error = NULL; GValue v_string = G_VALUE_INIT; + g_debug ("%s", G_STRFUNC); + g_type_init (); main_loop = g_main_loop_new (NULL, FALSE);