app-filter: Add mct_app_filter_is_enabled() API

This is a high-level API to indicate whether parental controls are
‘enabled’ for the given user. Specifically, whether any of the
properties of the `MctAppFilter` differ from their default value.

Includes tests.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
This commit is contained in:
Philip Withnall 2020-03-20 14:56:36 +00:00
parent faa0b9a3eb
commit f106319fdd
3 changed files with 112 additions and 0 deletions

View File

@ -123,6 +123,54 @@ oars_str_to_enum (const gchar *value_str)
return MCT_APP_FILTER_OARS_VALUE_UNKNOWN;
}
/**
* mct_app_filter_is_enabled:
* @filter: an #MctAppFilter
*
* Check whether the app filter is enabled and is going to impose at least one
* restriction on the user. This gives a high level view of whether app filter
* parental controls are enabled for the given user.
*
* Returns: %TRUE if the app filter contains at least one non-default value,
* %FALSE if its entirely default
* Since: 0.7.0
*/
gboolean
mct_app_filter_is_enabled (MctAppFilter *filter)
{
gboolean oars_ratings_all_intense_or_unknown;
GVariantIter iter;
const gchar *oars_value;
g_return_val_if_fail (filter != NULL, FALSE);
g_return_val_if_fail (filter->ref_count >= 1, FALSE);
/* The least restrictive OARS filter has all values as intense, or unknown. */
oars_ratings_all_intense_or_unknown = TRUE;
g_variant_iter_init (&iter, filter->oars_ratings);
while (g_variant_iter_loop (&iter, "{&s&s}", NULL, &oars_value))
{
MctAppFilterOarsValue value = oars_str_to_enum (oars_value);
if (value != MCT_APP_FILTER_OARS_VALUE_UNKNOWN &&
value != MCT_APP_FILTER_OARS_VALUE_INTENSE)
{
oars_ratings_all_intense_or_unknown = FALSE;
break;
}
}
/* Check all fields against their default values. Ignore
* `allow_system_installation` since its false by default, so the default
* value is already the most restrictive. */
return ((filter->app_list_type == MCT_APP_FILTER_LIST_BLACKLIST &&
filter->app_list[0] != NULL) ||
filter->app_list_type == MCT_APP_FILTER_LIST_WHITELIST ||
!oars_ratings_all_intense_or_unknown ||
!filter->allow_user_installation);
}
/**
* mct_app_filter_is_path_allowed:
* @filter: an #MctAppFilter

View File

@ -78,6 +78,9 @@ void mct_app_filter_unref (MctAppFilter *filter);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MctAppFilter, mct_app_filter_unref)
uid_t mct_app_filter_get_user_id (MctAppFilter *filter);
gboolean mct_app_filter_is_enabled (MctAppFilter *filter);
gboolean mct_app_filter_is_path_allowed (MctAppFilter *filter,
const gchar *path);
gboolean mct_app_filter_is_flatpak_ref_allowed (MctAppFilter *filter,

View File

@ -162,6 +162,55 @@ test_app_filter_deserialize_invalid (void)
}
}
/* Test that mct_app_filter_is_enabled() returns the correct results on various
* app filters. */
static void
test_app_filter_is_enabled (void)
{
const struct
{
const gchar *serialized;
gboolean is_enabled;
}
app_filters[] =
{
{ "@a{sv} {}", FALSE },
{ "{ 'AppFilter': <(true, @as [])> }", TRUE },
{ "{ 'AppFilter': <(false, @as [])> }", FALSE },
{ "{ 'AppFilter': <(false, @as [ '/usr/bin/gnome-software' ])> }", TRUE },
{ "{ 'OarsFilter': <('oars-1.1', @a{ss} {})> }", FALSE },
{ "{ 'OarsFilter': <('oars-1.1', { 'violence-cartoon': 'mild' })> }", TRUE },
{ "{ 'OarsFilter': <('oars-1.1', { 'violence-cartoon': 'intense' })> }", FALSE },
{ "{ 'OarsFilter': <('oars-1.1', { 'violence-cartoon': '' })> }", FALSE }, /* technically an invalid serialisation */
{ "{ 'OarsFilter': <('oars-1.1', { 'violence-cartoon': 'none' })> }", TRUE },
{ "{ 'OarsFilter': <('oars-1.1', { 'violence-cartoon': 'mild', 'violence-realistic': 'intense' })> }", TRUE },
{ "{ 'OarsFilter': <('oars-1.1', { 'violence-cartoon': 'mild', 'violence-realistic': 'none' })> }", TRUE },
{ "{ 'AllowUserInstallation': <true> }", FALSE },
{ "{ 'AllowUserInstallation': <false> }", TRUE },
{ "{ 'AllowSystemInstallation': <true> }", FALSE },
{ "{ 'AllowSystemInstallation': <false> }", FALSE },
};
for (gsize i = 0; i < G_N_ELEMENTS (app_filters); i++)
{
g_autoptr(GVariant) variant = NULL;
g_autoptr(MctAppFilter) filter = NULL;
g_test_message ("%" G_GSIZE_FORMAT ": %s", i, app_filters[i].serialized);
variant = g_variant_parse (NULL, app_filters[i].serialized, NULL, NULL, NULL);
g_assert (variant != NULL);
filter = mct_app_filter_deserialize (variant, 1, NULL);
g_assert (filter != NULL);
if (app_filters[i].is_enabled)
g_assert_true (mct_app_filter_is_enabled (filter));
else
g_assert_false (mct_app_filter_is_enabled (filter));
}
}
/* Fixture for tests which use an #MctAppFilterBuilder. The builder can either
* be heap- or stack-allocated. @builder will always be a valid pointer to it.
*/
@ -244,6 +293,8 @@ test_app_filter_builder_non_empty (BuilderFixture *fixture,
filter = mct_app_filter_builder_end (fixture->builder);
g_assert_true (mct_app_filter_is_enabled (filter));
g_assert_true (mct_app_filter_is_path_allowed (filter, "/bin/false"));
g_assert_false (mct_app_filter_is_path_allowed (filter,
"/usr/bin/gnome-software"));
@ -285,6 +336,8 @@ test_app_filter_builder_empty (BuilderFixture *fixture,
filter = mct_app_filter_builder_end (fixture->builder);
g_assert_false (mct_app_filter_is_enabled (filter));
g_assert_true (mct_app_filter_is_path_allowed (filter, "/bin/false"));
g_assert_true (mct_app_filter_is_path_allowed (filter,
"/usr/bin/gnome-software"));
@ -332,6 +385,7 @@ test_app_filter_builder_copy_empty (void)
"x-scheme-handler/http");
filter = mct_app_filter_builder_end (builder_copy);
g_assert_true (mct_app_filter_is_enabled (filter));
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_true (mct_app_filter_is_content_type_allowed (filter,
@ -359,6 +413,7 @@ test_app_filter_builder_copy_full (void)
builder_copy = mct_app_filter_builder_copy (builder);
filter = mct_app_filter_builder_end (builder_copy);
g_assert_true (mct_app_filter_is_enabled (filter));
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_true (mct_app_filter_is_content_type_allowed (filter,
@ -691,6 +746,7 @@ test_app_filter_bus_get (BusFixture *fixture,
/* Check the app filter properties. */
g_assert_cmpuint (mct_app_filter_get_user_id (app_filter), ==, fixture->valid_uid);
g_assert_true (mct_app_filter_is_enabled (app_filter));
g_assert_false (mct_app_filter_is_flatpak_app_allowed (app_filter, "org.gnome.Builder"));
g_assert_true (mct_app_filter_is_flatpak_app_allowed (app_filter, "org.gnome.Chess"));
}
@ -736,6 +792,7 @@ test_app_filter_bus_get_whitelist (BusFixture *fixture,
/* Check the app filter properties. The returned filter is a whitelist,
* whereas typically a blacklist is returned. */
g_assert_cmpuint (mct_app_filter_get_user_id (app_filter), ==, fixture->valid_uid);
g_assert_true (mct_app_filter_is_enabled (app_filter));
g_assert_false (mct_app_filter_is_flatpak_app_allowed (app_filter, "org.gnome.Builder"));
g_assert_true (mct_app_filter_is_flatpak_app_allowed (app_filter, "org.gnome.Whitelisted1"));
g_assert_true (mct_app_filter_is_flatpak_app_allowed (app_filter, "org.gnome.Whitelisted2"));
@ -791,6 +848,7 @@ test_app_filter_bus_get_all_oars_values (BusFixture *fixture,
/* Check the OARS filter properties. Each OARS value should have been parsed
* correctly, except for the unknown `other` one. */
g_assert_cmpuint (mct_app_filter_get_user_id (app_filter), ==, fixture->valid_uid);
g_assert_true (mct_app_filter_is_enabled (app_filter));
g_assert_cmpint (mct_app_filter_get_oars_value (app_filter, "violence-bloodshed"), ==,
MCT_APP_FILTER_OARS_VALUE_NONE);
g_assert_cmpint (mct_app_filter_get_oars_value (app_filter, "violence-sexual"), ==,
@ -838,6 +896,7 @@ test_app_filter_bus_get_defaults (BusFixture *fixture,
/* Check the default values for the properties. */
g_assert_cmpuint (mct_app_filter_get_user_id (app_filter), ==, fixture->valid_uid);
g_assert_false (mct_app_filter_is_enabled (app_filter));
oars_sections = mct_app_filter_get_oars_sections (app_filter);
g_assert_cmpuint (g_strv_length ((gchar **) oars_sections), ==, 0);
g_assert_cmpint (mct_app_filter_get_oars_value (app_filter, "violence-bloodshed"), ==,
@ -1462,6 +1521,8 @@ main (int argc,
g_test_add_func ("/app-filter/deserialize", test_app_filter_deserialize);
g_test_add_func ("/app-filter/deserialize/invalid", test_app_filter_deserialize_invalid);
g_test_add_func ("/app-filter/is-enabled", test_app_filter_is_enabled);
g_test_add ("/app-filter/builder/stack/non-empty", BuilderFixture, NULL,
builder_set_up_stack, test_app_filter_builder_non_empty,
builder_tear_down_stack);