1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of libsignon-glib
6 * Copyright (C) 2009-2010 Nokia Corporation.
7 * Copyright (C) 2012 Canonical Ltd.
8 * Copyright (C) 2012-2013 Intel Corporation.
10 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
11 * Contact: Jussi Laako <jussi.laako@linux.intel.com>
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public License
15 * version 2.1 as published by the Free Software Foundation.
17 * This library is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
29 * SECTION:signon-identity
30 * @title: SignonIdentity
31 * @short_description: Client side presentation of a credential.
33 * The #SignonIdentity represents a database entry for a single identity.
36 #include "signon-identity.h"
37 #include "signon-auth-session.h"
38 #include "signon-internals.h"
39 #include "signon-dbus-queue.h"
40 #include "signon-utils.h"
41 #include "signon-errors.h"
42 #include "sso-auth-service.h"
43 #include "sso-identity-gen.h"
45 G_DEFINE_TYPE (SignonIdentity, signon_identity, G_TYPE_OBJECT);
58 } IdentityRegistrationState;
64 } RemoteIdentityState;
66 struct _SignonIdentityPrivate
69 SsoAuthService *auth_service_proxy;
70 GCancellable *cancellable;
72 SignonIdentityInfo *identity_info;
75 IdentityRegistrationState registration_state;
84 guint signal_info_updated;
85 guint signal_unregistered;
93 static guint signals[LAST_SIGNAL];
95 #define SIGNON_IDENTITY_PRIV(obj) (SIGNON_IDENTITY(obj)->priv)
97 typedef struct _IdentityStoreCredentialsCbData
100 SignonIdentityStoreCredentialsCb cb;
102 } IdentityStoreCredentialsCbData;
104 typedef struct _IdentityStoreCredentialsData
106 GVariant *info_variant;
108 } IdentityStoreCredentialsData;
112 SIGNON_VERIFY_SECRET,
118 typedef struct _IdentitySessionCbData
120 SignonIdentity *self;
121 SignonAuthSession *session;
122 SignonIdentitySessionReadyCb cb;
123 } IdentitySessionCbData;
125 typedef struct _IdentitySessionData
129 } IdentitySessionData;
131 typedef struct _IdentityVerifyCbData
133 SignonIdentity *self;
134 SignonIdentityVerifyCb cb;
136 } IdentityVerifyCbData;
138 typedef struct _IdentityVerifyData
142 IdentityOperation operation;
144 } IdentityVerifyData;
146 typedef struct _IdentityInfoCbData
148 SignonIdentity *self;
149 SignonIdentityInfoCb cb;
151 } IdentityInfoCbData;
153 typedef struct _IdentityVoidCbData
155 SignonIdentity *self;
156 SignonIdentityVoidCb cb;
158 } IdentityVoidCbData;
160 typedef struct _IdentityVoidData
162 IdentityOperation operation;
166 static void identity_check_remote_registration (SignonIdentity *self);
167 static void identity_store_credentials_ready_cb (gpointer object, const GError *error, gpointer user_data);
168 static void identity_store_credentials_reply (GObject *object,
171 static void identity_verify_data (SignonIdentity *self, const gchar *data_to_send, gint operation,
172 SignonIdentityVerifyCb cb, gpointer user_data);
173 static void identity_verify_ready_cb (gpointer object, const GError *error, gpointer user_data);
175 static void identity_remove_ready_cb (gpointer object, const GError *error, gpointer user_data);
176 static void identity_signout_ready_cb (gpointer object, const GError *error, gpointer user_data);
177 static void identity_info_ready_cb (gpointer object, const GError *error, gpointer user_data);
179 static void identity_process_signout (SignonIdentity *self);
180 static void identity_process_updated (SignonIdentity *self);
181 static void identity_process_removed (SignonIdentity *self);
182 static void identity_get_auth_session_reply (GObject *object,
185 static void identity_session_ready_cb (gpointer object, const GError *error,
187 static void identity_session_object_destroyed_cb (gpointer data,
188 GObject *where_the_session_was);
191 identity_object_quark ()
193 static GQuark quark = 0;
196 quark = g_quark_from_static_string ("identity_object_quark");
202 signon_identity_set_property (GObject *object,
207 SignonIdentity *self = SIGNON_IDENTITY (object);
212 self->priv->id = g_value_get_uint (value);
215 g_free (self->priv->app_ctx);
216 self->priv->app_ctx = g_strdup (g_value_get_string (value));
219 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
225 signon_identity_get_property (GObject *object,
230 SignonIdentity *self = SIGNON_IDENTITY (object);
235 g_value_set_uint (value, self->priv->id);
238 g_value_set_string (value, self->priv->app_ctx);
241 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
247 signon_identity_init (SignonIdentity *identity)
249 SignonIdentityPrivate *priv;
251 identity->priv = G_TYPE_INSTANCE_GET_PRIVATE (identity,
252 SIGNON_TYPE_IDENTITY,
253 SignonIdentityPrivate);
255 priv = identity->priv;
257 priv->auth_service_proxy = sso_auth_service_get_instance();
258 priv->cancellable = g_cancellable_new ();
259 priv->registration_state = NOT_REGISTERED;
261 priv->removed = FALSE;
262 priv->signed_out = FALSE;
263 priv->updated = FALSE;
265 priv->app_ctx = NULL;
269 signon_identity_dispose (GObject *object)
271 SignonIdentity *identity = SIGNON_IDENTITY (object);
272 SignonIdentityPrivate *priv = identity->priv;
274 if (priv->cancellable)
276 g_cancellable_cancel (priv->cancellable);
277 g_object_unref (priv->cancellable);
278 priv->cancellable = NULL;
281 if (priv->identity_info)
283 signon_identity_info_free (priv->identity_info);
284 priv->identity_info = NULL;
287 g_clear_object (&priv->auth_service_proxy);
291 g_signal_handler_disconnect (priv->proxy, priv->signal_info_updated);
292 g_signal_handler_disconnect (priv->proxy, priv->signal_unregistered);
293 g_object_unref (priv->proxy);
298 g_critical ("SignonIdentity: the list of AuthSessions MUST be empty");
300 g_free(priv->app_ctx);
302 G_OBJECT_CLASS (signon_identity_parent_class)->dispose (object);
306 signon_identity_finalize (GObject *object)
308 G_OBJECT_CLASS (signon_identity_parent_class)->finalize (object);
312 signon_identity_class_init (SignonIdentityClass *klass)
314 GObjectClass *object_class = G_OBJECT_CLASS (klass);
317 object_class->set_property = signon_identity_set_property;
318 object_class->get_property = signon_identity_get_property;
320 pspec = g_param_spec_uint ("id",
322 "Set/Get Identity ID",
327 g_object_class_install_property (object_class,
331 pspec = g_param_spec_string ("app_ctx",
332 "Application Context",
333 "Set/Get Application Security Context",
336 g_object_class_install_property (object_class,
340 g_type_class_add_private (object_class, sizeof (SignonIdentityPrivate));
343 * SignonIdentity::signout:
345 * Emitted when the identity was signed out.
347 signals[SIGNEDOUT_SIGNAL] = g_signal_new("signout",
348 G_TYPE_FROM_CLASS (klass),
349 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
350 0 /* class closure */,
351 NULL /* accumulator */,
352 NULL /* accu_data */,
353 g_cclosure_marshal_VOID__VOID,
354 G_TYPE_NONE /* return_type */,
357 object_class->dispose = signon_identity_dispose;
358 object_class->finalize = signon_identity_finalize;
362 identity_state_changed_cb (GDBusProxy *proxy,
366 g_return_if_fail (SIGNON_IS_IDENTITY (user_data));
367 SignonIdentity *self = SIGNON_IDENTITY (user_data);
371 DEBUG ("State changed to DATA_UPDATED");
372 identity_process_updated (self);
374 case IDENTITY_REMOVED:
375 DEBUG ("State changed to IDENTITY_REMOVED");
376 identity_process_removed (self);
378 case IDENTITY_SIGNED_OUT:
379 DEBUG ("State changed to IDENTITY_SIGNED_OUT");
380 identity_process_signout (self);
383 g_critical ("wrong state value obtained from signon daemon");
388 identity_remote_object_destroyed_cb(GDBusProxy *proxy,
391 g_return_if_fail (SIGNON_IS_IDENTITY (user_data));
392 SignonIdentity *self = SIGNON_IDENTITY (user_data);
394 SignonIdentityPrivate *priv = self->priv;
395 g_return_if_fail (priv != NULL);
399 g_object_unref (priv->proxy);
403 DEBUG ("%s %d", G_STRFUNC, __LINE__);
405 _signon_object_not_ready(self);
407 priv->registration_state = NOT_REGISTERED;
409 signon_identity_info_free (priv->identity_info);
410 priv->identity_info = NULL;
412 priv->removed = FALSE;
413 priv->signed_out = FALSE;
414 priv->updated = FALSE;
418 identity_registered (SignonIdentity *identity,
419 char *object_path, GVariant *identity_data,
422 g_return_if_fail (SIGNON_IS_IDENTITY (identity));
424 SignonIdentityPrivate *priv;
425 priv = identity->priv;
427 g_return_if_fail (priv != NULL);
431 GDBusConnection *connection;
432 GDBusProxy *auth_service_proxy;
433 const gchar *bus_name;
434 GError *proxy_error = NULL;
436 DEBUG("%s: %s", G_STRFUNC, object_path);
438 * TODO: as Aurel will finalize the code polishing so we will
439 * need to implement the refresh of the proxy to SignonIdentity
441 g_return_if_fail (priv->proxy == NULL);
443 auth_service_proxy = (GDBusProxy *)priv->auth_service_proxy;
444 connection = g_dbus_proxy_get_connection (auth_service_proxy);
445 bus_name = g_dbus_proxy_get_name (auth_service_proxy);
448 sso_identity_proxy_new_sync (connection,
449 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
454 if (G_UNLIKELY (proxy_error != NULL))
456 g_warning ("Failed to initialize Identity proxy: %s",
457 proxy_error->message);
458 g_clear_error (&proxy_error);
461 priv->signal_info_updated =
462 g_signal_connect (priv->proxy,
464 G_CALLBACK (identity_state_changed_cb),
467 priv->signal_unregistered =
468 g_signal_connect (priv->proxy,
470 G_CALLBACK (identity_remote_object_destroyed_cb),
475 DEBUG("%s: ", G_STRFUNC);
476 priv->identity_info =
477 signon_identity_info_new_from_variant (identity_data);
478 g_variant_unref (identity_data);
481 priv->updated = TRUE;
484 g_warning ("%s: %s", G_STRFUNC, error->message);
487 * execute queued operations or emit errors on each of them
489 priv->registration_state = REGISTERED;
492 * TODO: if we will add a new state for identity: "INVALID"
493 * consider emission of another error, like "invalid"
495 _signon_object_ready (identity, identity_object_quark (), error);
498 * as the registration failed we do not
499 * request for new registration, but emit
500 * same error again and again
505 * signon_identity_get_last_error:
506 * @identity: the #SignonIdentity.
508 * Get the most recent error that occurred on @identity.
510 * Returns: a #GError containing the most recent error, or %NULL on failure.
513 signon_identity_get_last_error (SignonIdentity *identity)
515 g_return_val_if_fail (SIGNON_IS_IDENTITY (identity), NULL);
516 return _signon_object_last_error(identity);
520 identity_new_cb (GObject *object, GAsyncResult *res,
523 SignonIdentity *identity = (SignonIdentity*)userdata;
524 SsoAuthService *proxy = SSO_AUTH_SERVICE (object);
525 gchar *object_path = NULL;
526 GError *error = NULL;
528 g_return_if_fail (identity != NULL);
529 DEBUG ("%s", G_STRFUNC);
531 sso_auth_service_call_register_new_identity_finish (proxy,
535 SIGNON_RETURN_IF_CANCELLED (error);
536 identity_registered (identity, object_path, NULL, error);
537 g_free (object_path);
541 identity_new_from_db_cb (GObject *object, GAsyncResult *res,
544 SignonIdentity *identity = (SignonIdentity*)userdata;
545 SsoAuthService *proxy = SSO_AUTH_SERVICE (object);
546 gchar *object_path = NULL;
547 GVariant *identity_data;
548 GError *error = NULL;
550 g_return_if_fail (identity != NULL);
551 DEBUG ("%s", G_STRFUNC);
553 sso_auth_service_call_get_identity_finish (proxy,
558 SIGNON_RETURN_IF_CANCELLED (error);
559 identity_registered (identity, object_path, identity_data, error);
560 g_free (object_path);
564 identity_check_remote_registration (SignonIdentity *self)
566 g_return_if_fail (self != NULL);
567 SignonIdentityPrivate *priv = self->priv;
569 g_return_if_fail (priv != NULL);
571 if (priv->registration_state != NOT_REGISTERED)
575 sso_auth_service_call_get_identity (priv->auth_service_proxy,
579 identity_new_from_db_cb,
582 sso_auth_service_call_register_new_identity (priv->auth_service_proxy,
588 priv->registration_state = PENDING_REGISTRATION;
592 * signon_identity_new_from_db:
594 * @application_context: application security context, can be %NULL.
596 * Construct an identity object associated with an existing identity
599 * Returns: an instance of a #SignonIdentity.
602 signon_identity_new_from_db (guint32 id, const gchar *application_context)
604 SignonIdentity *identity;
605 DEBUG ("%s %d: %d\n", G_STRFUNC, __LINE__, id);
609 identity = g_object_new (SIGNON_TYPE_IDENTITY,
611 "app_ctx", application_context,
613 g_return_val_if_fail (SIGNON_IS_IDENTITY (identity), NULL);
614 g_return_val_if_fail (identity->priv != NULL, NULL);
616 identity->priv->id = id;
617 identity->priv->app_ctx = (application_context) ?
618 g_strdup (application_context) : g_strdup ("");
619 identity_check_remote_registration (identity);
625 * signon_identity_new:
626 * @application_context: application security context, can be %NULL.
628 * Construct new, empty, identity object.
630 * Returns: an instance of an #SignonIdentity.
633 signon_identity_new (const gchar *application_context)
635 DEBUG ("%s %d", G_STRFUNC, __LINE__);
636 SignonIdentity *identity = g_object_new (
637 SIGNON_TYPE_IDENTITY,
638 "app_ctx", application_context,
640 g_return_val_if_fail (SIGNON_IS_IDENTITY (identity), NULL);
641 g_return_val_if_fail (identity->priv != NULL, NULL);
643 identity->priv->app_ctx = (application_context) ?
644 g_strdup (application_context) : g_strdup ("");
645 identity_check_remote_registration (identity);
651 * signon_identity_create_session:
652 * @self: the #SignonIdentity.
654 * @error: pointer to a location which will receive the error, if any.
656 * Creates an authentication session for this identity.
658 * Returns: (transfer full): a new #SignonAuthSession.
661 signon_identity_create_session(SignonIdentity *self,
665 g_return_val_if_fail (SIGNON_IS_IDENTITY (self), NULL);
667 SignonIdentityPrivate *priv = self->priv;
668 g_return_val_if_fail (priv != NULL, NULL);
670 DEBUG ("%s %d", G_STRFUNC, __LINE__);
674 DEBUG ("NULL method as input. Aborting.");
676 signon_error_quark(),
677 SIGNON_ERROR_UNKNOWN,
678 "NULL input method.");
682 GSList *list = priv->sessions;
685 SignonAuthSession *session = SIGNON_AUTH_SESSION (priv->sessions->data);
686 const gchar *sessionMethod = signon_auth_session_get_method (session);
687 if (g_strcmp0(sessionMethod, method) == 0)
689 DEBUG ("Auth Session with method `%s` already created.", method);
691 signon_error_quark(),
692 SIGNON_ERROR_METHOD_NOT_AVAILABLE,
693 "Authentication session for this method already requested.");
700 SignonAuthSession *session = signon_auth_session_new (G_OBJECT(self),
705 DEBUG ("%s %d - success", G_STRFUNC, __LINE__);
706 priv->sessions = g_slist_append(priv->sessions, session);
707 g_object_weak_ref (G_OBJECT(session),
708 identity_session_object_destroyed_cb,
711 * if you want to delete the identity
712 * you MUST delete all authsessions
716 priv->signed_out = FALSE;
723 * signon_identity_store_credentials_with_info:
724 * @self: the #SignonIdentity.
725 * @info: the #SignonIdentityInfo data to store.
726 * @cb: (scope async): callback.
727 * @user_data: user_data.
729 * Stores the data from @info into the identity.
732 signon_identity_store_credentials_with_info(SignonIdentity *self,
733 const SignonIdentityInfo *info,
734 SignonIdentityStoreCredentialsCb cb,
737 IdentityStoreCredentialsCbData *cb_data;
738 IdentityStoreCredentialsData *operation_data;
741 g_return_if_fail (SIGNON_IS_IDENTITY (self));
742 g_return_if_fail (info != NULL);
744 SignonIdentityPrivate *priv = self->priv;
745 if (priv->identity_info)
746 signon_identity_info_free (priv->identity_info);
747 priv->identity_info = signon_identity_info_copy (info);
749 cb_data = g_slice_new0 (IdentityStoreCredentialsCbData);
750 cb_data->self = self;
752 cb_data->user_data = user_data;
754 operation_data = g_slice_new0 (IdentityStoreCredentialsData);
755 operation_data->info_variant = signon_identity_info_to_variant (info);
756 operation_data->cb_data = cb_data;
758 identity_check_remote_registration (self);
759 _signon_object_call_when_ready (self,
760 identity_object_quark(),
761 identity_store_credentials_ready_cb,
766 * signon_identity_store_credentials_with_args:
767 * @self: the #SignonIdentity.
768 * @username: username.
770 * @store_secret: whether signond should store the password.
771 * @methods: (transfer none) (element-type utf8 GStrv): methods.
774 * @access_control_list: access control list.
775 * @type: the type of the identity.
776 * @cb: (scope async): callback.
777 * @user_data: user_data.
779 * Stores the given data into the identity.
781 void signon_identity_store_credentials_with_args(SignonIdentity *self,
782 const gchar *username,
784 const gboolean store_secret,
785 const GHashTable *methods,
786 const gchar *caption,
787 const gchar* const *realms,
788 const SignonSecurityContext *owner,
789 const SignonSecurityContextList *access_control_list,
790 SignonIdentityType type,
791 SignonIdentityStoreCredentialsCb cb,
794 SignonIdentityInfo *info;
796 g_return_if_fail (SIGNON_IS_IDENTITY (self));
798 info = signon_identity_info_new ();
799 signon_identity_info_set_username (info, username);
800 signon_identity_info_set_secret (info, secret, store_secret);
801 signon_identity_info_set_methods (info, methods);
802 signon_identity_info_set_caption (info, caption);
803 signon_identity_info_set_realms (info, realms);
806 signon_identity_info_set_owner (info, owner);
808 if (access_control_list)
810 signon_identity_info_set_access_control_list (info,
811 access_control_list);
813 signon_identity_info_set_identity_type (info, type);
815 signon_identity_store_credentials_with_info (self, info, cb, user_data);
816 signon_identity_info_free (info);
820 identity_store_credentials_ready_cb (gpointer object, const GError *error, gpointer user_data)
822 g_return_if_fail (SIGNON_IS_IDENTITY (object));
824 SignonIdentity *self = SIGNON_IDENTITY (object);
825 SignonIdentityPrivate *priv = self->priv;
826 g_return_if_fail (priv != NULL);
828 DEBUG ("%s %d", G_STRFUNC, __LINE__);
830 IdentityStoreCredentialsData *operation_data =
831 (IdentityStoreCredentialsData *)user_data;
832 g_return_if_fail (operation_data != NULL);
834 IdentityStoreCredentialsCbData *cb_data = operation_data->cb_data;
835 g_return_if_fail (cb_data != NULL);
839 DEBUG ("IdentityError: %s", error->message);
843 (cb_data->cb) (self, 0, error, cb_data->user_data);
846 g_slice_free (IdentityStoreCredentialsCbData, cb_data);
850 g_return_if_fail (priv->proxy != NULL);
852 sso_identity_call_store (priv->proxy,
853 operation_data->info_variant,
855 identity_store_credentials_reply,
859 g_slice_free (IdentityStoreCredentialsData, operation_data);
863 identity_store_credentials_reply (GObject *object, GAsyncResult *res,
866 IdentityStoreCredentialsCbData *cb_data = (IdentityStoreCredentialsCbData *)userdata;
867 SsoIdentity *proxy = SSO_IDENTITY (object);
869 GError *error = NULL;
871 g_return_if_fail (cb_data != NULL);
872 g_return_if_fail (cb_data->self != NULL);
873 g_return_if_fail (cb_data->self->priv != NULL);
875 SignonIdentityPrivate *priv = cb_data->self->priv;
877 sso_identity_call_store_finish (proxy, &id, res, &error);
878 SIGNON_RETURN_IF_CANCELLED (error);
882 g_return_if_fail (priv->identity_info == NULL);
884 g_object_set (cb_data->self, "id", id, NULL);
885 cb_data->self->priv->id = id;
888 * if the previous state was REMOVED
889 * then we need to reset it
891 priv->removed = FALSE;
896 (cb_data->cb) (cb_data->self, id, error, cb_data->user_data);
899 g_clear_error(&error);
900 g_slice_free (IdentityStoreCredentialsCbData, cb_data);
904 identity_verify_reply (GObject *object, GAsyncResult *res,
907 SsoIdentity *proxy = SSO_IDENTITY (object);
909 GError *error = NULL;
910 IdentityVerifyCbData *cb_data = (IdentityVerifyCbData *)userdata;
912 g_return_if_fail (cb_data != NULL);
913 g_return_if_fail (cb_data->self != NULL);
915 sso_identity_call_verify_secret_finish (proxy, &valid, res, &error);
916 SIGNON_RETURN_IF_CANCELLED (error);
920 (cb_data->cb) (cb_data->self, valid, error, cb_data->user_data);
923 g_clear_error(&error);
924 g_slice_free (IdentityVerifyCbData, cb_data);
928 identity_verify_ready_cb (gpointer object, const GError *error, gpointer user_data)
930 g_return_if_fail (SIGNON_IS_IDENTITY (object));
932 SignonIdentity *self = SIGNON_IDENTITY (object);
933 SignonIdentityPrivate *priv = self->priv;
934 g_return_if_fail (priv != NULL);
936 DEBUG ("%s %d", G_STRFUNC, __LINE__);
938 IdentityVerifyData *operation_data =
939 (IdentityVerifyData *)user_data;
940 g_return_if_fail (operation_data != NULL);
942 IdentityVerifyCbData *cb_data = operation_data->cb_data;
943 g_return_if_fail (cb_data != NULL);
945 if (priv->removed == TRUE)
947 GError *new_error = g_error_new (signon_error_quark(),
948 SIGNON_ERROR_IDENTITY_NOT_FOUND,
949 "Already removed from database.");
953 (cb_data->cb) (self, FALSE, new_error, cb_data->user_data);
956 g_error_free (new_error);
957 g_slice_free (IdentityVerifyCbData, cb_data);
961 DEBUG ("IdentityError: %s", error->message);
965 (cb_data->cb) (self, FALSE, error, cb_data->user_data);
968 g_slice_free (IdentityVerifyCbData, cb_data);
972 DEBUG ("%s %d", G_STRFUNC, __LINE__);
973 g_return_if_fail (priv->proxy != NULL);
975 switch (operation_data->operation) {
976 case SIGNON_VERIFY_SECRET:
977 sso_identity_call_verify_secret (priv->proxy,
978 operation_data->data_to_send,
980 identity_verify_reply,
983 default: g_critical ("Wrong operation code");
986 g_free (operation_data->params);
987 g_free (operation_data->data_to_send);
988 g_slice_free (IdentityVerifyData, operation_data);
992 identity_verify_data(SignonIdentity *self,
993 const gchar *data_to_send,
995 SignonIdentityVerifyCb cb,
998 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1000 SignonIdentityPrivate *priv = self->priv;
1001 g_return_if_fail (priv != NULL);
1003 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1005 IdentityVerifyCbData *cb_data = g_slice_new0 (IdentityVerifyCbData);
1006 cb_data->self = self;
1008 cb_data->user_data = user_data;
1010 IdentityVerifyData *operation_data = g_slice_new0 (IdentityVerifyData);
1012 operation_data->params = NULL;
1013 operation_data->data_to_send = g_strdup (data_to_send);
1014 operation_data->operation = operation;
1015 operation_data->cb_data = cb_data;
1017 identity_check_remote_registration (self);
1018 _signon_object_call_when_ready (self,
1019 identity_object_quark(),
1020 identity_verify_ready_cb,
1025 * signon_identity_verify_secret:
1026 * @self: the #SignonIdentity.
1027 * @secret: the secret (password) to be verified.
1028 * @cb: (scope async): callback.
1029 * @user_data: user_data.
1031 * Verifies the given secret.
1033 void signon_identity_verify_secret(SignonIdentity *self,
1034 const gchar *secret,
1035 SignonIdentityVerifyCb cb,
1038 identity_verify_data (self,
1040 SIGNON_VERIFY_SECRET,
1046 identity_process_updated (SignonIdentity *self)
1048 DEBUG ("%d %s", __LINE__, __func__);
1050 g_return_if_fail (self != NULL);
1051 g_return_if_fail (self->priv != NULL);
1053 SignonIdentityPrivate *priv = self->priv;
1054 g_return_if_fail (priv->proxy != NULL);
1056 signon_identity_info_free (priv->identity_info);
1057 priv->identity_info = NULL;
1058 priv->updated = FALSE;
1060 DEBUG ("%s info freed, to be updated", __func__);
1064 identity_process_removed (SignonIdentity *self)
1066 g_return_if_fail (self != NULL);
1067 g_return_if_fail (self->priv != NULL);
1069 DEBUG ("%d %s", __LINE__, __func__);
1071 SignonIdentityPrivate *priv = self->priv;
1073 if (priv->removed == TRUE)
1076 priv->removed = TRUE;
1077 signon_identity_info_free (priv->identity_info);
1078 priv->identity_info = NULL;
1080 g_object_set (self, "id", 0, NULL);
1085 identity_process_signout(SignonIdentity *self)
1087 g_return_if_fail (self != NULL);
1088 g_return_if_fail (self->priv != NULL);
1090 DEBUG ("%d %s", __LINE__, __func__);
1091 SignonIdentityPrivate *priv = self->priv;
1093 if (priv->signed_out == TRUE)
1096 GSList *llink = priv->sessions;
1099 GSList *next = llink->next;
1100 g_object_unref (G_OBJECT(llink->data));
1104 priv->signed_out = TRUE;
1105 g_signal_emit(G_OBJECT(self), signals[SIGNEDOUT_SIGNAL], 0);
1109 * TODO: fix the implementation
1110 * of signond: it returns result = TRUE
1114 identity_signout_reply (GObject *object, GAsyncResult *res,
1117 SsoIdentity *proxy = SSO_IDENTITY (object);
1119 GError *error = NULL;
1120 IdentityVoidCbData *cb_data = (IdentityVoidCbData *)userdata;
1122 g_return_if_fail (cb_data != NULL);
1123 g_return_if_fail (cb_data->self != NULL);
1124 g_return_if_fail (cb_data->self->priv != NULL);
1126 sso_identity_call_sign_out_finish (proxy, &result, res, &error);
1127 SIGNON_RETURN_IF_CANCELLED (error);
1131 (cb_data->cb) (cb_data->self, error, cb_data->user_data);
1134 g_clear_error(&error);
1135 g_slice_free (IdentityVoidCbData, cb_data);
1139 identity_removed_reply (GObject *object, GAsyncResult *res,
1142 SsoIdentity *proxy = SSO_IDENTITY (object);
1143 GError *error = NULL;
1144 IdentityVoidCbData *cb_data = (IdentityVoidCbData *)userdata;
1146 g_return_if_fail (cb_data != NULL);
1147 g_return_if_fail (cb_data->self != NULL);
1148 g_return_if_fail (cb_data->self->priv != NULL);
1150 sso_identity_call_remove_finish (proxy, res, &error);
1151 SIGNON_RETURN_IF_CANCELLED (error);
1155 (cb_data->cb) (cb_data->self, error, cb_data->user_data);
1158 g_clear_error(&error);
1159 g_slice_free (IdentityVoidCbData, cb_data);
1163 identity_info_reply(GObject *object, GAsyncResult *res,
1166 SsoIdentity *proxy = SSO_IDENTITY (object);
1167 GVariant *identity_data = NULL;
1168 DEBUG ("%d %s", __LINE__, __func__);
1170 GError *error = NULL;
1171 IdentityInfoCbData *cb_data = (IdentityInfoCbData *)userdata;
1173 g_return_if_fail (cb_data != NULL);
1174 g_return_if_fail (cb_data->self != NULL);
1175 g_return_if_fail (cb_data->self->priv != NULL);
1177 SignonIdentityPrivate *priv = cb_data->self->priv;
1179 sso_identity_call_get_info_finish (proxy, &identity_data, res, &error);
1180 SIGNON_RETURN_IF_CANCELLED (error);
1181 priv->identity_info =
1182 signon_identity_info_new_from_variant (identity_data);
1183 if (identity_data != NULL)
1184 g_variant_unref (identity_data);
1188 (cb_data->cb) (cb_data->self, priv->identity_info, error, cb_data->user_data);
1191 g_clear_error(&error);
1192 g_slice_free (IdentityInfoCbData, cb_data);
1194 priv->updated = TRUE;
1198 identity_info_ready_cb(gpointer object, const GError *error, gpointer user_data)
1200 g_return_if_fail (SIGNON_IS_IDENTITY (object));
1202 SignonIdentity *self = SIGNON_IDENTITY (object);
1203 SignonIdentityPrivate *priv = self->priv;
1204 g_return_if_fail (priv != NULL);
1206 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1208 IdentityVoidData *operation_data =
1209 (IdentityVoidData *)user_data;
1210 g_return_if_fail (operation_data != NULL);
1212 IdentityInfoCbData *cb_data = operation_data->cb_data;
1213 g_return_if_fail (cb_data != NULL);
1215 if (priv->removed == TRUE)
1217 DEBUG ("%s identity removed", G_STRFUNC);
1219 GError *new_error = g_error_new (signon_error_quark(),
1220 SIGNON_ERROR_IDENTITY_NOT_FOUND,
1221 "Already removed from database.");
1223 (cb_data->cb) (self, NULL, new_error, cb_data->user_data);
1225 g_error_free (new_error);
1227 else if (error || priv->id == 0)
1229 DEBUG ("%s identity is new", G_STRFUNC);
1232 DEBUG ("IdentityError: %s", error->message);
1234 DEBUG ("Identity is not stored and has no info yet");
1237 (cb_data->cb) (self, NULL, error, cb_data->user_data);
1239 else if (priv->updated == FALSE)
1241 DEBUG ("%s identity needs update, call daemon", G_STRFUNC);
1243 g_return_if_fail (priv->proxy != NULL);
1244 sso_identity_call_get_info (priv->proxy,
1246 identity_info_reply,
1251 DEBUG ("%s pass existing one", G_STRFUNC);
1254 (cb_data->cb) (self, priv->identity_info, error, cb_data->user_data);
1257 if (priv->updated == TRUE)
1258 g_slice_free (IdentityInfoCbData, cb_data);
1260 g_slice_free (IdentityVoidData, operation_data);
1264 identity_signout_ready_cb(gpointer object, const GError *error, gpointer user_data)
1266 g_return_if_fail (SIGNON_IS_IDENTITY (object));
1268 SignonIdentity *self = SIGNON_IDENTITY (object);
1269 SignonIdentityPrivate *priv = self->priv;
1270 g_return_if_fail (priv != NULL);
1272 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1273 IdentityVoidCbData *cb_data = (IdentityVoidCbData *)user_data;
1275 g_return_if_fail (cb_data != NULL);
1277 if (priv->removed == TRUE)
1279 GError *new_error = g_error_new (signon_error_quark(),
1280 SIGNON_ERROR_IDENTITY_NOT_FOUND,
1281 "Already removed from database.");
1284 (cb_data->cb) (self, new_error, cb_data->user_data);
1287 g_error_free (new_error);
1288 g_slice_free (IdentityVoidCbData, cb_data);
1292 DEBUG ("IdentityError: %s", error->message);
1295 (cb_data->cb) (self, error, cb_data->user_data);
1298 g_slice_free (IdentityVoidCbData, cb_data);
1302 g_return_if_fail (priv->proxy != NULL);
1303 sso_identity_call_sign_out (priv->proxy,
1305 identity_signout_reply,
1311 identity_remove_ready_cb(gpointer object, const GError *error, gpointer user_data)
1313 g_return_if_fail (SIGNON_IS_IDENTITY (object));
1315 SignonIdentity *self = SIGNON_IDENTITY (object);
1316 SignonIdentityPrivate *priv = self->priv;
1317 g_return_if_fail (priv != NULL);
1319 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1320 IdentityVoidCbData *cb_data = (IdentityVoidCbData *)user_data;
1321 g_return_if_fail (cb_data != NULL);
1323 if (priv->removed == TRUE)
1325 GError *new_error = g_error_new (signon_error_quark(),
1326 SIGNON_ERROR_IDENTITY_NOT_FOUND,
1327 "Already removed from database.");
1330 (cb_data->cb) (self, new_error, cb_data->user_data);
1333 g_error_free (new_error);
1334 g_slice_free (IdentityVoidCbData, cb_data);
1338 DEBUG ("IdentityError: %s", error->message);
1341 (cb_data->cb) (self, error, cb_data->user_data);
1344 g_slice_free (IdentityVoidCbData, cb_data);
1348 g_return_if_fail (priv->proxy != NULL);
1349 sso_identity_call_remove (priv->proxy,
1351 identity_removed_reply,
1357 identity_void_operation(SignonIdentity *self,
1361 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1363 SignonIdentityPrivate *priv = self->priv;
1364 g_return_if_fail (priv != NULL);
1366 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1368 IdentityVoidData *operation_data = g_slice_new0 (IdentityVoidData);
1369 operation_data->cb_data = cb_data;
1370 _signon_object_call_when_ready (self,
1371 identity_object_quark(),
1372 identity_info_ready_cb,
1377 * signon_identity_remove:
1378 * @self: the #SignonIdentity.
1379 * @cb: (scope async): callback to be called when the operation has completed.
1380 * @user_data: user_data to pass to the callback.
1382 * Removes the corresponding credentials record from the database.
1384 void signon_identity_remove(SignonIdentity *self,
1385 SignonIdentityRemovedCb cb,
1388 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1390 SignonIdentityPrivate *priv = self->priv;
1391 g_return_if_fail (priv != NULL);
1393 IdentityVoidCbData *cb_data = g_slice_new0 (IdentityVoidCbData);
1394 cb_data->self = self;
1395 cb_data->cb = (SignonIdentityVoidCb)cb;
1396 cb_data->user_data = user_data;
1398 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1400 identity_check_remote_registration (self);
1401 _signon_object_call_when_ready (self,
1402 identity_object_quark(),
1403 identity_remove_ready_cb,
1408 * signon_identity_signout:
1409 * @self: the #SignonIdentity.
1410 * @cb: (scope async): callback.
1411 * @user_data: user_data.
1413 * Asks signond to close all authentication sessions for this
1414 * identity, and to remove any stored secrets associated with it (password and
1415 * authentication tokens).
1417 void signon_identity_signout(SignonIdentity *self,
1418 SignonIdentitySignedOutCb cb,
1421 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1423 SignonIdentityPrivate *priv = self->priv;
1424 g_return_if_fail (priv != NULL);
1426 IdentityVoidCbData *cb_data = g_slice_new0 (IdentityVoidCbData);
1427 cb_data->self = self;
1428 cb_data->cb = (SignonIdentityVoidCb)cb;
1429 cb_data->user_data = user_data;
1431 identity_check_remote_registration (self);
1432 _signon_object_call_when_ready (self,
1433 identity_object_quark(),
1434 identity_signout_ready_cb,
1439 * signon_identity_add_reference:
1440 * @self: the #SignonIdentity.
1441 * @reference: reference to be added
1443 * @user_data: user_data.
1445 * Adds named reference to identity
1447 void signon_identity_add_reference(SignonIdentity *self,
1448 const gchar *reference,
1449 SignonIdentityReferenceAddedCb cb,
1452 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1454 SignonIdentityPrivate *priv = self->priv;
1455 g_return_if_fail (priv != NULL);
1460 (cb) (self, NULL, user_data);
1464 * signon_identity_remove_reference:
1465 * @self: the #SignonIdentity.
1466 * @reference: reference to be removed
1468 * @user_data: user_data.
1470 * Removes named reference from identity
1472 void signon_identity_remove_reference(SignonIdentity *self,
1473 const gchar *reference,
1474 SignonIdentityReferenceRemovedCb cb,
1477 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1479 SignonIdentityPrivate *priv = self->priv;
1480 g_return_if_fail (priv != NULL);
1485 (cb) (self, NULL, user_data);
1489 * signon_identity_query_info:
1490 * @self: the #SignonIdentity.
1491 * @cb: (scope async): callback.
1492 * @user_data: user_data.
1494 * Fetches the #SignonIdentityInfo data associated with this
1497 void signon_identity_query_info(SignonIdentity *self,
1498 SignonIdentityInfoCb cb,
1501 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1503 SignonIdentityPrivate *priv = self->priv;
1504 g_return_if_fail (priv != NULL);
1506 IdentityInfoCbData *cb_data = g_slice_new0 (IdentityInfoCbData);
1507 cb_data->self = self;
1509 cb_data->user_data = user_data;
1511 identity_check_remote_registration (self);
1512 identity_void_operation(self,
1518 identity_get_auth_session_reply (GObject *object, GAsyncResult *res,
1521 SsoIdentity *proxy = SSO_IDENTITY (object);
1522 gchar *object_path = NULL;
1523 GError *error = NULL;
1525 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1527 sso_identity_call_get_auth_session_finish (proxy,
1531 SIGNON_RETURN_IF_CANCELLED (error);
1533 IdentitySessionCbData *cb_data = (IdentitySessionCbData *) userdata;
1534 g_return_if_fail (cb_data != NULL);
1535 g_return_if_fail (cb_data->cb != NULL);
1537 (cb_data->cb) (cb_data->session,
1539 g_dbus_proxy_get_connection ((GDBusProxy *)proxy),
1540 g_dbus_proxy_get_name ((GDBusProxy *)proxy),
1543 g_slice_free (IdentitySessionCbData, cb_data);
1544 g_free (object_path);
1545 g_clear_error (&error);
1549 identity_session_ready_cb(gpointer object, const GError *error, gpointer user_data)
1551 g_return_if_fail (SIGNON_IS_IDENTITY (object));
1552 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1554 SignonIdentity *self = SIGNON_IDENTITY (object);
1555 SignonIdentityPrivate *priv = self->priv;
1556 g_return_if_fail (priv != NULL);
1558 IdentitySessionData *operation_data = (IdentitySessionData *) user_data;
1559 g_return_if_fail (operation_data != NULL);
1561 IdentitySessionCbData *cb_data = operation_data->cb_data;
1562 g_return_if_fail (cb_data != NULL);
1564 if (priv->removed == TRUE)
1566 GError *new_error = g_error_new (signon_error_quark(),
1567 SIGNON_ERROR_IDENTITY_NOT_FOUND,
1568 "Already removed from database.");
1571 (cb_data->cb) (cb_data->session, new_error, NULL, NULL, NULL);
1574 g_error_free (new_error);
1578 g_return_if_fail (priv->proxy != NULL);
1580 sso_identity_call_get_auth_session (
1582 operation_data->method,
1584 identity_get_auth_session_reply,
1588 g_slice_free (IdentitySessionData, operation_data);
1592 identity_session_object_destroyed_cb(gpointer data,
1593 GObject *where_the_session_was)
1595 g_return_if_fail (SIGNON_IS_IDENTITY (data));
1596 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1598 SignonIdentity *self = SIGNON_IDENTITY (data);
1599 SignonIdentityPrivate *priv = self->priv;
1600 g_return_if_fail (priv != NULL);
1602 priv->sessions = g_slist_remove(priv->sessions, (gpointer)where_the_session_was);
1603 g_object_unref (self);
1606 void signon_identity_get_auth_session (SignonIdentity *self,
1607 SignonAuthSession *session,
1608 const gchar *method,
1609 SignonIdentitySessionReadyCb cb)
1611 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1612 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1614 SignonIdentityPrivate *priv = self->priv;
1615 g_return_if_fail (priv != NULL);
1617 IdentitySessionCbData *cb_data = g_slice_new0 (IdentitySessionCbData);
1618 cb_data->self = self;
1619 cb_data->session = session;
1622 IdentitySessionData *operation_data = g_slice_new0 (IdentitySessionData);
1623 operation_data->method = method;
1624 operation_data->cb_data = cb_data;
1626 identity_check_remote_registration (self);
1627 _signon_object_call_when_ready (self,
1628 identity_object_quark(),
1629 identity_session_ready_cb,