[gnome-online-accounts/wip/kerberos: 1/4] Allow for transient, "non-permanent" accounts



commit 78ba52ee74c47b6e84dfbaf3eaaf9804429bd1d7
Author: Debarshi Ray <debarshir gnome org>
Date:   Sun Aug 12 20:41:42 2012 -0400

    Allow for transient, "non-permanent" accounts
    
    One prerequisite for adding kerberos support to online accounts
    is for it to allow accounts to show up that weren't explicitly
    previously added by the user from control-center. For instance,
    if a user runs "kinit" they should still be able to see their
    kerberos tickets in the dialog, and even destroy the credentials
    and remove the account.
    
    Of course these accounts have a lifetime limited to the current
    session.  We don't want a user to unintentionally trigger permanent
    behavior by just doing a one off kinit.
    
    Loosely based on work by Ray Strode
    
    https://bugzilla.gnome.org/show_bug.cgi?id=679253

 data/dbus-interfaces.xml                |   17 +++++-
 src/daemon/goadaemon.c                  |   77 +++++++++++++++++++----
 src/goabackend/goaexchangeprovider.c    |    2 +
 src/goabackend/goafacebookprovider.c    |    2 +
 src/goabackend/goagoogleprovider.c      |    2 +
 src/goabackend/goaprovider.c            |   15 ++++-
 src/goabackend/goaprovider.h            |    3 +-
 src/goabackend/goatwitterprovider.c     |    2 +
 src/goabackend/goautils.c               |  104 ++++++++++++++++++++++++++++++-
 src/goabackend/goautils.h               |    4 +
 src/goabackend/goawindowsliveprovider.c |    2 +
 src/goabackend/goayahooprovider.c       |    2 +
 12 files changed, 214 insertions(+), 18 deletions(-)
---
diff --git a/data/dbus-interfaces.xml b/data/dbus-interfaces.xml
index 48ad569..09b7ef9 100644
--- a/data/dbus-interfaces.xml
+++ b/data/dbus-interfaces.xml
@@ -69,6 +69,22 @@
       -->
     <property name="Id" type="s" access="read"/>
 
+    <!-- IsTemporary:
+
+         Whether or not the account is remembered from session to session.
+
+         Temporary accounts are added implicitly when the user is granted
+         credentials from some mechanism other than Online Accounts, but that
+         Online Accounts still knows how to deal with.
+
+         They are specific to the machine/session and are silently disregarded
+         after logout.
+
+         Accounts are permanant by default unless created with "IsTemporary"
+         "true" detail.
+      -->
+    <property name="IsTemporary" type="b" access="readwrite"/>
+
     <!-- AttentionNeeded: Set to %TRUE if the account is in need of attention.
 
          This is used when a human operator is needed to service the
@@ -176,7 +192,6 @@
     <method name="EnsureCredentials">
       <arg name="expires_in" type="i" direction="out"/>
     </method>
-
   </interface>
 
   <!--
diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c
index e2cca23..2debae3 100644
--- a/src/daemon/goadaemon.c
+++ b/src/daemon/goadaemon.c
@@ -330,7 +330,8 @@ key_file_data_new (GKeyFile    *key_file,
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-add_config_file (const gchar   *path,
+add_config_file (GoaDaemon     *daemon,
+                 const gchar   *path,
                  GHashTable    *group_name_to_key_file_data,
                  GList        **key_files_to_free)
 {
@@ -357,14 +358,48 @@ add_config_file (const gchar   *path,
   else
     {
       gchar **groups;
+      const char *guid;
       gsize num_groups;
       guint n;
 
+      guid = g_dbus_connection_get_guid (daemon->connection);
       groups = g_key_file_get_groups (key_file, &num_groups);
       for (n = 0; n < num_groups; n++)
         {
           if (g_str_has_prefix (groups[n], "Account "))
             {
+              gboolean is_temporary;
+              char *session_id;
+
+              is_temporary = g_key_file_get_boolean (key_file,
+                                                     groups[n],
+                                                     "IsTemporary",
+                                                     NULL);
+
+              if (is_temporary)
+                {
+                  session_id = g_key_file_get_string (key_file,
+                                                      groups[n],
+                                                      "SessionId",
+                                                      NULL);
+
+                  /* discard temporary accounts from older sessions */
+                  if (session_id != NULL &&
+                      g_strcmp0 (session_id, guid) != 0)
+                    {
+                      goa_debug ("ignoring account \"%s\" in file %s because it's stale",
+                                 groups[n], path);
+                      g_free (groups[n]);
+                      g_free (session_id);
+                      continue;
+                    }
+                  g_free (session_id);
+                }
+              else
+                {
+                  g_key_file_remove_key (key_file, groups[n], "SessionId", NULL);
+                }
+
               g_hash_table_insert (group_name_to_key_file_data,
                                    groups[n], /* steals string */
                                    key_file_data_new (key_file, path));
@@ -450,7 +485,7 @@ update_account_object (GoaDaemon           *daemon,
   goa_account_set_presentation_identity (account, presentation_identity);
 
   error = NULL;
-  if (!goa_provider_build_object (provider, object, key_file, group, just_added, &error))
+  if (!goa_provider_build_object (provider, object, key_file, group, daemon->connection, just_added, &error))
     {
       goa_warning ("Error parsing account: %s (%s, %d)",
                    error->message, g_quark_to_string (error->domain), error->code);
@@ -657,7 +692,7 @@ goa_daemon_reload_configuration (GoaDaemon *daemon)
 
   /* Read the main user config file at $HOME/.config/goa-1.0/accounts.conf */
   path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ());
-  add_config_file (path, group_name_to_key_file_data, &key_files_to_free);
+  add_config_file (daemon, path, group_name_to_key_file_data, &key_files_to_free);
   g_free (path);
 
   /* now process the group_name_to_key_file_data hash table */
@@ -788,6 +823,21 @@ on_manager_handle_add_account (GoaManager             *manager,
   g_variant_iter_init (&iter, details);
   while (g_variant_iter_next (&iter, "{&s&s}", &key, &value))
     {
+      /* We treat IsTemporary special.  If it's true we add in
+       * the current session guid, so it can be ignored after
+       * the session is over.
+       */
+      if (g_strcmp0 (key, "IsTemporary") == 0)
+        {
+          if (g_strcmp0 (value, "true") == 0)
+            {
+              const char *guid;
+
+              guid = g_dbus_connection_get_guid (daemon->connection);
+              g_key_file_set_string (key_file, group, "SessionId", guid);
+            }
+        }
+
       g_key_file_set_string (key_file, group, key, value);
     }
 
@@ -1105,15 +1155,15 @@ typedef struct
   GoaDaemon *daemon;
   GoaObject *object;
   GDBusMethodInvocation *invocation;
-} EnsureCredentialsData;
+} EnsureData;
 
-static EnsureCredentialsData *
-ensure_credentials_data_new (GoaDaemon             *daemon,
+static EnsureData *
+ensure_data_new (GoaDaemon             *daemon,
                              GoaObject             *object,
                              GDBusMethodInvocation *invocation)
 {
-  EnsureCredentialsData *data;
-  data = g_slice_new0 (EnsureCredentialsData);
+  EnsureData *data;
+  data = g_slice_new0 (EnsureData);
   data->daemon = g_object_ref (daemon);
   data->object = g_object_ref (object);
   data->invocation = invocation;
@@ -1121,11 +1171,11 @@ ensure_credentials_data_new (GoaDaemon             *daemon,
 }
 
 static void
-ensure_credentials_data_unref (EnsureCredentialsData *data)
+ensure_data_unref (EnsureData *data)
 {
   g_object_unref (data->daemon);
   g_object_unref (data->object);
-  g_slice_free (EnsureCredentialsData, data);
+  g_slice_free (EnsureData, data);
 }
 
 static gboolean
@@ -1154,7 +1204,7 @@ ensure_credentials_cb (GoaProvider   *provider,
                        GAsyncResult  *res,
                        gpointer       user_data)
 {
-  EnsureCredentialsData *data = user_data;
+  EnsureData *data = user_data;
   gint expires_in;
   GError *error;
 
@@ -1195,7 +1245,7 @@ ensure_credentials_cb (GoaProvider   *provider,
                                                data->invocation,
                                                expires_in);
     }
-  ensure_credentials_data_unref (data);
+  ensure_data_unref (data);
 }
 
 static gboolean
@@ -1224,9 +1274,8 @@ on_account_handle_ensure_credentials (GoaAccount            *account,
                                    object,
                                    NULL, /* GCancellable */
                                    (GAsyncReadyCallback) ensure_credentials_cb,
-                                   ensure_credentials_data_new (daemon, object, invocation));
+                                   ensure_data_new (daemon, object, invocation));
 
  out:
   return TRUE; /* invocation was handled */
 }
-
diff --git a/src/goabackend/goaexchangeprovider.c b/src/goabackend/goaexchangeprovider.c
index 7473bc2..219997c 100644
--- a/src/goabackend/goaexchangeprovider.c
+++ b/src/goabackend/goaexchangeprovider.c
@@ -89,6 +89,7 @@ build_object (GoaProvider         *provider,
               GoaObjectSkeleton   *object,
               GKeyFile            *key_file,
               const gchar         *group,
+              GDBusConnection     *connection,
               gboolean             just_added,
               GError             **error)
 {
@@ -116,6 +117,7 @@ build_object (GoaProvider         *provider,
                                                                               object,
                                                                               key_file,
                                                                               group,
+                                                                              connection,
                                                                               just_added,
                                                                               error))
     goto out;
diff --git a/src/goabackend/goafacebookprovider.c b/src/goabackend/goafacebookprovider.c
index 40fcebb..37121ec 100644
--- a/src/goabackend/goafacebookprovider.c
+++ b/src/goabackend/goafacebookprovider.c
@@ -281,6 +281,7 @@ build_object (GoaProvider         *provider,
               GoaObjectSkeleton   *object,
               GKeyFile            *key_file,
               const gchar         *group,
+              GDBusConnection     *connection,
               gboolean             just_added,
               GError             **error)
 {
@@ -296,6 +297,7 @@ build_object (GoaProvider         *provider,
                                                                               object,
                                                                               key_file,
                                                                               group,
+                                                                              connection,
                                                                               just_added,
                                                                               error))
     goto out;
diff --git a/src/goabackend/goagoogleprovider.c b/src/goabackend/goagoogleprovider.c
index 270ef65..7a65d28 100644
--- a/src/goabackend/goagoogleprovider.c
+++ b/src/goabackend/goagoogleprovider.c
@@ -315,6 +315,7 @@ build_object (GoaProvider         *provider,
               GoaObjectSkeleton   *object,
               GKeyFile            *key_file,
               const gchar         *group,
+              GDBusConnection     *connection,
               gboolean             just_added,
               GError             **error)
 {
@@ -344,6 +345,7 @@ build_object (GoaProvider         *provider,
                                                                             object,
                                                                             key_file,
                                                                             group,
+                                                                            connection,
                                                                             just_added,
                                                                             error))
     goto out;
diff --git a/src/goabackend/goaprovider.c b/src/goabackend/goaprovider.c
index fc92d7f..0462e25 100644
--- a/src/goabackend/goaprovider.c
+++ b/src/goabackend/goaprovider.c
@@ -54,6 +54,7 @@ static gboolean goa_provider_build_object_real (GoaProvider         *provider,
                                                 GoaObjectSkeleton   *object,
                                                 GKeyFile            *key_file,
                                                 const gchar         *group,
+                                                GDBusConnection     *connection,
                                                 gboolean             just_added,
                                                 GError             **error);
 
@@ -326,6 +327,7 @@ goa_provider_show_account_real (GoaProvider         *provider,
  * @object: The #GoaObjectSkeleton that is being built.
  * @key_file: The #GKeyFile with configuation data.
  * @group: The group in @key_file to get data from.
+ * @connection: The #GDBusConnection used by the daemon to connect to the message bus.
  * @just_added: Whether the account was newly created or being updated.
  * @error: Return location for error or %NULL.
  *
@@ -350,6 +352,7 @@ goa_provider_build_object (GoaProvider         *provider,
                            GoaObjectSkeleton   *object,
                            GKeyFile            *key_file,
                            const gchar         *group,
+                           GDBusConnection     *connection,
                            gboolean             just_added,
                            GError             **error)
 {
@@ -357,8 +360,15 @@ goa_provider_build_object (GoaProvider         *provider,
   g_return_val_if_fail (GOA_IS_OBJECT_SKELETON (object) && goa_object_peek_account (GOA_OBJECT (object)) != NULL, FALSE);
   g_return_val_if_fail (key_file != NULL, FALSE);
   g_return_val_if_fail (group != NULL, FALSE);
+  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE);
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-  return GOA_PROVIDER_GET_CLASS (provider)->build_object (provider, object, key_file, group, just_added, error);
+  return GOA_PROVIDER_GET_CLASS (provider)->build_object (provider,
+                                                          object,
+                                                          key_file,
+                                                          group,
+                                                          connection,
+                                                          just_added,
+                                                          error);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -521,6 +531,8 @@ goa_provider_ensure_credentials_sync (GoaProvider     *provider,
   return GOA_PROVIDER_GET_CLASS (provider)->ensure_credentials_sync (provider, object, out_expires_in, cancellable, error);
 }
 
+/* ---------------------------------------------------------------------------------------------------- */
+
 static gboolean
 goa_provider_ensure_credentials_sync_real (GoaProvider   *provider,
                                            GoaObject     *object,
@@ -541,6 +553,7 @@ goa_provider_build_object_real (GoaProvider         *provider,
                                 GoaObjectSkeleton   *object,
                                 GKeyFile            *key_file,
                                 const gchar         *group,
+                                GDBusConnection     *connection,
                                 gboolean             just_added,
                                 GError             **error)
 {
diff --git a/src/goabackend/goaprovider.h b/src/goabackend/goaprovider.h
index b5e186e..cc58d7e 100644
--- a/src/goabackend/goaprovider.h
+++ b/src/goabackend/goaprovider.h
@@ -93,9 +93,9 @@ struct _GoaProviderClass
                                      GoaObjectSkeleton  *object,
                                      GKeyFile           *key_file,
                                      const gchar        *group,
+                                     GDBusConnection    *connection,
                                      gboolean            just_added,
                                      GError            **error);
-
   /* virtual but with default implementation */
   gboolean (*ensure_credentials_sync) (GoaProvider         *provider,
                                        GoaObject           *object,
@@ -141,6 +141,7 @@ gboolean     goa_provider_build_object              (GoaProvider         *provid
                                                      GoaObjectSkeleton   *object,
                                                      GKeyFile            *key_file,
                                                      const gchar         *group,
+                                                     GDBusConnection     *connection,
                                                      gboolean             just_added,
                                                      GError             **error);
 void         goa_provider_ensure_credentials        (GoaProvider         *provider,
diff --git a/src/goabackend/goatwitterprovider.c b/src/goabackend/goatwitterprovider.c
index c1ef907..3895e6f 100644
--- a/src/goabackend/goatwitterprovider.c
+++ b/src/goabackend/goatwitterprovider.c
@@ -218,6 +218,7 @@ build_object (GoaProvider         *provider,
               GoaObjectSkeleton   *object,
               GKeyFile            *key_file,
               const gchar         *group,
+              GDBusConnection     *connection,
               gboolean             just_added,
               GError             **error)
 {
@@ -229,6 +230,7 @@ build_object (GoaProvider         *provider,
                                                                              object,
                                                                              key_file,
                                                                              group,
+                                                                             connection,
                                                                              just_added,
                                                                              error))
     goto out;
diff --git a/src/goabackend/goautils.c b/src/goabackend/goautils.c
index 0ed8fa0..69d8bf5 100644
--- a/src/goabackend/goautils.c
+++ b/src/goabackend/goautils.c
@@ -17,7 +17,8 @@
  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  * Boston, MA 02111-1307, USA.
  *
- * Author: Debarshi Ray <debarshir gnome org>
+ * Authors: Debarshi Ray <debarshir gnome org>
+ *          Ray Strode <rstrode redhat com>
  */
 
 #include "config.h"
@@ -26,6 +27,7 @@
 #include <libsecret/secret.h>
 
 #include "goaprovider.h"
+#include "goalogging.h"
 #include "goautils.h"
 
 static const SecretSchema secret_password_schema =
@@ -298,3 +300,103 @@ goa_utils_store_credentials_for_object_sync (GoaProvider   *provider,
   id = goa_account_get_id (goa_object_peek_account (object));
   return goa_utils_store_credentials_for_id_sync (provider, id, credentials, cancellable, error);
 }
+
+void
+goa_utils_keyfile_remove_key (GoaAccount *account, const gchar *key)
+{
+  GError *error;
+  GKeyFile *key_file;
+  gchar *contents;
+  gchar *group;
+  gchar *path;
+  gsize length;
+
+  contents = NULL;
+
+  path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ());
+  group = g_strdup_printf ("Account %s", goa_account_get_id (account));
+
+  key_file = g_key_file_new ();
+  error = NULL;
+  if (!g_key_file_load_from_file (key_file,
+                                  path,
+                                  G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
+                                  &error))
+    {
+      goa_warning ("Error loading keyfile %s: %s (%s, %d)",
+                   path,
+                   error->message,
+                   g_quark_to_string (error->domain),
+                   error->code);
+      g_error_free (error);
+      goto out;
+    }
+
+  g_key_file_remove_key (key_file, group, key, NULL);
+  contents = g_key_file_to_data (key_file, &length, NULL);
+
+  error = NULL;
+  if (!g_file_set_contents (path, contents, length, &error))
+    {
+      g_prefix_error (&error, "Error writing key-value-file %s: ", path);
+      goa_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+      goto out;
+    }
+
+ out:
+  g_free (contents);
+  g_key_file_free (key_file);
+  g_free (group);
+  g_free (path);
+}
+
+void
+goa_utils_keyfile_set_string (GoaAccount *account, const gchar *key, const gchar *value)
+{
+  GError *error;
+  GKeyFile *key_file;
+  gchar *contents;
+  gchar *group;
+  gchar *path;
+  gsize length;
+
+  contents = NULL;
+
+  path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ());
+  group = g_strdup_printf ("Account %s", goa_account_get_id (account));
+
+  key_file = g_key_file_new ();
+  error = NULL;
+  if (!g_key_file_load_from_file (key_file,
+                                  path,
+                                  G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
+                                  &error))
+    {
+      goa_warning ("Error loading keyfile %s: %s (%s, %d)",
+                   path,
+                   error->message,
+                   g_quark_to_string (error->domain),
+                   error->code);
+      g_error_free (error);
+      goto out;
+    }
+
+  g_key_file_set_string (key_file, group, key, value);
+  contents = g_key_file_to_data (key_file, &length, NULL);
+
+  error = NULL;
+  if (!g_file_set_contents (path, contents, length, &error))
+    {
+      g_prefix_error (&error, "Error writing key-value-file %s: ", path);
+      goa_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+      goto out;
+    }
+
+ out:
+  g_free (contents);
+  g_key_file_free (key_file);
+  g_free (group);
+  g_free (path);
+}
diff --git a/src/goabackend/goautils.h b/src/goabackend/goautils.h
index 406de34..0418fb7 100644
--- a/src/goabackend/goautils.h
+++ b/src/goabackend/goautils.h
@@ -65,6 +65,10 @@ gboolean         goa_utils_store_credentials_for_object_sync (GoaProvider    *pr
                                                               GCancellable   *cancellable,
                                                               GError        **error);
 
+void             goa_utils_keyfile_remove_key (GoaAccount *account, const gchar *key);
+
+void             goa_utils_keyfile_set_string (GoaAccount *account, const gchar *key, const gchar *value);
+
 G_END_DECLS
 
 #endif /* __GOA_UTILS_H__ */
diff --git a/src/goabackend/goawindowsliveprovider.c b/src/goabackend/goawindowsliveprovider.c
index 70432c4..03c1670 100644
--- a/src/goabackend/goawindowsliveprovider.c
+++ b/src/goabackend/goawindowsliveprovider.c
@@ -263,6 +263,7 @@ build_object (GoaProvider         *provider,
               GoaObjectSkeleton   *object,
               GKeyFile            *key_file,
               const gchar         *group,
+              GDBusConnection     *connection,
               gboolean             just_added,
               GError             **error)
 {
@@ -280,6 +281,7 @@ build_object (GoaProvider         *provider,
                                                                               object,
                                                                               key_file,
                                                                               group,
+                                                                              connection,
                                                                               just_added,
                                                                               error))
     goto out;
diff --git a/src/goabackend/goayahooprovider.c b/src/goabackend/goayahooprovider.c
index 2620e24..dc6d011 100644
--- a/src/goabackend/goayahooprovider.c
+++ b/src/goabackend/goayahooprovider.c
@@ -282,6 +282,7 @@ build_object (GoaProvider         *provider,
               GoaObjectSkeleton   *object,
               GKeyFile            *key_file,
               const gchar         *group,
+              GDBusConnection     *connection,
               gboolean             just_added,
               GError             **error)
 {
@@ -294,6 +295,7 @@ build_object (GoaProvider         *provider,
                                                                            object,
                                                                            key_file,
                                                                            group,
+                                                                           connection,
                                                                            just_added,
                                                                            error))
     goto out;



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