[gnome-online-accounts/wip/rishi/templates: 10/10] daemon: Add support for account templates
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-online-accounts/wip/rishi/templates: 10/10] daemon: Add support for account templates
- Date: Fri, 26 Aug 2016 19:06:58 +0000 (UTC)
commit dba3cc96a504d7dd40cbcbc3075b1e58573950c2
Author: Debarshi Ray <debarshir gnome org>
Date: Fri Aug 26 21:04:52 2016 +0200
daemon: Add support for account templates
src/daemon/goadaemon.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 230 insertions(+), 0 deletions(-)
---
diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c
index d44097d..1bd0999 100644
--- a/src/daemon/goadaemon.c
+++ b/src/daemon/goadaemon.c
@@ -419,6 +419,13 @@ account_object_path_to_group (const gchar *object_path)
return g_strdup_printf ("Account %s", object_path + sizeof "/org/gnome/OnlineAccounts/Accounts/" - 1);
}
+static const gchar *
+template_group_to_id (const gchar *group)
+{
+ g_return_val_if_fail (g_str_has_prefix (group, "Template "), NULL);
+ return group + sizeof "Template " - 1;
+}
+
/* ---------------------------------------------------------------------------------------------------- */
typedef struct
@@ -556,6 +563,12 @@ add_config_file (GoaDaemon *self,
groups[n], /* steals string */
key_file_data_new (key_file, path));
}
+ else if (g_str_has_prefix (groups[n], "Template "))
+ {
+ g_hash_table_insert (group_name_to_key_file_data,
+ groups[n], /* steals string */
+ key_file_data_new (key_file, path));
+ }
else
{
g_warning ("Unexpected group \"%s\" in file %s", groups[n], path);
@@ -703,6 +716,9 @@ process_config_entries (GoaDaemon *self,
const gchar *id;
gchar *object_path;
+ if (!g_str_has_prefix (group, "Account "))
+ continue;
+
id = account_group_to_id (group);
/* create and validate object path */
@@ -812,6 +828,217 @@ process_config_entries (GoaDaemon *self,
g_list_free_full (config_object_paths, g_free);
}
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gint
+compare_account_and_template_groups (const gchar *account_group, const gchar *template_group)
+{
+ const gchar *account_id;
+ const gchar *template_id;
+
+ g_return_val_if_fail (g_str_has_prefix (account_group, "Account "), 0);
+ g_return_val_if_fail (g_str_has_prefix (template_group, "Template "), 0);
+
+ account_id = account_group + sizeof "Account " - 1;
+ template_id = template_group + sizeof "Template " - 1;
+
+ return g_strcmp0 (account_id, template_id);
+}
+
+static void
+process_template_entries (GoaDaemon *self,
+ GHashTable *group_name_to_key_file_data)
+{
+ GError *error;
+ GHashTable *key_files_to_update = NULL;
+ GHashTableIter iter;
+ GKeyFile *home_conf_key_file = NULL;
+ KeyFileData *key_file_data;
+ gboolean needs_update = FALSE;
+ const gchar *group;
+ GList *config_object_groups = NULL;
+ GList *config_template_groups = NULL;
+ GList *added;
+ GList *removed;
+ GList *unchanged;
+ GList *l;
+
+ key_files_to_update = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)
g_key_file_unref);
+
+ g_hash_table_iter_init (&iter, group_name_to_key_file_data);
+ while (g_hash_table_iter_next (&iter, (gpointer*) &group, (gpointer*) &key_file_data))
+ {
+ if (home_conf_key_file == NULL && g_strcmp0 (key_file_data->path, self->home_conf_file_path) == 0)
+ home_conf_key_file = g_key_file_ref (key_file_data->key_file);
+
+ if (g_str_has_prefix (group, "Account "))
+ config_object_groups = g_list_prepend (config_object_groups, g_strdup (group));
+ else if (g_str_has_prefix (group, "Template "))
+ config_template_groups = g_list_prepend (config_template_groups, g_strdup (group));
+ }
+
+ if (home_conf_key_file == NULL)
+ home_conf_key_file = g_key_file_new ();
+
+ config_object_groups = g_list_sort (config_object_groups, (GCompareFunc) g_strcmp0);
+ config_template_groups = g_list_sort (config_template_groups, (GCompareFunc) g_strcmp0);
+ diff_sorted_lists (config_object_groups,
+ config_template_groups,
+ (GCompareFunc) compare_account_and_template_groups,
+ &added,
+ &removed,
+ &unchanged);
+
+ for (l = removed; l != NULL; l = l->next)
+ {
+ gboolean is_locked;
+ gboolean removed;
+ const gchar *object_group = l->data;
+
+ key_file_data = g_hash_table_lookup (group_name_to_key_file_data, object_group);
+ g_assert_nonnull (key_file_data);
+
+ error = NULL;
+ is_locked = g_key_file_get_boolean (key_file_data->key_file, object_group, "IsLocked", &error);
+ if (error != NULL)
+ {
+ if (!g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND))
+ {
+ g_warning ("Error reading key IsLocked from group %s in keyfile %s: %s (%s, %d)",
+ object_group,
+ key_file_data->path,
+ error->message,
+ g_quark_to_string (error->domain),
+ error->code);
+ }
+
+ g_error_free (error);
+ }
+
+ if (is_locked)
+ {
+ error = NULL;
+ removed = g_key_file_remove_group (key_file_data->key_file, object_group, &error);
+ if (error != NULL)
+ {
+ g_warning ("Error removing group %s from %s: %s (%s, %d)",
+ object_group,
+ key_file_data->path,
+ error->message,
+ g_quark_to_string (error->domain),
+ error->code);
+ g_error_free (error);
+ }
+
+ needs_update = needs_update || removed;
+ g_hash_table_insert (key_files_to_update,
+ g_strdup (key_file_data->path),
+ g_key_file_ref (key_file_data->key_file));
+
+ removed = g_hash_table_remove (group_name_to_key_file_data, object_group);
+ g_warn_if_fail (removed);
+
+ g_debug ("Missing from templates, removing: %s", object_group);
+ }
+ }
+
+ for (l = added; l != NULL; l = l->next)
+ {
+ const gchar *id;
+ const gchar *template_group = l->data;
+ gchar *object_group = NULL;
+
+ g_debug ("Adding from a template: %s", template_group);
+
+ key_file_data = g_hash_table_lookup (group_name_to_key_file_data, template_group);
+ g_assert_nonnull (key_file_data);
+
+ id = template_group_to_id (template_group);
+ object_group = g_strdup_printf ("Account %s", id);
+ g_warn_if_fail (!g_key_file_has_group (home_conf_key_file, object_group));
+
+ needs_update = goa_utils_keyfile_copy_group (key_file_data->key_file,
+ template_group,
+ home_conf_key_file,
+ object_group);
+
+ if (needs_update)
+ {
+ g_key_file_set_boolean (home_conf_key_file, object_group, "IsLocked", TRUE);
+ g_hash_table_insert (key_files_to_update,
+ g_strdup (self->home_conf_file_path),
+ g_key_file_ref (home_conf_key_file));
+ }
+
+ g_free (object_group);
+ }
+
+ for (l = unchanged; l != NULL; l = l->next)
+ {
+ KeyFileData *dest_key_file_data;
+ KeyFileData *src_key_file_data;
+ const gchar *id;
+ const gchar *object_group = l->data;
+ gchar *template_group = NULL;
+
+ g_debug ("Updating from a template: %s", object_group);
+
+ dest_key_file_data = g_hash_table_lookup (group_name_to_key_file_data, object_group);
+ g_assert_nonnull (dest_key_file_data);
+
+ g_warn_if_fail (g_key_file_has_group (dest_key_file_data->key_file, object_group));
+
+ id = account_group_to_id (object_group);
+ template_group = g_strdup_printf ("Template %s", id);
+
+ src_key_file_data = g_hash_table_lookup (group_name_to_key_file_data, template_group);
+ g_assert_nonnull (src_key_file_data);
+
+ needs_update = goa_utils_keyfile_copy_group (src_key_file_data->key_file,
+ template_group,
+ dest_key_file_data->key_file,
+ object_group);
+
+ if (needs_update)
+ {
+ g_key_file_set_boolean (home_conf_key_file, object_group, "IsLocked", TRUE);
+ g_hash_table_insert (key_files_to_update,
+ g_strdup (self->home_conf_file_path),
+ g_key_file_ref (home_conf_key_file));
+ }
+
+ g_free (template_group);
+ }
+
+ if (needs_update)
+ {
+ GKeyFile *key_file;
+ const gchar *path;
+
+ g_hash_table_iter_init (&iter, key_files_to_update);
+ while (g_hash_table_iter_next (&iter, (gpointer *) &path, (gpointer *) &key_file))
+ {
+ error = NULL;
+ if (!g_key_file_save_to_file (key_file, path, &error))
+ {
+ g_prefix_error (&error, "Error writing key-value-file %s: ", path);
+ g_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code);
+ g_error_free (error);
+ }
+ }
+ }
+
+ g_hash_table_unref (key_files_to_update);
+ g_key_file_unref (home_conf_key_file);
+ g_list_free (removed);
+ g_list_free (added);
+ g_list_free (unchanged);
+ g_list_free_full (config_object_groups, g_free);
+ g_list_free_full (config_template_groups, g_free);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
/* <internal>
* goa_daemon_reload_configuration:
* @self: A #GoaDaemon
@@ -832,6 +1059,9 @@ goa_daemon_reload_configuration (GoaDaemon *self)
/* Read the main user config file at $HOME/.config/goa-1.0/accounts.conf */
add_config_file (self, self->home_conf_file_path, group_name_to_key_file_data);
+ add_config_file (self, "/tmp/accounts.conf", group_name_to_key_file_data);
+
+ process_template_entries (self, group_name_to_key_file_data);
/* now process the group_name_to_key_file_data hash table */
process_config_entries (self, group_name_to_key_file_data);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]