[gnome-online-accounts/wip/kerberos: 7/7] stuff that needs to be squashed



commit d0b4bef8a97928a4104b14d4205dc2566a6c9f71
Author: Ray Strode <rstrode redhat com>
Date:   Wed Aug 15 19:48:26 2012 -0400

    stuff that needs to be squashed

 data/dbus-interfaces.xml                     |    7 +
 src/Makefile.am                              |    2 +-
 src/goabackend/Makefile.am                   |   17 +-
 src/goabackend/goakerberosprovider.c         | 1043 +++++++++++++++++---------
 src/goabackend/org.gnome.Identity.xml        |   73 --
 src/goaidentity/Makefile.am                  |    2 +
 src/goaidentity/goaalarm.c                   |   25 +-
 src/goaidentity/goaidentity.c                |    6 -
 src/goaidentity/goaidentity.h                |    2 -
 src/goaidentity/goaidentityservice.c         |  800 ++++++++++----------
 src/goaidentity/goaidentityutils.c           |    4 +-
 src/goaidentity/goaidentityutils.h           |    4 +-
 src/goaidentity/goakerberosidentity.c        |  120 +---
 src/goaidentity/goakerberosidentitymanager.c |    2 +-
 src/goaidentity/org.gnome.Identity.xml       |    6 +
 15 files changed, 1142 insertions(+), 971 deletions(-)
---
diff --git a/data/dbus-interfaces.xml b/data/dbus-interfaces.xml
index 07aac04..c58aed0 100644
--- a/data/dbus-interfaces.xml
+++ b/data/dbus-interfaces.xml
@@ -486,6 +486,13 @@
       ticketing capabilities.
   -->
   <interface name="org.gnome.OnlineAccounts.Ticketing">
+    <!--
+      GetTicket:
+
+      Use this method to obtain an ticket that can be used to
+      access resources for the account.
+    -->
+    <method name="GetTicket"/>
   </interface>
 
 </node>
diff --git a/src/Makefile.am b/src/Makefile.am
index 21cf4e5..63a20e5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
 
 NULL =
 
-SUBDIRS = goa goabackend goaidentity daemon examples
+SUBDIRS = goa goaidentity goabackend daemon examples
 
 -include $(top_srcdir)/git.mk
diff --git a/src/goabackend/Makefile.am b/src/goabackend/Makefile.am
index b9d607f..ee2536d 100644
--- a/src/goabackend/Makefile.am
+++ b/src/goabackend/Makefile.am
@@ -6,6 +6,7 @@ EXTRA_DIST =
 INCLUDES = 							\
 	-I$(top_builddir)/src -I$(top_srcdir)/src		\
 	-I$(top_builddir)/src -I$(top_srcdir)/src		\
+	-I$(top_srcdir)/src/goaidentity				\
 	-DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" 		\
 	-DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" 		\
 	-DPACKAGE_DATA_DIR=\""$(datadir)"\" 			\
@@ -35,19 +36,6 @@ enum_built_sources =							\
 
 EXTRA_DIST += goabackendenumtypes.h.template goabackendenumtypes.c.template
 
-dbus_built_sources = org.gnome.Identity.c org.gnome.Identity.h
-
-$(dbus_built_sources) : Makefile.am org.gnome.Identity.xml
-	gdbus-codegen                                       \
-		--interface-prefix org.gnome.Identity.      \
-		--c-namespace GoaIdentity                   \
-		--c-generate-object-manager                 \
-		--generate-c-code org.gnome.Identity        \
-		org.gnome.Identity.xml                      \
-		$(NULL)
-
-EXTRA_DIST += $(dbus_built_sources)
-
 # ----------------------------------------------------------------------------------------------------
 
 lib_LTLIBRARIES = libgoa-backend-1.0.la
@@ -71,7 +59,6 @@ libgoa_backend_1_0_la_HEADERS =						\
 	goayahooprovider.h						\
 	goatwitterprovider.h						\
 	goawindowsliveprovider.h					\
-	org.gnome.Identity.h						\
 	$(NULL)
 
 libgoa_backend_1_0_la_SOURCES =						\
@@ -95,7 +82,7 @@ libgoa_backend_1_0_la_SOURCES =						\
 	goautils.h			goautils.c			\
 	goawebview.h			goawebview.c			\
 	nautilus-floating-bar.h		nautilus-floating-bar.c		\
-	org.gnome.Identity.c		 org.gnome.Identity.h		\
+	$(top_srcdir)/src/goaidentity/org.gnome.Identity.c		\
 	$(NULL)
 
 libgoa_backend_1_0_la_CPPFLAGS =				\
diff --git a/src/goabackend/goakerberosprovider.c b/src/goabackend/goakerberosprovider.c
index 1b8b75b..a6f0d8e 100644
--- a/src/goabackend/goakerberosprovider.c
+++ b/src/goabackend/goakerberosprovider.c
@@ -42,7 +42,8 @@ struct _GoaKerberosProvider
 {
   /*< private >*/
   GoaProvider parent_instance;
-  GoaIdentityManager *identity_manager;
+  GoaIdentityServiceManager *identity_manager;
+  GDBusObjectManager *object_manager;
 };
 
 typedef struct _GoaKerberosProviderClass GoaKerberosProviderClass;
@@ -78,96 +79,6 @@ get_provider_name (GoaProvider *provider, GoaObject *object)
   return g_strdup(_("Enterprise Identity"));
 }
 
-static gboolean
-build_object (GoaProvider         *provider,
-              GoaObjectSkeleton   *object,
-              GKeyFile            *key_file,
-              const gchar         *group,
-              gboolean             just_added,
-              GError             **error)
-{
-  GoaAccount   *account;
-  GoaTicketing *ticketing;
-  gboolean      ticketing_enabled;
-  gboolean      ret;
-
-  ret = FALSE;
-
-  if (!GOA_PROVIDER_CLASS (goa_kerberos_provider_parent_class)->build_object (provider,
-                                                                              object,
-                                                                              key_file,
-                                                                              group,
-                                                                              just_added,
-                                                                              error))
-    goto out;
-
-  account = goa_object_get_account (GOA_OBJECT (object));
-
-  ticketing = goa_object_get_ticketing (GOA_OBJECT (object));
-  ticketing_enabled = g_key_file_get_boolean (key_file, group, "TicketingEnabled", NULL);
-
-  if (ticketing_enabled)
-    {
-      if (ticketing == NULL)
-        {
-          ticketing = goa_ticketing_skeleton_new ();
-          goa_object_skeleton_set_ticketing (object, ticketing);
-        }
-    }
-  else
-    {
-      if (ticketing != NULL)
-        goa_object_skeleton_set_ticketing (object, NULL);
-    }
-
-  if (just_added)
-    {
-      goa_account_set_ticketing_disabled (account, !ticketing_enabled);
-
-      g_signal_connect (account,
-                        "notify::ticketing-disabled",
-                        G_CALLBACK (goa_util_account_notify_property_cb),
-                        "TicketingEnabled");
-    }
-
-  ret = TRUE;
-
- out:
-  if (ticketing != NULL)
-    g_object_unref (ticketing);
-
-  return ret;
-}
-
-static void
-add_entry (GtkWidget     *grid1,
-           GtkWidget     *grid2,
-           const gchar   *text,
-           GtkWidget    **out_entry)
-{
-  GtkStyleContext *context;
-  GtkWidget *label;
-  GtkWidget *entry;
-
-  label = gtk_label_new_with_mnemonic (text);
-  context = gtk_widget_get_style_context (label);
-  gtk_style_context_add_class (context, GTK_STYLE_CLASS_DIM_LABEL);
-  gtk_widget_set_vexpand (label, TRUE);
-  gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
-  gtk_container_add (GTK_CONTAINER (grid1), label);
-
-  entry = gtk_entry_new ();
-  gtk_widget_set_hexpand (entry, TRUE);
-  gtk_widget_set_vexpand (entry, TRUE);
-  gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
-  gtk_entry_set_max_length (GTK_ENTRY (entry), 132);
-  gtk_container_add (GTK_CONTAINER (grid2), entry);
-
-  gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
-  if (out_entry != NULL)
-    *out_entry = entry;
-}
-
 typedef struct
 {
   GtkDialog *dialog;
@@ -189,85 +100,7 @@ typedef struct
 } SignInRequest;
 
 static void
