summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2015-08-20 20:36:56 +0200
committerAlexander Larsson <alexl@redhat.com>2015-08-20 20:36:56 +0200
commit303b9872a4a5364f5ff9b95cb73f59f172b4fa9d (patch)
treee174905dd175063b58a9980cc008fb35992db9bd
parente8bfb2e4a89b8316988de36174dfdef9360e03b7 (diff)
downloadxdg-app-wip/alexl/permission-store.tar.gz
Add db modification callswip/alexl/permission-store
-rw-r--r--lib/xdg-app-db.c166
-rw-r--r--lib/xdg-app-db.h57
2 files changed, 187 insertions, 36 deletions
diff --git a/lib/xdg-app-db.c b/lib/xdg-app-db.c
index 5a6fab8..cf3ca74 100644
--- a/lib/xdg-app-db.c
+++ b/lib/xdg-app-db.c
@@ -35,7 +35,7 @@ struct XdgAppDb {
char *path;
GvdbTable *gvdb;
- /* Map id => GVariant (data, array[(appid, perms)]) */
+ /* Map id => GVariant (data, sorted-dict[appid->perms]) */
GvdbTable *main_table;
GHashTable *main_updates;
@@ -332,19 +332,6 @@ xdg_app_db_list_ids_by_value (XdgAppDb *self,
return (char **)g_ptr_array_free (res, FALSE);
}
-XdgAppDbEntry *
-xdg_app_db_entry_ref (XdgAppDbEntry *entry)
-{
- g_variant_ref ((GVariant *)entry);
- return entry;
-}
-
-void
-xdg_app_db_entry_unref (XdgAppDbEntry *entry)
-{
- g_variant_unref ((GVariant *)entry);
-}
-
/* Transfer: full */
XdgAppDbEntry *
xdg_app_db_lookup (XdgAppDb *self,
@@ -369,6 +356,31 @@ xdg_app_db_lookup (XdgAppDb *self,
return (XdgAppDbEntry *)res;
}
+/* add, replace, or NULL entry to remove */
+void
+xdg_app_db_set_entry (XdgAppDb *self,
+ const char *id,
+ XdgAppDbEntry *entry)
+{
+ g_hash_table_insert (self->main_updates,
+ g_strdup (id),
+ xdg_app_db_entry_ref (entry));
+ /* TODO: Update app_updates */
+}
+
+XdgAppDbEntry *
+xdg_app_db_entry_ref (XdgAppDbEntry *entry)
+{
+ g_variant_ref ((GVariant *)entry);
+ return entry;
+}
+
+void
+xdg_app_db_entry_unref (XdgAppDbEntry *entry)
+{
+ g_variant_unref ((GVariant *)entry);
+}
+
/* Transfer: full */
GVariant *
xdg_app_db_entry_get_data (XdgAppDbEntry *entry)
@@ -493,3 +505,129 @@ xdg_app_db_entry_has_permissions (XdgAppDbEntry *entry,
return TRUE;
}
+
+static GVariant *
+make_entry (GVariant *data,
+ GVariant *app_permissions)
+{
+ return g_variant_new ("(v@a{sas})", data, app_permissions);
+}
+
+static GVariant *
+make_empty_app_permissions (void)
+{
+ return g_variant_new_array (G_VARIANT_TYPE ("{sas}"), NULL, 0);
+}
+
+static GVariant *
+make_permissions (const char *app, const char **permissions)
+{
+ static const char **empty = { NULL };
+ if (permissions == NULL)
+ permissions = empty;
+
+ return g_variant_new ("{s@as})",
+ app,
+ g_variant_new_strv (permissions, -1));
+}
+
+static GVariant *
+add_permissions (GVariant *app_permissions,
+ GVariant *permissions)
+{
+ GVariantBuilder builder;
+ GVariantIter iter;
+ GVariant *child;
+ gboolean added = FALSE;
+ int cmp;
+ const char *new_app_id;
+ const char *child_app_id;
+ g_autoptr(GVariant) new_perms_array = NULL;
+
+ g_variant_get (permissions, "{&s@as}", &new_app_id, &new_perms_array);
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
+
+ /* Insert or replace permissions in sorted order */
+
+ g_variant_iter_init (&iter, app_permissions);
+ while ((child = g_variant_iter_next_value (&iter)))
+ {
+ g_autoptr(GVariant) old_perms_array = NULL;
+
+ g_variant_get (child, "{&s@as}", &child_app_id, &old_perms_array);
+
+ cmp = strcmp (new_app_id, child_app_id);
+ if (cmp == 0)
+ {
+ added = TRUE;
+ /* Replace old permissions */
+ g_variant_builder_add (&builder, "@{sas}", permissions);
+ }
+ else if (cmp < 0)
+ {
+ g_variant_builder_add (&builder, "@{sas}", child);
+ }
+ else /* cmp > 0 */
+ {
+ if (!added)
+ {
+ added = TRUE;
+ g_variant_builder_add (&builder, "@{sas}", permissions);
+ }
+ g_variant_builder_add_value (&builder, child);
+ }
+
+ g_variant_unref (child);
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+XdgAppDbEntry *
+xdg_app_db_entry_new (XdgAppDbEntry *entry,
+ GVariant *data)
+{
+ GVariant *res;
+
+ if (data == NULL)
+ data = g_variant_new_byte (0);
+
+ res = make_entry (data,
+ make_empty_app_permissions ());
+
+ return (XdgAppDbEntry *)g_variant_ref_sink (res);
+}
+
+XdgAppDbEntry *
+xdg_app_db_entry_modify_data (XdgAppDbEntry *entry,
+ GVariant *data)
+{
+ GVariant *v = (GVariant *)entry;
+ GVariant *res;
+
+ if (data == NULL)
+ data = g_variant_new_byte (0);
+
+ res = make_entry (data,
+ g_variant_get_child_value (v, 1));
+ return (XdgAppDbEntry *)g_variant_ref_sink (res);
+}
+
+/* NULL (or empty) permissions to remove permissions */
+XdgAppDbEntry *
+xdg_app_db_entry_set_app_permissions (XdgAppDbEntry *entry,
+ const char *app,
+ const char **permissions)
+{
+ GVariant *v = (GVariant *)entry;
+ GVariant *res;
+ GVariant *old_data = g_variant_get_child_value (v, 0);
+ GVariant *old_permissions = g_variant_get_child_value (v, 1);
+
+ res = make_entry (old_data,
+ add_permissions (old_permissions,
+ make_permissions (app,
+ permissions)));
+ return (XdgAppDbEntry *)g_variant_ref_sink (res);
+}
diff --git a/lib/xdg-app-db.h b/lib/xdg-app-db.h
index 573dd52..a68ab16 100644
--- a/lib/xdg-app-db.h
+++ b/lib/xdg-app-db.h
@@ -38,28 +38,41 @@ typedef struct _XdgAppDbEntry XdgAppDbEntry;
GType xdg_app_db_get_type (void);
-XdgAppDb *xdg_app_db_new (const char *path,
- GError **error);
-char ** xdg_app_db_list_ids (XdgAppDb *self);
-char ** xdg_app_db_list_ids_by_app (XdgAppDb *self,
- const char *app);
-char ** xdg_app_db_list_ids_by_value (XdgAppDb *self,
- GVariant *data);
-XdgAppDbEntry * xdg_app_db_lookup (XdgAppDb *self,
- const char *id);
-
-XdgAppDbEntry *xdg_app_db_entry_ref (XdgAppDbEntry *entry);
-void xdg_app_db_entry_unref (XdgAppDbEntry *entry);
-GVariant * xdg_app_db_entry_get_data (XdgAppDbEntry *entry);
-const char ** xdg_app_db_entry_list_apps (XdgAppDbEntry *entry);
-const char ** xdg_app_db_entry_list_permissions (XdgAppDbEntry *entry,
- const char *app);
-gboolean xdg_app_db_entry_has_permission (XdgAppDbEntry *entry,
- const char *app,
- const char *permission);
-gboolean xdg_app_db_entry_has_permissions (XdgAppDbEntry *entry,
- const char *app,
- const char **permissions);
+XdgAppDb * xdg_app_db_new (const char *path,
+ GError **error);
+char ** xdg_app_db_list_ids (XdgAppDb *self);
+char ** xdg_app_db_list_ids_by_app (XdgAppDb *self,
+ const char *app);
+char ** xdg_app_db_list_ids_by_value (XdgAppDb *self,
+ GVariant *data);
+XdgAppDbEntry *xdg_app_db_lookup (XdgAppDb *self,
+ const char *id);
+
+void xdg_app_db_set_entry (XdgAppDb *self,
+ const char *id,
+ XdgAppDbEntry *entry);
+
+
+XdgAppDbEntry *xdg_app_db_entry_ref (XdgAppDbEntry *entry);
+void xdg_app_db_entry_unref (XdgAppDbEntry *entry);
+GVariant * xdg_app_db_entry_get_data (XdgAppDbEntry *entry);
+const char ** xdg_app_db_entry_list_apps (XdgAppDbEntry *entry);
+const char ** xdg_app_db_entry_list_permissions (XdgAppDbEntry *entry,
+ const char *app);
+gboolean xdg_app_db_entry_has_permission (XdgAppDbEntry *entry,
+ const char *app,
+ const char *permission);
+gboolean xdg_app_db_entry_has_permissions (XdgAppDbEntry *entry,
+ const char *app,
+ const char **permissions);
+
+XdgAppDbEntry *xdg_app_db_entry_new (XdgAppDbEntry *entry,
+ GVariant *data);
+XdgAppDbEntry *xdg_app_db_entry_modify_data (XdgAppDbEntry *entry,
+ GVariant *data);
+XdgAppDbEntry *xdg_app_db_entry_set_app_permissions (XdgAppDbEntry *entry,
+ const char *app,
+ const char **permissions);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(XdgAppDb, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(XdgAppDbEntry, xdg_app_db_entry_unref)