[gnome-online-accounts/wip/kerberos: 1/4] Allow for transient, "non-permanent" accounts
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-online-accounts/wip/kerberos: 1/4] Allow for transient, "non-permanent" accounts
- Date: Mon, 20 Aug 2012 19:14:30 +0000 (UTC)
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]