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 libgsignon-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_OBJECT_CLASS (signon_identity_parent_class)->dispose (object);
304 signon_identity_finalize (GObject *object)
306 SignonIdentity *identity = SIGNON_IDENTITY (object);
307 if (identity->priv->app_ctx)
309 g_free(identity->priv->app_ctx);
310 identity->priv->app_ctx = NULL;
313 G_OBJECT_CLASS (signon_identity_parent_class)->finalize (object);
317 signon_identity_class_init (SignonIdentityClass *klass)
319 GObjectClass *object_class = G_OBJECT_CLASS (klass);
322 object_class->set_property = signon_identity_set_property;
323 object_class->get_property = signon_identity_get_property;
325 pspec = g_param_spec_uint ("id",
327 "Set/Get Identity ID",
332 g_object_class_install_property (object_class,
336 pspec = g_param_spec_string ("app_ctx",
337 "Application Context",
338 "Set/Get Application Security Context",
341 g_object_class_install_property (object_class,
345 g_type_class_add_private (object_class, sizeof (SignonIdentityPrivate));
348 * SignonIdentity::signout:
350 * Emitted when the identity was signed out.
352 signals[SIGNEDOUT_SIGNAL] = g_signal_new("signout",
353 G_TYPE_FROM_CLASS (klass),
354 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
355 0 /* class closure */,
356 NULL /* accumulator */,
357 NULL /* accu_data */,
358 g_cclosure_marshal_VOID__VOID,
359 G_TYPE_NONE /* return_type */,
362 object_class->dispose = signon_identity_dispose;
363 object_class->finalize = signon_identity_finalize;
367 identity_state_changed_cb (GDBusProxy *proxy,
371 g_return_if_fail (SIGNON_IS_IDENTITY (user_data));
372 SignonIdentity *self = SIGNON_IDENTITY (user_data);
376 DEBUG ("State changed to DATA_UPDATED");
377 identity_process_updated (self);
379 case IDENTITY_REMOVED:
380 DEBUG ("State changed to IDENTITY_REMOVED");
381 identity_process_removed (self);
383 case IDENTITY_SIGNED_OUT:
384 DEBUG ("State changed to IDENTITY_SIGNED_OUT");
385 identity_process_signout (self);
388 g_critical ("wrong state value obtained from signon daemon");
393 identity_remote_object_destroyed_cb(GDBusProxy *proxy,
396 g_return_if_fail (SIGNON_IS_IDENTITY (user_data));
397 SignonIdentity *self = SIGNON_IDENTITY (user_data);
399 SignonIdentityPrivate *priv = self->priv;
400 g_return_if_fail (priv != NULL);
404 g_object_unref (priv->proxy);
408 DEBUG ("%s %d", G_STRFUNC, __LINE__);
410 _signon_object_not_ready(self);
412 priv->registration_state = NOT_REGISTERED;
414 signon_identity_info_free (priv->identity_info);
415 priv->identity_info = NULL;
417 priv->removed = FALSE;
418 priv->signed_out = FALSE;
419 priv->updated = FALSE;
423 identity_registered (SignonIdentity *identity,
424 char *object_path, GVariant *identity_data,
427 g_return_if_fail (SIGNON_IS_IDENTITY (identity));
429 SignonIdentityPrivate *priv;
430 priv = identity->priv;
432 g_return_if_fail (priv != NULL);
436 GDBusConnection *connection;
437 GDBusProxy *auth_service_proxy;
438 const gchar *bus_name;
439 GError *proxy_error = NULL;
441 DEBUG("%s: %s", G_STRFUNC, object_path);
443 * TODO: as Aurel will finalize the code polishing so we will
444 * need to implement the refresh of the proxy to SignonIdentity
446 g_return_if_fail (priv->proxy == NULL);
448 auth_service_proxy = (GDBusProxy *)priv->auth_service_proxy;
449 connection = g_dbus_proxy_get_connection (auth_service_proxy);
450 bus_name = g_dbus_proxy_get_name (auth_service_proxy);
453 sso_identity_proxy_new_sync (connection,
454 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
459 if (G_UNLIKELY (proxy_error != NULL))
461 g_warning ("Failed to initialize Identity proxy: %s",
462 proxy_error->message);
463 g_clear_error (&proxy_error);
466 priv->signal_info_updated =
467 g_signal_connect (priv->proxy,
469 G_CALLBACK (identity_state_changed_cb),
472 priv->signal_unregistered =
473 g_signal_connect (priv->proxy,
475 G_CALLBACK (identity_remote_object_destroyed_cb),
480 DEBUG("%s: ", G_STRFUNC);
481 priv->identity_info =
482 signon_identity_info_new_from_variant (identity_data);
483 g_variant_unref (identity_data);
486 priv->updated = TRUE;
489 g_warning ("%s: %s", G_STRFUNC, error->message);
492 * execute queued operations or emit errors on each of them
494 priv->registration_state = REGISTERED;
497 * TODO: if we will add a new state for identity: "INVALID"
498 * consider emission of another error, like "invalid"
500 _signon_object_ready (identity, identity_object_quark (), error);
503 * as the registration failed we do not
504 * request for new registration, but emit
505 * same error again and again
510 * signon_identity_get_last_error:
511 * @identity: the #SignonIdentity.
513 * Get the most recent error that occurred on @identity.
515 * Returns: a #GError containing the most recent error, or %NULL on failure.
518 signon_identity_get_last_error (SignonIdentity *identity)
520 g_return_val_if_fail (SIGNON_IS_IDENTITY (identity), NULL);
521 return _signon_object_last_error(identity);
525 identity_new_cb (GObject *object, GAsyncResult *res,
528 SignonIdentity *identity = (SignonIdentity*)userdata;
529 SsoAuthService *proxy = SSO_AUTH_SERVICE (object);
530 gchar *object_path = NULL;
531 GError *error = NULL;
533 g_return_if_fail (identity != NULL);
534 DEBUG ("%s", G_STRFUNC);
536 sso_auth_service_call_register_new_identity_finish (proxy,
540 if (SIGNON_IS_NOT_CANCELLED (error))
542 identity_registered (identity, object_path, NULL, error);
544 if (object_path) g_free (object_path);
545 g_clear_error (&error);
549 identity_new_from_db_cb (GObject *object, GAsyncResult *res,
552 SignonIdentity *identity = (SignonIdentity*)userdata;
553 SsoAuthService *proxy = SSO_AUTH_SERVICE (object);
554 gchar *object_path = NULL;
555 GVariant *identity_data;
556 GError *error = NULL;
558 g_return_if_fail (identity != NULL);
559 DEBUG ("%s", G_STRFUNC);
561 sso_auth_service_call_get_identity_finish (proxy,
566 if (SIGNON_IS_NOT_CANCELLED (error))
568 identity_registered (identity, object_path, identity_data, error);
570 if (object_path) g_free (object_path);
571 g_clear_error (&error);
575 identity_check_remote_registration (SignonIdentity *self)
577 g_return_if_fail (self != NULL);
578 SignonIdentityPrivate *priv = self->priv;
580 g_return_if_fail (priv != NULL);
582 if (priv->registration_state != NOT_REGISTERED)
586 sso_auth_service_call_get_identity (priv->auth_service_proxy,
590 identity_new_from_db_cb,
593 sso_auth_service_call_register_new_identity (priv->auth_service_proxy,
599 priv->registration_state = PENDING_REGISTRATION;
603 * signon_identity_new_from_db:
605 * @application_context: application security context, can be %NULL.
607 * Construct an identity object associated with an existing identity
610 * Returns: an instance of a #SignonIdentity.
613 signon_identity_new_from_db (guint32 id, const gchar *application_context)
615 SignonIdentity *identity;
616 DEBUG ("%s %d: %d\n", G_STRFUNC, __LINE__, id);
620 identity = g_object_new (SIGNON_TYPE_IDENTITY,
622 "app_ctx", application_context,
624 g_return_val_if_fail (SIGNON_IS_IDENTITY (identity), NULL);
625 g_return_val_if_fail (identity->priv != NULL, NULL);
627 identity->priv->id = id;
628 identity->priv->app_ctx = (application_context) ?
629 g_strdup (application_context) : g_strdup ("");
630 identity_check_remote_registration (identity);
636 * signon_identity_new:
637 * @application_context: application security context, can be %NULL.
639 * Construct new, empty, identity object.
641 * Returns: an instance of an #SignonIdentity.
644 signon_identity_new (const gchar *application_context)
646 DEBUG ("%s %d", G_STRFUNC, __LINE__);
647 SignonIdentity *identity = g_object_new (
648 SIGNON_TYPE_IDENTITY,
649 "app_ctx", application_context,
651 g_return_val_if_fail (SIGNON_IS_IDENTITY (identity), NULL);
652 g_return_val_if_fail (identity->priv != NULL, NULL);
654 identity->priv->app_ctx = (application_context) ?
655 g_strdup (application_context) : g_strdup ("");
656 identity_check_remote_registration (identity);
662 * signon_identity_create_session:
663 * @self: the #SignonIdentity.
665 * @error: pointer to a location which will receive the error, if any.
667 * Creates an authentication session for this identity.
669 * Returns: (transfer full): a new #SignonAuthSession.
672 signon_identity_create_session(SignonIdentity *self,
676 g_return_val_if_fail (SIGNON_IS_IDENTITY (self), NULL);
678 SignonIdentityPrivate *priv = self->priv;
679 g_return_val_if_fail (priv != NULL, NULL);
681 DEBUG ("%s %d", G_STRFUNC, __LINE__);
685 DEBUG ("NULL method as input. Aborting.");
687 signon_error_quark(),
688 SIGNON_ERROR_UNKNOWN,
689 "NULL input method.");
693 GSList *list = priv->sessions;
696 SignonAuthSession *session = SIGNON_AUTH_SESSION (priv->sessions->data);
697 const gchar *sessionMethod = signon_auth_session_get_method (session);
698 if (g_strcmp0(sessionMethod, method) == 0)
700 DEBUG ("Auth Session with method `%s` already created.", method);
702 signon_error_quark(),
703 SIGNON_ERROR_METHOD_NOT_AVAILABLE,
704 "Authentication session for this method already requested.");
711 SignonAuthSession *session = signon_auth_session_new (G_OBJECT(self),
716 DEBUG ("%s %d - success", G_STRFUNC, __LINE__);
717 priv->sessions = g_slist_append(priv->sessions, session);
718 g_object_weak_ref (G_OBJECT(session),
719 identity_session_object_destroyed_cb,
722 * if you want to delete the identity
723 * you MUST delete all authsessions
727 priv->signed_out = FALSE;
734 * signon_identity_store_credentials_with_info:
735 * @self: the #SignonIdentity.
736 * @info: the #SignonIdentityInfo data to store.
737 * @cb: (scope async): callback.
738 * @user_data: user_data.
740 * Stores the data from @info into the identity.
743 signon_identity_store_credentials_with_info(SignonIdentity *self,
744 const SignonIdentityInfo *info,
745 SignonIdentityStoreCredentialsCb cb,
748 IdentityStoreCredentialsCbData *cb_data;
749 IdentityStoreCredentialsData *operation_data;
752 g_return_if_fail (SIGNON_IS_IDENTITY (self));
753 g_return_if_fail (info != NULL);
755 SignonIdentityPrivate *priv = self->priv;
756 if (priv->identity_info)
757 signon_identity_info_free (priv->identity_info);
758 priv->identity_info = signon_identity_info_copy (info);
760 cb_data = g_slice_new0 (IdentityStoreCredentialsCbData);
761 cb_data->self = self;
763 cb_data->user_data = user_data;
765 operation_data = g_slice_new0 (IdentityStoreCredentialsData);
766 operation_data->info_variant = signon_identity_info_to_variant (info);
767 operation_data->cb_data = cb_data;
769 identity_check_remote_registration (self);
770 _signon_object_call_when_ready (self,
771 identity_object_quark(),
772 identity_store_credentials_ready_cb,
777 * signon_identity_store_credentials_with_args:
778 * @self: the #SignonIdentity.
779 * @username: username.
781 * @store_secret: whether signond should store the password.
782 * @methods: (transfer none) (element-type utf8 GStrv): methods.
786 * @access_control_list: access control list.
787 * @type: the type of the identity.
788 * @cb: (scope async): callback.
789 * @user_data: user_data.
791 * Stores the given data into the identity.
793 void signon_identity_store_credentials_with_args(SignonIdentity *self,
794 const gchar *username,
796 const gboolean store_secret,
797 const GHashTable *methods,
798 const gchar *caption,
799 const gchar* const *realms,
800 const SignonSecurityContext *owner,
801 const SignonSecurityContextList *access_control_list,
802 SignonIdentityType type,
803 SignonIdentityStoreCredentialsCb cb,
806 SignonIdentityInfo *info;
808 g_return_if_fail (SIGNON_IS_IDENTITY (self));
810 info = signon_identity_info_new ();
811 signon_identity_info_set_username (info, username);
812 signon_identity_info_set_secret (info, secret, store_secret);
813 signon_identity_info_set_methods (info, methods);
814 signon_identity_info_set_caption (info, caption);
815 signon_identity_info_set_realms (info, realms);
818 signon_identity_info_set_owner (info, owner);
820 if (access_control_list)
822 signon_identity_info_set_access_control_list (info,
823 access_control_list);
825 signon_identity_info_set_identity_type (info, type);
827 signon_identity_store_credentials_with_info (self, info, cb, user_data);
828 signon_identity_info_free (info);
832 identity_store_credentials_ready_cb (gpointer object, const GError *error, gpointer user_data)
834 g_return_if_fail (SIGNON_IS_IDENTITY (object));
836 SignonIdentity *self = SIGNON_IDENTITY (object);
837 SignonIdentityPrivate *priv = self->priv;
838 g_return_if_fail (priv != NULL);
840 DEBUG ("%s %d", G_STRFUNC, __LINE__);
842 IdentityStoreCredentialsData *operation_data =
843 (IdentityStoreCredentialsData *)user_data;
844 g_return_if_fail (operation_data != NULL);
846 IdentityStoreCredentialsCbData *cb_data = operation_data->cb_data;
847 g_return_if_fail (cb_data != NULL);
851 DEBUG ("IdentityError: %s", error->message);
855 (cb_data->cb) (self, 0, error, cb_data->user_data);
858 g_slice_free (IdentityStoreCredentialsCbData, cb_data);
862 g_return_if_fail (priv->proxy != NULL);
864 sso_identity_call_store (priv->proxy,
865 operation_data->info_variant,
867 identity_store_credentials_reply,
871 g_slice_free (IdentityStoreCredentialsData, operation_data);
875 identity_store_credentials_reply (GObject *object, GAsyncResult *res,
878 IdentityStoreCredentialsCbData *cb_data = (IdentityStoreCredentialsCbData *)userdata;
879 SsoIdentity *proxy = SSO_IDENTITY (object);
881 GError *error = NULL;
883 g_return_if_fail (cb_data != NULL);
884 g_return_if_fail (cb_data->self != NULL);
885 g_return_if_fail (cb_data->self->priv != NULL);
887 SignonIdentityPrivate *priv = cb_data->self->priv;
889 sso_identity_call_store_finish (proxy, &id, res, &error);
893 g_return_if_fail (priv->identity_info == NULL);
895 g_object_set (cb_data->self, "id", id, NULL);
896 cb_data->self->priv->id = id;
899 * if the previous state was REMOVED
900 * then we need to reset it
902 priv->removed = FALSE;
905 if (SIGNON_IS_NOT_CANCELLED (error) && cb_data->cb)
907 (cb_data->cb) (cb_data->self, id, error, cb_data->user_data);
910 g_clear_error(&error);
911 g_slice_free (IdentityStoreCredentialsCbData, cb_data);
915 identity_verify_reply (GObject *object, GAsyncResult *res,
918 SsoIdentity *proxy = SSO_IDENTITY (object);
920 GError *error = NULL;
921 IdentityVerifyCbData *cb_data = (IdentityVerifyCbData *)userdata;
923 g_return_if_fail (cb_data != NULL);
924 g_return_if_fail (cb_data->self != NULL);
926 sso_identity_call_verify_secret_finish (proxy, &valid, res, &error);
928 if (SIGNON_IS_NOT_CANCELLED (error) && cb_data->cb)
930 (cb_data->cb) (cb_data->self, valid, error, cb_data->user_data);
933 g_clear_error(&error);
934 g_slice_free (IdentityVerifyCbData, cb_data);
938 identity_verify_ready_cb (gpointer object, const GError *error, gpointer user_data)
940 g_return_if_fail (SIGNON_IS_IDENTITY (object));
942 SignonIdentity *self = SIGNON_IDENTITY (object);
943 SignonIdentityPrivate *priv = self->priv;
944 g_return_if_fail (priv != NULL);
946 DEBUG ("%s %d", G_STRFUNC, __LINE__);
948 IdentityVerifyData *operation_data =
949 (IdentityVerifyData *)user_data;
950 g_return_if_fail (operation_data != NULL);
952 IdentityVerifyCbData *cb_data = operation_data->cb_data;
953 g_return_if_fail (cb_data != NULL);
955 if (priv->removed == TRUE)
957 GError *new_error = g_error_new (signon_error_quark(),
958 SIGNON_ERROR_IDENTITY_NOT_FOUND,
959 "Already removed from database.");
963 (cb_data->cb) (self, FALSE, new_error, cb_data->user_data);
966 g_error_free (new_error);
967 g_slice_free (IdentityVerifyCbData, cb_data);
971 DEBUG ("IdentityError: %s", error->message);
975 (cb_data->cb) (self, FALSE, error, cb_data->user_data);
978 g_slice_free (IdentityVerifyCbData, cb_data);
982 DEBUG ("%s %d", G_STRFUNC, __LINE__);
983 g_return_if_fail (priv->proxy != NULL);
985 switch (operation_data->operation) {
986 case SIGNON_VERIFY_SECRET:
987 sso_identity_call_verify_secret (priv->proxy,
988 operation_data->data_to_send,
990 identity_verify_reply,
993 default: g_critical ("Wrong operation code");
996 g_free (operation_data->params);
997 g_free (operation_data->data_to_send);
998 g_slice_free (IdentityVerifyData, operation_data);
1002 identity_verify_data(SignonIdentity *self,
1003 const gchar *data_to_send,
1005 SignonIdentityVerifyCb cb,
1008 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1010 SignonIdentityPrivate *priv = self->priv;
1011 g_return_if_fail (priv != NULL);
1013 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1015 IdentityVerifyCbData *cb_data = g_slice_new0 (IdentityVerifyCbData);
1016 cb_data->self = self;
1018 cb_data->user_data = user_data;
1020 IdentityVerifyData *operation_data = g_slice_new0 (IdentityVerifyData);
1022 operation_data->params = NULL;
1023 operation_data->data_to_send = g_strdup (data_to_send);
1024 operation_data->operation = operation;
1025 operation_data->cb_data = cb_data;
1027 identity_check_remote_registration (self);
1028 _signon_object_call_when_ready (self,
1029 identity_object_quark(),
1030 identity_verify_ready_cb,
1035 * signon_identity_verify_secret:
1036 * @self: the #SignonIdentity.
1037 * @secret: the secret (password) to be verified.
1038 * @cb: (scope async): callback.
1039 * @user_data: user_data.
1041 * Verifies the given secret.
1043 void signon_identity_verify_secret(SignonIdentity *self,
1044 const gchar *secret,
1045 SignonIdentityVerifyCb cb,
1048 identity_verify_data (self,
1050 SIGNON_VERIFY_SECRET,
1056 identity_process_updated (SignonIdentity *self)
1058 DEBUG ("%d %s", __LINE__, __func__);
1060 g_return_if_fail (self != NULL);
1061 g_return_if_fail (self->priv != NULL);
1063 SignonIdentityPrivate *priv = self->priv;
1064 g_return_if_fail (priv->proxy != NULL);
1066 signon_identity_info_free (priv->identity_info);
1067 priv->identity_info = NULL;
1068 priv->updated = FALSE;
1070 DEBUG ("%s info freed, to be updated", __func__);
1074 identity_process_removed (SignonIdentity *self)
1076 g_return_if_fail (self != NULL);
1077 g_return_if_fail (self->priv != NULL);
1079 DEBUG ("%d %s", __LINE__, __func__);
1081 SignonIdentityPrivate *priv = self->priv;
1083 if (priv->removed == TRUE)
1086 priv->removed = TRUE;
1087 signon_identity_info_free (priv->identity_info);
1088 priv->identity_info = NULL;
1090 g_object_set (self, "id", 0, NULL);
1095 identity_process_signout(SignonIdentity *self)
1097 g_return_if_fail (self != NULL);
1098 g_return_if_fail (self->priv != NULL);
1100 DEBUG ("%d %s", __LINE__, __func__);
1101 SignonIdentityPrivate *priv = self->priv;
1103 if (priv->signed_out == TRUE)
1106 GSList *llink = priv->sessions;
1109 GSList *next = llink->next;
1110 g_object_unref (G_OBJECT(llink->data));
1114 priv->signed_out = TRUE;
1115 g_signal_emit(G_OBJECT(self), signals[SIGNEDOUT_SIGNAL], 0);
1119 * TODO: fix the implementation
1120 * of signond: it returns result = TRUE
1124 identity_signout_reply (GObject *object, GAsyncResult *res,
1127 SsoIdentity *proxy = SSO_IDENTITY (object);
1129 GError *error = NULL;
1130 IdentityVoidCbData *cb_data = (IdentityVoidCbData *)userdata;
1132 g_return_if_fail (cb_data != NULL);
1133 g_return_if_fail (cb_data->self != NULL);
1134 g_return_if_fail (cb_data->self->priv != NULL);
1136 sso_identity_call_sign_out_finish (proxy, &result, res, &error);
1138 if (SIGNON_IS_NOT_CANCELLED (error) && cb_data->cb)
1140 (cb_data->cb) (cb_data->self, error, cb_data->user_data);
1143 g_clear_error(&error);
1144 g_slice_free (IdentityVoidCbData, cb_data);
1148 identity_removed_reply (GObject *object, GAsyncResult *res,
1151 SsoIdentity *proxy = SSO_IDENTITY (object);
1152 GError *error = NULL;
1153 IdentityVoidCbData *cb_data = (IdentityVoidCbData *)userdata;
1155 g_return_if_fail (cb_data != NULL);
1156 g_return_if_fail (cb_data->self != NULL);
1157 g_return_if_fail (cb_data->self->priv != NULL);
1159 sso_identity_call_remove_finish (proxy, res, &error);
1161 if (SIGNON_IS_NOT_CANCELLED (error) && cb_data->cb)
1163 (cb_data->cb) (cb_data->self, error, cb_data->user_data);
1166 g_clear_error(&error);
1167 g_slice_free (IdentityVoidCbData, cb_data);
1171 identity_info_reply(GObject *object, GAsyncResult *res,
1174 SsoIdentity *proxy = SSO_IDENTITY (object);
1175 GVariant *identity_data = NULL;
1176 DEBUG ("%d %s", __LINE__, __func__);
1178 GError *error = NULL;
1179 IdentityInfoCbData *cb_data = (IdentityInfoCbData *)userdata;
1181 g_return_if_fail (cb_data != NULL);
1182 g_return_if_fail (cb_data->self != NULL);
1183 g_return_if_fail (cb_data->self->priv != NULL);
1185 SignonIdentityPrivate *priv = cb_data->self->priv;
1187 sso_identity_call_get_info_finish (proxy, &identity_data, res, &error);
1189 if (identity_data != NULL)
1191 priv->identity_info =
1192 signon_identity_info_new_from_variant (identity_data);
1193 g_variant_unref (identity_data);
1196 if (SIGNON_IS_NOT_CANCELLED (error) && cb_data->cb)
1198 (cb_data->cb) (cb_data->self, priv->identity_info, error, cb_data->user_data);
1201 g_clear_error(&error);
1202 g_slice_free (IdentityInfoCbData, cb_data);
1204 priv->updated = TRUE;
1208 identity_info_ready_cb(gpointer object, const GError *error, gpointer user_data)
1210 g_return_if_fail (SIGNON_IS_IDENTITY (object));
1212 SignonIdentity *self = SIGNON_IDENTITY (object);
1213 SignonIdentityPrivate *priv = self->priv;
1214 g_return_if_fail (priv != NULL);
1216 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1218 IdentityVoidData *operation_data =
1219 (IdentityVoidData *)user_data;
1220 g_return_if_fail (operation_data != NULL);
1222 IdentityInfoCbData *cb_data = operation_data->cb_data;
1223 g_return_if_fail (cb_data != NULL);
1225 if (priv->removed == TRUE)
1227 DEBUG ("%s identity removed", G_STRFUNC);
1229 GError *new_error = g_error_new (signon_error_quark(),
1230 SIGNON_ERROR_IDENTITY_NOT_FOUND,
1231 "Already removed from database.");
1233 (cb_data->cb) (self, NULL, new_error, cb_data->user_data);
1235 g_error_free (new_error);
1237 else if (error || priv->id == 0)
1239 DEBUG ("%s identity is new", G_STRFUNC);
1242 DEBUG ("IdentityError: %s", error->message);
1244 DEBUG ("Identity is not stored and has no info yet");
1247 (cb_data->cb) (self, NULL, error, cb_data->user_data);
1249 else if (priv->updated == FALSE)
1251 DEBUG ("%s identity needs update, call daemon", G_STRFUNC);
1253 g_return_if_fail (priv->proxy != NULL);
1254 sso_identity_call_get_info (priv->proxy,
1256 identity_info_reply,
1262 DEBUG ("%s pass existing one", G_STRFUNC);
1265 (cb_data->cb) (self, priv->identity_info, error, cb_data->user_data);
1268 g_slice_free (IdentityInfoCbData, cb_data);
1271 g_slice_free (IdentityVoidData, operation_data);
1275 identity_signout_ready_cb(gpointer object, const GError *error, gpointer user_data)
1277 g_return_if_fail (SIGNON_IS_IDENTITY (object));
1279 SignonIdentity *self = SIGNON_IDENTITY (object);
1280 SignonIdentityPrivate *priv = self->priv;
1281 g_return_if_fail (priv != NULL);
1283 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1284 IdentityVoidCbData *cb_data = (IdentityVoidCbData *)user_data;
1286 g_return_if_fail (cb_data != NULL);
1288 if (priv->removed == TRUE)
1290 GError *new_error = g_error_new (signon_error_quark(),
1291 SIGNON_ERROR_IDENTITY_NOT_FOUND,
1292 "Already removed from database.");
1295 (cb_data->cb) (self, new_error, cb_data->user_data);
1298 g_error_free (new_error);
1299 g_slice_free (IdentityVoidCbData, cb_data);
1303 DEBUG ("IdentityError: %s", error->message);
1306 (cb_data->cb) (self, error, cb_data->user_data);
1309 g_slice_free (IdentityVoidCbData, cb_data);
1313 g_return_if_fail (priv->proxy != NULL);
1314 sso_identity_call_sign_out (priv->proxy,
1316 identity_signout_reply,
1322 identity_remove_ready_cb(gpointer object, const GError *error, gpointer user_data)
1324 g_return_if_fail (SIGNON_IS_IDENTITY (object));
1326 SignonIdentity *self = SIGNON_IDENTITY (object);
1327 SignonIdentityPrivate *priv = self->priv;
1328 g_return_if_fail (priv != NULL);
1330 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1331 IdentityVoidCbData *cb_data = (IdentityVoidCbData *)user_data;
1332 g_return_if_fail (cb_data != NULL);
1334 if (priv->removed == TRUE)
1336 GError *new_error = g_error_new (signon_error_quark(),
1337 SIGNON_ERROR_IDENTITY_NOT_FOUND,
1338 "Already removed from database.");
1341 (cb_data->cb) (self, new_error, cb_data->user_data);
1344 g_error_free (new_error);
1345 g_slice_free (IdentityVoidCbData, cb_data);
1349 DEBUG ("IdentityError: %s", error->message);
1352 (cb_data->cb) (self, error, cb_data->user_data);
1355 g_slice_free (IdentityVoidCbData, cb_data);
1359 g_return_if_fail (priv->proxy != NULL);
1360 sso_identity_call_remove (priv->proxy,
1362 identity_removed_reply,
1368 identity_void_operation(SignonIdentity *self,
1372 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1374 SignonIdentityPrivate *priv = self->priv;
1375 g_return_if_fail (priv != NULL);
1377 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1379 IdentityVoidData *operation_data = g_slice_new0 (IdentityVoidData);
1380 operation_data->cb_data = cb_data;
1381 _signon_object_call_when_ready (self,
1382 identity_object_quark(),
1383 identity_info_ready_cb,
1388 * signon_identity_remove:
1389 * @self: the #SignonIdentity.
1390 * @cb: (scope async): callback to be called when the operation has completed.
1391 * @user_data: user_data to pass to the callback.
1393 * Removes the corresponding credentials record from the database.
1395 void signon_identity_remove(SignonIdentity *self,
1396 SignonIdentityRemovedCb cb,
1399 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1401 SignonIdentityPrivate *priv = self->priv;
1402 g_return_if_fail (priv != NULL);
1404 IdentityVoidCbData *cb_data = g_slice_new0 (IdentityVoidCbData);
1405 cb_data->self = self;
1406 cb_data->cb = (SignonIdentityVoidCb)cb;
1407 cb_data->user_data = user_data;
1409 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1411 identity_check_remote_registration (self);
1412 _signon_object_call_when_ready (self,
1413 identity_object_quark(),
1414 identity_remove_ready_cb,
1419 * signon_identity_signout:
1420 * @self: the #SignonIdentity.
1421 * @cb: (scope async): callback.
1422 * @user_data: user_data.
1424 * Asks signond to close all authentication sessions for this
1425 * identity, and to remove any stored secrets associated with it (password and
1426 * authentication tokens).
1428 void signon_identity_signout(SignonIdentity *self,
1429 SignonIdentitySignedOutCb cb,
1432 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1434 SignonIdentityPrivate *priv = self->priv;
1435 g_return_if_fail (priv != NULL);
1437 IdentityVoidCbData *cb_data = g_slice_new0 (IdentityVoidCbData);
1438 cb_data->self = self;
1439 cb_data->cb = (SignonIdentityVoidCb)cb;
1440 cb_data->user_data = user_data;
1442 identity_check_remote_registration (self);
1443 _signon_object_call_when_ready (self,
1444 identity_object_quark(),
1445 identity_signout_ready_cb,
1450 * signon_identity_add_reference:
1451 * @self: the #SignonIdentity.
1452 * @reference: reference to be added
1454 * @user_data: user_data.
1456 * Adds named reference to identity
1458 void signon_identity_add_reference(SignonIdentity *self,
1459 const gchar *reference,
1460 SignonIdentityReferenceAddedCb cb,
1463 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1465 SignonIdentityPrivate *priv = self->priv;
1466 g_return_if_fail (priv != NULL);
1471 (cb) (self, NULL, user_data);
1475 * signon_identity_remove_reference:
1476 * @self: the #SignonIdentity.
1477 * @reference: reference to be removed
1479 * @user_data: user_data.
1481 * Removes named reference from identity
1483 void signon_identity_remove_reference(SignonIdentity *self,
1484 const gchar *reference,
1485 SignonIdentityReferenceRemovedCb cb,
1488 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1490 SignonIdentityPrivate *priv = self->priv;
1491 g_return_if_fail (priv != NULL);
1496 (cb) (self, NULL, user_data);
1500 * signon_identity_query_info:
1501 * @self: the #SignonIdentity.
1502 * @cb: (scope async): callback.
1503 * @user_data: user_data.
1505 * Fetches the #SignonIdentityInfo data associated with this
1508 void signon_identity_query_info(SignonIdentity *self,
1509 SignonIdentityInfoCb cb,
1512 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1514 SignonIdentityPrivate *priv = self->priv;
1515 g_return_if_fail (priv != NULL);
1517 IdentityInfoCbData *cb_data = g_slice_new0 (IdentityInfoCbData);
1518 cb_data->self = self;
1520 cb_data->user_data = user_data;
1522 identity_check_remote_registration (self);
1523 identity_void_operation(self,
1529 identity_get_auth_session_reply (GObject *object, GAsyncResult *res,
1532 SsoIdentity *proxy = SSO_IDENTITY (object);
1533 gchar *object_path = NULL;
1534 GError *error = NULL;
1536 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1538 sso_identity_call_get_auth_session_finish (proxy,
1543 IdentitySessionCbData *cb_data = (IdentitySessionCbData *) userdata;
1544 g_return_if_fail (cb_data != NULL);
1545 g_return_if_fail (cb_data->cb != NULL);
1547 if (SIGNON_IS_NOT_CANCELLED (error))
1549 (cb_data->cb) (cb_data->session,
1551 g_dbus_proxy_get_connection ((GDBusProxy *)proxy),
1552 g_dbus_proxy_get_name ((GDBusProxy *)proxy),
1555 g_slice_free (IdentitySessionCbData, cb_data);
1556 if (object_path) g_free (object_path);
1557 g_clear_error (&error);
1561 identity_session_ready_cb(gpointer object, const GError *error, gpointer user_data)
1563 g_return_if_fail (SIGNON_IS_IDENTITY (object));
1564 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1566 SignonIdentity *self = SIGNON_IDENTITY (object);
1567 SignonIdentityPrivate *priv = self->priv;
1568 g_return_if_fail (priv != NULL);
1570 IdentitySessionData *operation_data = (IdentitySessionData *) user_data;
1571 g_return_if_fail (operation_data != NULL);
1573 IdentitySessionCbData *cb_data = operation_data->cb_data;
1574 g_return_if_fail (cb_data != NULL);
1575 g_return_if_fail (cb_data->cb != NULL);
1579 (cb_data->cb) (cb_data->session, (GError *)error, NULL, NULL, NULL);
1581 else if (priv->removed == TRUE)
1583 GError *new_error = g_error_new (signon_error_quark(),
1584 SIGNON_ERROR_IDENTITY_NOT_FOUND,
1585 "Already removed from database.");
1586 (cb_data->cb) (cb_data->session, new_error, NULL, NULL, NULL);
1587 g_error_free (new_error);
1591 g_return_if_fail (priv->proxy != NULL);
1593 sso_identity_call_get_auth_session (
1595 operation_data->method,
1597 identity_get_auth_session_reply,
1601 g_slice_free (IdentitySessionData, operation_data);
1605 identity_session_object_destroyed_cb(gpointer data,
1606 GObject *where_the_session_was)
1608 g_return_if_fail (SIGNON_IS_IDENTITY (data));
1609 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1611 SignonIdentity *self = SIGNON_IDENTITY (data);
1612 SignonIdentityPrivate *priv = self->priv;
1613 g_return_if_fail (priv != NULL);
1615 priv->sessions = g_slist_remove(priv->sessions, (gpointer)where_the_session_was);
1616 g_object_unref (self);
1620 * signon_identity_get_auth_session:
1621 * @self: the #SignonIdentity.
1622 * @session: the #SignonAuthSession object to get the remote object for.
1623 * @method: method name for the session.
1624 * @cb: (scope async): completion callback.
1626 * Obtain a remote object for a local session object.
1628 void signon_identity_get_auth_session (SignonIdentity *self,
1629 SignonAuthSession *session,
1630 const gchar *method,
1631 SignonIdentitySessionReadyCb cb)
1633 g_return_if_fail (SIGNON_IS_IDENTITY (self));
1634 DEBUG ("%s %d", G_STRFUNC, __LINE__);
1636 SignonIdentityPrivate *priv = self->priv;
1637 g_return_if_fail (priv != NULL);
1639 IdentitySessionCbData *cb_data = g_slice_new0 (IdentitySessionCbData);
1640 cb_data->self = self;
1641 cb_data->session = session;
1644 IdentitySessionData *operation_data = g_slice_new0 (IdentitySessionData);
1645 operation_data->method = method;
1646 operation_data->cb_data = cb_data;
1648 identity_check_remote_registration (self);
1649 _signon_object_call_when_ready (self,
1650 identity_object_quark(),
1651 identity_session_ready_cb,