-create_account_details_ui (GtkBox *vbox, gboolean new_account, SignInRequest *request)
-{
-  GtkWidget *header_grid;
-  GtkWidget *grid1;
-  GtkWidget *grid2;
-  GtkWidget *hbox;
-  GtkWidget *label;
-  gchar *markup;
-  gint width;
-
-  request->cluebar = gtk_info_bar_new ();
-  gtk_info_bar_set_message_type (GTK_INFO_BAR (request->cluebar), GTK_MESSAGE_ERROR);
-  gtk_widget_set_no_show_all (request->cluebar, TRUE);
-  gtk_box_pack_start (GTK_BOX (vbox), request->cluebar, FALSE, FALSE, 0);
-
-  request->cluebar_label = gtk_label_new ("");
-  gtk_label_set_line_wrap (GTK_LABEL (request->cluebar_label), TRUE);
-  gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (request->cluebar))),
-                     request->cluebar_label);
-
-  header_grid = gtk_grid_new ();
-  gtk_orientable_set_orientation (GTK_ORIENTABLE (header_grid), GTK_ORIENTATION_HORIZONTAL);
-  gtk_box_pack_start (vbox, header_grid, FALSE, FALSE, 0);
-
-  label = gtk_label_new (NULL);
-  gtk_widget_set_hexpand (label, TRUE);
-  markup = g_strconcat ("<b>",
-                        (new_account) ? _("New Enterprise Identity") : _("Enterpise Identity"),
-                        "</b>",
-                        NULL);
-  gtk_label_set_markup (GTK_LABEL (label), markup);
-  g_free (markup);
-  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-  gtk_container_add (GTK_CONTAINER (header_grid), label);
-
-  request->spinner = gtk_spinner_new ();
-  gtk_widget_set_no_show_all (request->spinner, TRUE);
-  gtk_container_add (GTK_CONTAINER (header_grid), request->spinner);
-
-  grid1 = gtk_grid_new ();
-  gtk_orientable_set_orientation (GTK_ORIENTABLE (grid1), GTK_ORIENTATION_VERTICAL);
-  gtk_grid_set_row_spacing (GTK_GRID (grid1), 12);
-
-  grid2 = gtk_grid_new ();
-  gtk_orientable_set_orientation (GTK_ORIENTABLE (grid2), GTK_ORIENTATION_VERTICAL);
-  gtk_grid_set_row_spacing (GTK_GRID (grid2), 12);
-
-  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
-  gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
-  gtk_box_pack_start (GTK_BOX (hbox), grid1, FALSE, FALSE, 0);
-  gtk_box_pack_start (GTK_BOX (hbox), grid2, TRUE, TRUE, 0);
-  gtk_box_pack_start (vbox, hbox, FALSE, FALSE, 0);
-
-  add_entry (grid1, grid2, _("User_name"), &request->username);
-  add_entry (grid1, grid2, _("_Realm"), &request->realm);
-
-  gtk_widget_grab_focus (request->username);
-
-  gtk_dialog_add_button (request->dialog, GTK_STOCK_CONNECT, GTK_RESPONSE_OK);
-  gtk_dialog_set_default_response (request->dialog, GTK_RESPONSE_OK);
-  gtk_dialog_set_response_sensitive (request->dialog, GTK_RESPONSE_OK, TRUE);
-
-  gtk_window_get_size (GTK_WINDOW (request->dialog), &width, NULL);
-  gtk_widget_set_size_request (GTK_WIDGET (request->dialog), width, -1);
-}
-
-static void
-add_account_cb (GoaManager *manager, GAsyncResult *res, gpointer user_request)
-{
-  SignInRequest *request = user_request;
-  goa_manager_call_add_account_finish (manager,
-                                       &request->account_object_path,
-                                       res,
-                                       &request->error);
-  g_main_loop_quit (request->loop);
-}
-
-static void
-on_identity_signed_in (GoaIdentityManager *manager,
+on_identity_signed_in (GoaIdentityServiceManager *manager,
                        GAsyncResult       *result,
                        GSimpleAsyncResult *operation_result)
 {
@@ -276,15 +109,16 @@ on_identity_signed_in (GoaIdentityManager *manager,
   char     *identity_object_path;
 
   error = NULL;
-  signed_in = goa_identity_manager_call_sign_in_finish (manager,
-                                                        &identity_object_path,
-                                                        result,
-                                                        &error);
+  signed_in = goa_identity_service_manager_call_sign_in_finish (manager,
+                                                                &identity_object_path,
+                                                                result,
+                                                                &error);
 
   if (!signed_in)
     {
       g_simple_async_result_take_error (operation_result, error);
       g_simple_async_result_complete_in_idle (operation_result);
+      g_object_unref (operation_result);
       return;
     }
 
@@ -293,6 +127,7 @@ on_identity_signed_in (GoaIdentityManager *manager,
                                              (GDestroyNotify)
                                              g_free);
   g_simple_async_result_complete_in_idle (operation_result);
+  g_object_unref (operation_result);
 }
 
 static void
@@ -300,15 +135,16 @@ on_identity_manager_ensured (GoaKerberosProvider *self,
                              GAsyncResult        *result,
                              GSimpleAsyncResult  *operation_result)
 {
-  GoaIdentityManager *manager;
+  GoaIdentityServiceManager *manager;
   GError             *error;
 
   error = NULL;
-  manager = goa_identity_manager_proxy_new_for_bus_finish (result, &error);
+  manager = goa_identity_service_manager_proxy_new_for_bus_finish (result, &error);
   if (manager == NULL)
     {
       g_simple_async_result_take_error (operation_result, error);
       g_simple_async_result_complete_in_idle (operation_result);
+      g_object_unref (operation_result);
       return;
     }
 
@@ -317,6 +153,7 @@ on_identity_manager_ensured (GoaKerberosProvider *self,
                                              (GDestroyNotify)
                                              g_object_unref);
   g_simple_async_result_complete_in_idle (operation_result);
+  g_object_unref (operation_result);
 }
 
 static void
@@ -344,110 +181,553 @@ ensure_identity_manager (GoaKerberosProvider *self,
                                                  (GDestroyNotify)
                                                  g_object_unref);
       g_simple_async_result_complete_in_idle (operation_result);
+      g_object_unref (operation_result);
+      return;
+    }
+
+  goa_identity_service_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+                                                  G_DBUS_PROXY_FLAGS_NONE,
+                                                  "org.gnome.Identity",
+                                                  "/org/gnome/Identity/Manager",
+                                                  cancellable,
+                                                  (GAsyncReadyCallback)
+                                                  on_identity_manager_ensured,
+                                                  operation_result);
+}
+
+static void
+on_object_manager_ensured (GoaKerberosProvider *self,
+                           GAsyncResult        *result,
+                           GSimpleAsyncResult  *operation_result)
+{
+  GDBusObjectManager *manager;
+  GError *error;
+
+  error = NULL;
+  manager = goa_identity_service_object_manager_client_new_for_bus_finish (result, &error);
+  if (manager == NULL)
+    {
+      g_simple_async_result_take_error (operation_result, error);
+      g_simple_async_result_complete_in_idle (operation_result);
+      g_object_unref (operation_result);
+      return;
+    }
+
+  g_simple_async_result_set_op_res_gpointer (operation_result,
+                                             g_object_ref (manager),
+                                             (GDestroyNotify)
+                                             g_object_unref);
+  g_simple_async_result_complete_in_idle (operation_result);
+  g_object_unref (operation_result);
+}
+
+static void
+ensure_object_manager (GoaKerberosProvider *self,
+                       GCancellable        *cancellable,
+                       GAsyncReadyCallback  callback,
+                       gpointer             user_data)
+{
+  GSimpleAsyncResult *operation_result;
+
+  operation_result = g_simple_async_result_new (G_OBJECT (self),
+                                                callback,
+                                                user_data,
+                                                ensure_object_manager);
+  g_simple_async_result_set_check_cancellable (operation_result, cancellable);
+
+  g_object_set_data (G_OBJECT (operation_result),
+                     "cancellable",
+                     cancellable);
+
+  if (self->object_manager != NULL)
+    {
+      g_simple_async_result_set_op_res_gpointer (operation_result,
+                                                 g_object_ref (self->object_manager),
+                                                 (GDestroyNotify)
+                                                 g_object_unref);
+      g_simple_async_result_complete_in_idle (operation_result);
+      g_object_unref (operation_result);
       return;
     }
+  goa_identity_service_object_manager_client_new_for_bus (G_BUS_TYPE_SESSION,
+                                                          G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
+                                                          "org.gnome.Identity",
+                                                          "/org/gnome/Identity",
+                                                          cancellable,
+                                                          (GAsyncReadyCallback)
+                                                          on_object_manager_ensured,
+                                                          operation_result);
+}
+
+static void
+on_identity_manager_ensured_for_sign_in (GoaKerberosProvider *self,
+                                         GAsyncResult        *result,
+                                         GSimpleAsyncResult  *operation_result)
+{
+  GoaIdentityServiceManager *manager;
+  const char         *identifier;
+  const char         *password;
+  GCancellable       *cancellable;
+  GError             *error;
+  GVariantBuilder     details;
+
+  error = NULL;
+
+  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
+                                             &error))
+    {
+      g_simple_async_result_take_error (operation_result, error);
+      g_simple_async_result_complete_in_idle (operation_result);
+      g_object_unref (operation_result);
+      return;
+    }
+
+  manager = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+  if (self->identity_manager == NULL)
+    self->identity_manager = g_object_ref (manager);
+
+  cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+  password = g_object_get_data (G_OBJECT (operation_result), "password");
+  identifier = g_simple_async_result_get_source_tag (operation_result);
+
+  g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
+
+  if (password != NULL)
+    g_variant_builder_add (&details, "{ss}", "initial-password", password);
+
+  goa_identity_service_manager_call_sign_in (self->identity_manager,
+                                             identifier,
+                                             g_variant_builder_end (&details),
+                                             cancellable,
+                                             (GAsyncReadyCallback)
+                                             on_identity_signed_in,
+                                             operation_result);
+}
+
+static void
+sign_in_identity (GoaKerberosProvider  *self,
+                  const char           *identifier,
+                  const char           *password,
+                  GCancellable         *cancellable,
+                  GAsyncReadyCallback   callback,
+                  gpointer              user_data)
+{
+  GSimpleAsyncResult *operation_result;
+
+  operation_result = g_simple_async_result_new (G_OBJECT (self),
+                                                callback,
+                                                user_data,
+                                                (gpointer)
+                                                identifier);
+
+  g_simple_async_result_set_check_cancellable (operation_result, cancellable);
+
+  g_object_set_data (G_OBJECT (operation_result),
+                     "cancellable",
+                     cancellable);
+  g_object_set_data (G_OBJECT (operation_result),
+                     "password",
+                     (gpointer)
+                     password);
+
+  ensure_identity_manager (self,
+                           cancellable,
+                           (GAsyncReadyCallback)
+                           on_identity_manager_ensured_for_sign_in,
+                           operation_result);
+}
+
+static void
+on_object_manager_ensured_for_look_up (GoaKerberosProvider *self,
+                                       GAsyncResult        *result,
+                                       GSimpleAsyncResult  *operation_result)
+{
+  GDBusObjectManager *manager;
+  const char         *identifier;
+  GList              *objects, *node;
+  GError             *error;
+
+  error = NULL;
+
+  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
+                                             &error))
+    {
+      g_simple_async_result_take_error (operation_result, error);
+      g_simple_async_result_complete_in_idle (operation_result);
+      g_object_unref (operation_result);
+      return;
+    }
+
+  manager = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+  if (self->object_manager == NULL)
+    self->object_manager = g_object_ref (manager);
+
+  identifier = g_simple_async_result_get_source_tag (operation_result);
+
+  g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
+                                             NULL,
+                                             NULL);
+  objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (self->object_manager));
+
+  for (node = objects; node != NULL; node = node->next)
+    {
+      GoaIdentityServiceIdentity *candidate_identity;
+      const char                 *candidate_identifier;
+      GDBusObject                *object;
+
+      object = node->data;
+
+      candidate_identity = GOA_IDENTITY_SERVICE_IDENTITY (g_dbus_object_get_interface (object, "org.gnome.Identity"));
+
+      if (candidate_identity == NULL)
+        continue;
+
+      candidate_identifier = goa_identity_service_identity_get_identifier (candidate_identity);
+
+      if (g_strcmp0 (candidate_identifier, identifier) == 0)
+        {
+          g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
+                                                     candidate_identity,
+                                                     (GDestroyNotify)
+                                                     g_object_unref);
+          break;
+        }
+
+      g_object_unref (candidate_identity);
+    }
+
+  g_list_free_full (objects, (GDestroyNotify) g_object_unref);
+  g_simple_async_result_complete_in_idle (G_SIMPLE_ASYNC_RESULT (operation_result));
+  g_object_unref (operation_result);
+}
+
+static void
+look_up_identity (GoaKerberosProvider  *self,
+                  const char           *identifier,
+                  GCancellable         *cancellable,
+                  GAsyncReadyCallback   callback,
+                  gpointer              user_data)
+{
+  GSimpleAsyncResult *operation_result;
+
+  operation_result = g_simple_async_result_new (G_OBJECT (self),
+                                                callback,
+                                                user_data,
+                                                (gpointer)
+                                                identifier);
+
+  g_simple_async_result_set_check_cancellable (operation_result, cancellable);
+
+  g_object_set_data (G_OBJECT (operation_result),
+                     "cancellable",
+                     cancellable);
+  ensure_object_manager (self,
+                         cancellable,
+                         (GAsyncReadyCallback)
+                         on_object_manager_ensured_for_look_up,
+                         operation_result);
+}
+
+static void
+on_account_signed_in (GoaProvider   *provider,
+                      GAsyncResult  *result,
+                      SignInRequest *request)
+{
+  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
+                                             &request->error))
+    {
+      g_main_loop_quit (request->loop);
+      return;
+    }
+
+  g_main_loop_quit (request->loop);
+}
+
+static gboolean
+get_ticket_sync (GoaKerberosProvider *self,
+                 GoaObject           *object,
+                 gboolean             is_interactive,
+                 GCancellable        *cancellable,
+                 GError             **error)
+{
+  GVariant            *credentials;
+  GError              *lookup_error;
+  GoaAccount          *account;
+  const char          *identifier;
+  const char          *password;
+  SignInRequest        request;
+  gboolean             ret;
+
+  ret = FALSE;
+
+  account = goa_object_peek_account (object);
+  identifier = goa_account_get_identity (account);
+  password = NULL;
+
+  lookup_error = NULL;
+  credentials = goa_utils_lookup_credentials_sync (GOA_PROVIDER (self),
+                                                   object,
+                                                   cancellable,
+                                                   &lookup_error);
+  if (!is_interactive)
+    {
+      if (credentials == NULL)
+        {
+          if (lookup_error == NULL)
+              g_propagate_error (error, lookup_error);
+          else
+              g_set_error (error,
+                           GOA_ERROR,
+                           GOA_ERROR_NOT_AUTHORIZED,
+                           _("Could not find saved credentials for principal `%s' in keyring"), identifier);
+          goto out;
+        }
+
+      if (!g_variant_lookup (credentials, "password", "&s", &password))
+        {
+          g_set_error (error,
+                       GOA_ERROR,
+                       GOA_ERROR_NOT_AUTHORIZED,
+                       _("Did not find password for principal `%s' in credentials"),
+                       identifier);
+          goto out;
+        }
+    }
+
+  memset (&request, 0, sizeof (SignInRequest));
+  request.loop = g_main_loop_new (NULL, FALSE);
+  request.error = NULL;
+
+  sign_in_identity (self,
+                    identifier,
+                    password,
+                    NULL,
+                    (GAsyncReadyCallback)
+                    on_account_signed_in,
+                    &request);
+
+  g_main_loop_run (request.loop);
+  g_main_loop_unref (request.loop);
+
+  if (request.error != NULL)
+    {
+      g_propagate_error (error, request.error);
+      goto out;
+    }
+
+  ret = TRUE;
+out:
+  if (credentials != NULL)
+    g_variant_unref (credentials);
+
+  return ret;
+}
+
+static gboolean
+on_handle_get_ticket (GoaTicketing          *interface,
+                      GDBusMethodInvocation *invocation)
+{
+  GoaObject *object;
+  GoaAccount *account;
+  GoaProvider *provider;
+  GError *error;
+  gboolean got_ticket;
+
+  object = GOA_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (interface)));
+  account = goa_object_peek_account (object);
+
+  provider = goa_provider_get_for_provider_type (goa_account_get_provider_type (account));
+  error = NULL;
+  got_ticket = get_ticket_sync (GOA_KERBEROS_PROVIDER (provider),
+                                object,
+                                TRUE /* Allow interaction */,
+                                NULL,
+                                &error);
+
+  if (!got_ticket)
+    g_dbus_method_invocation_take_error (invocation, error);
+  else
+    goa_ticketing_complete_get_ticket (interface, invocation);
+
+  g_object_unref (provider);
+  return TRUE;
+}
+
+static gboolean
+build_object (GoaProvider         *provider,
+              GoaObjectSkeleton   *object,
+              GKeyFile            *key_file,
+              const gchar         *group,
+              gboolean             just_added,
+              GError             **error)
+{
+  GoaAccount   *account;
+  GoaTicketing *ticketing;
+  gboolean      ticketing_enabled;
+  gboolean      ret;
+
+  ret = FALSE;
+
+  if (!GOA_PROVIDER_CLASS (goa_kerberos_provider_parent_class)->build_object (provider,
+                                                                              object,
+                                                                              key_file,
+                                                                              group,
+                                                                              just_added,
+                                                                              error))
+    goto out;
+
+  account = goa_object_get_account (GOA_OBJECT (object));
+
+  ticketing = goa_object_get_ticketing (GOA_OBJECT (object));
+  ticketing_enabled = g_key_file_get_boolean (key_file, group, "TicketingEnabled", NULL);
+
+  if (ticketing_enabled)
+    {
+      if (ticketing == NULL)
+        {
+          ticketing = goa_ticketing_skeleton_new ();
+
+          g_signal_connect (ticketing,
+                            "handle-get-ticket",
+                            G_CALLBACK (on_handle_get_ticket),
+                            NULL);
+
+          goa_object_skeleton_set_ticketing (object, ticketing);
+
+        }
+    }
+  else if (ticketing != NULL)
+    {
+      goa_object_skeleton_set_ticketing (object, NULL);
+    }
+
+  if (just_added)
+    {
+      goa_account_set_ticketing_disabled (account, !ticketing_enabled);
+
+      g_signal_connect (account,
+                        "notify::ticketing-disabled",
+                        G_CALLBACK (goa_util_account_notify_property_cb),
+                        "TicketingEnabled");
+    }
+
+  ret = TRUE;
+
+ out:
+  if (ticketing != NULL)
+    g_object_unref (ticketing);
+
+  return ret;
+}
+
+static void
+add_entry (GtkWidget     *grid1,
+           GtkWidget     *grid2,
+           const gchar   *text,
+           GtkWidget    **out_entry)
+{
+  GtkStyleContext *context;
+  GtkWidget *label;
+  GtkWidget *entry;
+
+  label = gtk_label_new_with_mnemonic (text);
+  context = gtk_widget_get_style_context (label);
+  gtk_style_context_add_class (context, GTK_STYLE_CLASS_DIM_LABEL);
+  gtk_widget_set_vexpand (label, TRUE);
+  gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+  gtk_container_add (GTK_CONTAINER (grid1), label);
+
+  entry = gtk_entry_new ();
+  gtk_widget_set_hexpand (entry, TRUE);
+  gtk_widget_set_vexpand (entry, TRUE);
+  gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
+  gtk_entry_set_max_length (GTK_ENTRY (entry), 132);
+  gtk_container_add (GTK_CONTAINER (grid2), entry);
 
-  goa_identity_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION,
-                                          G_DBUS_PROXY_FLAGS_NONE,
-                                          "org.gnome.Identity",
-                                          "/org/gnome/Identity/Manager",
-                                          cancellable,
-                                          (GAsyncReadyCallback)
-                                          on_identity_manager_ensured,
-                                          operation_result);
+  gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
+  if (out_entry != NULL)
+    *out_entry = entry;
 }
 
 static void
