Merge branch 'filter-content-type' into 'master'
Add support to filter by content type See merge request pwithnall/malcontent!15
This commit is contained in:
commit
90f961dc74
|
@ -1,6 +1,6 @@
|
||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||||
*
|
*
|
||||||
* Copyright © 2018 Endless Mobile, Inc.
|
* Copyright © 2018-2019 Endless Mobile, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* - Philip Withnall <withnall@endlessm.com>
|
* - Philip Withnall <withnall@endlessm.com>
|
||||||
|
* - Andre Moreira Magalhaes <andre@endlessm.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -124,8 +125,12 @@ mct_app_filter_is_path_allowed (MctAppFilter *filter,
|
||||||
g_return_val_if_fail (g_path_is_absolute (path), FALSE);
|
g_return_val_if_fail (g_path_is_absolute (path), FALSE);
|
||||||
|
|
||||||
g_autofree gchar *canonical_path = g_canonicalize_filename (path, "/");
|
g_autofree gchar *canonical_path = g_canonicalize_filename (path, "/");
|
||||||
|
g_autofree gchar *canonical_path_utf8 = g_filename_to_utf8 (canonical_path, -1,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
g_return_val_if_fail (canonical_path_utf8 != NULL, FALSE);
|
||||||
|
|
||||||
gboolean path_in_list = g_strv_contains ((const gchar * const *) filter->app_list,
|
gboolean path_in_list = g_strv_contains ((const gchar * const *) filter->app_list,
|
||||||
canonical_path);
|
canonical_path_utf8);
|
||||||
|
|
||||||
switch (filter->app_list_type)
|
switch (filter->app_list_type)
|
||||||
{
|
{
|
||||||
|
@ -138,6 +143,34 @@ mct_app_filter_is_path_allowed (MctAppFilter *filter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check whether a given @ref is a valid flatpak ref.
|
||||||
|
*
|
||||||
|
* For simplicity and to avoid duplicating the whole logic behind
|
||||||
|
* flatpak_ref_parse() this method will only check whether:
|
||||||
|
* - the @ref contains exactly 3 slash chars
|
||||||
|
* - the @ref starts with either app/ or runtime/
|
||||||
|
* - the name, arch and branch components of the @ref are not empty
|
||||||
|
*
|
||||||
|
* We avoid using flatpak_ref_parse() to allow for libflatpak
|
||||||
|
* to depend on malcontent without causing a cyclic dependency.
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
is_valid_flatpak_ref (const gchar *ref)
|
||||||
|
{
|
||||||
|
g_auto(GStrv) parts = NULL;
|
||||||
|
|
||||||
|
if (ref == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
parts = g_strsplit (ref, "/", 0);
|
||||||
|
return (g_strv_length (parts) == 4 &&
|
||||||
|
(strcmp (parts[0], "app") == 0 ||
|
||||||
|
strcmp (parts[0], "runtime") == 0) &&
|
||||||
|
*parts[1] != '\0' &&
|
||||||
|
*parts[2] != '\0' &&
|
||||||
|
*parts[3] != '\0');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mct_app_filter_is_flatpak_ref_allowed:
|
* mct_app_filter_is_flatpak_ref_allowed:
|
||||||
* @filter: an #MctAppFilter
|
* @filter: an #MctAppFilter
|
||||||
|
@ -157,6 +190,7 @@ mct_app_filter_is_flatpak_ref_allowed (MctAppFilter *filter,
|
||||||
g_return_val_if_fail (filter != NULL, FALSE);
|
g_return_val_if_fail (filter != NULL, FALSE);
|
||||||
g_return_val_if_fail (filter->ref_count >= 1, FALSE);
|
g_return_val_if_fail (filter->ref_count >= 1, FALSE);
|
||||||
g_return_val_if_fail (app_ref != NULL, FALSE);
|
g_return_val_if_fail (app_ref != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (is_valid_flatpak_ref (app_ref), FALSE);
|
||||||
|
|
||||||
gboolean ref_in_list = g_strv_contains ((const gchar * const *) filter->app_list,
|
gboolean ref_in_list = g_strv_contains ((const gchar * const *) filter->app_list,
|
||||||
app_ref);
|
app_ref);
|
||||||
|
@ -201,9 +235,8 @@ mct_app_filter_is_flatpak_app_allowed (MctAppFilter *filter,
|
||||||
gboolean id_in_list = FALSE;
|
gboolean id_in_list = FALSE;
|
||||||
for (gsize i = 0; filter->app_list[i] != NULL; i++)
|
for (gsize i = 0; filter->app_list[i] != NULL; i++)
|
||||||
{
|
{
|
||||||
/* Avoid using flatpak_ref_parse() to avoid a dependency on libflatpak
|
if (is_valid_flatpak_ref (filter->app_list[i]) &&
|
||||||
* just for that one function. */
|
g_str_has_prefix (filter->app_list[i], "app/") &&
|
||||||
if (g_str_has_prefix (filter->app_list[i], "app/") &&
|
|
||||||
strncmp (filter->app_list[i] + strlen ("app/"), app_id, app_id_len) == 0 &&
|
strncmp (filter->app_list[i] + strlen ("app/"), app_id, app_id_len) == 0 &&
|
||||||
filter->app_list[i][strlen ("app/") + app_id_len] == '/')
|
filter->app_list[i][strlen ("app/") + app_id_len] == '/')
|
||||||
{
|
{
|
||||||
|
@ -242,6 +275,7 @@ mct_app_filter_is_appinfo_allowed (MctAppFilter *filter,
|
||||||
GAppInfo *app_info)
|
GAppInfo *app_info)
|
||||||
{
|
{
|
||||||
g_autofree gchar *abs_path = NULL;
|
g_autofree gchar *abs_path = NULL;
|
||||||
|
const gchar * const *types = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (filter != NULL, FALSE);
|
g_return_val_if_fail (filter != NULL, FALSE);
|
||||||
g_return_val_if_fail (filter->ref_count >= 1, FALSE);
|
g_return_val_if_fail (filter->ref_count >= 1, FALSE);
|
||||||
|
@ -253,6 +287,13 @@ mct_app_filter_is_appinfo_allowed (MctAppFilter *filter,
|
||||||
!mct_app_filter_is_path_allowed (filter, abs_path))
|
!mct_app_filter_is_path_allowed (filter, abs_path))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
types = g_app_info_get_supported_types (app_info);
|
||||||
|
for (gsize i = 0; types != NULL && types[i] != NULL; i++)
|
||||||
|
{
|
||||||
|
if (!mct_app_filter_is_content_type_allowed (filter, types[i]))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (G_IS_DESKTOP_APP_INFO (app_info))
|
if (G_IS_DESKTOP_APP_INFO (app_info))
|
||||||
{
|
{
|
||||||
g_autofree gchar *flatpak_app = NULL;
|
g_autofree gchar *flatpak_app = NULL;
|
||||||
|
@ -292,6 +333,67 @@ mct_app_filter_is_appinfo_allowed (MctAppFilter *filter,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check whether a given @content_type is valid.
|
||||||
|
*
|
||||||
|
* For simplicity this method will only check whether:
|
||||||
|
* - the @content_type contains exactly 1 slash char
|
||||||
|
* - the @content_type does not start with a slash char
|
||||||
|
* - the type and subtype components of the @content_type are not empty
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
is_valid_content_type (const gchar *content_type)
|
||||||
|
{
|
||||||
|
g_auto(GStrv) parts = NULL;
|
||||||
|
|
||||||
|
if (content_type == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
parts = g_strsplit (content_type, "/", 0);
|
||||||
|
return (g_strv_length (parts) == 2 &&
|
||||||
|
*parts[0] != '\0' &&
|
||||||
|
*parts[1] != '\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mct_app_filter_is_content_type_allowed:
|
||||||
|
* @filter: an #MctAppFilter
|
||||||
|
* @content_type: content type to check
|
||||||
|
*
|
||||||
|
* Check whether apps handling the given @content_type are allowed to be run
|
||||||
|
* according to this app filter.
|
||||||
|
*
|
||||||
|
* Note that this method doesn’t match content subtypes. For example, if
|
||||||
|
* `application/xml` is added to the blacklist but `application/xspf+xml` is not,
|
||||||
|
* a check for whether `application/xspf+xml` is blacklisted would return false.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the user this @filter corresponds to is allowed to run
|
||||||
|
* programs handling @content_type according to the @filter policy;
|
||||||
|
* %FALSE otherwise
|
||||||
|
* Since: 0.4.0
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
mct_app_filter_is_content_type_allowed (MctAppFilter *filter,
|
||||||
|
const gchar *content_type)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (filter != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (filter->ref_count >= 1, FALSE);
|
||||||
|
g_return_val_if_fail (content_type != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (is_valid_content_type (content_type), FALSE);
|
||||||
|
|
||||||
|
gboolean ref_in_list = g_strv_contains ((const gchar * const *) filter->app_list,
|
||||||
|
content_type);
|
||||||
|
|
||||||
|
switch (filter->app_list_type)
|
||||||
|
{
|
||||||
|
case MCT_APP_FILTER_LIST_BLACKLIST:
|
||||||
|
return !ref_in_list;
|
||||||
|
case MCT_APP_FILTER_LIST_WHITELIST:
|
||||||
|
return ref_in_list;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
strcmp_cb (gconstpointer a,
|
strcmp_cb (gconstpointer a,
|
||||||
gconstpointer b)
|
gconstpointer b)
|
||||||
|
@ -433,7 +535,7 @@ mct_app_filter_is_system_installation_allowed (MctAppFilter *filter)
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GPtrArray *paths_blacklist; /* (nullable) (owned) (element-type filename) */
|
GPtrArray *blacklist; /* (nullable) (owned) (element-type utf8) */
|
||||||
GHashTable *oars; /* (nullable) (owned) (element-type utf8 MctAppFilterOarsValue) */
|
GHashTable *oars; /* (nullable) (owned) (element-type utf8 MctAppFilterOarsValue) */
|
||||||
gboolean allow_user_installation;
|
gboolean allow_user_installation;
|
||||||
gboolean allow_system_installation;
|
gboolean allow_system_installation;
|
||||||
|
@ -471,7 +573,7 @@ mct_app_filter_builder_init (MctAppFilterBuilder *builder)
|
||||||
MctAppFilterBuilderReal *_builder = (MctAppFilterBuilderReal *) builder;
|
MctAppFilterBuilderReal *_builder = (MctAppFilterBuilderReal *) builder;
|
||||||
|
|
||||||
g_return_if_fail (_builder != NULL);
|
g_return_if_fail (_builder != NULL);
|
||||||
g_return_if_fail (_builder->paths_blacklist == NULL);
|
g_return_if_fail (_builder->blacklist == NULL);
|
||||||
g_return_if_fail (_builder->oars == NULL);
|
g_return_if_fail (_builder->oars == NULL);
|
||||||
|
|
||||||
memcpy (builder, &local_builder, sizeof (local_builder));
|
memcpy (builder, &local_builder, sizeof (local_builder));
|
||||||
|
@ -497,7 +599,7 @@ mct_app_filter_builder_clear (MctAppFilterBuilder *builder)
|
||||||
|
|
||||||
g_return_if_fail (_builder != NULL);
|
g_return_if_fail (_builder != NULL);
|
||||||
|
|
||||||
g_clear_pointer (&_builder->paths_blacklist, g_ptr_array_unref);
|
g_clear_pointer (&_builder->blacklist, g_ptr_array_unref);
|
||||||
g_clear_pointer (&_builder->oars, g_hash_table_unref);
|
g_clear_pointer (&_builder->oars, g_hash_table_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,8 +649,8 @@ mct_app_filter_builder_copy (MctAppFilterBuilder *builder)
|
||||||
_copy = (MctAppFilterBuilderReal *) copy;
|
_copy = (MctAppFilterBuilderReal *) copy;
|
||||||
|
|
||||||
mct_app_filter_builder_clear (copy);
|
mct_app_filter_builder_clear (copy);
|
||||||
if (_builder->paths_blacklist != NULL)
|
if (_builder->blacklist != NULL)
|
||||||
_copy->paths_blacklist = g_ptr_array_ref (_builder->paths_blacklist);
|
_copy->blacklist = g_ptr_array_ref (_builder->blacklist);
|
||||||
if (_builder->oars != NULL)
|
if (_builder->oars != NULL)
|
||||||
_copy->oars = g_hash_table_ref (_builder->oars);
|
_copy->oars = g_hash_table_ref (_builder->oars);
|
||||||
_copy->allow_user_installation = _builder->allow_user_installation;
|
_copy->allow_user_installation = _builder->allow_user_installation;
|
||||||
|
@ -598,11 +700,11 @@ mct_app_filter_builder_end (MctAppFilterBuilder *builder)
|
||||||
g_autoptr(GVariant) oars_variant = NULL;
|
g_autoptr(GVariant) oars_variant = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (_builder != NULL, NULL);
|
g_return_val_if_fail (_builder != NULL, NULL);
|
||||||
g_return_val_if_fail (_builder->paths_blacklist != NULL, NULL);
|
g_return_val_if_fail (_builder->blacklist != NULL, NULL);
|
||||||
g_return_val_if_fail (_builder->oars != NULL, NULL);
|
g_return_val_if_fail (_builder->oars != NULL, NULL);
|
||||||
|
|
||||||
/* Ensure the paths list is %NULL-terminated. */
|
/* Ensure the paths list is %NULL-terminated. */
|
||||||
g_ptr_array_add (_builder->paths_blacklist, NULL);
|
g_ptr_array_add (_builder->blacklist, NULL);
|
||||||
|
|
||||||
/* Build the OARS variant. */
|
/* Build the OARS variant. */
|
||||||
g_hash_table_iter_init (&iter, _builder->oars);
|
g_hash_table_iter_init (&iter, _builder->oars);
|
||||||
|
@ -633,7 +735,7 @@ mct_app_filter_builder_end (MctAppFilterBuilder *builder)
|
||||||
app_filter = g_new0 (MctAppFilter, 1);
|
app_filter = g_new0 (MctAppFilter, 1);
|
||||||
app_filter->ref_count = 1;
|
app_filter->ref_count = 1;
|
||||||
app_filter->user_id = -1;
|
app_filter->user_id = -1;
|
||||||
app_filter->app_list = (gchar **) g_ptr_array_free (g_steal_pointer (&_builder->paths_blacklist), FALSE);
|
app_filter->app_list = (gchar **) g_ptr_array_free (g_steal_pointer (&_builder->blacklist), FALSE);
|
||||||
app_filter->app_list_type = MCT_APP_FILTER_LIST_BLACKLIST;
|
app_filter->app_list_type = MCT_APP_FILTER_LIST_BLACKLIST;
|
||||||
app_filter->oars_ratings = g_steal_pointer (&oars_variant);
|
app_filter->oars_ratings = g_steal_pointer (&oars_variant);
|
||||||
app_filter->allow_user_installation = _builder->allow_user_installation;
|
app_filter->allow_user_installation = _builder->allow_user_installation;
|
||||||
|
@ -662,15 +764,18 @@ mct_app_filter_builder_blacklist_path (MctAppFilterBuilder *builder,
|
||||||
MctAppFilterBuilderReal *_builder = (MctAppFilterBuilderReal *) builder;
|
MctAppFilterBuilderReal *_builder = (MctAppFilterBuilderReal *) builder;
|
||||||
|
|
||||||
g_return_if_fail (_builder != NULL);
|
g_return_if_fail (_builder != NULL);
|
||||||
g_return_if_fail (_builder->paths_blacklist != NULL);
|
g_return_if_fail (_builder->blacklist != NULL);
|
||||||
g_return_if_fail (path != NULL);
|
g_return_if_fail (path != NULL);
|
||||||
g_return_if_fail (g_path_is_absolute (path));
|
g_return_if_fail (g_path_is_absolute (path));
|
||||||
|
|
||||||
g_autofree gchar *canonical_path = g_canonicalize_filename (path, "/");
|
g_autofree gchar *canonical_path = g_canonicalize_filename (path, "/");
|
||||||
|
g_autofree gchar *canonical_path_utf8 = g_filename_to_utf8 (canonical_path, -1,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
g_return_if_fail (canonical_path_utf8 != NULL);
|
||||||
|
|
||||||
if (!g_ptr_array_find_with_equal_func (_builder->paths_blacklist,
|
if (!g_ptr_array_find_with_equal_func (_builder->blacklist,
|
||||||
canonical_path, g_str_equal, NULL))
|
canonical_path_utf8, g_str_equal, NULL))
|
||||||
g_ptr_array_add (_builder->paths_blacklist, g_steal_pointer (&canonical_path));
|
g_ptr_array_add (_builder->blacklist, g_steal_pointer (&canonical_path_utf8));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -691,12 +796,44 @@ mct_app_filter_builder_blacklist_flatpak_ref (MctAppFilterBuilder *builder,
|
||||||
MctAppFilterBuilderReal *_builder = (MctAppFilterBuilderReal *) builder;
|
MctAppFilterBuilderReal *_builder = (MctAppFilterBuilderReal *) builder;
|
||||||
|
|
||||||
g_return_if_fail (_builder != NULL);
|
g_return_if_fail (_builder != NULL);
|
||||||
g_return_if_fail (_builder->paths_blacklist != NULL);
|
g_return_if_fail (_builder->blacklist != NULL);
|
||||||
g_return_if_fail (app_ref != NULL);
|
g_return_if_fail (app_ref != NULL);
|
||||||
|
g_return_if_fail (is_valid_flatpak_ref (app_ref));
|
||||||
|
|
||||||
if (!g_ptr_array_find_with_equal_func (_builder->paths_blacklist,
|
if (!g_ptr_array_find_with_equal_func (_builder->blacklist,
|
||||||
app_ref, g_str_equal, NULL))
|
app_ref, g_str_equal, NULL))
|
||||||
g_ptr_array_add (_builder->paths_blacklist, g_strdup (app_ref));
|
g_ptr_array_add (_builder->blacklist, g_strdup (app_ref));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mct_app_filter_builder_blacklist_content_type:
|
||||||
|
* @builder: an initialised #MctAppFilterBuilder
|
||||||
|
* @content_type: a content type to blacklist
|
||||||
|
*
|
||||||
|
* Add @content_type to the blacklist of content types in the filter under
|
||||||
|
* construction. The @content_type will not be added again if it’s already been
|
||||||
|
* added.
|
||||||
|
*
|
||||||
|
* Note that this method doesn’t handle content subtypes. For example, if
|
||||||
|
* `application/xml` is added to the blacklist but `application/xspf+xml` is not,
|
||||||
|
* a check for whether `application/xspf+xml` is blacklisted would return false.
|
||||||
|
*
|
||||||
|
* Since: 0.4.0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mct_app_filter_builder_blacklist_content_type (MctAppFilterBuilder *builder,
|
||||||
|
const gchar *content_type)
|
||||||
|
{
|
||||||
|
MctAppFilterBuilderReal *_builder = (MctAppFilterBuilderReal *) builder;
|
||||||
|
|
||||||
|
g_return_if_fail (_builder != NULL);
|
||||||
|
g_return_if_fail (_builder->blacklist != NULL);
|
||||||
|
g_return_if_fail (content_type != NULL);
|
||||||
|
g_return_if_fail (is_valid_content_type (content_type));
|
||||||
|
|
||||||
|
if (!g_ptr_array_find_with_equal_func (_builder->blacklist,
|
||||||
|
content_type, g_str_equal, NULL))
|
||||||
|
g_ptr_array_add (_builder->blacklist, g_strdup (content_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||||
*
|
*
|
||||||
* Copyright © 2018 Endless Mobile, Inc.
|
* Copyright © 2018-2019 Endless Mobile, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* - Philip Withnall <withnall@endlessm.com>
|
* - Philip Withnall <withnall@endlessm.com>
|
||||||
|
* - Andre Moreira Magalhaes <andre@endlessm.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -109,6 +110,8 @@ gboolean mct_app_filter_is_flatpak_app_allowed (MctAppFilter *filter,
|
||||||
const gchar *app_id);
|
const gchar *app_id);
|
||||||
gboolean mct_app_filter_is_appinfo_allowed (MctAppFilter *filter,
|
gboolean mct_app_filter_is_appinfo_allowed (MctAppFilter *filter,
|
||||||
GAppInfo *app_info);
|
GAppInfo *app_info);
|
||||||
|
gboolean mct_app_filter_is_content_type_allowed (MctAppFilter *filter,
|
||||||
|
const gchar *content_type);
|
||||||
|
|
||||||
const gchar **mct_app_filter_get_oars_sections (MctAppFilter *filter);
|
const gchar **mct_app_filter_get_oars_sections (MctAppFilter *filter);
|
||||||
MctAppFilterOarsValue mct_app_filter_get_oars_value (MctAppFilter *filter,
|
MctAppFilterOarsValue mct_app_filter_get_oars_value (MctAppFilter *filter,
|
||||||
|
@ -182,6 +185,9 @@ void mct_app_filter_builder_blacklist_path (MctAppFilterBuilder *builde
|
||||||
const gchar *path);
|
const gchar *path);
|
||||||
void mct_app_filter_builder_blacklist_flatpak_ref (MctAppFilterBuilder *builder,
|
void mct_app_filter_builder_blacklist_flatpak_ref (MctAppFilterBuilder *builder,
|
||||||
const gchar *app_ref);
|
const gchar *app_ref);
|
||||||
|
void mct_app_filter_builder_blacklist_content_type (MctAppFilterBuilder *builder,
|
||||||
|
const gchar *content_type);
|
||||||
|
|
||||||
void mct_app_filter_builder_set_oars_value (MctAppFilterBuilder *builder,
|
void mct_app_filter_builder_set_oars_value (MctAppFilterBuilder *builder,
|
||||||
const gchar *oars_section,
|
const gchar *oars_section,
|
||||||
MctAppFilterOarsValue value);
|
MctAppFilterOarsValue value);
|
||||||
|
|
|
@ -155,6 +155,9 @@ test_app_filter_builder_non_empty (BuilderFixture *fixture,
|
||||||
mct_app_filter_builder_blacklist_flatpak_ref (fixture->builder,
|
mct_app_filter_builder_blacklist_flatpak_ref (fixture->builder,
|
||||||
"app/org.doom.Doom/x86_64/master");
|
"app/org.doom.Doom/x86_64/master");
|
||||||
|
|
||||||
|
mct_app_filter_builder_blacklist_content_type (fixture->builder,
|
||||||
|
"x-scheme-handler/http");
|
||||||
|
|
||||||
mct_app_filter_builder_set_oars_value (fixture->builder, "drugs-alcohol",
|
mct_app_filter_builder_set_oars_value (fixture->builder, "drugs-alcohol",
|
||||||
MCT_APP_FILTER_OARS_VALUE_MILD);
|
MCT_APP_FILTER_OARS_VALUE_MILD);
|
||||||
mct_app_filter_builder_set_oars_value (fixture->builder, "language-humor",
|
mct_app_filter_builder_set_oars_value (fixture->builder, "language-humor",
|
||||||
|
@ -175,6 +178,11 @@ test_app_filter_builder_non_empty (BuilderFixture *fixture,
|
||||||
"app/org.doom.Doom/x86_64/master"));
|
"app/org.doom.Doom/x86_64/master"));
|
||||||
g_assert_false (mct_app_filter_is_flatpak_app_allowed (filter, "org.doom.Doom"));
|
g_assert_false (mct_app_filter_is_flatpak_app_allowed (filter, "org.doom.Doom"));
|
||||||
|
|
||||||
|
g_assert_false (mct_app_filter_is_content_type_allowed (filter,
|
||||||
|
"x-scheme-handler/http"));
|
||||||
|
g_assert_true (mct_app_filter_is_content_type_allowed (filter,
|
||||||
|
"text/plain"));
|
||||||
|
|
||||||
g_assert_cmpint (mct_app_filter_get_oars_value (filter, "drugs-alcohol"), ==,
|
g_assert_cmpint (mct_app_filter_get_oars_value (filter, "drugs-alcohol"), ==,
|
||||||
MCT_APP_FILTER_OARS_VALUE_MILD);
|
MCT_APP_FILTER_OARS_VALUE_MILD);
|
||||||
g_assert_cmpint (mct_app_filter_get_oars_value (filter, "language-humor"), ==,
|
g_assert_cmpint (mct_app_filter_get_oars_value (filter, "language-humor"), ==,
|
||||||
|
@ -211,6 +219,9 @@ test_app_filter_builder_empty (BuilderFixture *fixture,
|
||||||
"app/org.doom.Doom/x86_64/master"));
|
"app/org.doom.Doom/x86_64/master"));
|
||||||
g_assert_true (mct_app_filter_is_flatpak_app_allowed (filter, "org.doom.Doom"));
|
g_assert_true (mct_app_filter_is_flatpak_app_allowed (filter, "org.doom.Doom"));
|
||||||
|
|
||||||
|
g_assert_true (mct_app_filter_is_content_type_allowed (filter,
|
||||||
|
"x-scheme-handler/http"));
|
||||||
|
|
||||||
g_assert_cmpint (mct_app_filter_get_oars_value (filter, "drugs-alcohol"), ==,
|
g_assert_cmpint (mct_app_filter_get_oars_value (filter, "drugs-alcohol"), ==,
|
||||||
MCT_APP_FILTER_OARS_VALUE_UNKNOWN);
|
MCT_APP_FILTER_OARS_VALUE_UNKNOWN);
|
||||||
g_assert_cmpint (mct_app_filter_get_oars_value (filter, "language-humor"), ==,
|
g_assert_cmpint (mct_app_filter_get_oars_value (filter, "language-humor"), ==,
|
||||||
|
@ -240,11 +251,16 @@ test_app_filter_builder_copy_empty (void)
|
||||||
|
|
||||||
mct_app_filter_builder_init (builder_copy);
|
mct_app_filter_builder_init (builder_copy);
|
||||||
mct_app_filter_builder_blacklist_path (builder_copy, "/bin/true");
|
mct_app_filter_builder_blacklist_path (builder_copy, "/bin/true");
|
||||||
|
mct_app_filter_builder_blacklist_content_type (builder_copy,
|
||||||
|
"x-scheme-handler/http");
|
||||||
filter = mct_app_filter_builder_end (builder_copy);
|
filter = mct_app_filter_builder_end (builder_copy);
|
||||||
|
|
||||||
g_assert_true (mct_app_filter_is_path_allowed (filter, "/bin/false"));
|
g_assert_true (mct_app_filter_is_path_allowed (filter, "/bin/false"));
|
||||||
g_assert_false (mct_app_filter_is_path_allowed (filter, "/bin/true"));
|
g_assert_false (mct_app_filter_is_path_allowed (filter, "/bin/true"));
|
||||||
|
g_assert_true (mct_app_filter_is_content_type_allowed (filter,
|
||||||
|
"text/plain"));
|
||||||
|
g_assert_false (mct_app_filter_is_content_type_allowed (filter,
|
||||||
|
"x-scheme-handler/http"));
|
||||||
g_assert_true (mct_app_filter_is_user_installation_allowed (filter));
|
g_assert_true (mct_app_filter_is_user_installation_allowed (filter));
|
||||||
g_assert_false (mct_app_filter_is_system_installation_allowed (filter));
|
g_assert_false (mct_app_filter_is_system_installation_allowed (filter));
|
||||||
}
|
}
|
||||||
|
@ -259,6 +275,8 @@ test_app_filter_builder_copy_full (void)
|
||||||
g_autoptr(MctAppFilter) filter = NULL;
|
g_autoptr(MctAppFilter) filter = NULL;
|
||||||
|
|
||||||
mct_app_filter_builder_blacklist_path (builder, "/bin/true");
|
mct_app_filter_builder_blacklist_path (builder, "/bin/true");
|
||||||
|
mct_app_filter_builder_blacklist_content_type (builder,
|
||||||
|
"x-scheme-handler/http");
|
||||||
mct_app_filter_builder_set_allow_user_installation (builder, FALSE);
|
mct_app_filter_builder_set_allow_user_installation (builder, FALSE);
|
||||||
mct_app_filter_builder_set_allow_system_installation (builder, TRUE);
|
mct_app_filter_builder_set_allow_system_installation (builder, TRUE);
|
||||||
builder_copy = mct_app_filter_builder_copy (builder);
|
builder_copy = mct_app_filter_builder_copy (builder);
|
||||||
|
@ -266,6 +284,10 @@ test_app_filter_builder_copy_full (void)
|
||||||
|
|
||||||
g_assert_true (mct_app_filter_is_path_allowed (filter, "/bin/false"));
|
g_assert_true (mct_app_filter_is_path_allowed (filter, "/bin/false"));
|
||||||
g_assert_false (mct_app_filter_is_path_allowed (filter, "/bin/true"));
|
g_assert_false (mct_app_filter_is_path_allowed (filter, "/bin/true"));
|
||||||
|
g_assert_true (mct_app_filter_is_content_type_allowed (filter,
|
||||||
|
"text/plain"));
|
||||||
|
g_assert_false (mct_app_filter_is_content_type_allowed (filter,
|
||||||
|
"x-scheme-handler/http"));
|
||||||
g_assert_false (mct_app_filter_is_user_installation_allowed (filter));
|
g_assert_false (mct_app_filter_is_user_installation_allowed (filter));
|
||||||
g_assert_true (mct_app_filter_is_system_installation_allowed (filter));
|
g_assert_true (mct_app_filter_is_system_installation_allowed (filter));
|
||||||
}
|
}
|
||||||
|
@ -290,42 +312,56 @@ test_app_filter_appinfo (void)
|
||||||
"Name=Some Name\n"
|
"Name=Some Name\n"
|
||||||
"Exec=/bin/true\n"
|
"Exec=/bin/true\n"
|
||||||
"Type=Application\n" },
|
"Type=Application\n" },
|
||||||
/* Allowed by its path and its flatpak ID: */
|
/* Allowed by its path and its content type: */
|
||||||
{ TRUE,
|
{ TRUE,
|
||||||
"[Desktop Entry]\n"
|
"[Desktop Entry]\n"
|
||||||
"Name=Some Name\n"
|
"Name=Some Name\n"
|
||||||
"Exec=/bin/true\n"
|
"Exec=/bin/true\n"
|
||||||
"Type=Application\n"
|
"Type=Application\n"
|
||||||
|
"MimeType=text/plain\n" },
|
||||||
|
/* Allowed by its path, its content type and its flatpak ID: */
|
||||||
|
{ TRUE,
|
||||||
|
"[Desktop Entry]\n"
|
||||||
|
"Name=Some Name\n"
|
||||||
|
"Exec=/bin/true\n"
|
||||||
|
"Type=Application\n"
|
||||||
|
"MimeType=text/plain\n"
|
||||||
"X-Flatpak=org.gnome.Nice\n" },
|
"X-Flatpak=org.gnome.Nice\n" },
|
||||||
/* Allowed by its path and its flatpak ID: */
|
/* Allowed by its path, its content type and its flatpak ID: */
|
||||||
{ TRUE,
|
{ TRUE,
|
||||||
"[Desktop Entry]\n"
|
"[Desktop Entry]\n"
|
||||||
"Name=Some Name\n"
|
"Name=Some Name\n"
|
||||||
"Exec=/bin/true\n"
|
"Exec=/bin/true\n"
|
||||||
"Type=Application\n"
|
"Type=Application\n"
|
||||||
|
"MimeType=text/plain\n"
|
||||||
"X-Flatpak=org.gnome.Nice\n"
|
"X-Flatpak=org.gnome.Nice\n"
|
||||||
"X-Flatpak-RenamedFrom=\n" },
|
"X-Flatpak-RenamedFrom=\n" },
|
||||||
/* Allowed by its path, its flatpak ID and its old flatpak IDs: */
|
/* Allowed by its path, its content type, its flatpak ID and
|
||||||
|
* its old flatpak IDs: */
|
||||||
{ TRUE,
|
{ TRUE,
|
||||||
"[Desktop Entry]\n"
|
"[Desktop Entry]\n"
|
||||||
"Name=Some Name\n"
|
"Name=Some Name\n"
|
||||||
"Exec=/bin/true\n"
|
"Exec=/bin/true\n"
|
||||||
"Type=Application\n"
|
"Type=Application\n"
|
||||||
|
"MimeType=text/plain\n"
|
||||||
"X-Flatpak-RenamedFrom=org.gnome.OldNice\n" },
|
"X-Flatpak-RenamedFrom=org.gnome.OldNice\n" },
|
||||||
/* Allowed by its path, its flatpak ID and its old flatpak IDs (which
|
/* Allowed by its path, its content type, its flatpak ID and its old
|
||||||
* contain some spurious entries): */
|
* flatpak IDs (which contain some spurious entries): */
|
||||||
{ TRUE,
|
{ TRUE,
|
||||||
"[Desktop Entry]\n"
|
"[Desktop Entry]\n"
|
||||||
"Name=Some Name\n"
|
"Name=Some Name\n"
|
||||||
"Exec=/bin/true\n"
|
"Exec=/bin/true\n"
|
||||||
"Type=Application\n"
|
"Type=Application\n"
|
||||||
|
"MimeType=text/plain\n"
|
||||||
"X-Flatpak-RenamedFrom=org.gnome.OldNice;;;\n" },
|
"X-Flatpak-RenamedFrom=org.gnome.OldNice;;;\n" },
|
||||||
/* Allowed by its path, its flatpak ID and its old flatpak IDs: */
|
/* Allowed by its path, its content type, its flatpak ID and
|
||||||
|
* its old flatpak IDs: */
|
||||||
{ TRUE,
|
{ TRUE,
|
||||||
"[Desktop Entry]\n"
|
"[Desktop Entry]\n"
|
||||||
"Name=Some Name\n"
|
"Name=Some Name\n"
|
||||||
"Exec=/bin/true\n"
|
"Exec=/bin/true\n"
|
||||||
"Type=Application\n"
|
"Type=Application\n"
|
||||||
|
"MimeType=text/plain\n"
|
||||||
"X-Flatpak-RenamedFrom=org.gnome.OldNice.desktop\n" },
|
"X-Flatpak-RenamedFrom=org.gnome.OldNice.desktop\n" },
|
||||||
/* Disallowed by its path: */
|
/* Disallowed by its path: */
|
||||||
{ FALSE,
|
{ FALSE,
|
||||||
|
@ -333,6 +369,13 @@ test_app_filter_appinfo (void)
|
||||||
"Name=Some Name\n"
|
"Name=Some Name\n"
|
||||||
"Exec=/bin/false\n"
|
"Exec=/bin/false\n"
|
||||||
"Type=Application\n" },
|
"Type=Application\n" },
|
||||||
|
/* Allowed by its path, disallowed by its content type: */
|
||||||
|
{ FALSE,
|
||||||
|
"[Desktop Entry]\n"
|
||||||
|
"Name=Some Name\n"
|
||||||
|
"Exec=/bin/true\n"
|
||||||
|
"Type=Application\n"
|
||||||
|
"MimeType=x-scheme-handler/http\n" },
|
||||||
/* Allowed by its path, disallowed by its flatpak ID: */
|
/* Allowed by its path, disallowed by its flatpak ID: */
|
||||||
{ FALSE,
|
{ FALSE,
|
||||||
"[Desktop Entry]\n"
|
"[Desktop Entry]\n"
|
||||||
|
@ -358,10 +401,21 @@ test_app_filter_appinfo (void)
|
||||||
"Type=Application\n"
|
"Type=Application\n"
|
||||||
"X-Flatpak=org.gnome.WasNasty\n"
|
"X-Flatpak=org.gnome.WasNasty\n"
|
||||||
"X-Flatpak-RenamedFrom=org.gnome.Nasty.desktop;\n" },
|
"X-Flatpak-RenamedFrom=org.gnome.Nasty.desktop;\n" },
|
||||||
|
/* Allowed by its path, current flatpak ID, old flatpak ID, but
|
||||||
|
* disabled by content type: */
|
||||||
|
{ FALSE,
|
||||||
|
"[Desktop Entry]\n"
|
||||||
|
"Name=Some Name\n"
|
||||||
|
"Exec=/bin/true\n"
|
||||||
|
"Type=Application\n"
|
||||||
|
"X-Flatpak=org.gnome.WasNasty\n"
|
||||||
|
"X-Flatpak-RenamedFrom=org.gnome.OldNice\n"
|
||||||
|
"MimeType=x-scheme-handler/http\n" },
|
||||||
};
|
};
|
||||||
|
|
||||||
mct_app_filter_builder_blacklist_path (&builder, "/bin/false");
|
mct_app_filter_builder_blacklist_path (&builder, "/bin/false");
|
||||||
mct_app_filter_builder_blacklist_flatpak_ref (&builder, "app/org.gnome.Nasty/x86_64/stable");
|
mct_app_filter_builder_blacklist_flatpak_ref (&builder, "app/org.gnome.Nasty/x86_64/stable");
|
||||||
|
mct_app_filter_builder_blacklist_content_type (&builder, "x-scheme-handler/http");
|
||||||
|
|
||||||
filter = mct_app_filter_builder_end (&builder);
|
filter = mct_app_filter_builder_end (&builder);
|
||||||
|
|
||||||
|
@ -584,7 +638,8 @@ test_app_filter_bus_get_whitelist (BusFixture *fixture,
|
||||||
"'AppFilter': <(true, ["
|
"'AppFilter': <(true, ["
|
||||||
"'app/org.gnome.Whitelisted1/x86_64/stable',"
|
"'app/org.gnome.Whitelisted1/x86_64/stable',"
|
||||||
"'app/org.gnome.Whitelisted2/x86_64/stable',"
|
"'app/org.gnome.Whitelisted2/x86_64/stable',"
|
||||||
"'/usr/bin/true'"
|
"'/usr/bin/true',"
|
||||||
|
"'text/plain'"
|
||||||
"])>,"
|
"])>,"
|
||||||
"'OarsFilter': <('oars-1.1', @a{ss} {})>"
|
"'OarsFilter': <('oars-1.1', @a{ss} {})>"
|
||||||
"}"
|
"}"
|
||||||
|
@ -611,6 +666,10 @@ test_app_filter_bus_get_whitelist (BusFixture *fixture,
|
||||||
g_assert_false (mct_app_filter_is_flatpak_ref_allowed (app_filter, "app/org.gnome.Whitelisted1/x86_64/unknown"));
|
g_assert_false (mct_app_filter_is_flatpak_ref_allowed (app_filter, "app/org.gnome.Whitelisted1/x86_64/unknown"));
|
||||||
g_assert_true (mct_app_filter_is_path_allowed (app_filter, "/usr/bin/true"));
|
g_assert_true (mct_app_filter_is_path_allowed (app_filter, "/usr/bin/true"));
|
||||||
g_assert_false (mct_app_filter_is_path_allowed (app_filter, "/usr/bin/false"));
|
g_assert_false (mct_app_filter_is_path_allowed (app_filter, "/usr/bin/false"));
|
||||||
|
g_assert_true (mct_app_filter_is_content_type_allowed (app_filter,
|
||||||
|
"text/plain"));
|
||||||
|
g_assert_false (mct_app_filter_is_content_type_allowed (app_filter,
|
||||||
|
"x-scheme-handler/http"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test that getting an #MctAppFilter containing all possible OARS values from
|
/* Test that getting an #MctAppFilter containing all possible OARS values from
|
||||||
|
@ -1097,7 +1156,7 @@ test_app_filter_bus_set (BusFixture *fixture,
|
||||||
const SetAppFilterData set_app_filter_data =
|
const SetAppFilterData set_app_filter_data =
|
||||||
{
|
{
|
||||||
.expected_uid = fixture->valid_uid,
|
.expected_uid = fixture->valid_uid,
|
||||||
.expected_app_filter_value = "(false, ['/usr/bin/false', '/usr/bin/banned', 'app/org.gnome.Nasty/x86_64/stable'])",
|
.expected_app_filter_value = "(false, ['/usr/bin/false', '/usr/bin/banned', 'app/org.gnome.Nasty/x86_64/stable', 'x-scheme-handler/http'])",
|
||||||
.expected_oars_filter_value = "('oars-1.1', { 'violence-fantasy': 'intense' })",
|
.expected_oars_filter_value = "('oars-1.1', { 'violence-fantasy': 'intense' })",
|
||||||
.expected_allow_user_installation_value = "true",
|
.expected_allow_user_installation_value = "true",
|
||||||
.expected_allow_system_installation_value = "true",
|
.expected_allow_system_installation_value = "true",
|
||||||
|
@ -1108,6 +1167,7 @@ test_app_filter_bus_set (BusFixture *fixture,
|
||||||
mct_app_filter_builder_blacklist_path (&builder, "/usr/bin/false");
|
mct_app_filter_builder_blacklist_path (&builder, "/usr/bin/false");
|
||||||
mct_app_filter_builder_blacklist_path (&builder, "/usr/bin/banned");
|
mct_app_filter_builder_blacklist_path (&builder, "/usr/bin/banned");
|
||||||
mct_app_filter_builder_blacklist_flatpak_ref (&builder, "app/org.gnome.Nasty/x86_64/stable");
|
mct_app_filter_builder_blacklist_flatpak_ref (&builder, "app/org.gnome.Nasty/x86_64/stable");
|
||||||
|
mct_app_filter_builder_blacklist_content_type (&builder, "x-scheme-handler/http");
|
||||||
mct_app_filter_builder_set_oars_value (&builder, "violence-fantasy", MCT_APP_FILTER_OARS_VALUE_INTENSE);
|
mct_app_filter_builder_set_oars_value (&builder, "violence-fantasy", MCT_APP_FILTER_OARS_VALUE_INTENSE);
|
||||||
mct_app_filter_builder_set_allow_user_installation (&builder, TRUE);
|
mct_app_filter_builder_set_allow_user_installation (&builder, TRUE);
|
||||||
mct_app_filter_builder_set_allow_system_installation (&builder, TRUE);
|
mct_app_filter_builder_set_allow_system_installation (&builder, TRUE);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
.\" Manpage for malcontent\-client.
|
.\" Manpage for malcontent\-client.
|
||||||
.\" Documentation is under the same licence as the malcontent
|
.\" Documentation is under the same licence as the malcontent
|
||||||
.\" package.
|
.\" package.
|
||||||
.TH man 8 "03 Oct 2018" "1.0" "malcontent\-client man page"
|
.TH man 8 "13 Jun 2019" "1.1" "malcontent\-client man page"
|
||||||
.\"
|
.\"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
.IX Header "NAME"
|
.IX Header "NAME"
|
||||||
|
@ -12,7 +12,7 @@ malcontent\-client — Parental Controls Access Utility
|
||||||
.\"
|
.\"
|
||||||
\fBmalcontent\-client get [\-q] [\-n] [\fPUSER\fB]
|
\fBmalcontent\-client get [\-q] [\-n] [\fPUSER\fB]
|
||||||
.PP
|
.PP
|
||||||
\fBmalcontent\-client check [\-q] [\-n] [\fPUSER\fB] \fPPATH\fB
|
\fBmalcontent\-client check [\-q] [\-n] [\fPUSER\fB] \fPARG\fB
|
||||||
.\"
|
.\"
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.IX Header "DESCRIPTION"
|
.IX Header "DESCRIPTION"
|
||||||
|
@ -50,9 +50,9 @@ authorization.)
|
||||||
Username or ID of the user to get the app filter for. If not specified, the
|
Username or ID of the user to get the app filter for. If not specified, the
|
||||||
current user will be used by default.
|
current user will be used by default.
|
||||||
.\"
|
.\"
|
||||||
.IP "\fBPATH\fP"
|
.IP "\fBARG\fP"
|
||||||
Path to a program to check against the app filter, to see if it can be run by
|
Path to a program, content type or flatpak ref to check against the app filter,
|
||||||
the specified user.
|
to see if it is allowed for the specified user.
|
||||||
.\"
|
.\"
|
||||||
.IP "\fB\-q\fP, \fB\-\-quiet\fP"
|
.IP "\fB\-q\fP, \fB\-\-quiet\fP"
|
||||||
Only output error messages, and no informational messages, as the operation
|
Only output error messages, and no informational messages, as the operation
|
||||||
|
@ -85,8 +85,8 @@ encounters problems.
|
||||||
.IP "0" 4
|
.IP "0" 4
|
||||||
.IX Item "0"
|
.IX Item "0"
|
||||||
No problems occurred. The utility ran and successfully queried the app filter.
|
No problems occurred. The utility ran and successfully queried the app filter.
|
||||||
If running the \fBcheck\fP command, the given path was allowed to be run by the
|
If running the \fBcheck\fP command, the given path, content type or flatpak ref
|
||||||
given user.
|
was allowed for the given user.
|
||||||
.\"
|
.\"
|
||||||
.IP "1" 4
|
.IP "1" 4
|
||||||
.IX Item "1"
|
.IX Item "1"
|
||||||
|
@ -99,8 +99,8 @@ The current user was not authorized to query the app filter for the given user.
|
||||||
.\"
|
.\"
|
||||||
.IP "3" 4
|
.IP "3" 4
|
||||||
.IX Item "3"
|
.IX Item "3"
|
||||||
If running the \fBcheck\fP command, the given path was \fInot\fP allowed to be
|
If running the \fBcheck\fP command, the given path, content type or flatpak ref
|
||||||
run by the given user.
|
was \fInot\fP allowed for the given user.
|
||||||
.\"
|
.\"
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
.IX Header "BUGS"
|
.IX Header "BUGS"
|
||||||
|
|
|
@ -194,36 +194,77 @@ def command_monitor(user, quiet=False, interactive=True):
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def command_check(user, path, quiet=False, interactive=True):
|
# Simple check to check whether @arg is a valid flatpak ref - it uses the
|
||||||
"""Check the given path or flatpak ref is runnable by the given user,
|
# same logic as 'MctAppFilter' to determine it and should be kept in sync
|
||||||
according to their app filter."""
|
# with its implementation
|
||||||
|
def is_valid_flatpak_ref(arg):
|
||||||
|
parts = arg.split('/')
|
||||||
|
return (len(parts) == 4 and \
|
||||||
|
(parts[0] == 'app' or parts[0] == 'runtime') and \
|
||||||
|
parts[1] != '' and parts[2] != '' and parts[3] != '')
|
||||||
|
|
||||||
|
|
||||||
|
# Simple check to check whether @arg is a valid content type - it uses the
|
||||||
|
# same logic as 'MctAppFilter' to determine it and should be kept in sync
|
||||||
|
# with its implementation
|
||||||
|
def is_valid_content_type(arg):
|
||||||
|
parts = arg.split('/')
|
||||||
|
return (len(parts) == 2 and \
|
||||||
|
parts[0] != '' and parts[1] != '')
|
||||||
|
|
||||||
|
|
||||||
|
def command_check(user, arg, quiet=False, interactive=True):
|
||||||
|
"""Check the given path, content type or flatpak ref is runnable by the
|
||||||
|
given user, according to their app filter."""
|
||||||
user_id = __lookup_user_id_or_error(user)
|
user_id = __lookup_user_id_or_error(user)
|
||||||
app_filter = __get_app_filter_or_error(user_id, interactive)
|
app_filter = __get_app_filter_or_error(user_id, interactive)
|
||||||
|
|
||||||
if path.startswith('app/') and path.count('/') < 3:
|
is_maybe_flatpak_id = arg.startswith('app/') and arg.count('/') < 3
|
||||||
|
is_maybe_flatpak_ref = is_valid_flatpak_ref(arg)
|
||||||
|
# Only check if arg is a valid content type if not already considered a
|
||||||
|
# valid flatpak id, otherwise we always get multiple types recognised
|
||||||
|
# when passing flatpak IDs as argument
|
||||||
|
is_maybe_content_type = not is_maybe_flatpak_id and is_valid_content_type(arg)
|
||||||
|
is_maybe_path = os.path.exists(arg)
|
||||||
|
|
||||||
|
recognised_types = sum([is_maybe_flatpak_id, is_maybe_flatpak_ref,
|
||||||
|
is_maybe_content_type, is_maybe_path])
|
||||||
|
if recognised_types == 0:
|
||||||
|
print('Unknown argument ‘{}’'.format(arg), file=sys.stderr)
|
||||||
|
raise SystemExit(EXIT_INVALID_OPTION)
|
||||||
|
elif recognised_types > 1:
|
||||||
|
print('Ambiguous argument ‘{}’ recognised as multiple types'.format(arg),
|
||||||
|
file=sys.stderr)
|
||||||
|
raise SystemExit(EXIT_INVALID_OPTION)
|
||||||
|
elif is_maybe_flatpak_id:
|
||||||
# Flatpak app ID
|
# Flatpak app ID
|
||||||
path = path[4:]
|
arg = arg[4:]
|
||||||
is_allowed = app_filter.is_flatpak_app_allowed(path)
|
is_allowed = app_filter.is_flatpak_app_allowed(arg)
|
||||||
noun = 'Flatpak app ID'
|
noun = 'Flatpak app ID'
|
||||||
elif path.startswith('app/') or path.startswith('runtime/'):
|
elif is_maybe_flatpak_ref:
|
||||||
# Flatpak ref
|
# Flatpak ref
|
||||||
is_allowed = app_filter.is_flatpak_ref_allowed(path)
|
is_allowed = app_filter.is_flatpak_ref_allowed(arg)
|
||||||
noun = 'Flatpak ref'
|
noun = 'Flatpak ref'
|
||||||
else:
|
elif is_maybe_content_type:
|
||||||
# File system path
|
# Content type
|
||||||
path = os.path.abspath(path)
|
is_allowed = app_filter.is_content_type_allowed(arg)
|
||||||
|
noun = 'Content type'
|
||||||
|
elif is_maybe_path:
|
||||||
|
path = os.path.abspath(arg)
|
||||||
is_allowed = app_filter.is_path_allowed(path)
|
is_allowed = app_filter.is_path_allowed(path)
|
||||||
noun = 'Path'
|
noun = 'Path'
|
||||||
|
else:
|
||||||
|
raise AssertionError('code should not be reached')
|
||||||
|
|
||||||
if is_allowed:
|
if is_allowed:
|
||||||
if not quiet:
|
if not quiet:
|
||||||
print('{} {} is allowed by app filter for user {}'.format(
|
print('{} {} is allowed by app filter for user {}'.format(
|
||||||
noun, path, user_id))
|
noun, arg, user_id))
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
if not quiet:
|
if not quiet:
|
||||||
print('{} {} is not allowed by app filter for user {}'.format(
|
print('{} {} is not allowed by app filter for user {}'.format(
|
||||||
noun, path, user_id))
|
noun, arg, user_id))
|
||||||
raise SystemExit(EXIT_PATH_NOT_ALLOWED)
|
raise SystemExit(EXIT_PATH_NOT_ALLOWED)
|
||||||
|
|
||||||
|
|
||||||
|
@ -257,10 +298,30 @@ def command_set(user, allow_user_installation=True,
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
raise SystemExit(EXIT_INVALID_OPTION)
|
raise SystemExit(EXIT_INVALID_OPTION)
|
||||||
builder.set_oars_value(section, value)
|
builder.set_oars_value(section, value)
|
||||||
elif arg.startswith('app/') or arg.startswith('runtime/'):
|
|
||||||
builder.blacklist_flatpak_ref(arg)
|
|
||||||
else:
|
else:
|
||||||
builder.blacklist_path(arg)
|
is_maybe_flatpak_ref = is_valid_flatpak_ref(arg)
|
||||||
|
is_maybe_content_type = is_valid_content_type(arg)
|
||||||
|
is_maybe_path = os.path.exists(arg)
|
||||||
|
|
||||||
|
recognised_types = sum([is_maybe_flatpak_ref,
|
||||||
|
is_maybe_content_type, is_maybe_path])
|
||||||
|
if recognised_types == 0:
|
||||||
|
print('Unknown argument ‘{}’'.format(arg), file=sys.stderr)
|
||||||
|
raise SystemExit(EXIT_INVALID_OPTION)
|
||||||
|
elif recognised_types > 1:
|
||||||
|
print('Ambiguous argument ‘{}’ recognised as multiple types'.format(arg),
|
||||||
|
file=sys.stderr)
|
||||||
|
raise SystemExit(EXIT_INVALID_OPTION)
|
||||||
|
elif is_maybe_flatpak_ref:
|
||||||
|
builder.blacklist_flatpak_ref(arg)
|
||||||
|
elif is_maybe_content_type:
|
||||||
|
builder.blacklist_content_type(arg)
|
||||||
|
elif is_maybe_path:
|
||||||
|
path = os.path.abspath(arg)
|
||||||
|
builder.blacklist_path(path)
|
||||||
|
else:
|
||||||
|
raise AssertionError('code should not be reached')
|
||||||
|
|
||||||
app_filter = builder.end()
|
app_filter = builder.end()
|
||||||
|
|
||||||
__set_app_filter_or_error(user_id, app_filter, interactive)
|
__set_app_filter_or_error(user_id, app_filter, interactive)
|
||||||
|
@ -312,14 +373,16 @@ def main():
|
||||||
|
|
||||||
# ‘check’ command
|
# ‘check’ command
|
||||||
parser_check = subparsers.add_parser('check', parents=[common_parser],
|
parser_check = subparsers.add_parser('check', parents=[common_parser],
|
||||||
help='check whether a path is '
|
help='check whether a path, content '
|
||||||
|
'type or flatpak ref is '
|
||||||
'allowed by app filter')
|
'allowed by app filter')
|
||||||
parser_check.set_defaults(function=command_check)
|
parser_check.set_defaults(function=command_check)
|
||||||
parser_check.add_argument('user', default='', nargs='?',
|
parser_check.add_argument('user', default='', nargs='?',
|
||||||
help='user ID or username to get the app filter '
|
help='user ID or username to get the app filter '
|
||||||
'for (default: current user)')
|
'for (default: current user)')
|
||||||
parser_check.add_argument('path',
|
parser_check.add_argument('arg',
|
||||||
help='path to a program to check')
|
help='path to a program, content type or '
|
||||||
|
'flatpak ref to check')
|
||||||
|
|
||||||
# ‘oars-section’ command
|
# ‘oars-section’ command
|
||||||
parser_oars_section = subparsers.add_parser('oars-section',
|
parser_oars_section = subparsers.add_parser('oars-section',
|
||||||
|
@ -362,7 +425,8 @@ def main():
|
||||||
help='unconditionally disallow installation to '
|
help='unconditionally disallow installation to '
|
||||||
'the system flatpak repo')
|
'the system flatpak repo')
|
||||||
parser_set.add_argument('app_filter_args', nargs='*',
|
parser_set.add_argument('app_filter_args', nargs='*',
|
||||||
help='paths to blacklist and OARS section=value '
|
help='paths, content types or flatpak refs to '
|
||||||
|
'blacklist and OARS section=value '
|
||||||
'pairs to store')
|
'pairs to store')
|
||||||
parser_set.set_defaults(allow_user_installation=True,
|
parser_set.set_defaults(allow_user_installation=True,
|
||||||
allow_system_installation=False)
|
allow_system_installation=False)
|
||||||
|
|
Loading…
Reference in New Issue