diff --git a/eos-parental-controls-client/eos-parental-controls-client.py b/eos-parental-controls-client/eos-parental-controls-client.py index d5a163e..cbc6af2 100644 --- a/eos-parental-controls-client/eos-parental-controls-client.py +++ b/eos-parental-controls-client/eos-parental-controls-client.py @@ -171,20 +171,28 @@ def command_get(user, quiet=False, interactive=True): def command_check(user, path, quiet=False, interactive=True): - """Check the given path is runnable by the given user, according to their - app filter.""" + """Check the given path or flatpak ref is runnable by the given user, + according to their app filter.""" user_id = __lookup_user_id_or_error(user) app_filter = __get_app_filter_or_error(user_id, interactive) - path = os.path.abspath(path) + if path.startswith('app/') or path.startswith('runtime/'): + # Flatpak ref + is_allowed = app_filter.is_flatpak_ref_allowed(path) + noun = 'Flatpak ref' + else: + # File system path + path = os.path.abspath(path) + is_allowed = app_filter.is_path_allowed(path) + noun = 'Path' - if app_filter.is_path_allowed(path): - print('Path {} is allowed by app filter for user {}'.format( - path, user_id)) + if is_allowed: + print('{} {} is allowed by app filter for user {}'.format( + noun, path, user_id)) return else: - print('Path {} is not allowed by app filter for user {}'.format( - path, user_id)) + print('{} {} is not allowed by app filter for user {}'.format( + noun, path, user_id)) raise SystemExit(EXIT_PATH_NOT_ALLOWED) @@ -214,6 +222,8 @@ def command_set(user, app_filter_args=None, quiet=False, interactive=True): file=sys.stderr) raise SystemExit(EXIT_INVALID_OPTION) builder.set_oars_value(section, value) + elif arg.startswith('app/') or arg.startswith('runtime/'): + builder.blacklist_flatpak_ref(arg) else: builder.blacklist_path(arg) app_filter = builder.end() diff --git a/libeos-parental-controls/app-filter.c b/libeos-parental-controls/app-filter.c index da7efdf..9dcacc1 100644 --- a/libeos-parental-controls/app-filter.c +++ b/libeos-parental-controls/app-filter.c @@ -162,6 +162,40 @@ epc_app_filter_is_path_allowed (EpcAppFilter *filter, } } +/** + * epc_app_filter_is_flatpak_ref_allowed: + * @filter: an #EpcAppFilter + * @app_ref: flatpak ref for the app + * + * Check whether the flatpak app with the given @app_ref is allowed to be run + * according to this app filter. + * + * Returns: %TRUE if the user this @filter corresponds to is allowed to run the + * flatpak called @app_ref according to the @filter policy; %FALSE otherwise + * Since: 0.1.0 + */ +gboolean +epc_app_filter_is_flatpak_ref_allowed (EpcAppFilter *filter, + const gchar *app_ref) +{ + g_return_val_if_fail (filter != NULL, FALSE); + g_return_val_if_fail (filter->ref_count >= 1, FALSE); + g_return_val_if_fail (app_ref != NULL, FALSE); + + gboolean ref_in_list = g_strv_contains ((const gchar * const *) filter->app_list, + app_ref); + + switch (filter->app_list_type) + { + case EPC_APP_FILTER_LIST_BLACKLIST: + return !ref_in_list; + case EPC_APP_FILTER_LIST_WHITELIST: + return ref_in_list; + default: + g_assert_not_reached (); + } +} + /** * epc_app_filter_get_oars_value: * @filter: an #EpcAppFilter @@ -977,6 +1011,32 @@ epc_app_filter_builder_blacklist_path (EpcAppFilterBuilder *builder, g_ptr_array_add (_builder->paths_blacklist, g_steal_pointer (&canonical_path)); } +/** + * epc_app_filter_builder_blacklist_flatpak_ref: + * @builder: an initialised #EpcAppFilterBuilder + * @app_ref: a flatpak app ref to blacklist + * + * Add @app_ref to the blacklist of flatpak refs in the filter under + * construction. The @app_ref will not be added again if it’s already been + * added. + * + * Since: 0.1.0 + */ +void +epc_app_filter_builder_blacklist_flatpak_ref (EpcAppFilterBuilder *builder, + const gchar *app_ref) +{ + EpcAppFilterBuilderReal *_builder = (EpcAppFilterBuilderReal *) builder; + + g_return_if_fail (_builder != NULL); + g_return_if_fail (_builder->paths_blacklist != NULL); + g_return_if_fail (app_ref != NULL); + + if (!g_ptr_array_find_with_equal_func (_builder->paths_blacklist, + app_ref, g_str_equal, NULL)) + g_ptr_array_add (_builder->paths_blacklist, g_strdup (app_ref)); +} + /** * epc_app_filter_builder_set_oars_value: * @builder: an initialised #EpcAppFilterBuilder diff --git a/libeos-parental-controls/app-filter.h b/libeos-parental-controls/app-filter.h index 458827b..98652d0 100644 --- a/libeos-parental-controls/app-filter.h +++ b/libeos-parental-controls/app-filter.h @@ -97,9 +97,11 @@ void epc_app_filter_unref (EpcAppFilter *filter); G_DEFINE_AUTOPTR_CLEANUP_FUNC (EpcAppFilter, epc_app_filter_unref) -uid_t epc_app_filter_get_user_id (EpcAppFilter *filter); -gboolean epc_app_filter_is_path_allowed (EpcAppFilter *filter, - const gchar *path); +uid_t epc_app_filter_get_user_id (EpcAppFilter *filter); +gboolean epc_app_filter_is_path_allowed (EpcAppFilter *filter, + const gchar *path); +gboolean epc_app_filter_is_flatpak_ref_allowed (EpcAppFilter *filter, + const gchar *flatpak_ref); EpcAppFilterOarsValue epc_app_filter_get_oars_value (EpcAppFilter *filter, const gchar *oars_section); @@ -177,10 +179,12 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (EpcAppFilterBuilder, epc_app_filter_builder_free) EpcAppFilter *epc_app_filter_builder_end (EpcAppFilterBuilder *builder); -void epc_app_filter_builder_blacklist_path (EpcAppFilterBuilder *builder, - const gchar *path); -void epc_app_filter_builder_set_oars_value (EpcAppFilterBuilder *builder, - const gchar *oars_section, - EpcAppFilterOarsValue value); +void epc_app_filter_builder_blacklist_path (EpcAppFilterBuilder *builder, + const gchar *path); +void epc_app_filter_builder_blacklist_flatpak_ref (EpcAppFilterBuilder *builder, + const gchar *app_ref); +void epc_app_filter_builder_set_oars_value (EpcAppFilterBuilder *builder, + const gchar *oars_section, + EpcAppFilterOarsValue value); G_END_DECLS diff --git a/libeos-parental-controls/tests/app-filter.c b/libeos-parental-controls/tests/app-filter.c index bd72dad..c0062c3 100644 --- a/libeos-parental-controls/tests/app-filter.c +++ b/libeos-parental-controls/tests/app-filter.c @@ -102,6 +102,9 @@ test_app_filter_builder_non_empty (BuilderFixture *fixture, epc_app_filter_builder_blacklist_path (fixture->builder, "/bin/true"); epc_app_filter_builder_blacklist_path (fixture->builder, "/usr/bin/gnome-software"); + epc_app_filter_builder_blacklist_flatpak_ref (fixture->builder, + "app/org.doom.Doom/x86_64/master"); + epc_app_filter_builder_set_oars_value (fixture->builder, "drugs-alcohol", EPC_APP_FILTER_OARS_VALUE_MILD); epc_app_filter_builder_set_oars_value (fixture->builder, "language-humor", @@ -113,6 +116,11 @@ test_app_filter_builder_non_empty (BuilderFixture *fixture, g_assert_false (epc_app_filter_is_path_allowed (filter, "/usr/bin/gnome-software")); + g_assert_true (epc_app_filter_is_flatpak_ref_allowed (filter, + "app/org.gnome.Ponies/x86_64/master")); + g_assert_false (epc_app_filter_is_flatpak_ref_allowed (filter, + "app/org.doom.Doom/x86_64/master")); + g_assert_cmpint (epc_app_filter_get_oars_value (filter, "drugs-alcohol"), ==, EPC_APP_FILTER_OARS_VALUE_MILD); g_assert_cmpint (epc_app_filter_get_oars_value (filter, "language-humor"), ==, @@ -134,6 +142,11 @@ test_app_filter_builder_empty (BuilderFixture *fixture, g_assert_true (epc_app_filter_is_path_allowed (filter, "/usr/bin/gnome-software")); + g_assert_true (epc_app_filter_is_flatpak_ref_allowed (filter, + "app/org.gnome.Ponies/x86_64/master")); + g_assert_true (epc_app_filter_is_flatpak_ref_allowed (filter, + "app/org.doom.Doom/x86_64/master")); + g_assert_cmpint (epc_app_filter_get_oars_value (filter, "drugs-alcohol"), ==, EPC_APP_FILTER_OARS_VALUE_UNKNOWN); g_assert_cmpint (epc_app_filter_get_oars_value (filter, "language-humor"), ==,