-on_identity_manager_ensured_for_sign_in (GoaKerberosProvider *self,
-                                         GAsyncResult        *result,
-                                         GSimpleAsyncResult  *operation_result)
+create_account_details_ui (GtkBox        *vbox,
+                           gboolean       new_account,
+                           SignInRequest *request)
 {
-  GoaIdentityManager *manager;
-  const char         *identity;
-  const char         *password;
-  GCancellable       *cancellable;
-  GError             *error;
-  GVariantBuilder     details;
-
-  error = NULL;
+  GtkWidget *header_grid;
+  GtkWidget *grid1;
+  GtkWidget *grid2;
+  GtkWidget *hbox;
+  GtkWidget *label;
+  gchar *markup;
+  gint width;
 
-  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
-                                             &error))
-    {
-      g_simple_async_result_take_error (operation_result, error);
-      g_simple_async_result_complete_in_idle (operation_result);
-      return;
-    }
+  request->cluebar = gtk_info_bar_new ();
+  gtk_info_bar_set_message_type (GTK_INFO_BAR (request->cluebar), GTK_MESSAGE_ERROR);
+  gtk_widget_set_no_show_all (request->cluebar, TRUE);
+  gtk_box_pack_start (GTK_BOX (vbox), request->cluebar, FALSE, FALSE, 0);
 
-  manager = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+  request->cluebar_label = gtk_label_new ("");
+  gtk_label_set_line_wrap (GTK_LABEL (request->cluebar_label), TRUE);
+  gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (request->cluebar))),
+                     request->cluebar_label);
 
-  if (self->identity_manager == NULL) {
-        self->identity_manager = g_object_ref (manager);
-  }
+  header_grid = gtk_grid_new ();
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (header_grid), GTK_ORIENTATION_HORIZONTAL);
+  gtk_box_pack_start (vbox, header_grid, FALSE, FALSE, 0);
 
-  cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
-  password = g_object_get_data (G_OBJECT (operation_result), "password");
-  identity = g_simple_async_result_get_source_tag (operation_result);
+  label = gtk_label_new (NULL);
+  gtk_widget_set_hexpand (label, TRUE);
+  markup = g_strconcat ("<b>",
+                        (new_account) ? _("New Enterprise Identity") : _("Enterpise Identity"),
+                        "</b>",
+                        NULL);
+  gtk_label_set_markup (GTK_LABEL (label), markup);
+  g_free (markup);
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_container_add (GTK_CONTAINER (header_grid), label);
 
-  g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
+  request->spinner = gtk_spinner_new ();
+  gtk_widget_set_no_show_all (request->spinner, TRUE);
+  gtk_container_add (GTK_CONTAINER (header_grid), request->spinner);
 
-  if (password != NULL)
-    g_variant_builder_add (&details, "{ss}", "initial-password", password);
+  grid1 = gtk_grid_new ();
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (grid1), GTK_ORIENTATION_VERTICAL);
+  gtk_grid_set_row_spacing (GTK_GRID (grid1), 12);
 
-  goa_identity_manager_call_sign_in (self->identity_manager,
-                                     identity,
-                                     g_variant_builder_end (&details),
-                                     cancellable,
-                                     (GAsyncReadyCallback)
-                                     on_identity_signed_in,
-                                     operation_result);
-}
+  grid2 = gtk_grid_new ();
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (grid2), GTK_ORIENTATION_VERTICAL);
+  gtk_grid_set_row_spacing (GTK_GRID (grid2), 12);
 
-static void
-sign_in_identity (GoaKerberosProvider  *self,
-                  const char           *identity,
-                  const char           *password,
-                  GCancellable         *cancellable,
-                  GAsyncReadyCallback   callback,
-                  gpointer              user_data)
-{
-  GSimpleAsyncResult *operation_result;
+  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+  gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
+  gtk_box_pack_start (GTK_BOX (hbox), grid1, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (hbox), grid2, TRUE, TRUE, 0);
+  gtk_box_pack_start (vbox, hbox, FALSE, FALSE, 0);
 
-  operation_result = g_simple_async_result_new (G_OBJECT (self),
-                                                callback,
-                                                user_data,
-                                                (gpointer)
-                                                identity);
+  add_entry (grid1, grid2, _("User_name"), &request->username);
+  add_entry (grid1, grid2, _("_Realm"), &request->realm);
 
-  g_simple_async_result_set_check_cancellable (operation_result, cancellable);
+  gtk_widget_grab_focus (request->username);
 
-  g_object_set_data (G_OBJECT (operation_result),
-                     "cancellable",
-                     cancellable);
-  g_object_set_data (G_OBJECT (operation_result),
-                     "password",
-                     (gpointer)
-                     password);
+  gtk_dialog_add_button (request->dialog, GTK_STOCK_CONNECT, GTK_RESPONSE_OK);
+  gtk_dialog_set_default_response (request->dialog, GTK_RESPONSE_OK);
+  gtk_dialog_set_response_sensitive (request->dialog, GTK_RESPONSE_OK, TRUE);
 
-  ensure_identity_manager (self,
-                           cancellable,
-                           (GAsyncReadyCallback)
-                           on_identity_manager_ensured_for_sign_in,
-                           operation_result);
+  gtk_window_get_size (GTK_WINDOW (request->dialog), &width, NULL);
+  gtk_widget_set_size_request (GTK_WIDGET (request->dialog), width, -1);
 }
 
 static void
-on_account_signed_in (GoaProvider   *provider,
-                      GAsyncResult  *result,
-                      SignInRequest *request)
+add_account_cb (GoaManager *manager, GAsyncResult *res, gpointer user_request)
 {
-  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
-                                             &request->error))
-    {
-      g_main_loop_quit (request->loop);
-      return;
-    }
-
+  SignInRequest *request = user_request;
+  goa_manager_call_add_account_finish (manager,
+                                       &request->account_object_path,
+                                       res,
+                                       &request->error);
   g_main_loop_quit (request->loop);
 }
 
