diff --git a/src/test/unit/web_interface/test_app_jinja_filter.py b/src/test/unit/web_interface/test_app_jinja_filter.py index e668b1043..94fe42224 100644 --- a/src/test/unit/web_interface/test_app_jinja_filter.py +++ b/src/test/unit/web_interface/test_app_jinja_filter.py @@ -6,7 +6,7 @@ @pytest.fixture def filter_class(web_frontend): - return FilterClass(web_frontend.app, '', web_frontend.db) + return FilterClass(web_frontend.app, web_frontend.db) class TestAppShowAnalysis: diff --git a/src/test/unit/web_interface/test_app_jinja_functions.py b/src/test/unit/web_interface/test_app_jinja_functions.py new file mode 100644 index 000000000..77fcfa1e6 --- /dev/null +++ b/src/test/unit/web_interface/test_app_jinja_functions.py @@ -0,0 +1,25 @@ +from typing import Any + +import pytest +from flask import render_template_string + +from version import __VERSION__ + + +def test_auth_is_disabled(web_frontend): + _assert_is_rendered(web_frontend, 'auth_is_enabled', False) + + +@pytest.mark.frontend_config_overwrite({'authentication': {'enabled': True}}) +def test_auth_is_enabled(web_frontend): + _assert_is_rendered(web_frontend, 'auth_is_enabled', True) + + +def test_get_fact_version(web_frontend): + _assert_is_rendered(web_frontend, 'get_fact_version', __VERSION__) + + +def _assert_is_rendered(web_frontend, function: str, expected_value: Any): + with web_frontend.app.test_request_context(): + template = render_template_string(f'
{{{{ {function}() }}}}
') + assert f'
{expected_value}
' in template diff --git a/src/web_interface/components/jinja_filter.py b/src/web_interface/components/jinja_filter.py index 11fa4b2cf..47a96e97b 100644 --- a/src/web_interface/components/jinja_filter.py +++ b/src/web_interface/components/jinja_filter.py @@ -27,16 +27,12 @@ class FilterClass: This is WEB front end main class """ - def __init__(self, app, program_version, db: FrontendDatabase, **_): - self._program_version = program_version + def __init__(self, app, db: FrontendDatabase, **_): self._app = app self.db = db self._setup_filters() - def _filter_print_program_version(self, *_): - return f'{self._program_version}' - def _filter_replace_uid_with_file_name(self, input_data): tmp = input_data.__str__() uid_list = flt.get_all_uids_in_string(tmp) @@ -117,9 +113,6 @@ def _virtual_path_element_to_span(hid_element: str, uid: str, root_uid: str, cur '' ) - def check_auth(self, _): - return config.frontend.authentication.enabled - def data_to_chart_limited(self, data, limit: int | None = None, color_list=None): limit = self._get_chart_element_count() if limit is None else limit try: @@ -150,7 +143,6 @@ def _setup_filters(self): { 'all_items_equal': lambda data: len({str(value) for value in data.values()}) == 1, 'as_ascii_table': flt.as_ascii_table, - 'auth_enabled': self.check_auth, 'base64_encode': flt.encode_base64_filter, 'bytes_to_str': flt.bytes_to_str_filter, 'data_to_chart': self.data_to_chart, @@ -189,7 +181,6 @@ def _setup_filters(self): 'nice_virtual_path_list': self._nice_virtual_path_list, 'number_format': flt.byte_number_filter, 'octal_to_readable': flt.octal_to_readable, - 'print_program_version': self._filter_print_program_version, 'regex_meta': flt.comment_out_regex_meta_chars, 'remaining_time': elapsed_time, 'render_analysis_tags': flt.render_analysis_tags, diff --git a/src/web_interface/frontend_main.py b/src/web_interface/frontend_main.py index 906ee01bc..070440de8 100644 --- a/src/web_interface/frontend_main.py +++ b/src/web_interface/frontend_main.py @@ -1,10 +1,12 @@ from __future__ import annotations import logging +from inspect import getmembers, isfunction from intercom.front_end_binding import InterComFrontEndBinding from storage.redis_status_interface import RedisStatusInterface from version import __VERSION__ +from web_interface import jinja_functions from web_interface.app import create_app from web_interface.components.ajax_routes import AjaxRoutes from web_interface.components.analysis_routes import AnalysisRoutes @@ -29,6 +31,7 @@ def __init__(self, db: FrontendDatabase | None = None, intercom=None, status_int self.status_interface = RedisStatusInterface() if status_interface is None else status_interface self._setup_app() + self._register_jinja_functions() logging.info('Web front end online') def _setup_app(self): @@ -47,4 +50,13 @@ def _setup_app(self): rest_base = RestBase(**base_args) PluginRoutes(**base_args, api=rest_base.api) - FilterClass(self.app, self.program_version, self.db) + FilterClass(self.app, self.db) + + def _register_jinja_functions(self): + # add functions from the module to the globals in jinja so that the functions can be called from templates + for function_name, function in getmembers(jinja_functions, isfunction): + if ( + (not function_name.startswith('_')) # we assume all function beginning with "_" are helper functions + and (function.__module__ == jinja_functions.__name__) # only functions from the module, no imports + ): + self.app.jinja_env.globals.update({function_name: function}) diff --git a/src/web_interface/jinja_functions.py b/src/web_interface/jinja_functions.py new file mode 100644 index 000000000..03c55d83c --- /dev/null +++ b/src/web_interface/jinja_functions.py @@ -0,0 +1,10 @@ +import config +from version import __VERSION__ + + +def auth_is_enabled() -> bool: + return config.frontend.authentication.enabled + + +def get_fact_version(): + return __VERSION__ diff --git a/src/web_interface/templates/base.html b/src/web_interface/templates/base.html index b753faf0b..a8e3cdab4 100644 --- a/src/web_interface/templates/base.html +++ b/src/web_interface/templates/base.html @@ -1,19 +1,35 @@ -{% set navigation_bar = [ -("Home", "/", ''), -("Database", None, None), -("Upload", "/upload", ''), -("Info", None, ''), -("Feedback", None, ''), -("Admin", None, '') -] -%} - -{% if ("string only here to have input to " | auth_enabled) %} -{% do navigation_bar.append(("Login", None, None)) %} -{% endif %} {% set active_page = active_page | default('Home') %} +{% macro navbar_item(caption, link, icon, options=None) %} +
  • +  {{ caption }} +
  • +{%- endmacro %} + +{% macro navbar_dropdown_menu(caption, icon) %} + +{%- endmacro %} + +{% macro navbar_dropdown_item(link, icon, caption) %} + + {{ caption }} + +{%- endmacro %} + @@ -58,6 +74,7 @@ +{# Navbar #}