diff --git a/app/Makefile.am.inc b/app/Makefile.am.inc index 1a522f60..46eb1c50 100644 --- a/app/Makefile.am.inc +++ b/app/Makefile.am.inc @@ -51,6 +51,7 @@ flatpak_SOURCES = \ app/flatpak-builtins-document-unexport.c \ app/flatpak-builtins-document-info.c \ app/flatpak-builtins-document-list.c \ + app/flatpak-builtins-permission-list.c \ app/flatpak-builtins-search.c \ app/flatpak-builtins-repair.c \ app/flatpak-table-printer.c \ diff --git a/app/flatpak-builtins-permission-list.c b/app/flatpak-builtins-permission-list.c new file mode 100644 index 00000000..f0f89435 --- /dev/null +++ b/app/flatpak-builtins-permission-list.c @@ -0,0 +1,285 @@ +/* + * Copyright © 2018 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.1 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: + * Matthias Clasen + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include + +#include "libglnx/libglnx.h" +#include "flatpak-permission-dbus-generated.h" + +#include "flatpak-builtins.h" +#include "flatpak-table-printer.h" +#include "flatpak-utils-private.h" +#include "flatpak-run-private.h" + +static GOptionEntry options[] = { + { NULL } +}; + +static char ** +get_permission_tables (XdpDbusPermissionStore *store) +{ + g_autofree char *path = NULL; + GDir *dir; + const char *name; + GPtrArray *tables = NULL; + + tables = g_ptr_array_new (); + + path = g_build_filename (g_get_user_data_dir (), "flatpak/db", NULL); + dir = g_dir_open (path, 0, NULL); + if (dir != NULL) + { + while ((name = g_dir_read_name (dir)) != NULL) + { + g_ptr_array_add (tables, g_strdup (name)); + } + } + + g_dir_close (dir); + + g_ptr_array_add (tables, NULL); + + return (char **)g_ptr_array_free (tables, FALSE); +} + +static char ** +get_ids_for_table (XdpDbusPermissionStore *store, + const char *table) +{ + char **ids = NULL; + + xdp_dbus_permission_store_call_list_sync (store, table, &ids, NULL, NULL); + + return ids; +} + +static gboolean +list_table (XdpDbusPermissionStore *store, + const char *table, + const char *id, + FlatpakTablePrinter *printer, + GError **error) +{ + const char *one_id[2]; + char **ids; + int i; + + if (id) + { + one_id[0] = id; + one_id[1] = NULL; + ids = (char **)one_id; + } + else + { + if (!xdp_dbus_permission_store_call_list_sync (store, table, &ids, NULL, error)) + return FALSE; + } + + for (i = 0; ids[i]; i++) + { + g_autoptr(GVariant) permissions = NULL; + g_autoptr(GVariant) data = NULL; + g_autoptr(GVariant) d = NULL; + g_autofree char *txt = NULL; + GVariantIter iter; + char *key; + GVariantIter *val; + + if (!xdp_dbus_permission_store_call_lookup_sync (store, table, ids[i], &permissions, &data, NULL, error)) + return FALSE; + + d = g_variant_get_child_value (data, 0); + txt = g_variant_print (d, FALSE); + + if (g_variant_iter_init (&iter, permissions) == 0 && id != 0) + { + flatpak_table_printer_add_column (printer, table); + flatpak_table_printer_add_column (printer, ids[i]); + flatpak_table_printer_add_column (printer, ""); + flatpak_table_printer_add_column (printer, ""); + flatpak_table_printer_add_column (printer, txt); + flatpak_table_printer_finish_row (printer); + } + + while (g_variant_iter_loop (&iter, "{sas}", &key, &val)) + { + char *p; + + flatpak_table_printer_add_column (printer, table); + flatpak_table_printer_add_column (printer, ids[i]); + flatpak_table_printer_add_column (printer, key); + flatpak_table_printer_add_column (printer, ""); + + while (g_variant_iter_loop (val, "s", &p)) + { + flatpak_table_printer_append_with_comma (printer, p); + } + + flatpak_table_printer_add_column (printer, txt); + flatpak_table_printer_finish_row (printer); + } + } + + return TRUE; +} + +gboolean +flatpak_builtin_permission_list (int argc, char **argv, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GOptionContext) context = NULL; + g_autoptr(GDBusConnection) session_bus = NULL; + XdpDbusPermissionStore *store = NULL; + const char *table; + const char *id; + FlatpakTablePrinter *printer = NULL; + + context = g_option_context_new (_("[TABLE] [ID] - List permissions")); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + + if (!flatpak_option_context_parse (context, options, &argc, &argv, + FLATPAK_BUILTIN_FLAG_NO_DIR, + NULL, cancellable, error)) + return FALSE; + + if (argc < 2) + table = NULL; + else + table = argv[1]; + + if (argc < 3) + id = NULL; + else + id = argv[2]; + + if (argc > 3) + return usage_error (context, _("Too many arguments"), error); + + session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error); + if (session_bus == NULL) + return FALSE; + + store = xdp_dbus_permission_store_proxy_new_sync (session_bus, 0, + "org.freedesktop.impl.portal.PermissionStore", + "/org/freedesktop/impl/portal/PermissionStore", + NULL, error); + if (store == NULL) + return FALSE; + + printer = flatpak_table_printer_new (); + int i; + + i = 0; + flatpak_table_printer_set_column_title (printer, i++, _("Table")); + flatpak_table_printer_set_column_title (printer, i++, _("Object")); + flatpak_table_printer_set_column_title (printer, i++, _("App")); + flatpak_table_printer_set_column_title (printer, i++, _("Permissions")); + flatpak_table_printer_set_column_title (printer, i++, _("Data")); + + if (table) + { + if (!list_table (store, table, id, printer, error)) + return FALSE; + } + else + { + int i; + g_auto(GStrv) tables = get_permission_tables (store); + + for (i = 0; tables[i]; i++) + { + if (!list_table (store, tables[i], NULL, printer, error)) + return FALSE; + } + } + + flatpak_table_printer_print (printer); + flatpak_table_printer_free (printer); + + return TRUE; +} + +gboolean +flatpak_complete_permission_list (FlatpakCompletion *completion) +{ + g_autoptr(GOptionContext) context = NULL; + g_autoptr(GDBusConnection) session_bus = NULL; + XdpDbusPermissionStore *store = NULL; + int i; + + context = g_option_context_new (""); + + if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv, + FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, NULL, NULL)) + return FALSE; + + session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + if (session_bus == NULL) + return FALSE; + + store = xdp_dbus_permission_store_proxy_new_sync (session_bus, 0, + "org.freedesktop.impl.portal.PermissionStore", + "/org/freedesktop/impl/portal/PermissionStore", + NULL, NULL); + + if (store == NULL) + return FALSE; + + switch (completion->argc) + { + case 0: + case 1: /* TABLE */ + flatpak_complete_options (completion, global_entries); + flatpak_complete_options (completion, options); + + { + g_auto(GStrv) tables = get_permission_tables (store); + for (i = 0; tables != NULL && tables[i] != NULL; i++) + { + flatpak_complete_word (completion, "%s ", tables[i]); + } + } + + break; + + case 2: + { + g_auto(GStrv) ids = get_ids_for_table (store, completion->argv[1]); + for (i = 0; ids != NULL && ids[i] != NULL; i++) + { + flatpak_complete_word (completion, "%s ", ids[i]); + } + } + + break; + } + + return TRUE; +} diff --git a/app/flatpak-builtins.h b/app/flatpak-builtins.h index a2a5f232..7e32f4cb 100644 --- a/app/flatpak-builtins.h +++ b/app/flatpak-builtins.h @@ -87,6 +87,7 @@ BUILTINPROTO (document_export) BUILTINPROTO (document_unexport) BUILTINPROTO (document_info) BUILTINPROTO (document_list) +BUILTINPROTO (permission_list) BUILTINPROTO (override) BUILTINPROTO (repo) BUILTINPROTO (config) diff --git a/app/flatpak-main.c b/app/flatpak-main.c index 735ce917..a02d8be1 100644 --- a/app/flatpak-main.c +++ b/app/flatpak-main.c @@ -88,6 +88,10 @@ static FlatpakCommand commands[] = { { "document-info", N_("Show information about a specific file"), flatpak_builtin_document_info, flatpak_complete_document_info }, { "document-list", N_("List exported files"), flatpak_builtin_document_list, flatpak_complete_document_list }, + /* translators: please keep the leading newline and space */ + { N_("\n Manage dynamic permissions") }, + { "permission-list", N_("List permissions"), flatpak_builtin_permission_list, flatpak_complete_permission_list }, + /* translators: please keep the leading newline and space */ { N_("\n Manage remote repositories") }, { "remotes", N_("List all configured remotes"), flatpak_builtin_list_remotes, flatpak_complete_list_remotes }, diff --git a/doc/Makefile.am b/doc/Makefile.am index 9e6d1f45..f831a62a 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -39,6 +39,7 @@ man1 = \ flatpak-document-unexport.1 \ flatpak-document-info.1 \ flatpak-document-list.1 \ + flatpak-permission-list.1 \ flatpak-build-init.1 \ flatpak-build.1 \ flatpak-build-bundle.1 \ diff --git a/doc/flatpak-docs.xml.in b/doc/flatpak-docs.xml.in index d3a20c24..1405550e 100644 --- a/doc/flatpak-docs.xml.in +++ b/doc/flatpak-docs.xml.in @@ -33,6 +33,7 @@ + diff --git a/doc/flatpak-permission-list.xml b/doc/flatpak-permission-list.xml new file mode 100644 index 00000000..46823d7c --- /dev/null +++ b/doc/flatpak-permission-list.xml @@ -0,0 +1,111 @@ + + + + + + + flatpak permission-list + flatpak + + + + Developer + Matthias + Clasen + mclasen@redhat.com + + + + + + flatpak permission-list + 1 + + + + flatpak-permission-list + List permissions + + + + + flatpak permission-list + OPTION + TABLE + ID + + + + + Description + + + Lists dynamic permissions which are stored in the Flatpak + permission store. + + + + When called without arguments, lists all + the entries in all permission store tables. When called + with one argument, lists all the entries in the named + table. When called with two arguments, lists the entry + in the named table for the given object ID. + + + + The permission store is used by portals. + Each portal generally has its own table in the permission + store, and the format of the table entries is specific to + each portal. + + + + + + Options + + The following options are understood: + + + + + + + + Show help options and exit. + + + + + + + + + Print debug information during command processing. + + + + + + + + Print OSTree debug information during command processing. + + + + + + + See also + + + flatpak1, + flatpak-permission-show1, + flatpak-permission-remove1, + flatpak-permission-reset1, + + + + +