@@ -459,9 +739,7 @@ refresh_account (GoaProvider    *provider,
                  GError        **error)
 {
   GoaKerberosProvider *self = GOA_KERBEROS_PROVIDER (provider);
-  SignInRequest        request;
-  GoaAccount          *account;
-  const char          *identity;
+  gboolean             got_ticket;
 
   g_return_val_if_fail (GOA_IS_KERBEROS_PROVIDER (provider), FALSE);
   g_return_val_if_fail (GOA_IS_CLIENT (client), FALSE);
@@ -469,32 +747,13 @@ refresh_account (GoaProvider    *provider,
   g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), FALSE);
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
-  account = goa_object_peek_account (object);
-  identity = goa_account_get_identity (account);
-
-  memset (&request, 0, sizeof (SignInRequest));
-  request.loop = g_main_loop_new (NULL, FALSE);
-  request.error = NULL;
-
   error = NULL;
-  sign_in_identity (self,
-                    identity,
-                    NULL,
-                    NULL,
-                    (GAsyncReadyCallback)
-                    on_account_signed_in,
-                    &request);
-
-  g_main_loop_run (request.loop);
-  g_main_loop_unref (request.loop);
-
-  if (request.error != NULL)
-    {
-      g_propagate_error (error, request.error);
-      return FALSE;
-    }
-
-  return TRUE;
+  got_ticket = get_ticket_sync (self,
+                                object,
+                                TRUE /* Allow interaction */,
+                                NULL,
+                                error);
+  return got_ticket;
 }
 
 static GoaObject *
@@ -550,9 +809,7 @@ start_over:
    * given identity
    */
   provider_type = goa_provider_get_provider_type (provider);
-  /* FIXME: consider adding a new credentials interface for
-   * kerberos
-   */
+
   if (!goa_utils_check_duplicate (client,
                                   principal,
                                   provider_type,
@@ -668,6 +925,111 @@ show_account (GoaProvider         *provider,
                                                    _("Network Resources"));
 }
 
+static void
+on_identity_looked_up (GoaKerberosProvider *provider,
+                       GAsyncResult        *result,
+                       GSimpleAsyncResult  *operation_result)
+{
+
+  GoaIdentityServiceIdentity *identity;
+  GError                     *error;
+
+  error = NULL;
+  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
+    {
+      g_simple_async_result_take_error (operation_result, error);
+      g_simple_async_result_complete_in_idle (operation_result);
+      g_object_unref (operation_result);
+      return;
+    }
+
+  identity = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+  if (identity != NULL)
+    g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
+                                               g_object_ref (identity),
+                                               (GDestroyNotify)
+                                               g_object_unref);
+  else
+    g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
+                                               NULL,
+                                               NULL);
+
+  g_simple_async_result_complete_in_idle (operation_result);
+  g_object_unref (operation_result);
+}
+
+static void
+on_identity_looked_up_to_ensure_credentials (GoaKerberosProvider *self,
+                                             GAsyncResult        *result,
+                                             GSimpleAsyncResult  *operation_result)
+{
+
+  GoaIdentityServiceIdentity *identity;
+  GError                     *error;
+  GoaObject                  *object;
+  GoaAccount                 *account;
+  const char                 *identifier;
+  GCancellable               *cancellable;
+
+  error = NULL;
+  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
+    {
+      g_simple_async_result_take_error (operation_result, error);
+      g_simple_async_result_complete_in_idle (operation_result);
+      g_object_unref (operation_result);
+      return;
+    }
+
+  identity = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+  if (identity != NULL && goa_identity_service_identity_get_is_signed_in (identity))
+    {
+      g_simple_async_result_set_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (operation_result),
+                                                 g_object_ref (identity),
+                                                 (GDestroyNotify)
+                                                 g_object_unref);
+      g_simple_async_result_complete_in_idle (operation_result);
+      g_object_unref (operation_result);
+      return;
+    }
+
+  object = GOA_OBJECT (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
+  cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+
+  if (!get_ticket_sync (self,
+                        object,
+                        FALSE /* Don't allow interaction */,
+                        cancellable,
+                        &error))
+    {
+      g_simple_async_result_take_error (operation_result, error);
+      g_simple_async_result_complete_in_idle (operation_result);
+      g_object_unref (operation_result);
+      return;
+    }
+
+  account = goa_object_peek_account (object);
+  identifier = goa_account_get_identity (account);
+
+  look_up_identity (self,
+                    identifier,
+                    cancellable,
+                    (GAsyncReadyCallback)
+                    on_identity_looked_up,
+                    operation_result);
+
+  g_simple_async_result_complete_in_idle (operation_result);
+  g_object_unref (operation_result);
+}
+
+static void
+on_credentials_ensured (GoaObject    *object,
+                        GAsyncResult *result,
+                        GMainLoop    *loop)
+{
+  g_main_loop_quit (loop);
+}
+
 static gboolean
 ensure_credentials_sync (GoaProvider         *provider,
                          GoaObject           *object,
@@ -675,73 +1037,66 @@ ensure_credentials_sync (GoaProvider         *provider,
                          GCancellable        *cancellable,
                          GError             **error)
 {
-  GoaKerberosProvider *self = GOA_KERBEROS_PROVIDER (provider);
-  GVariant            *credentials;
-  GoaAccount          *account;
-  const char          *identity;
-  const char          *password;
-  SignInRequest        request;
-  gboolean             ret;
-
-  ret = FALSE;
+  GoaIdentityServiceIdentity *identity;
+  GoaAccount                 *account;
+  const char                 *identifier;
+  GSimpleAsyncResult         *operation_result;
+  GMainLoop                  *loop;
+  gint64                      timestamp;
+  GDateTime                  *now, *expiration_time;
+  GTimeSpan                   time_span;
 
   account = goa_object_peek_account (object);
-  identity = goa_account_get_identity (account);
+  identifier = goa_account_get_identity (account);
+
+  loop = g_main_loop_new (NULL, FALSE);
+  operation_result = g_simple_async_result_new (G_OBJECT (object),
+                                                (GAsyncReadyCallback)
+                                                on_credentials_ensured,
+                                                loop,
+                                                ensure_credentials_sync);
+  g_simple_async_result_set_check_cancellable (operation_result, cancellable);
 
-  credentials = goa_utils_lookup_credentials_sync (provider,
-                                                   object,
-                                                   cancellable,
-                                                   error);
-  if (credentials == NULL)
-    {
-      if (error != NULL && *error == NULL)
-        g_set_error (error,
-                     GOA_ERROR,
-                     GOA_ERROR_NOT_AUTHORIZED,
-                     _("Could not find saved credentials for principal `%s' in keyring"), identity);
-      goto out;
-    }
+  g_object_set_data (G_OBJECT (operation_result),
+                     "cancellable",
+                     cancellable);
+
+  g_object_ref (operation_result);
+  look_up_identity (GOA_KERBEROS_PROVIDER (provider),
+                    identifier,
+                    cancellable,
+                    (GAsyncReadyCallback)
+                    on_identity_looked_up_to_ensure_credentials,
+                    operation_result);
+
+  g_main_loop_run (loop);
+  g_main_loop_unref (loop);
 
-  if (!g_variant_lookup (credentials, "password", "&s", &password))
+  if (g_simple_async_result_propagate_error (operation_result, error))
     {
-      g_set_error (error,
-                   GOA_ERROR,
-                   GOA_ERROR_NOT_AUTHORIZED,
-                   _("Did not find password for principal `%s' in credentials"),
-                   identity);
-      goto out;
+      g_object_unref (operation_result);
+      return FALSE;
     }
 
-  memset (&request, 0, sizeof (SignInRequest));
-  request.loop = g_main_loop_new (NULL, FALSE);
-  request.error = NULL;
+  identity = g_simple_async_result_get_op_res_gpointer (operation_result);
 
-  error = NULL;
-  sign_in_identity (self,
-                    identity,
-                    password,
+  now = g_date_time_new_now_local ();
+  timestamp = goa_identity_service_identity_get_expiration_timestamp (identity);
+  expiration_time = g_date_time_new_from_unix_local (timestamp);
+  time_span = g_date_time_difference (expiration_time, now);
 
-                    NULL,
-                    (GAsyncReadyCallback)
-                    on_account_signed_in,
-                    &request);
+  time_span /= G_TIME_SPAN_SECOND;
 
-  g_main_loop_run (request.loop);
-  g_main_loop_unref (request.loop);
+  if (time_span < 0 || time_span > G_MAXINT)
+    time_span = 0;
 
-  if (request.error != NULL)
-    {
-      g_propagate_error (error, request.error);
-      goto out;
-    }
+  *out_expires_in = (int) time_span;
 
-  *out_expires_in = -1;
-  ret = TRUE;
-out:
-  if (credentials != NULL)
-    g_variant_unref (credentials);
+  g_date_time_unref (now);
+  g_date_time_unref (expiration_time);
+  g_object_unref (operation_result);
 
-  return ret;
+  return TRUE;
 }
 
 static void
@@ -750,11 +1105,11 @@ goa_kerberos_provider_init (GoaKerberosProvider *provider)
 }
 
 static void
-goa_kerberos_provider_class_init (GoaKerberosProviderClass *klass)
+goa_kerberos_provider_class_init (GoaKerberosProviderClass *kerberos_class)
 {
   GoaProviderClass *provider_class;
 
-  provider_class = GOA_PROVIDER_CLASS (klass);
+  provider_class = GOA_PROVIDER_CLASS (kerberos_class);
   provider_class->get_provider_type          = get_provider_type;
   provider_class->get_provider_name          = get_provider_name;
   provider_class->build_object               = build_object;
diff --git a/src/goaidentity/Makefile.am b/src/goaidentity/Makefile.am
index 8fa4ad3..46f1c92 100644
--- a/src/goaidentity/Makefile.am
+++ b/src/goaidentity/Makefile.am
@@ -56,6 +56,8 @@ $(identity_dbus_built_sources) : Makefile.am org.gnome.Identity.xml
 		--c-generate-object-manager			\
 		--generate-c-code org.gnome.Identity		\
 		org.gnome.Identity.xml				\
+		--annotate "org.gnome.Identity"			\
+		           "org.gtk.GDBus.C.Name" Identity	\
 		$(NULL)
 BUILT_SOURCES += $(identity_dbus_built_sources)
 EXTRA_DIST += org.gnome.Identity.xml
diff --git a/src/goaidentity/goaalarm.c b/src/goaidentity/goaalarm.c
index 545a5ec..e28dd86 100644
--- a/src/goaidentity/goaalarm.c
+++ b/src/goaidentity/goaalarm.c
@@ -392,6 +392,7 @@ schedule_wakeups_with_timerfd (GoaAlarm *self)
   struct itimerspec timer_spec;
   int fd;
   int result;
+  GSource *source;
   static gboolean seen_before = FALSE;
 
   if (!seen_before)
@@ -424,15 +425,16 @@ schedule_wakeups_with_timerfd (GoaAlarm *self)
   self->priv->type = GOA_ALARM_TYPE_TIMER;
   self->priv->timer.stream = g_unix_input_stream_new (fd, TRUE);
 
-  self->priv->timer.source =
+  source =
     g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM
                                            (self->priv->timer.stream),
                                            self->priv->cancellable);
+  self->priv->timer.source = source;
   g_source_set_callback (self->priv->timer.source,
                          (GSourceFunc) on_timer_source_ready, self,
                          (GDestroyNotify) clear_timer_source_pointer);
   g_source_attach (self->priv->timer.source, self->priv->context);
-  g_source_unref (self->priv->timer.source);
+  g_source_unref (source);
 
   return TRUE;
 
