From b78d9e599d622b1f63038bd502c0ce30ec06a662 Mon Sep 17 00:00:00 2001 From: gethvi Date: Wed, 20 Dec 2023 17:55:12 +0100 Subject: [PATCH] Changes to the WebGUI: changes to jinja2 templates, uses FastAPI server, hides login button when session_store is null, fixes double slash issue. --- intelmq/app/server.py | 8 + intelmq/app/webgui/__init__.py | 10 - intelmq/app/webgui/build.py | 60 ------ intelmq/app/webgui/router.py | 101 ++++++++++ .../images/{config.png => configuration.png} | Bin .../images/{botnet.png => management.png} | Bin intelmq/app/webgui/static/js/about.js | 4 - intelmq/app/webgui/static/js/configs.js | 6 +- .../app/webgui/static/js/intelmq-manager.js | 29 --- intelmq/app/webgui/static/js/static.js | 2 +- .../templates/{about.mako => about.html} | 16 +- intelmq/app/webgui/templates/base.html | 162 ++++++++++++++++ intelmq/app/webgui/templates/base.mako | 181 ------------------ .../templates/{check.mako => check.html} | 14 +- .../{configs.mako => configuration.html} | 19 +- intelmq/app/webgui/templates/dynvar.mako | 5 - .../templates/{index.mako => index.html} | 34 ++-- .../{management.mako => management.html} | 16 +- .../templates/{monitor.mako => monitor.html} | 19 +- intelmq/app/webgui/version.py | 7 - 20 files changed, 359 insertions(+), 334 deletions(-) delete mode 100644 intelmq/app/webgui/build.py create mode 100644 intelmq/app/webgui/router.py rename intelmq/app/webgui/static/images/{config.png => configuration.png} (100%) rename intelmq/app/webgui/static/images/{botnet.png => management.png} (100%) delete mode 100644 intelmq/app/webgui/static/js/intelmq-manager.js rename intelmq/app/webgui/templates/{about.mako => about.html} (90%) create mode 100644 intelmq/app/webgui/templates/base.html delete mode 100644 intelmq/app/webgui/templates/base.mako rename intelmq/app/webgui/templates/{check.mako => check.html} (66%) rename intelmq/app/webgui/templates/{configs.mako => configuration.html} (87%) delete mode 100644 intelmq/app/webgui/templates/dynvar.mako rename intelmq/app/webgui/templates/{index.mako => index.html} (67%) rename intelmq/app/webgui/templates/{management.mako => management.html} (89%) rename intelmq/app/webgui/templates/{monitor.mako => monitor.html} (92%) delete mode 100644 intelmq/app/webgui/version.py diff --git a/intelmq/app/server.py b/intelmq/app/server.py index 1c46f25056..34cec9679f 100644 --- a/intelmq/app/server.py +++ b/intelmq/app/server.py @@ -5,8 +5,10 @@ """ import os +import pathlib from fastapi import FastAPI +from fastapi.staticfiles import StaticFiles from fastapi.middleware.cors import CORSMiddleware from intelmq.version import __version__ @@ -15,6 +17,7 @@ from intelmq.app.config import config from intelmq.app.api.router import router as api_router +from intelmq.app.webgui.router import router as web_router app = FastAPI( title="IntelMQ", @@ -32,4 +35,9 @@ def init_app(): app.include_router(api_router, prefix="/api/v1") +if config.enable_webgui: + static_files = pathlib.Path(__file__).parent / "webgui" / "static" + app.mount("/static", StaticFiles(directory=static_files), name="static") + app.include_router(web_router) + intelmq.app.api.exceptions.register(app) diff --git a/intelmq/app/webgui/__init__.py b/intelmq/app/webgui/__init__.py index f1e51caf64..e69de29bb2 100644 --- a/intelmq/app/webgui/__init__.py +++ b/intelmq/app/webgui/__init__.py @@ -1,10 +0,0 @@ -"""Python __init__ file that provides the path to the module - -SPDX-FileCopyrightText: 2020 IntelMQ Team -SPDX-License-Identifier: AGPL-3.0-or-later - -""" -import pathlib -from .version import __version__, __version_info__ # noqa - -path = pathlib.Path(__file__).parent diff --git a/intelmq/app/webgui/build.py b/intelmq/app/webgui/build.py deleted file mode 100644 index 04e15c2fb1..0000000000 --- a/intelmq/app/webgui/build.py +++ /dev/null @@ -1,60 +0,0 @@ -""" -Build statically rendered files. - -SPDX-FileCopyrightText: 2021 Birger Schacht , Mikk Margus Möll , Sebastian Wagner -SPDX-License-Identifier: AGPL-3.0-or-later -""" -import argparse -import pathlib -import shutil -from mako.lookup import TemplateLookup - - -def render_page(pagename: str, **template_args) -> str: - template_dir = pathlib.Path(__file__).parent / 'templates' - template_lookup = TemplateLookup(directories=[template_dir], default_filters=["h"], input_encoding='utf8') - template = template_lookup.get_template(f'{pagename}.mako') - - return template.render(pagename=pagename, **template_args) - - -def buildhtml(outputdir: pathlib.Path = pathlib.Path('html')): - outputdir.mkdir(parents=True, exist_ok=True) - - htmlfiles = ["configs", "management", "monitor", "check", "about", "index"] - for filename in htmlfiles: - print(f"Rendering {filename}.html") - html = render_page(filename) - outputdir.joinpath(f"{filename}.html").write_text(html) - - staticfiles = ["css", "images", "js", "plugins", "less"] - for filename in staticfiles: - print(f"Copying {filename} recursively") - src = pathlib.Path(__file__).parent / 'static' / filename - dst = outputdir / filename - if dst.exists(): - shutil.rmtree(dst) - shutil.copytree(src, dst) - - print('rendering dynvar.js') - rendered = render_page('dynvar', allowed_path='/opt/intelmq/var/lib/bots/', controller_cmd='intelmq') - outputdir.joinpath('js/dynvar.js').write_text(rendered) - - -def main(): - parser = argparse.ArgumentParser( - prog='intelmq-manager-build', - description='Build statically rendered files for intelmq-manager.', - epilog='This command renders and saves all files required for IntelMQ Manager at the given directory, which can be served by Webservers statically', - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - - parser.add_argument('--output-dir', '-o', default='html', - type=pathlib.Path, - help='The destination directory, will be created if needed.') - args = parser.parse_args() - buildhtml(outputdir=args.output_dir) - - -if __name__ == '__main__': - main() diff --git a/intelmq/app/webgui/router.py b/intelmq/app/webgui/router.py new file mode 100644 index 0000000000..add8c4d144 --- /dev/null +++ b/intelmq/app/webgui/router.py @@ -0,0 +1,101 @@ +# SPDX-FileCopyrightText: 2023 IntelMQ Team +# SPDX-License-Identifier: AGPL-3.0-or-later + +import collections +import pathlib + +from fastapi import APIRouter, Request +from fastapi.responses import HTMLResponse +from fastapi.templating import Jinja2Templates + +from intelmq.app.config import config + +SHOW_LOGIN = True if config.session_store else False + +router = APIRouter(default_response_class=HTMLResponse) +templates_dir = pathlib.Path(__file__).parent / "templates" +templates = Jinja2Templates(directory=templates_dir) +Page = collections.namedtuple("Page", ["name", "title", "url", "icon_url"]) + + +def get_pages(request: Request): + return [ + Page( + name="configs", + title="Configuration", + url=request.url_for('get_configuration'), + icon_url=request.url_for('static', path='images/configuration.png'), + ), + Page( + name="management", + title="Management", + url=request.url_for('get_management'), + icon_url=request.url_for('static', path='images/management.png'), + ), + Page( + name="monitor", + title="Monitor", + url=request.url_for('get_monitor'), + icon_url=request.url_for('static', path='images/monitor.png'), + ), + Page( + name="check", + title="Check", + url=request.url_for('get_check'), + icon_url=request.url_for('static', path='images/check.png'), + ), + Page( + name="about", + title="About", + url=request.url_for('get_about'), + icon_url=request.url_for('static', path='images/about.png'), + ) + ] + + +@router.get("/", include_in_schema=False) +async def get_index(request: Request): + return templates.TemplateResponse("index.html", { + "request": request, + "pages": get_pages(request) + }) + + +@router.get("/configuration", include_in_schema=False) +async def get_configuration(request: Request): + return templates.TemplateResponse("configuration.html", { + "request": request, + "pages": get_pages(request) + }) + + +@router.get("/management", include_in_schema=False) +def get_management(request: Request): + return templates.TemplateResponse("management.html", { + "request": request, + "pages": get_pages(request) + }) + + +@router.get("/monitor", include_in_schema=False) +def get_monitor(request: Request): + return templates.TemplateResponse("monitor.html", { + "request": request, + "pages": get_pages(request) + }) + + +@router.get("/check", include_in_schema=False) +def get_check(request: Request): + return templates.TemplateResponse("check.html", { + "request": request, + "pages": get_pages(request) + }) + + +@router.get("/about", include_in_schema=False) +def get_about(request: Request): + return templates.TemplateResponse("about.html", { + "request": request, + "pages": get_pages(request) + }) diff --git a/intelmq/app/webgui/static/images/config.png b/intelmq/app/webgui/static/images/configuration.png similarity index 100% rename from intelmq/app/webgui/static/images/config.png rename to intelmq/app/webgui/static/images/configuration.png diff --git a/intelmq/app/webgui/static/images/botnet.png b/intelmq/app/webgui/static/images/management.png similarity index 100% rename from intelmq/app/webgui/static/images/botnet.png rename to intelmq/app/webgui/static/images/management.png diff --git a/intelmq/app/webgui/static/js/about.js b/intelmq/app/webgui/static/js/about.js index c18470de59..13b36b4662 100644 --- a/intelmq/app/webgui/static/js/about.js +++ b/intelmq/app/webgui/static/js/about.js @@ -5,14 +5,10 @@ function get_versions() { let intelmq_version_element = document.getElementById('intelmq-version'); - let intelmq_api_version_element = document.getElementById('intelmq-api-version'); - let intelmq_manager_version_element = document.getElementById('intelmq-manager-version'); authenticatedGetJson(managementUrl('version')) .done(function (data) { intelmq_version_element.innerHTML = data.intelmq; - intelmq_api_version_element.innerHTML = data['intelmq-api']; - intelmq_manager_version_element.innerHTML = '3.2.0'; }) .fail(function (jqxhr, textStatus, error) { let err = `${textStatus}, ${error}`; diff --git a/intelmq/app/webgui/static/js/configs.js b/intelmq/app/webgui/static/js/configs.js index 8dd3b1ea3f..aa744dca53 100644 --- a/intelmq/app/webgui/static/js/configs.js +++ b/intelmq/app/webgui/static/js/configs.js @@ -30,7 +30,7 @@ var documentation = null; var span = null; var table = null; var disabledKeys = ['group', 'name', 'module']; -var $manipulation, $saveButton; // jQuery of Vis control panel; elements reseted with network +var $manipulation, $saveButton; // jQuery of Vis control panel; elements reset with network var node = null; var $EDIT_DEFAULT_BUTTON = $("#editDefaults"); @@ -544,7 +544,7 @@ function saveData(data, callback) { saveFormData(); - // check inputs beeing valid + // check inputs being valid if (node.bot_id === '' && node.group === '') { show_error('fields id and group must not be empty!'); return; @@ -740,7 +740,7 @@ function draw() { initNetwork(); if (window.location.hash) { let node = window.location.hash.substr(1); - setTimeout(() => { // doesnt work immediately, I don't know why. Maybe a js guru would bind to visjs onready if that exists or sth. + setTimeout(() => { // doesn't work immediately, I don't know why. Maybe a js guru would bind to visjs onready if that exists or sth. try { fitNode(node); } catch (e) { diff --git a/intelmq/app/webgui/static/js/intelmq-manager.js b/intelmq/app/webgui/static/js/intelmq-manager.js deleted file mode 100644 index b9b952ca30..0000000000 --- a/intelmq/app/webgui/static/js/intelmq-manager.js +++ /dev/null @@ -1,29 +0,0 @@ -/* intelmq-manager.js javascript file for intelmq-manager - * - * SPDX-FileCopyrightText: 2020 IntelMQ Team - * SPDX-License-Identifier: AGPL-3.0-or-later - * - * Do not change this file! If you want to customize the settings, - * create a 'var.js' file and define the custom settings there with - * var VARIABLENAME = value - */ - -/* - * ROOT points to the URI of the API service. - * Set this for example to `https://intelmq.organization.tld/` - * By default ROOT points to the host the manager runs on, but the path '/intelmq' - */ -'use strict'; - -var arr = window.location.href.split('/'); -var ROOT = ROOT ?? `${arr[0]}//${arr[2]}/intelmq`; - -/* - * If there are multiple versions of the API, they can be defined here - */ -var API_V1 = ROOT + '/v1/api/' - -/* - * use a specific version when accessing the API variable - */ -var API = API_V1 diff --git a/intelmq/app/webgui/static/js/static.js b/intelmq/app/webgui/static/js/static.js index 4fc6c8e7c0..432bf772b8 100644 --- a/intelmq/app/webgui/static/js/static.js +++ b/intelmq/app/webgui/static/js/static.js @@ -76,7 +76,7 @@ var LOAD_X_LOG_LINES = 30; var MESSAGE_LENGTH = 200; -var MONITOR_BOT_URL = "monitor.html?bot_id={0}"; +var MONITOR_BOT_URL = "monitor?bot_id={0}"; var page_is_exiting = false; diff --git a/intelmq/app/webgui/templates/about.mako b/intelmq/app/webgui/templates/about.html similarity index 90% rename from intelmq/app/webgui/templates/about.mako rename to intelmq/app/webgui/templates/about.html index 242610d370..bb52ce3a6f 100644 --- a/intelmq/app/webgui/templates/about.mako +++ b/intelmq/app/webgui/templates/about.html @@ -1,8 +1,11 @@ -## SPDX-FileCopyrightText: 2020 IntelMQ Team -## SPDX-License-Identifier: AGPL-3.0-or-later +{#SPDX-FileCopyrightText: 2020 IntelMQ Team #} +{#SPDX-License-Identifier: AGPL-3.0-or-later#} -<%inherit file="base.mako" /> +{% extends "base.html" %} +{% block title %}About{% endblock %} + +{% block content %}
@@ -51,8 +54,6 @@

Version

- -
IntelMQ
IntelMQ API
IntelMQ Manager
@@ -63,3 +64,8 @@

Debugging

+{% endblock %} + +{% block javascript %} + +{% endblock %} diff --git a/intelmq/app/webgui/templates/base.html b/intelmq/app/webgui/templates/base.html new file mode 100644 index 0000000000..3a2eeea5fb --- /dev/null +++ b/intelmq/app/webgui/templates/base.html @@ -0,0 +1,162 @@ +{#SPDX-FileCopyrightText: 2020 IntelMQ Team #} +{#SPDX-License-Identifier: AGPL-3.0-or-later#} + + + + + + + + + + + + IntelMQ - {% block title %}{% endblock %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + +
+ {% block content %} + {% endblock %} +
+ + + + + + + + + + + + + + + + {% block javascript %} + {% endblock %} + +
+
+ + + + + +
+
+ + + \ No newline at end of file diff --git a/intelmq/app/webgui/templates/base.mako b/intelmq/app/webgui/templates/base.mako deleted file mode 100644 index a36aff559a..0000000000 --- a/intelmq/app/webgui/templates/base.mako +++ /dev/null @@ -1,181 +0,0 @@ -## SPDX-FileCopyrightText: 2020 IntelMQ Team -## SPDX-License-Identifier: AGPL-3.0-or-later - -<%! - import collections - - Page = collections.namedtuple("Page", ["name", "title", "icon", "libraries"]) - pages = [Page("configs", "Configuration", "config.png", - ["plugins/vis.js/vis.js", - "js/runtime.js", - "js/positions.js", - "js/defaults.js", - "js/network-configuration.js", - "js/configs.js", - ]), - Page("management", "Management", "botnet.png", - ["js/runtime.js", "js/management.js"]), - Page("monitor", "Monitor", "monitor.png", - ["js/runtime.js", - "js/defaults.js", - "js/monitor.js"]), - Page("check", "Check", "check.png", ["js/check.js"]), - Page("about", "About", "about.png", ["js/about.js"])] - - common_libraries = [ - "js/dynvar.js", - "js/var.js", - "js/intelmq-manager.js", - "js/static.js", - "js/sb-admin-2.js", - ## XX this don't have to be on every page: - "plugins/dataTables/jquery.dataTables.js", - "plugins/dataTables/dataTables.bootstrap.js", - ] - - page_map = {page.name: page for page in pages} - page_map["index"] = Page("index", "", "", []) -%> - - - - - - - - - - - - - IntelMQ Manager - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - ${next.body()} - - - - - - - - - - - % for lib in common_libraries + page_map[pagename].libraries: - - % endfor - ?> - -
-
-
- - - - - -
-
- - diff --git a/intelmq/app/webgui/templates/check.mako b/intelmq/app/webgui/templates/check.html similarity index 66% rename from intelmq/app/webgui/templates/check.mako rename to intelmq/app/webgui/templates/check.html index 0d027e177b..8e49226aaf 100644 --- a/intelmq/app/webgui/templates/check.mako +++ b/intelmq/app/webgui/templates/check.html @@ -1,8 +1,11 @@ -## SPDX-FileCopyrightText: 2020 IntelMQ Team -## SPDX-License-Identifier: AGPL-3.0-or-later +{#SPDX-FileCopyrightText: 2020 IntelMQ Team #} +{#SPDX-License-Identifier: AGPL-3.0-or-later#} -<%inherit file="base.mako" /> +{% extends "base.html" %} +{% block title %}Check{% endblock %} + +{% block content %}
@@ -22,3 +25,8 @@

Check output

+{% endblock %} + +{% block javascript %} + +{% endblock %} \ No newline at end of file diff --git a/intelmq/app/webgui/templates/configs.mako b/intelmq/app/webgui/templates/configuration.html similarity index 87% rename from intelmq/app/webgui/templates/configs.mako rename to intelmq/app/webgui/templates/configuration.html index 61e0c4e80c..cc057d0ab5 100644 --- a/intelmq/app/webgui/templates/configs.mako +++ b/intelmq/app/webgui/templates/configuration.html @@ -1,8 +1,11 @@ -## SPDX-FileCopyrightText: 2020 IntelMQ Team -## SPDX-License-Identifier: AGPL-3.0-or-later +{#SPDX-FileCopyrightText: 2020 IntelMQ Team #} +{#SPDX-License-Identifier: AGPL-3.0-or-later#} -<%inherit file="base.mako" /> +{% extends "base.html" %} +{% block title %}Configuration{% endblock %} + +{% block content %} +{% endblock %} + +{% block javascript %} + + + + + + +{% endblock %} \ No newline at end of file diff --git a/intelmq/app/webgui/templates/dynvar.mako b/intelmq/app/webgui/templates/dynvar.mako deleted file mode 100644 index cb4f692c1c..0000000000 --- a/intelmq/app/webgui/templates/dynvar.mako +++ /dev/null @@ -1,5 +0,0 @@ -## SPDX-FileCopyrightText: 2021 Mikk Margus Möll -## SPDX-License-Identifier: AGPL-3.0-or-later - -var ALLOWED_PATH = "${allowed_path}"; -var CONTROLLER_CMD = "${controller_cmd}"; diff --git a/intelmq/app/webgui/templates/index.mako b/intelmq/app/webgui/templates/index.html similarity index 67% rename from intelmq/app/webgui/templates/index.mako rename to intelmq/app/webgui/templates/index.html index 91d8ebc0a9..d46c5b0a87 100644 --- a/intelmq/app/webgui/templates/index.mako +++ b/intelmq/app/webgui/templates/index.html @@ -1,17 +1,19 @@ -## SPDX-FileCopyrightText: 2020 IntelMQ Team -## SPDX-License-Identifier: AGPL-3.0-or-later +{#SPDX-FileCopyrightText: 2020 IntelMQ Team #} +{#SPDX-License-Identifier: AGPL-3.0-or-later#} -<%inherit file="base.mako" /> +{% extends "base.html" %} +{% block title %}Home{% endblock %} +{% block content %}
- Logo - IntelMQ Manager + Logo + IntelMQ
@@ -20,9 +22,9 @@
- +
- +

Configuration

To either change the currently deployed configuration or to create a new one in a graphical fashion.

@@ -32,9 +34,9 @@

Configuration

- +
- +

Management

This is where you go to start/stop your bots or check on their status.

@@ -44,9 +46,9 @@

Management

- +
- +

Monitor

This feature is meant to allow you to check on the overall status of your botnet. You can read the bot logs, see how the queues are behaving and other features that allow you to have a better overview of the overall health of the system.

@@ -60,9 +62,9 @@

Monitor

- +
- +

Check

Check IntelMQ is running properly.

@@ -72,9 +74,9 @@

Check

- +
- +

About

To learn more about the project's goals and contributors.

@@ -88,3 +90,5 @@

About

+{% endblock %} + diff --git a/intelmq/app/webgui/templates/management.mako b/intelmq/app/webgui/templates/management.html similarity index 89% rename from intelmq/app/webgui/templates/management.mako rename to intelmq/app/webgui/templates/management.html index 3830ad8cee..33f9d0e339 100644 --- a/intelmq/app/webgui/templates/management.mako +++ b/intelmq/app/webgui/templates/management.html @@ -1,9 +1,11 @@ -## SPDX-FileCopyrightText: 2020 IntelMQ Team -## SPDX-License-Identifier: AGPL-3.0-or-later +{#SPDX-FileCopyrightText: 2020 IntelMQ Team #} +{#SPDX-License-Identifier: AGPL-3.0-or-later#} -<%inherit file="base.mako" /> +{% extends "base.html" %} - +{% block title %}Management{% endblock %} + +{% block content %}
@@ -74,3 +76,9 @@

Individual Bot Status:

+{% endblock %} + +{% block javascript %} + + +{% endblock %} diff --git a/intelmq/app/webgui/templates/monitor.mako b/intelmq/app/webgui/templates/monitor.html similarity index 92% rename from intelmq/app/webgui/templates/monitor.mako rename to intelmq/app/webgui/templates/monitor.html index 06ca50208e..69f4ec87dc 100644 --- a/intelmq/app/webgui/templates/monitor.mako +++ b/intelmq/app/webgui/templates/monitor.html @@ -1,8 +1,11 @@ -## SPDX-FileCopyrightText: 2020 IntelMQ Team -## SPDX-License-Identifier: AGPL-3.0-or-later +{#SPDX-FileCopyrightText: 2020 IntelMQ Team #} +{#SPDX-License-Identifier: AGPL-3.0-or-later#} -<%inherit file="base.mako" /> +{% extends "base.html" %} +{% block title %}Monitor{% endblock %} + +{% block content %}
+{% endblock %} + +{% block javascript %} + + + +{% endblock %} + diff --git a/intelmq/app/webgui/version.py b/intelmq/app/webgui/version.py deleted file mode 100644 index d0f244d030..0000000000 --- a/intelmq/app/webgui/version.py +++ /dev/null @@ -1,7 +0,0 @@ -""" Version file for intelmq-manager - -SPDX-FileCopyrightText: 2020-2021 Intelmq Team , 2022-2023 Intevation GmbH -SPDX-License-Identifier: AGPL-3.0-or-later -""" -__version_info__ = (3, 2, 0) -__version__ = '.'.join(map(str, __version_info__))