From 7ef861cedf03dd70fffefd3ddb19fc2ee2e0a37d Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Fri, 11 Sep 2015 16:07:31 +0200 Subject: [PATCH] Add new override builtin to override app permissions --- app/Makefile.am.inc | 1 + app/xdg-app-builtins-override.c | 95 ++++++++++++++++++++++++++++++++ app/xdg-app-builtins.h | 1 + app/xdg-app-main.c | 1 + lib/xdg-app-dir.c | 98 +++++++++++++++++++++++---------- lib/xdg-app-dir.h | 11 ++++ 6 files changed, 179 insertions(+), 28 deletions(-) create mode 100644 app/xdg-app-builtins-override.c diff --git a/app/Makefile.am.inc b/app/Makefile.am.inc index f82e16ec..70ac90cc 100644 --- a/app/Makefile.am.inc +++ b/app/Makefile.am.inc @@ -10,6 +10,7 @@ xdg_app_SOURCES = \ app/xdg-app-builtins-list-remotes.c \ app/xdg-app-builtins-repo-contents.c \ app/xdg-app-builtins-install.c \ + app/xdg-app-builtins-override.c \ app/xdg-app-builtins-make-current.c \ app/xdg-app-builtins-update.c \ app/xdg-app-builtins-uninstall.c \ diff --git a/app/xdg-app-builtins-override.c b/app/xdg-app-builtins-override.c new file mode 100644 index 00000000..679542c4 --- /dev/null +++ b/app/xdg-app-builtins-override.c @@ -0,0 +1,95 @@ +/* + * Copyright © 2014 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "libgsystem.h" +#include "libglnx/libglnx.h" + +#include "xdg-app-builtins.h" +#include "xdg-app-utils.h" +#include "xdg-app-run.h" + +static GOptionEntry options[] = { + { NULL } +}; + +gboolean +xdg_app_builtin_override (int argc, char **argv, GCancellable *cancellable, GError **error) +{ + g_autoptr(GOptionContext) context = NULL; + gboolean ret = FALSE; + const char *app; + g_autoptr(XdgAppContext) arg_context = NULL; + g_autoptr(XdgAppDir) dir = NULL; + g_autoptr(GKeyFile) metakey = NULL; + g_autoptr(XdgAppContext) overrides = NULL; + + context = g_option_context_new ("APP - Override settings for application"); + + arg_context = xdg_app_context_new (); + g_option_context_add_group (context, xdg_app_context_get_options (arg_context)); + + if (!xdg_app_option_context_parse (context, options, &argc, &argv, 0, &dir, cancellable, error)) + return FALSE; + + if (argc < 2) + { + usage_error (context, "APP must be specified", error); + return FALSE; + } + + app = argv[1]; + + if (!xdg_app_is_valid_name (app)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "'%s' is not a valid application name", app); + return FALSE; + } + + metakey = xdg_app_load_override_keyfile (app, xdg_app_dir_is_user (dir), error); + if (metakey == NULL) + return FALSE; + + overrides = xdg_app_context_new (); + if (!xdg_app_context_load_metadata (overrides, metakey, error)) + return FALSE; + + xdg_app_context_merge (overrides, arg_context); + + xdg_app_context_save_metadata (overrides, metakey); + + if (!xdg_app_save_override_keyfile (metakey, app, xdg_app_dir_is_user (dir), error)) + return FALSE; + + ret = TRUE; + + out: + /* if (context) + g_option_context_free (context);*/ + return ret; +} diff --git a/app/xdg-app-builtins.h b/app/xdg-app-builtins.h index c6107f50..90949450 100644 --- a/app/xdg-app-builtins.h +++ b/app/xdg-app-builtins.h @@ -68,6 +68,7 @@ BUILTINPROTO(build_finish); BUILTINPROTO(build_export); BUILTINPROTO(repo_update); BUILTINPROTO(export_file); +BUILTINPROTO(override); #undef BUILTINPROTO diff --git a/app/xdg-app-main.c b/app/xdg-app-main.c index e966b7e1..f40da309 100644 --- a/app/xdg-app-main.c +++ b/app/xdg-app-main.c @@ -51,6 +51,7 @@ static XdgAppCommand commands[] = { { "list-runtimes", xdg_app_builtin_list_runtimes }, { "install-app", xdg_app_builtin_install_app }, { "update-app", xdg_app_builtin_update_app }, + { "override", xdg_app_builtin_override }, { "make-app-current", xdg_app_builtin_make_current_app }, { "uninstall-app", xdg_app_builtin_uninstall_app }, { "list-apps", xdg_app_builtin_list_apps }, diff --git a/lib/xdg-app-dir.c b/lib/xdg-app-dir.c index ab86b632..e99e6431 100644 --- a/lib/xdg-app-dir.c +++ b/lib/xdg-app-dir.c @@ -50,8 +50,8 @@ struct XdgAppDeploy { GFile *dir; GKeyFile *metadata; - GKeyFile *system_overrides; - GKeyFile *user_overrides; + XdgAppContext *system_overrides; + XdgAppContext *user_overrides; }; typedef struct { @@ -81,8 +81,8 @@ xdg_app_deploy_finalize (GObject *object) g_clear_object (&self->dir); g_clear_pointer (&self->metadata, g_key_file_unref); - g_clear_pointer (&self->system_overrides, g_key_file_unref); - g_clear_pointer (&self->user_overrides, g_key_file_unref); + g_clear_pointer (&self->system_overrides, g_object_unref); + g_clear_pointer (&self->user_overrides, g_object_unref); G_OBJECT_CLASS (xdg_app_deploy_parent_class)->finalize (object); } @@ -116,22 +116,13 @@ xdg_app_deploy_get_files (XdgAppDeploy *deploy) XdgAppContext * xdg_app_deploy_get_overrides (XdgAppDeploy *deploy) { - GError *local_error = NULL; XdgAppContext *overrides = xdg_app_context_new (); - if (deploy->system_overrides && - !xdg_app_context_load_metadata (overrides, deploy->system_overrides, &local_error)) - { - g_warning ("Invalid system override file: %s\n", local_error->message); - g_clear_error (&local_error); - } + if (deploy->system_overrides) + xdg_app_context_merge (overrides, deploy->system_overrides); - if (deploy->user_overrides && - !xdg_app_context_load_metadata (overrides, deploy->user_overrides, &local_error)) - { - g_warning ("Invalid user override file: %s\n", local_error->message); - g_clear_error (&local_error); - } + if (deploy->user_overrides) + xdg_app_context_merge (overrides, deploy->user_overrides); return overrides; } @@ -265,14 +256,15 @@ xdg_app_dir_get_path (XdgAppDir *self) return self->basedir; } -static GKeyFile * -xdg_app_load_override_file (const char *app_id, gboolean user) +GKeyFile * +xdg_app_load_override_keyfile (const char *app_id, gboolean user, GError **error) { g_autoptr(GFile) base_dir = NULL; g_autoptr(GFile) override_dir = NULL; g_autoptr(GFile) file = NULL; g_autofree char *metadata_contents = NULL; gsize metadata_size; + g_autoptr(GKeyFile) metakey = g_key_file_new (); if (user) base_dir = xdg_app_get_user_base_dir_location (); @@ -285,17 +277,61 @@ xdg_app_load_override_file (const char *app_id, gboolean user) if (g_file_load_contents (file, NULL, &metadata_contents, &metadata_size, NULL, NULL)) { - g_autoptr(GError) local_error = NULL; - g_autoptr(GKeyFile) metakey = g_key_file_new (); if (!g_key_file_load_from_data (metakey, metadata_contents, metadata_size, - 0, &local_error)) - g_warning ("Invalid override file: %s\n", local_error->message); - else - return g_steal_pointer (&metakey); + 0, error)) + return NULL; } - return NULL; + + return g_steal_pointer (&metakey); +} + +XdgAppContext * +xdg_app_load_override_file (const char *app_id, gboolean user, GError **error) +{ + XdgAppContext *overrides = xdg_app_context_new (); + g_autoptr(GKeyFile) metakey = NULL; + + metakey = xdg_app_load_override_keyfile (app_id, user, error); + if (metakey == NULL) + return NULL; + + if (!xdg_app_context_load_metadata (overrides, metakey, error)) + return NULL; + + return g_steal_pointer (&overrides); +} + +gboolean +xdg_app_save_override_keyfile (GKeyFile *metakey, + const char *app_id, + gboolean user, + GError **error) +{ + g_autoptr(GFile) base_dir = NULL; + g_autoptr(GFile) override_dir = NULL; + g_autoptr(GFile) file = NULL; + g_autofree char *filename = NULL; + g_autofree char *parent = NULL; + + if (user) + base_dir = xdg_app_get_user_base_dir_location (); + else + base_dir = xdg_app_get_system_base_dir_location (); + + override_dir = g_file_get_child (base_dir, "overrides"); + file = g_file_get_child (override_dir, app_id); + + filename = g_file_get_path (file); + parent = g_path_get_dirname (filename); + if (g_mkdir_with_parents (parent, 0755)) + { + glnx_set_error_from_errno (error); + return FALSE; + } + + return g_key_file_save_to_file (metakey, filename, error); } XdgAppDeploy * @@ -338,10 +374,16 @@ xdg_app_dir_load_deployed (XdgAppDir *self, { /* Only load system overrides for system installed apps */ if (!self->user) - deploy->system_overrides = xdg_app_load_override_file (ref_parts[1], FALSE); + { + deploy->system_overrides = xdg_app_load_override_file (ref_parts[1], FALSE, error); + if (deploy->system_overrides == NULL) + return NULL; + } /* Always load user overrides */ - deploy->user_overrides = xdg_app_load_override_file (ref_parts[1], TRUE); + deploy->user_overrides = xdg_app_load_override_file (ref_parts[1], TRUE, error); + if (deploy->user_overrides == NULL) + return NULL; } return deploy; diff --git a/lib/xdg-app-dir.h b/lib/xdg-app-dir.h index e6d086c2..88d674ee 100644 --- a/lib/xdg-app-dir.h +++ b/lib/xdg-app-dir.h @@ -55,6 +55,17 @@ GQuark xdg_app_dir_error_quark (void); GFile * xdg_app_get_system_base_dir_location (void); GFile * xdg_app_get_user_base_dir_location (void); +GKeyFile * xdg_app_load_override_keyfile (const char *app_id, + gboolean user, + GError **error); +XdgAppContext *xdg_app_load_override_file (const char *app_id, + gboolean user, + GError **error); +gboolean xdg_app_save_override_keyfile (GKeyFile *metakey, + const char *app_id, + gboolean user, + GError **error); + GFile * xdg_app_deploy_get_dir (XdgAppDeploy *deploy); GFile * xdg_app_deploy_get_files (XdgAppDeploy *deploy); XdgAppContext *xdg_app_deploy_get_overrides (XdgAppDeploy *deploy);