@@ -474,8 +476,9 @@ static void
 schedule_wakeups_with_timeout_source (GoaAlarm *self)
 {
   GDateTime *now;
-  GTimeSpan time_span;
-  guint interval;
+  GSource   *source;
+  GTimeSpan  time_span;
+  guint      interval;
 
   self->priv->type = GOA_ALARM_TYPE_TIMEOUT;
 
@@ -492,14 +495,16 @@ schedule_wakeups_with_timeout_source (GoaAlarm *self)
    */
   interval = MIN (interval, MAX_TIMEOUT_INTERVAL);
 
-  self->priv->timeout.source = g_timeout_source_new (interval);
+  source = g_timeout_source_new (interval);
+
+  self->priv->timeout.source = source;
   g_source_set_callback (self->priv->timeout.source,
                          (GSourceFunc)
                          on_timeout_source_ready,
                          self, (GDestroyNotify) clear_timeout_source_pointer);
 
   g_source_attach (self->priv->timeout.source, self->priv->context);
-  g_source_unref (self->priv->timeout.source);
+  g_source_unref (source);
 }
 
 static void
@@ -531,15 +536,19 @@ clear_immediate_wakeup_source_pointer (GoaAlarm *self)
 static void
 schedule_immediate_wakeup (GoaAlarm *self)
 {
-  self->priv->immediate_wakeup_source = g_idle_source_new ();
+  GSource *source;
 
+  source = g_idle_source_new ();
+
+  self->priv->immediate_wakeup_source = source;
   g_source_set_callback (self->priv->immediate_wakeup_source,
                          (GSourceFunc)
                          on_immediate_wakeup_source_ready,
                          self,
                          (GDestroyNotify) clear_immediate_wakeup_source_pointer);
+
   g_source_attach (self->priv->immediate_wakeup_source, self->priv->context);
-  g_source_unref (self->priv->immediate_wakeup_source);
+  g_source_unref (source);
 }
 
 void
diff --git a/src/goaidentity/goaidentity.c b/src/goaidentity/goaidentity.c
index 03894e9..cf2f146 100644
--- a/src/goaidentity/goaidentity.c
+++ b/src/goaidentity/goaidentity.c
@@ -64,12 +64,6 @@ goa_identity_error_quark (void)
   return error_quark;
 }
 
-char **
-goa_identity_get_identifier_components (GoaIdentity *self)
-{
-  return GOA_IDENTITY_GET_IFACE (self)->get_identifier_components (self);
-}
-
 const char *
 goa_identity_get_identifier (GoaIdentity *self)
 {
diff --git a/src/goaidentity/goaidentity.h b/src/goaidentity/goaidentity.h
index 14fed36..5ede717 100644
--- a/src/goaidentity/goaidentity.h
+++ b/src/goaidentity/goaidentity.h
@@ -41,7 +41,6 @@ struct _GoaIdentityInterface
   GTypeInterface base_interface;
 
   const char * (* get_identifier)            (GoaIdentity *identity);
-  char **      (* get_identifier_components) (GoaIdentity *identity);
   gboolean     (* is_signed_in)              (GoaIdentity *identity);
 };
 
@@ -71,7 +70,6 @@ GType  goa_identity_get_type    (void);
 GQuark goa_identity_error_quark (void);
 
 const char  *goa_identity_get_identifier            (GoaIdentity *identity);
-char       **goa_identity_get_identifier_components (GoaIdentity *identity);
 gboolean     goa_identity_is_signed_in              (GoaIdentity *identity);
 
 
diff --git a/src/goaidentity/goaidentityservice.c b/src/goaidentity/goaidentityservice.c
index 0c66f24..d3ec342 100644
--- a/src/goaidentity/goaidentityservice.c
+++ b/src/goaidentity/goaidentityservice.c
@@ -28,7 +28,6 @@
 #include <glib-object.h>
 #include <gio/gio.h>
 
-#include <libnotify/notify.h>
 #include <gcr/gcr.h>
 
 #include "goakerberosprovider.h"
@@ -49,13 +48,15 @@ struct _GoaIdentityServicePrivate
 };
 
 static void identity_service_manager_interface_init (GoaIdentityServiceManagerIface *interface);
-static void ask_to_sign_in (GoaIdentityService            *self,
-                            GoaIdentity                   *identity,
-                            gconstpointer                  initial_password,
-                            GoaIdentitySignInFlags         flags,
-                            GCancellable                  *cancellable,
-                            GAsyncReadyCallback            callback,
-                            gpointer                       user_data);
+
+static void
+ask_to_sign_in (GoaIdentityService            *self,
+                const char                    *identifier,
+                gconstpointer                  initial_password,
+                GoaIdentitySignInFlags         flags,
+                GCancellable                  *cancellable,
+                GAsyncReadyCallback            callback,
+                gpointer                       user_data);
 
 G_DEFINE_TYPE_WITH_CODE (GoaIdentityService,
                          goa_identity_service,
@@ -67,29 +68,17 @@ static char *
 get_object_path_for_identity (GoaIdentityService *self,
                               GoaIdentity        *identity)
 {
-  char **components;
-  GString *object_path;
-  int i;
-
-  components = goa_identity_get_identifier_components (identity);
-  object_path = g_string_new ("/org/gnome/Identity/Manager");
-
-  for (i = 0; components[i] != NULL; i++)
-    {
-      char *escaped_component;
-
-      g_string_append_c (object_path, '/');
-      escaped_component = goa_identity_utils_escape_object_path_component (components[i],
-                                                                           (gsize)
-                                                                           strlen (components[i]));
-
-      g_string_append (object_path, escaped_component);
+  const char *identifier;
+  char       *escaped_identifier;
+  char       *object_path;
 
-      g_free (escaped_component);
-    }
-  g_strfreev (components);
+  identifier = goa_identity_get_identifier (identity);
+  escaped_identifier = goa_identity_utils_escape_object_path (identifier,
+                                                              strlen (identifier));
+  object_path = g_strdup_printf ("/org/gnome/Identity/Identities/%s", escaped_identifier);
 
-  return g_string_free (object_path, FALSE);
+  g_free (escaped_identifier);
+  return object_path;
 }
 
 static char *
@@ -101,20 +90,27 @@ export_identity (GoaIdentityService *self,
   GDBusInterfaceSkeleton *interface;
 
   object_path = get_object_path_for_identity (self, identity);
+
   object = G_DBUS_OBJECT_SKELETON (goa_identity_service_object_skeleton_new (object_path));
-  interface = G_DBUS_INTERFACE_SKELETON (goa_identity_service_org_gnome_identity_skeleton_new ());
+  interface = G_DBUS_INTERFACE_SKELETON (goa_identity_service_identity_skeleton_new ());
 
   g_object_bind_property (G_OBJECT (identity),
                           "identifier",
                           G_OBJECT (interface),
                           "identifier",
-                          G_BINDING_DEFAULT);
+                          G_BINDING_SYNC_CREATE);
 
   g_object_bind_property (G_OBJECT (identity),
                           "expiration-timestamp",
                           G_OBJECT (interface),
                           "expiration-timestamp",
-                          G_BINDING_DEFAULT);
+                          G_BINDING_SYNC_CREATE);
+
+  g_object_bind_property (G_OBJECT (identity),
+                          "is-signed-in",
+                          G_OBJECT (interface),
+                          "is-signed-in",
+                          G_BINDING_SYNC_CREATE);
 
   g_dbus_object_skeleton_add_interface (object, interface);
   g_object_unref (interface);
@@ -132,6 +128,7 @@ unexport_identity (GoaIdentityService *self,
   char *object_path;
 
   object_path = get_object_path_for_identity (self, identity);
+
   g_dbus_object_manager_server_unexport (self->priv->identity_object_manager_server,
                                          object_path);
   g_free (object_path);
@@ -164,45 +161,120 @@ on_sign_in_done (GoaIdentityService *self,
     }
 
   g_simple_async_result_complete_in_idle (operation_result);
+  g_object_unref (operation_result);
+}
+
+static GoaObject *
+find_object_with_principal (GoaIdentityService *self,
+                            const char         *principal,
+                            gboolean            must_be_enabled)
+{
+  GList      *objects;
+  GList      *node;
+  GoaObject  *found_object;
+
+  objects = goa_client_get_accounts (self->priv->client);
+
+  found_object = NULL;
+  for (node = objects; node != NULL; node = node->next)
+    {
+      GoaObject *object = GOA_OBJECT (node->data);
+      GoaAccount *account;
+      const char *provider_type;
+      const char *account_identity;
+
+      account = goa_object_peek_account (object);
+
+      if (account == NULL)
+        continue;
+
+      provider_type = goa_account_get_provider_type (account);
+
+      if (g_strcmp0 (provider_type, "kerberos") != 0)
+        continue;
+
+      if (must_be_enabled)
+        {
+          GoaTicketing *ticketing;
+
+          ticketing = goa_object_peek_ticketing (object);
+
+          if (ticketing == NULL)
+              continue;
+        }
+
+      account_identity = goa_account_get_identity (account);
+
+      if (g_strcmp0 (account_identity, principal) == 0)
+        {
+          found_object = g_object_ref (object);
+          break;
+        }
+    }
+  g_list_free_full (objects, (GDestroyNotify) g_object_unref);
 
+  return found_object;
 }
 
 static void
-on_got_identity_for_sign_in (GoaIdentityManager *manager,
-                             GAsyncResult       *result,
-                             GSimpleAsyncResult *operation_result)
+on_credentials_ensured (GoaAccount         *account,
+                        GAsyncResult       *result,
+                        GoaIdentityService *self)
 {
-  GoaIdentityService *self;
-  GError             *error;
-  GoaIdentity        *identity;
-  char               *password;
-  GoaIdentitySignInFlags flags;
+  GError     *error;
+  const char *account_identity;
+  int         expires_in;
 
-  error = NULL;
-  identity = goa_identity_manager_get_identity_finish (manager, result, &error);
+  account_identity = goa_account_get_identity (account);
 
-  if (error != NULL)
+  error = NULL;
+  if (!goa_account_call_ensure_credentials_finish (account,
+                                                   &expires_in,
+                                                   result,
+                                                   &error))
     {
-      goa_debug ("GoaIdentityService: Identity could not be signed in: %s",
+      goa_debug ("GoaIdentityService: could not ensure credentials for account %s: %s",
+                 account_identity,
                  error->message);
+      g_error_free (error);
       return;
     }
 
-  self = GOA_IDENTITY_SERVICE (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
+  goa_debug ("GoaIdentityService: credentials for account %s ensured for %d seconds",
+             account_identity,
+             expires_in);
+}
 
-  password = g_object_get_data (G_OBJECT (result),
-                                "initial-password");
-  flags = (GoaIdentitySignInFlags) GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (result),
-                                                                        "sign-in-flags"));
+static gboolean
+should_ignore_object (GoaIdentityService *self,
+                      GoaObject          *object)
+{
+  GoaAccount *account;
 
-  ask_to_sign_in (self,
-                  identity,
-                  password,
-                  flags,
-                  NULL,
-                  (GAsyncReadyCallback)
-                  on_sign_in_done,
-                  operation_result);
+  account = goa_object_peek_account (object);
+
+  if (goa_account_get_ticketing_disabled (account))
+    return TRUE;
+
+  return FALSE;
+}
+
+static void
+ensure_account_credentials (GoaIdentityService *self,
+                            GoaObject          *object)
+{
+
+  GoaAccount *account;
+
+  if (should_ignore_object (self, object))
+    return;
+
+  account = goa_object_peek_account (object);
+  goa_account_call_ensure_credentials (account,
+                                       NULL,
+                                       (GAsyncReadyCallback)
+                                       on_credentials_ensured,
+                                       self);
 }
 
 static void
@@ -211,6 +283,10 @@ on_sign_in_handled (GoaIdentityService    *self,
                     GDBusMethodInvocation *invocation)
 {
   GError *error = NULL;
+  GoaObject *object;
+  char *principal;
+
+  principal = g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (result));
 
   if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
     {
@@ -225,6 +301,14 @@ on_sign_in_handled (GoaIdentityService    *self,
                                                      invocation,
                                                      object_path);
     }
