Add new override builtin to override app permissions

This commit is contained in:
Alexander Larsson
2015-09-11 16:07:31 +02:00
parent c87e7e4e4f
commit 7ef861cedf
6 changed files with 179 additions and 28 deletions

View File

@@ -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 \

View File

@@ -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 <http://www.gnu.org/licenses/>.
*
* Authors:
* Alexander Larsson <alexl@redhat.com>
*/
#include "config.h"
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#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;
}

View File

@@ -68,6 +68,7 @@ BUILTINPROTO(build_finish);
BUILTINPROTO(build_export);
BUILTINPROTO(repo_update);
BUILTINPROTO(export_file);
BUILTINPROTO(override);
#undef BUILTINPROTO

View File

@@ -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 },

View File

@@ -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;

View File

@@ -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);