diff --git a/modules/test/services/python/src/services_module.py b/modules/test/services/python/src/services_module.py index 1a783e7dc..b6787e124 100644 --- a/modules/test/services/python/src/services_module.py +++ b/modules/test/services/python/src/services_module.py @@ -19,17 +19,19 @@ import xmltodict from test_module import TestModule import os +from jinja2 import Environment, FileSystemLoader LOG_NAME = 'test_services' -MODULE_REPORT_FILE_NAME = 'services_report.html' +MODULE_REPORT_FILE_NAME = 'services_report.j2.html' NMAP_SCAN_RESULTS_SCAN_FILE = 'services_scan_results.json' LOGGER = None +REPORT_TEMPLATE_FILE = 'report_template.jinja2' class ServicesModule(TestModule): """Services Test module""" - def __init__(self, + def __init__(self, # pylint: disable=R0917 module, conf_file=None, results_dir=None, @@ -52,6 +54,22 @@ def __init__(self, self._run_nmap() def generate_module_report(self): + # Load Jinja2 template + loader=FileSystemLoader(self._report_template_folder) + template = Environment(loader=loader).get_template(REPORT_TEMPLATE_FILE) + module_header = 'Services Module' + summary_headers = [ + 'TCP ports open', + 'UDP ports open', + 'Total ports open', + ] + module_data_headers = [ + 'Port', + 'State', + 'Service', + 'Version', + ] + # Use os.path.join to create the complete file path nmap_scan_results_file = os.path.join(self._nmap_scan_results_path, NMAP_SCAN_RESULTS_SCAN_FILE) @@ -81,65 +99,32 @@ def generate_module_report(self): else: udp_open += 1 - html_content = '

Services Module

' - - # Add summary table - html_content += (f''' - - - - - - - - - - - - - - -
TCP ports openUDP ports openTotal ports open
{tcp_open}{udp_open}{tcp_open + udp_open}
- ''') + summary_data = [ + tcp_open, + udp_open, + tcp_open + udp_open, + ] + module_data = [] if (tcp_open + udp_open) > 0: - - table_content = ''' - - - - - - - - - - ''' - for row in nmap_table_data: - - table_content += (f''' - - - - - - ''') - - table_content += ''' - -
PortStateServiceVersion
{row['Port']}/{row['Type']}{row['State']}{row['Service']}{row['Version']}
- ''' - - html_content += table_content - - else: - - html_content += (''' -
-
- No open ports detected -
''') + port = row['Port'] + type_ = row['Type'] + module_data.append({ + 'Port': f'{port}/{type_}', + 'State': row['State'], + 'Service': row['Service'], + 'Version': row['Version'], + }) + + html_content = template.render( + base_template=self._base_template_file, + module_header=module_header, + summary_headers=summary_headers, + summary_data=summary_data, + module_data_headers=module_data_headers, + module_data=module_data, + ) LOGGER.debug('Module report:\n' + html_content) diff --git a/modules/test/services/resources/report_template.jinja2 b/modules/test/services/resources/report_template.jinja2 new file mode 100644 index 000000000..c9b1438ae --- /dev/null +++ b/modules/test/services/resources/report_template.jinja2 @@ -0,0 +1,29 @@ +{% extends base_template %} +{% block content %} +{% if module_data %} + + + + {% for header in module_data_headers %} + + {% endfor %} + + + + {% for row in module_data %} + + + + + + + {% endfor %} + +
{{ header }}
{{ row['Port'] }}{{ row['State'] }}{{ row['Service'] }}{{ row['Version'] }}
+{% else %} +
+
+ No open ports detected +
+{% endif %} +{% endblock %} \ No newline at end of file diff --git a/modules/test/services/services.Dockerfile b/modules/test/services/services.Dockerfile index 8dcaafcc1..1277c2f8d 100644 --- a/modules/test/services/services.Dockerfile +++ b/modules/test/services/services.Dockerfile @@ -31,4 +31,7 @@ COPY $MODULE_DIR/conf /testrun/conf COPY $MODULE_DIR/bin /testrun/bin # Copy over all python files -COPY $MODULE_DIR/python /testrun/python \ No newline at end of file +COPY $MODULE_DIR/python /testrun/python + +# Copy Jinja template +COPY $MODULE_DIR/resources/report_template.jinja2 $REPORT_TEMPLATE_PATH/ \ No newline at end of file diff --git a/testing/unit/services/reports/services_report_all_closed_local.html b/testing/unit/services/reports/services_report_all_closed_local.html index 356a82d35..01ac50676 100644 --- a/testing/unit/services/reports/services_report_all_closed_local.html +++ b/testing/unit/services/reports/services_report_all_closed_local.html @@ -1,21 +1,67 @@ -

Services Module

- - - - - - - - - - - - - - -
TCP ports openUDP ports openTotal ports open
000
- -
-
- No open ports detected -
\ No newline at end of file + +
+
+
+ {# Badge #} +

+ {% if json_data['device']['test_pack'] == 'Device Qualification' %} + + Device Qualification + {% else %} + + Pilot Assessment + {% endif %} +

+ {{ title }} +
+ + {{ device['manufacturer'] }} + {{ device['model']}} + + Testrun +
+ +
+ +

Services Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
TCP ports openUDP ports openTotal ports open
000
+ + +
+
+ No open ports detected +
+ + +
+ + +
+
diff --git a/testing/unit/services/reports/services_report_local.html b/testing/unit/services/reports/services_report_local.html index ce601cfc0..71f929aeb 100644 --- a/testing/unit/services/reports/services_report_local.html +++ b/testing/unit/services/reports/services_report_local.html @@ -1,48 +1,102 @@ -

Services Module

- - - - - - - - - - - - - - -
TCP ports openUDP ports openTotal ports open
303
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PortStateServiceVersion
22/tcpopenssh8.8 protocol 2.0
443/tcpopenhttp
502/tcpopenmbap
- \ No newline at end of file + +
+
+
+ {# Badge #} +

+ {% if json_data['device']['test_pack'] == 'Device Qualification' %} + + Device Qualification + {% else %} + + Pilot Assessment + {% endif %} +

+ {{ title }} +
+ + {{ device['manufacturer'] }} + {{ device['model']}} + + Testrun +
+ +
+ +

Services Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
TCP ports openUDP ports openTotal ports open
303
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PortStateServiceVersion
22/tcpopenssh8.8 protocol 2.0
443/tcpopenhttp
502/tcpopenmbap
+ + +
+ + +
+