+
+  object = find_object_with_principal (self, principal, TRUE);
+  g_free (principal);
+
+  if (object == NULL)
+    return;
+
+  ensure_account_credentials (self, object);
 }
 
 static void
@@ -259,51 +343,49 @@ goa_identity_service_handle_sign_in (GoaIdentityServiceManager *manager,
                                      GVariant                  *details)
 {
   GoaIdentityService     *self = GOA_IDENTITY_SERVICE (manager);
-  GSimpleAsyncResult     *result;
+  GSimpleAsyncResult     *operation_result;
   GoaIdentitySignInFlags  flags;
   char                   *secret_key;
+  gconstpointer           initial_password;
+  GCancellable           *cancellable;
 
   secret_key = NULL;
+  initial_password = NULL;
 
-  result = g_simple_async_result_new (G_OBJECT (self),
-                                      (GAsyncReadyCallback)
-                                      on_sign_in_handled,
-                                      g_object_ref (invocation),
-                                      goa_identity_service_handle_sign_in);
+  operation_result = g_simple_async_result_new (G_OBJECT (self),
+                                                (GAsyncReadyCallback)
+                                                on_sign_in_handled,
+                                                g_object_ref (invocation),
+                                                g_strdup (identifier));
 
   read_sign_in_details (manager, details, &flags, &secret_key);
 
-  g_object_set_data (G_OBJECT (result),
-                     "sign-in-flags",
-                     GUINT_TO_POINTER ((guint) flags));
-
   if (secret_key != NULL)
     {
       GcrSecretExchange  *secret_exchange;
-      gconstpointer       initial_password;
 
       secret_exchange = gcr_secret_exchange_new (NULL);
 
-      g_object_weak_ref (G_OBJECT (result),
+      g_object_weak_ref (G_OBJECT (operation_result),
                          (GWeakNotify)
                          g_object_unref,
                          secret_exchange);
 
       gcr_secret_exchange_receive (secret_exchange, secret_key);
       initial_password = gcr_secret_exchange_get_secret (secret_exchange, NULL);
-
-      g_object_set_data (G_OBJECT (result),
-                         "initial-password",
-                         (gpointer)
-                         initial_password);
     }
 
-  goa_identity_manager_get_identity (self->priv->identity_manager,
-                                     identifier,
-                                     NULL,
-                                     (GAsyncReadyCallback)
-                                     on_got_identity_for_sign_in,
-                                     result);
+  cancellable = g_cancellable_new ();
+  ask_to_sign_in (self,
+                  identifier,
+                  initial_password,
+                  flags,
+                  cancellable,
+                  (GAsyncReadyCallback)
+                  on_sign_in_done,
+                  operation_result);
+  g_object_unref (cancellable);
+
   return TRUE;
 }
 
@@ -450,68 +532,6 @@ on_identity_renewed (GoaIdentityManager *manager,
   goa_debug ("GoaIdentityService: identity renewed");
 }
 
-static gboolean
-should_ignore_object (GoaIdentityService *self,
-                      GoaObject          *object)
-{
-  GoaAccount *account;
-
-  account = goa_object_peek_account (object);
-
-  if (goa_account_get_ticketing_disabled (account))
-    return TRUE;
-
-  return FALSE;
-}
-
-static GoaObject *
-find_object_with_principal (GoaIdentityService *self,
-                            const char         *principal)
-{
-  GList      *objects;
-  GList      *node;
-  GoaObject  *found_object;
-
-  objects = goa_client_get_accounts (self->priv->client);
-
-  found_object = NULL;
-  for (node = objects; node != NULL; node = node->next)
-    {
-      GoaObject *object = GOA_OBJECT (node->data);
-      GoaAccount *account;
-      GoaTicketing *ticketing;
-      const char *provider_type;
-      const char *account_identity;
-
-      account = goa_object_peek_account (object);
-
-      if (account == NULL)
-        continue;
-
-      provider_type = goa_account_get_provider_type (account);
-
-      if (g_strcmp0 (provider_type, "kerberos") != 0)
-        continue;
-
-      ticketing = goa_object_peek_ticketing (object);
-
-      if (ticketing == NULL)
-        continue;
-
-      account_identity = goa_account_get_identity (account);
-
-      if (g_strcmp0 (account_identity, principal) == 0)
-        {
-          found_object = g_object_ref (object);
-          break;
-        }
-    }
-  g_list_free_full (objects, (GDestroyNotify) g_object_unref);
-
-  return found_object;
-}
-
-
 static void
 on_identity_needs_renewal (GoaIdentityManager *identity_manager,
                            GoaIdentity        *identity,
@@ -524,7 +544,7 @@ on_identity_needs_renewal (GoaIdentityManager *identity_manager,
 
   goa_debug ("GoaIdentityService: identity %s needs renewal", principal);
 
-  object = find_object_with_principal (self, principal);
+  object = find_object_with_principal (self, principal, TRUE);
 
   if (object != NULL)
     {
@@ -541,64 +561,10 @@ on_identity_needs_renewal (GoaIdentityManager *identity_manager,
                                        self);
 }
 
-typedef struct
-{
-  GoaIdentityService *service;
-  GoaIdentity        *identity;
-  gconstpointer       initial_password;
-  NotifyNotification *notification;
-  GSimpleAsyncResult *result;
-  GCancellable       *cancellable;
-  gulong              refreshed_signal_id;
-
-  GoaIdentitySignInFlags flags;
-} SignInRequest;
-
-static SignInRequest *
-sign_in_request_new (GoaIdentityService *service,
-                     GoaIdentity        *identity,
-                     gconstpointer       initial_password,
-                     GoaIdentitySignInFlags flags,
-                     NotifyNotification *notification,
-                     GSimpleAsyncResult *result,
-                     GCancellable       *cancellable)
-{
-  SignInRequest *request;
-
-  request = g_slice_new0 (SignInRequest);
-
-  request->service = service;
-  request->identity = g_object_ref (identity);
-  /* intentionally not dup'd, it's sitting in mlocked memory */
-  request->initial_password = initial_password;
-  request->flags = flags;
-  request->notification = notification;
-  request->result = result;
-  request->cancellable = g_object_ref (cancellable);
-
-  return request;
-}
-
-static void
-sign_in_request_free (SignInRequest *data)
-{
-  GoaIdentityService *service = data->service;
-
-  g_signal_handler_disconnect (service->priv->identity_manager,
-                               data->refreshed_signal_id);
-  g_object_set_data (G_OBJECT (data->identity),
-                     "sign-in-request",
-                     NULL);
-  g_clear_object (&data->identity);
-  g_clear_object (&data->cancellable);
-  g_clear_object (&data->result);
-  g_slice_free (SignInRequest, data);
-}
-
 static void
 on_identity_signed_in (GoaIdentityManager *manager,
                        GAsyncResult       *result,
-                       SignInRequest      *request)
+                       GSimpleAsyncResult *operation_result)
 {
   GError *error;
   GoaIdentity *identity;
@@ -610,32 +576,60 @@ on_identity_signed_in (GoaIdentityManager *manager,
     {
       goa_debug ("GoaIdentityService: could not sign in identity: %s",
                error->message);
-      g_simple_async_result_take_error (request->result, error);
-      g_simple_async_result_complete_in_idle (request->result);
-      g_clear_object (&request->result);
-      g_clear_object (&request->cancellable);
+      g_simple_async_result_take_error (operation_result, error);
+    }
+  else
+    {
+      g_simple_async_result_set_op_res_gpointer (operation_result,
+                                                 g_object_ref (identity),
+                                                 (GDestroyNotify)
+                                                 g_object_unref);
+    }
+  g_simple_async_result_complete_in_idle (operation_result);
+  g_object_unref (operation_result);
+
+  goa_debug ("GoaIdentityService: identity signed in");
+}
+
+static void
+on_temporary_account_created_for_identity (GoaIdentityService *self,
+                                           GAsyncResult       *result,
+                                           GoaIdentity        *identity)
+{
+  GoaObject   *object;
+  GError      *error;
+
+  error = NULL;
+  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), &error))
+    {
+      const char *identifier;
+
+      identifier = goa_identity_get_identifier (identity);
+      goa_debug ("Could not add temporary account for identity %s: %s",
+                 identifier,
+                 error->message);
+      g_error_free (error);
       return;
     }
 
-  g_simple_async_result_set_op_res_gpointer (request->result,
-                                             g_object_ref (identity),
-                                             (GDestroyNotify)
-                                             g_object_unref);
-  g_simple_async_result_complete_in_idle (request->result);
-  g_clear_object (&request->result);
-  g_clear_object (&request->cancellable);
+  object = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
 
-  goa_debug ("GoaIdentityService: identity signed in");
+  if (object != NULL)
+    ensure_account_credentials (self, object);
 }
 
 static void
-on_account_created_for_identity (GoaManager         *manager,
-                                 GAsyncResult       *result,
-                                 GoaIdentityService *self)
+on_account_added (GoaManager         *manager,
+                  GAsyncResult       *result,
+                  GSimpleAsyncResult *operation_result)
 {
+  GoaIdentityService *self;
+  GDBusObjectManager *object_manager;
   char *object_path;
+  GoaObject *object;
   GError *error;
 
+  self = GOA_IDENTITY_SERVICE (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
   object_path = NULL;
   error = NULL;
 
@@ -644,8 +638,9 @@ on_account_created_for_identity (GoaManager         *manager,
                                             result,
                                             &error))
     {
-      goa_debug ("Could not create account for identity: %s", error->message);
-      g_error_free (error);
+      g_simple_async_result_take_error (operation_result, error);
+      g_simple_async_result_complete_in_idle (operation_result);
+      g_object_unref (operation_result);
       return;
     }
 
@@ -654,27 +649,35 @@ on_account_created_for_identity (GoaManager         *manager,
       goa_debug ("Created account for identity with object path %s", object_path);
       g_free (object_path);
     }
+
+  object_manager = goa_client_get_object_manager (self->priv->client);
+  object = GOA_OBJECT (g_dbus_object_manager_get_object (object_manager,
+                                                         object_path));
+
+  if (object == NULL)
+    g_simple_async_result_set_op_res_gpointer (operation_result, NULL, NULL);
+  else
+    g_simple_async_result_set_op_res_gpointer (operation_result,
+                                               object,
+                                               (GDestroyNotify)
+                                               g_object_unref);
+
+  g_simple_async_result_complete_in_idle (operation_result);
+  g_object_unref (operation_result);
 }
 
 static void
