mirror of
https://github.com/flatpak/flatpak.git
synced 2026-01-27 00:59:19 -05:00
Add new override builtin to override app permissions
This commit is contained in:
@@ -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 \
|
||||
|
||||
95
app/xdg-app-builtins-override.c
Normal file
95
app/xdg-app-builtins-override.c
Normal 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;
|
||||
}
|
||||
@@ -68,6 +68,7 @@ BUILTINPROTO(build_finish);
|
||||
BUILTINPROTO(build_export);
|
||||
BUILTINPROTO(repo_update);
|
||||
BUILTINPROTO(export_file);
|
||||
BUILTINPROTO(override);
|
||||
|
||||
#undef BUILTINPROTO
|
||||
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user