-add_temporary_account_if_necessary (GoaIdentityService *self,
-                                    GoaIdentity        *identity)
+add_temporary_account (GoaIdentityService *self,
+                       GoaIdentity        *identity)
 {
-  char            *realm;
-  const char      *principal;
-  const char      *principal_for_display;
-  GoaObject       *object;
-  GVariantBuilder  credentials;
-  GVariantBuilder  details;
+  char               *realm;
+  const char         *principal;
+  const char         *principal_for_display;
+  GSimpleAsyncResult *operation_result;
+  GVariantBuilder     credentials;
+  GVariantBuilder     details;
 
   principal = goa_identity_get_identifier (identity);
-  object = find_object_with_principal (self, principal);
-
-  if (object != NULL)
-    {
-      g_object_unref (object);
-      return;
-    }
 
   goa_debug ("GoaIdentityService: adding temporary identity %s", principal);
 
@@ -690,6 +693,16 @@ add_temporary_account_if_necessary (GoaIdentityService *self,
   g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
   g_variant_builder_add (&details, "{ss}", "Realm", realm);
   g_variant_builder_add (&details, "{ss}", "IsPermanent", "false");
+  g_variant_builder_add (&details, "{ss}", "TicketingEnabled", "true");
+
+
+  goa_debug ("GoaIdentityService: asking to sign back in");
+
+  operation_result = g_simple_async_result_new (G_OBJECT (self),
+                                                (GAsyncReadyCallback)
+                                                on_temporary_account_created_for_identity,
+                                                identity,
+                                                add_temporary_account);
 
   goa_manager_call_add_account (self->priv->accounts_manager,
                                 "kerberos",
@@ -699,8 +712,8 @@ add_temporary_account_if_necessary (GoaIdentityService *self,
                                 g_variant_builder_end (&details),
                                 NULL,
                                 (GAsyncReadyCallback)
-                                on_account_created_for_identity,
-                                self);
+                                on_account_added,
+                                operation_result);
   g_free (realm);
 }
 
@@ -709,8 +722,16 @@ on_identity_added (GoaIdentityManager *identity_manager,
                    GoaIdentity        *identity,
                    GoaIdentityService *self)
 {
+  GoaObject *object;
+  const char *identifier;
+
   export_identity (self, identity);
-  add_temporary_account_if_necessary (self, identity);
+
+  identifier = goa_identity_get_identifier (identity);
+  object = find_object_with_principal (self, identifier, FALSE);
+
+  if (object == NULL)
+    add_temporary_account (self, identity);
 }
 
 static void
@@ -726,7 +747,16 @@ on_identity_refreshed (GoaIdentityManager *identity_manager,
                        GoaIdentity        *identity,
                        GoaIdentityService *self)
 {
-  add_temporary_account_if_necessary (self, identity);
+  GoaObject *object;
+  const char *identifier;
+
+  identifier = goa_identity_get_identifier (identity);
+  object = find_object_with_principal (self, identifier, FALSE);
+
+  if (object == NULL)
+    add_temporary_account (self, identity);
+
+  ensure_account_credentials (self, object);
 }
 
 typedef struct
@@ -984,157 +1014,59 @@ on_identity_inquiry (GoaIdentityInquiry *inquiry,
 }
 
 static void
-on_sign_in_clicked (NotifyNotification *notification,
-                    const char         *action_id,
-                    SignInRequest      *request)
-{
-  GoaIdentityService *self = request->service;
-  GoaIdentity *identity = request->identity;
-  const char *identifier;
-
-  identifier = goa_identity_get_identifier (identity);
-  goa_identity_manager_sign_identity_in (self->priv->identity_manager,
-                                         identifier,
-                                         request->initial_password,
-                                         request->flags,
-                                         (GoaIdentityInquiryFunc)
-                                         on_identity_inquiry,
-                                         self,
-                                         request->cancellable,
-                                         (GAsyncReadyCallback)
-                                         on_identity_signed_in,
-                                         request);
-}
-
-static void
-close_notification (GCancellable       *cancellable,
-                    NotifyNotification *notification)
-{
-  notify_notification_close (notification, NULL);
-}
-
-static void
 cancel_sign_in (GoaIdentityManager *identity_manager,
                 GoaIdentity        *identity,
-                SignInRequest      *data)
+                GSimpleAsyncResult *operation_result)
 {
-  g_cancellable_cancel (data->cancellable);
-  g_clear_object (&data->cancellable);
+  GoaIdentity *operation_identity;
+
+  operation_identity = g_simple_async_result_get_source_tag (operation_result);
+  if (operation_identity == identity)
+    {
+      GCancellable *cancellable;
+
+      cancellable = g_object_get_data (G_OBJECT (operation_result),
+                                       "cancellable");
+      g_cancellable_cancel (cancellable);
+    }
 }
 
 static void
 ask_to_sign_in (GoaIdentityService            *self,
-                GoaIdentity                   *identity,
+                const char                    *identifier,
                 gconstpointer                  initial_password,
                 GoaIdentitySignInFlags         flags,
                 GCancellable                  *cancellable,
                 GAsyncReadyCallback            callback,
                 gpointer                       user_data)
 {
-  NotifyNotification *notification;
-  char *name;
-  char *description;
-  GSimpleAsyncResult *result;
-  SignInRequest *request;
-
-  if (cancellable == NULL)
-    cancellable = g_cancellable_new ();
-
-  result = g_simple_async_result_new (G_OBJECT (self),
-                                      callback,
-                                      user_data,
-                                      ask_to_sign_in);
-  g_simple_async_result_set_check_cancellable (result, cancellable);
-
-  request = g_object_get_data (G_OBJECT (identity), "sign-in-request");
-
-  if (request != NULL)
-    g_cancellable_cancel (request->cancellable);
+  GSimpleAsyncResult *operation_result;
 
   goa_debug ("GoaIdentityService: asking to sign back in");
 
-  name = goa_identity_manager_name_identity (self->priv->identity_manager, identity);
-  if (goa_identity_is_signed_in (identity))
-    {
-      description =
-        g_strdup_printf (_("The network realm %s will soon be inaccessible."),
-                         name);
-    }
-  else
-    {
-      description = g_strdup_printf (_("The network realm %s is now inaccessible."),
-                                     name);
-    }
-  g_free (name);
-
-  notification = notify_notification_new (_("Realm Access"),
-                                          description,
-                                          "dialog-password-symbolic");
-  g_free (description);
-  notify_notification_set_app_name (notification, _("Network Realm"));
-
-  request = sign_in_request_new (self,
-                                 identity,
-                                 initial_password,
-                                 flags,
-                                 notification,
-                                 result,
-                                 cancellable);
-
-  g_object_set_data (G_OBJECT (identity),
-                     "sign-in-request",
-                     request);
-
-  g_cancellable_connect (cancellable,
-                         G_CALLBACK (close_notification),
-                         notification,
-                         NULL);
-
-  request->refreshed_signal_id =
-    g_signal_connect (G_OBJECT (self->priv->identity_manager),
-                      "identity-refreshed",
-                      G_CALLBACK (cancel_sign_in),
-                      request);
-
-  notify_notification_add_action (notification,
-                                  "sign-in",
-                                  _("Sign In"),
-                                  (NotifyActionCallback)
-                                  on_sign_in_clicked,
-                                  request,
-                                  (GFreeFunc)
-                                  sign_in_request_free);
-
-  notify_notification_show (notification, NULL);
-}
-
-static void
-on_credentials_ensured (GoaAccount         *account,
-                        GAsyncResult       *result,
-                        GoaIdentityService *self)
-{
-  GError     *error;
-  const char *account_identity;
-  int         expires_in;
-
-  account_identity = goa_account_get_identity (account);
+  operation_result = g_simple_async_result_new (G_OBJECT (self),
+                                                callback,
+                                                user_data,
+                                                ask_to_sign_in);
+  g_simple_async_result_set_check_cancellable (operation_result, cancellable);
 
-  error = NULL;
-  if (!goa_account_call_ensure_credentials_finish (account,
-                                                   &expires_in,
-                                                   result,
-                                                   &error))
-    {
-      goa_debug ("GoaIdentityService: could not ensure credentials for account %s: %s",
-                 account_identity,
-                 error->message);
-      g_error_free (error);
-      return;
-    }
+  g_signal_connect_object (G_OBJECT (self->priv->identity_manager),
+                           "identity-refreshed",
+                           G_CALLBACK (cancel_sign_in),
+                           operation_result,
+                           0);
 
-  goa_debug ("GoaIdentityService: credentials for account %s ensured for %d seconds",
-             account_identity,
-             expires_in);
+  goa_identity_manager_sign_identity_in (self->priv->identity_manager,
+                                         identifier,
+                                         initial_password,
+                                         flags,
+                                         (GoaIdentityInquiryFunc)
+                                         on_identity_inquiry,
+                                         self,
+                                         cancellable,
+                                         (GAsyncReadyCallback)
+                                         on_identity_signed_in,
+                                         operation_result);
 }
 
 static void
@@ -1144,26 +1076,17 @@ on_identity_expiring (GoaIdentityManager *identity_manager,
 {
   const char *principal;
   GoaObject  *object;
-  GoaAccount *account;
 
   principal = goa_identity_get_identifier (identity);
 
   goa_debug ("GoaIdentityService: identity %s expiring", principal);
 
-  object = find_object_with_principal (self, principal);
+  object = find_object_with_principal (self, principal, TRUE);
 
   if (object == NULL)
     return;
 
-  if (should_ignore_object (self, object))
-    return;
-
-  account = goa_object_peek_account (object);
-  goa_account_call_ensure_credentials (account,
-                                       NULL,
-                                       (GAsyncReadyCallback)
-                                       on_credentials_ensured,
-                                       self);
+  ensure_account_credentials (self, object);
 }
 
 static void
@@ -1173,27 +1096,17 @@ on_identity_expired (GoaIdentityManager *identity_manager,
 {
   const char *principal;
   GoaObject  *object;
-  GoaAccount *account;
 
   principal = goa_identity_get_identifier (identity);
 
   goa_debug ("GoaIdentityService: identity %s expired", principal);
 
-  object = find_object_with_principal (self, principal);
+  object = find_object_with_principal (self, principal, TRUE);
 
   if (object == NULL)
     return;
 
-  if (should_ignore_object (self, object))
-    return;
-
-  account = goa_object_peek_account (object);
-
-  goa_account_call_ensure_credentials (account,
-                                       NULL,
-                                       (GAsyncReadyCallback)
-                                       on_credentials_ensured,
-                                       self);
+  ensure_account_credentials (self, object);
 }
 
 static void
@@ -1214,6 +1127,32 @@ on_sign_out_for_account_change_done (GoaIdentityService *self,
 }
 
 static void
+on_get_ticket (GoaTicketing       *ticketing,
+               GAsyncResult       *result,
+               GoaAccount         *account)
+{
+  GError     *error;
+  const char *account_identity;
+
+  account_identity = goa_account_get_identity (account);
+
+  error = NULL;
+  if (!goa_ticketing_call_get_ticket_finish (ticketing,
+                                             result,
+                                             &error))
+    {
+      goa_debug ("GoaIdentityService: could not get ticket for account %s: %s",
+                 account_identity,
+                 error->message);
+      g_error_free (error);
+      return;
+    }
+
+  goa_debug ("GoaIdentityService: got ticket for account %s",
+             account_identity);
+}
+
+static void
 on_account_interface_added (GDBusObjectManager *manager,
                             GoaObject          *object,
                             GDBusInterface     *interface,
@@ -1246,11 +1185,11 @@ on_account_interface_added (GDBusObjectManager *manager,
       /* Ticketing interface is present, sign in if not already
        * signed in.
        */
-      goa_account_call_ensure_credentials (account,
-                                           NULL,
-                                           (GAsyncReadyCallback)
-                                           on_credentials_ensured,
-                                           self);
+      goa_ticketing_call_get_ticket (ticketing,
+                                     NULL,
+                                     (GAsyncReadyCallback)
+                                     on_get_ticket,
+                                     account);
       return;
     }
 }
@@ -1355,7 +1294,6 @@ on_identities_listed (GoaIdentityManager *manager,
 {
   GError *error = NULL;
   GList *identities, *node;
-  GDBusObjectManager *object_manager;
 
   g_signal_connect (G_OBJECT (self->priv->identity_manager),
                     "identity-added",
@@ -1387,17 +1325,6 @@ on_identities_listed (GoaIdentityManager *manager,
                     G_CALLBACK (on_account_removed),
                     self);
 
-  object_manager = goa_client_get_object_manager (self->priv->client);
-
-  g_signal_connect (G_OBJECT (object_manager),
-                    "interface-added",
-                    G_CALLBACK (on_account_interface_added),
-                    self);
-  g_signal_connect (G_OBJECT (object_manager),
-                    "interface-removed",
-                    G_CALLBACK (on_account_interface_removed),
-                    self);
-
   identities = goa_identity_manager_list_identities_finish (manager, result, &error);
 
   if (identities == NULL)
@@ -1413,10 +1340,65 @@ on_identities_listed (GoaIdentityManager *manager,
   for (node = identities; node != NULL; node = node->next)
     {
       GoaIdentity *identity = node->data;
+      const char  *principal;
+      GoaObject   *object;
+
+      export_identity (self, identity);
+
+      principal = goa_identity_get_identifier (identity);
+      object = find_object_with_principal (self, principal, TRUE);
 
-      add_temporary_account_if_necessary (self, identity);
+      if (object == NULL)
+        add_temporary_account (self, identity);
+      else
+        g_object_unref (object);
     }
+}
+
+static void
+ensure_credentials_for_accounts (GoaIdentityService *self)
+{
+  GDBusObjectManager *object_manager;
+  GList      *accounts;
+  GList      *node;
 
+  object_manager = goa_client_get_object_manager (self->priv->client);
+
+  g_signal_connect (G_OBJECT (object_manager),
+                    "interface-added",
+                    G_CALLBACK (on_account_interface_added),
+                    self);
+  g_signal_connect (G_OBJECT (object_manager),
+                    "interface-removed",
+                    G_CALLBACK (on_account_interface_removed),
+                    self);
+
+  accounts = goa_client_get_accounts (self->priv->client);
+
+  for (node = accounts; node != NULL; node = node->next)
+    {
+      GoaObject *object = GOA_OBJECT (node->data);
+      GoaAccount *account;
+      GoaTicketing *ticketing;
+      const char *provider_type;
+
+      account = goa_object_peek_account (object);
+
+      if (account == NULL)
+        continue;
+
+      provider_type = goa_account_get_provider_type (account);
+
+      if (g_strcmp0 (provider_type, "kerberos") != 0)
+        continue;
+
+      ticketing = goa_object_peek_ticketing (object);
+
+      if (ticketing == NULL)
+        continue;
+
+      ensure_account_credentials (self, object);
+    }
 }
 
 static void
@@ -1451,6 +1433,8 @@ on_got_client (GoaClient          *client,
                                         (GAsyncReadyCallback)
                                         on_identities_listed,
                                         self);
+
+  ensure_credentials_for_accounts (self);
 }
 
 static void
diff --git a/src/goaidentity/goaidentityutils.c b/src/goaidentity/goaidentityutils.c
index 9cb8838..fb72916 100644
--- a/src/goaidentity/goaidentityutils.c
+++ b/src/goaidentity/goaidentityutils.c
@@ -32,8 +32,8 @@
 #include <gio/gio.h>
 
 char *
-goa_identity_utils_escape_object_path_component (const char *data,
-                                                 gsize       length)
+goa_identity_utils_escape_object_path (const char *data,
+                                       gsize       length)
 {
   const char *p;
   char *object_path;
diff --git a/src/goaidentity/goaidentityutils.h b/src/goaidentity/goaidentityutils.h
index 9c4cd25..6840431 100644
--- a/src/goaidentity/goaidentityutils.h
+++ b/src/goaidentity/goaidentityutils.h
@@ -29,8 +29,8 @@
 
 G_BEGIN_DECLS
 
-char *goa_identity_utils_escape_object_path_component (const char *data,
-                                                       gsize       length);
+char *goa_identity_utils_escape_object_path (const char *data,
+                                             gsize       length);
 void goa_identity_utils_register_error_domain (GQuark error_domain,
                                                GType  error_enum);
 
diff --git a/src/goaidentity/goakerberosidentity.c b/src/goaidentity/goakerberosidentity.c
index a66ff63..81ff5d0 100644
--- a/src/goaidentity/goakerberosidentity.c
+++ b/src/goaidentity/goakerberosidentity.c
@@ -47,8 +47,6 @@ struct _GoaKerberosIdentityPrivate
   char *identifier;
   guint identifier_idle_id;
 
-  char **identifier_components;
-
   krb5_timestamp expiration_time;
   guint          expiration_time_idle_id;
 
@@ -297,57 +295,6 @@ get_identifier (GoaKerberosIdentity  *self,
   return identifier;
 }
 
-static char **
-get_identifier_components (GoaKerberosIdentity *self)
-{
-  krb5_principal principal;
-  krb5_error_code error_code;
-  int size, i;
-  GPtrArray *array;
-
-  if (self->priv->identifier == NULL)
-    return g_new0 (char *, 1);
-
-  error_code = krb5_parse_name (self->priv->kerberos_context,
-                                self->priv->identifier,
-                                &principal);
-
-  if (error_code != 0)
-    {
-      const char *error_message;
-      error_message =
-        krb5_get_error_message (self->priv->kerberos_context, error_code);
-
-      goa_debug ("GoaKerberosIdentity: Error looking up principal "
-               "identity in credential cache: %s",
-               error_message);
-      krb5_free_error_message (self->priv->kerberos_context, error_message);
-      return g_new0 (char *, 1);
-    }
-
-  array = g_ptr_array_new ();
-
-  g_ptr_array_add (array,
-                   g_strndup (principal->realm.data, principal->realm.length));
-
-  size = krb5_princ_size (self->priv->kerberos_context, principal);
-
-  for (i = 0; i < size; i++)
-    {
-      krb5_data *component;
-      char *component_string;
-
-      component = krb5_princ_component (self->priv->kerberos_context, principal, i);
-
-      component_string = g_strndup (component->data, component->length);
-      g_ptr_array_add (array, component_string);
-
-    }
-  g_ptr_array_add (array, NULL);
-
-  return (char **) g_ptr_array_free (array, FALSE);
-}
-
 static void
 goa_kerberos_identity_init (GoaKerberosIdentity *self)
 {
@@ -478,14 +425,6 @@ goa_kerberos_identity_get_identifier (GoaIdentity *identity)
   return self->priv->identifier;
 }
 
-static char **
-goa_kerberos_identity_get_identifier_components (GoaIdentity *identity)
-{
-  GoaKerberosIdentity *self = GOA_KERBEROS_IDENTITY (identity);
-
-  return g_strdupv (self->priv->identifier_components);
-}
-
 static gboolean
 credentials_validate_existence (GoaKerberosIdentity *self,
                                 krb5_principal principal, krb5_creds * credentials)
@@ -750,7 +689,6 @@ static void
 identity_interface_init (GoaIdentityInterface *interface)
 {
   interface->get_identifier = goa_kerberos_identity_get_identifier;
-  interface->get_identifier_components = goa_kerberos_identity_get_identifier_components;
   interface->is_signed_in = goa_kerberos_identity_is_signed_in;
 }
 
@@ -982,9 +920,6 @@ goa_kerberos_identity_initable_init (GInitable     *initable,
         queue_notify (self, &self->priv->identifier_idle_id, "identifier");
     }
 
-  if (self->priv->identifier_components == NULL)
-    self->priv->identifier_components = get_identifier_components (self);
-
   verification_error = NULL;
   self->priv->cached_verification_level =
     verify_identity (self, &verification_error);
@@ -1283,38 +1218,6 @@ update_identifier (GoaKerberosIdentity *self, GoaKerberosIdentity *new_identity)
     }
 }
 
-static void
-update_identifier_components (GoaKerberosIdentity *self,
-                              GoaKerberosIdentity *new_identity)
-{
-  char **new_components;
-
-  new_components = get_identifier_components (self);
-
-  if (g_strv_length (self->priv->identifier_components) ==
-      g_strv_length (new_components))
-    {
-      int i;
-
-      for (i = 0; new_components[i] != NULL; i++)
-        {
-          if (g_strcmp0 (self->priv->identifier_components[i],
-                         new_components[i]) != 0)
-            {
-              break;
-            }
-          else
-            {
-              g_strfreev (new_components);
-              return;
-            }
-        }
-    }
-
-  g_strfreev (self->priv->identifier_components);
-  self->priv->identifier_components = new_components;
-}
-
 void
 goa_kerberos_identity_update (GoaKerberosIdentity *self,
                               GoaKerberosIdentity *new_identity)
@@ -1322,9 +1225,7 @@ goa_kerberos_identity_update (GoaKerberosIdentity *self,
   VerificationLevel verification_level;
 
   if (self->priv->credentials_cache != NULL)
-    {
-      krb5_cc_close (self->priv->kerberos_context, self->priv->credentials_cache);
-    }
+    krb5_cc_close (self->priv->kerberos_context, self->priv->credentials_cache);
 
   krb5_cc_dup (new_identity->priv->kerberos_context,
                new_identity->priv->credentials_cache,
@@ -1332,19 +1233,14 @@ goa_kerberos_identity_update (GoaKerberosIdentity *self,
 
   G_LOCK (identity_lock);
   update_identifier (self, new_identity);
-  update_identifier_components (self, new_identity);
   G_UNLOCK (identity_lock);
 
   verification_level = verify_identity (self, NULL);
 
   if (verification_level == VERIFICATION_LEVEL_SIGNED_IN)
-    {
-      reset_alarms (self);
-    }
+    reset_alarms (self);
   else
-    {
-      clear_alarms (self);
-    }
+    clear_alarms (self);
 
   if (verification_level != self->priv->cached_verification_level)
     {
@@ -1358,8 +1254,8 @@ goa_kerberos_identity_update (GoaKerberosIdentity *self,
 
           g_signal_emit (G_OBJECT (self), signals[EXPIRED], 0);
         }
-      if (self->priv->cached_verification_level == VERIFICATION_LEVEL_EXISTS &&
-          verification_level == VERIFICATION_LEVEL_SIGNED_IN)
+      else if (self->priv->cached_verification_level == VERIFICATION_LEVEL_EXISTS &&
+               verification_level == VERIFICATION_LEVEL_SIGNED_IN)
         {
 
           G_LOCK (identity_lock);
@@ -1368,6 +1264,12 @@ goa_kerberos_identity_update (GoaKerberosIdentity *self,
 
           g_signal_emit (G_OBJECT (self), signals[UNEXPIRED], 0);
         }
+      else
+        {
+          G_LOCK (identity_lock);
+          self->priv->cached_verification_level = verification_level;
+          G_UNLOCK (identity_lock);
+        }
       queue_notify (self, &self->priv->is_signed_in_idle_id, "is-signed-in");
     }
 }
diff --git a/src/goaidentity/goakerberosidentitymanager.c b/src/goaidentity/goakerberosidentitymanager.c
index b9eeac9..607f1de 100644
--- a/src/goaidentity/goakerberosidentitymanager.c
+++ b/src/goaidentity/goakerberosidentitymanager.c
@@ -1127,7 +1127,7 @@ goa_kerberos_identity_manager_renew_identity_finish (GoaIdentityManager  *self,
 static void
 goa_kerberos_identity_manager_sign_identity_in (GoaIdentityManager     *manager,
                                                 const char             *identifier,
-                                                gconstpointer          *initial_password,
+                                                gconstpointer           initial_password,
                                                 GoaIdentitySignInFlags  flags,
                                                 GoaIdentityInquiryFunc  inquiry_func,
                                                 gpointer                inquiry_data,
diff --git a/src/goaidentity/org.gnome.Identity.xml b/src/goaidentity/org.gnome.Identity.xml
index 0bf6394..758fc95 100644
--- a/src/goaidentity/org.gnome.Identity.xml
+++ b/src/goaidentity/org.gnome.Identity.xml
@@ -68,6 +68,12 @@
     -->
     <property name="ExpirationTimestamp" type="x" access="read"/>
 
+    <!--
+        IsSignedIn:
+        Whether or not the identity is currently signed in
+    -->
+    <property name="IsSignedIn" type="b" access="read"/>
+
   </interface>
 
 </node>



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