lanscape 1.3.1a8__py3-none-any.whl → 1.3.2a6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of lanscape might be problematic. Click here for more details.

Files changed (41) hide show
  1. lanscape/__init__.py +4 -1
  2. lanscape/__main__.py +4 -1
  3. lanscape/ui/static/css/style.css +1 -1
  4. lanscape/ui/templates/core/scripts.html +1 -1
  5. lanscape/ui/templates/info.html +1 -1
  6. lanscape/ui/templates/main.html +6 -4
  7. {lanscape-1.3.1a8.dist-info → lanscape-1.3.2a6.dist-info}/METADATA +4 -3
  8. lanscape-1.3.2a6.dist-info/RECORD +43 -0
  9. lanscape/libraries/app_scope.py +0 -70
  10. lanscape/libraries/decorators.py +0 -75
  11. lanscape/libraries/errors.py +0 -29
  12. lanscape/libraries/ip_parser.py +0 -65
  13. lanscape/libraries/logger.py +0 -42
  14. lanscape/libraries/mac_lookup.py +0 -69
  15. lanscape/libraries/net_tools.py +0 -480
  16. lanscape/libraries/port_manager.py +0 -59
  17. lanscape/libraries/runtime_args.py +0 -44
  18. lanscape/libraries/service_scan.py +0 -51
  19. lanscape/libraries/subnet_scan.py +0 -373
  20. lanscape/libraries/version_manager.py +0 -54
  21. lanscape/libraries/web_browser.py +0 -141
  22. lanscape/resources/mac_addresses/convert_csv.py +0 -27
  23. lanscape/resources/ports/convert_csv.py +0 -27
  24. lanscape/tests/__init__.py +0 -3
  25. lanscape/tests/_helpers.py +0 -15
  26. lanscape/tests/test_api.py +0 -194
  27. lanscape/tests/test_env.py +0 -30
  28. lanscape/tests/test_library.py +0 -53
  29. lanscape/ui/app.py +0 -122
  30. lanscape/ui/blueprints/__init__.py +0 -7
  31. lanscape/ui/blueprints/api/__init__.py +0 -5
  32. lanscape/ui/blueprints/api/port.py +0 -27
  33. lanscape/ui/blueprints/api/scan.py +0 -69
  34. lanscape/ui/blueprints/api/tools.py +0 -30
  35. lanscape/ui/blueprints/web/__init__.py +0 -5
  36. lanscape/ui/blueprints/web/routes.py +0 -74
  37. lanscape/ui/main.py +0 -138
  38. lanscape-1.3.1a8.dist-info/RECORD +0 -72
  39. {lanscape-1.3.1a8.dist-info → lanscape-1.3.2a6.dist-info}/WHEEL +0 -0
  40. {lanscape-1.3.1a8.dist-info → lanscape-1.3.2a6.dist-info}/licenses/LICENSE +0 -0
  41. {lanscape-1.3.1a8.dist-info → lanscape-1.3.2a6.dist-info}/top_level.txt +0 -0
@@ -1,194 +0,0 @@
1
- import unittest
2
- import json
3
- from ..ui.app import app
4
- from ..libraries.net_tools import get_network_subnet
5
- from ._helpers import right_size_subnet
6
- import time
7
-
8
-
9
-
10
- class ApiTestCase(unittest.TestCase):
11
- app = app.test_client()
12
-
13
- def test_port_lifecycle(self):
14
- # Delete the new port list if it exists
15
- self.app.delete('/api/port/list/test_port_list_lifecycle')
16
-
17
- # Get the list of port lists
18
- response = self.app.get('/api/port/list')
19
- self.assertEqual(response.status_code, 200)
20
- port_list_start = json.loads(response.data)
21
-
22
- # Create a new port list
23
- new_port_list = {'80': 'http', '443': 'https'}
24
- response = self.app.post('/api/port/list/test_port_list_lifecycle', json=new_port_list)
25
- self.assertEqual(response.status_code, 200)
26
-
27
-
28
- # Get the list of port lists again
29
- response = self.app.get('/api/port/list')
30
- self.assertEqual(response.status_code, 200)
31
- port_list_new = json.loads(response.data)
32
- # Verify that the new port list is in the list of port lists
33
- self.assertEqual(len(port_list_new), len(port_list_start) + 1)
34
-
35
- # Get the new port list
36
- response = self.app.get('/api/port/list/test_port_list_lifecycle')
37
- self.assertEqual(response.status_code, 200)
38
- port_list = json.loads(response.data)
39
- self.assertEqual(port_list, new_port_list)
40
-
41
- # Update the new port list
42
- updated_port_list = {'22': 'ssh', '8080': 'http-alt'}
43
- response = self.app.put('/api/port/list/test_port_list_lifecycle', json=updated_port_list)
44
- self.assertEqual(response.status_code, 200)
45
-
46
- # Get the new port list again
47
- response = self.app.get('/api/port/list/test_port_list_lifecycle')
48
- self.assertEqual(response.status_code, 200)
49
- port_list = json.loads(response.data)
50
-
51
- # Verify that the new port list has been updated
52
- self.assertEqual(port_list, updated_port_list)
53
-
54
- # Delete the new port list
55
- response = self.app.delete('/api/port/list/test_port_list_lifecycle')
56
- self.assertEqual(response.status_code, 200)
57
-
58
- def test_scan(self):
59
- # Delete the new port list if it exists
60
- self.app.delete('/api/port/list/test_port_list_scan')
61
-
62
- # Create a new port list
63
- new_port_list = {'80': 'http', '443': 'https'}
64
- response = self.app.post('/api/port/list/test_port_list_scan', json=new_port_list)
65
- self.assertEqual(response.status_code, 200)
66
-
67
- # Create a new scan, wait for completion
68
- new_scan = {'subnet': right_size_subnet(get_network_subnet()), 'port_list': 'test_port_list_scan'}
69
- response = self.app.post('/api/scan/async', json=new_scan)
70
- self.assertEqual(response.status_code, 200)
71
- scan_info = json.loads(response.data)
72
- self.assertEqual(scan_info['status'], 'complete')
73
- scanid = scan_info['scan_id']
74
- self.assertIsNotNone(scanid)
75
-
76
- # Validate the scan worked without error
77
- response = self.app.get(f"/api/scan/{scanid}")
78
- self.assertEqual(response.status_code, 200)
79
- scan_data = json.loads(response.data)
80
- self.assertEqual(scan_data['errors'], [])
81
- self.assertEqual(scan_data['stage'],'complete')
82
-
83
- # Render UI
84
- uris = [
85
- '/info',
86
- f'/?scan_id={scanid}',
87
- f'/scan/{scanid}/overview',
88
- f'/scan/{scanid}/table',
89
- f'/export/{scanid}'
90
- ]
91
- for uri in uris:
92
- response = self.app.get(uri)
93
- self.assertEqual(response.status_code,200)
94
-
95
-
96
- # Delete the new port list
97
- response = self.app.delete('/api/port/list/test_port_list_scan')
98
- self.assertEqual(response.status_code, 200)
99
-
100
-
101
- def test_subnet_ports(self):
102
- """
103
- Test to ensure multi-subnet dectection is working
104
- """
105
-
106
- response = self.app.get('/api/tools/subnet/list')
107
- self.assertEqual(response.status_code, 200)
108
-
109
- subnets = json.loads(response.data)
110
- self.assertIsNot(len(subnets), 0)
111
- self.assertIsInstance(subnets[0],dict)
112
- subnet:dict = subnets[0]
113
- self.assertIsNotNone(subnet.get('address_cnt'))
114
-
115
- def test_subnet_validation(self):
116
- """
117
- test subnet validation and parsing is working as expected
118
- """
119
- subnet_tests = {
120
- # subnet : count (-1 == invalid)
121
- '10.0.0.0/24': 254,
122
- '10.0.0.2/24': 254,
123
- '10.0.0.1-100': 100,
124
- '192.168.1.1/25': 126,
125
- '10.0.0.1/24, 192.168.1.1-100': 354,
126
- '10.0.0.1/20': 4094,
127
- '10.0.0.1/19': 8190,
128
- '': -1, # blank
129
- '10.0.1/24': -1, # invalid
130
- '10.0.0.1/2': -1, # too big
131
- '10.0.0.1/19, 192.168.1.1/20': 12284,
132
- '10.0.0.1/17, 192.168.0.1/16': 98300,
133
- '10.0.0.1/20, 192.168.0.1/20, 10.100.0.1/20': 12282,
134
- '10.0.0.1/17, 192.168.0.1/16, 10.100.0.1/20': -1
135
- }
136
-
137
- for subnet, count in subnet_tests.items():
138
- uri = f'/api/tools/subnet/test?subnet={subnet}'
139
- response = self.app.get(uri)
140
- self.assertEqual(response.status_code, 200)
141
-
142
- data:dict = json.loads(response.data)
143
- self.assertEqual(data.get('count'),count)
144
- self.assertIsNotNone(data.get('msg'))
145
- if count == -1:
146
- self.assertFalse(data.get('valid'))
147
-
148
- def test_scan_api(self):
149
- """
150
- Test the scan API endpoints
151
- """
152
- # Create a new scan
153
- new_scan = {
154
- 'subnet': right_size_subnet(get_network_subnet()),
155
- 'port_list': 'small',
156
- 'parallelism': 1
157
- }
158
- response = self.app.post('/api/scan', json=new_scan)
159
- self.assertEqual(response.status_code, 200)
160
- scan_info = json.loads(response.data)
161
- self.assertEqual(scan_info['status'], 'running')
162
- scan_id = scan_info['scan_id']
163
- self.assertIsNotNone(scan_id)
164
-
165
- percent_complete = 0
166
- while percent_complete < 100:
167
- # Get scan summary
168
- response = self.app.get(f'/api/scan/{scan_id}/summary')
169
- self.assertEqual(response.status_code, 200)
170
- summary = json.loads(response.data)
171
- self.assertTrue(summary['running'] or summary['stage'] == 'complete')
172
- percent_complete = summary['percent_complete']
173
- self.assertGreaterEqual(percent_complete, 0)
174
- self.assertLessEqual(percent_complete, 100)
175
- # Wait for a bit before checking again
176
- time.sleep(2)
177
-
178
- self.assertEqual(summary['running'], False)
179
- self.assertEqual(summary['stage'], 'complete')
180
- self.assertGreater(summary['runtime'], 0)
181
-
182
- devices_alive = summary['devices']['alive']
183
- devices_scanned = summary['devices']['scanned']
184
- devices_total = summary['devices']['total']
185
-
186
- self.assertEqual(devices_scanned, devices_total)
187
- self.assertGreater(devices_alive, 0)
188
-
189
-
190
-
191
-
192
-
193
- if __name__ == '__main__':
194
- unittest.main()
@@ -1,30 +0,0 @@
1
- import unittest
2
-
3
- from ..libraries.version_manager import lookup_latest_version
4
- from ..libraries.app_scope import ResourceManager, is_local_run
5
- from ..libraries.net_tools import is_arp_supported
6
-
7
-
8
-
9
- class EnvTestCase(unittest.TestCase):
10
- def test_versioning(self):
11
- version = lookup_latest_version()
12
- self.assertIsNotNone(version)
13
-
14
- def test_resource_manager(self):
15
- ports = ResourceManager('ports')
16
- self.assertGreater(len(ports.list()),0)
17
- mac = ResourceManager('mac_addresses')
18
- mac_list = mac.get('mac_db.json')
19
- self.assertIsNotNone(mac_list)
20
-
21
- def test_local_version(self):
22
- self.assertTrue(is_local_run())
23
-
24
- def test_arp_support(self):
25
- arp_supported = is_arp_supported()
26
- self.assertIn(arp_supported, [True, False],
27
- f"ARP support should be either True or False, not {arp_supported}"
28
- )
29
-
30
-
@@ -1,53 +0,0 @@
1
- import unittest
2
- from ..libraries.net_tools import smart_select_primary_subnet
3
- from ._helpers import right_size_subnet
4
- from ..libraries.subnet_scan import ScanManager, ScanConfig
5
-
6
- sm = ScanManager()
7
-
8
- class LibraryTestCase(unittest.TestCase):
9
- def test_scan(self):
10
- subnet = smart_select_primary_subnet()
11
- self.assertIsNotNone(subnet)
12
- cfg = ScanConfig(
13
- subnet = right_size_subnet(subnet),
14
- t_multiplier=1.0,
15
- port_list='small'
16
- )
17
- scan = sm.new_scan(cfg)
18
- self.assertTrue(scan.running)
19
- sm.wait_until_complete(scan.uid)
20
-
21
- self.assertFalse(scan.running)
22
-
23
- # ensure there are not any remaining running threads
24
- self.assertDictEqual(scan.job_stats.running,{})
25
-
26
-
27
- cnt_with_hostname = 0
28
- ips = []
29
- macs = []
30
- for d in scan.results.devices:
31
- if d.hostname: cnt_with_hostname += 1
32
- # ensure there arent dupe mac addresses
33
- self.assertNotIn(d.get_mac(), macs)
34
- macs.append(d.get_mac())
35
-
36
- # ensure there arent dupe ips
37
- self.assertNotIn(d.ip, ips)
38
- ips.append(d.ip)
39
-
40
- # device must be alive to be in this list
41
- self.assertTrue(d.alive)
42
-
43
- # find at least one device
44
- self.assertGreater(len(scan.results.devices),0)
45
-
46
- # ensure everything got scanned
47
- self.assertEqual(scan.results.devices_scanned, scan.results.devices_total)
48
-
49
-
50
-
51
-
52
-
53
-
lanscape/ui/app.py DELETED
@@ -1,122 +0,0 @@
1
- from flask import Flask, render_template, request
2
- from time import sleep
3
- import multiprocessing
4
- import traceback
5
- import threading
6
- import logging
7
- import os
8
-
9
- from ..libraries.runtime_args import RuntimeArgs, parse_args
10
- from ..libraries.version_manager import is_update_available, get_installed_version, lookup_latest_version
11
- from ..libraries.app_scope import is_local_run
12
- from ..libraries.net_tools import is_arp_supported
13
-
14
- app = Flask(
15
- __name__
16
- )
17
- log = logging.getLogger('flask')
18
-
19
- ## Import and register BPs
20
- ################################
21
-
22
- from .blueprints.api import api_bp
23
- from .blueprints.web import web_bp
24
-
25
- app.register_blueprint(api_bp)
26
- app.register_blueprint(web_bp)
27
-
28
- ## Define global jinja filters
29
- ################################
30
-
31
- def is_substring_in_values(results: dict, substring: str) -> bool:
32
- return any(substring.lower() in str(v).lower() for v in results.values()) if substring else True
33
-
34
- app.jinja_env.filters['is_substring_in_values'] = is_substring_in_values
35
-
36
- ## Define global jinja vars
37
- ################################
38
-
39
- def set_global_safe(key: str, value):
40
- """ Safely set global vars without worrying about an exception """
41
- app_globals = app.jinja_env.globals
42
- try:
43
- if callable(value): value = value()
44
-
45
- app_globals[key] = value
46
- log.debug(f'jinja_globals[{key}] = {value}')
47
- except:
48
- default = app_globals.get(key)
49
- log.debug(traceback.format_exc())
50
- log.info(
51
- f"Unable to set app global var '{key}'"+
52
- f"defaulting to '{default}'"
53
- )
54
- app_globals[key] = default
55
-
56
- set_global_safe('app_version',get_installed_version)
57
- set_global_safe('update_available', is_update_available)
58
- set_global_safe('latest_version',lookup_latest_version)
59
- set_global_safe('runtime_args', vars(parse_args()))
60
- set_global_safe('is_local',is_local_run)
61
- set_global_safe('is_arp_supported', is_arp_supported)
62
-
63
- ## External hook to kill flask server
64
- ################################
65
-
66
- exiting = False
67
- @app.route("/shutdown", methods=['GET', 'POST'])
68
- def exit_app():
69
-
70
- req_type = request.args.get('type')
71
- if req_type == 'browser-close':
72
- args = parse_args()
73
- if args.persistent:
74
- log.info('Dectected browser close, not exiting flask.')
75
- return "Ignored"
76
- log.info('Web browser closed, terminating flask. (disable with --peristent)')
77
- elif req_type == 'core':
78
- log.info('Core requested exit, terminating flask.')
79
- else:
80
- log.info('Received external exit request. Terminating flask.')
81
- global exiting
82
- exiting = True
83
- return "Done"
84
-
85
- @app.teardown_request
86
- def teardown(exception):
87
- if exiting:
88
- os._exit(0)
89
-
90
- ## Generalized error handling
91
- ################################
92
- @app.errorhandler(500)
93
- def internal_error(e):
94
- """
95
- handle internal errors nicely
96
- """
97
- tb = traceback.format_exc()
98
- return render_template('error.html',
99
- error=None,
100
- traceback=tb), 500
101
-
102
- ## Webserver creation functions
103
- ################################
104
-
105
- def start_webserver_daemon(args: RuntimeArgs) -> threading.Thread:
106
- proc = threading.Thread(target=start_webserver, args=(args,))
107
- proc.daemon = True # Kill thread when main thread exits
108
- proc.start()
109
- log.info('Flask server initializing as dameon')
110
- return proc
111
-
112
- def start_webserver(args: RuntimeArgs) -> int:
113
- run_args = {
114
- 'host':'0.0.0.0',
115
- 'port':args.port,
116
- 'debug':args.reloader,
117
- 'use_reloader':args.reloader
118
- }
119
- app.run(**run_args)
120
-
121
-
122
-
@@ -1,7 +0,0 @@
1
- from ...libraries.subnet_scan import ScanManager
2
- import logging
3
- # defining here so blueprints can access the same
4
- # manager instance
5
- scan_manager = ScanManager()
6
-
7
- log = logging.getLogger('Blueprints')
@@ -1,5 +0,0 @@
1
- from flask import Blueprint
2
-
3
- api_bp = Blueprint('api', __name__)
4
-
5
- from . import port, scan, tools
@@ -1,27 +0,0 @@
1
- from flask import request, jsonify
2
- from . import api_bp
3
- from ....libraries.port_manager import PortManager
4
-
5
- # Port Manager API
6
- ############################################
7
- @api_bp.route('/api/port/list', methods=['GET'])
8
- def get_port_lists():
9
- return jsonify(PortManager().get_port_lists())
10
-
11
- @api_bp.route('/api/port/list/<port_list>', methods=['GET'])
12
- def get_port_list(port_list):
13
- return jsonify(PortManager().get_port_list(port_list))
14
-
15
- @api_bp.route('/api/port/list/<port_list>', methods=['POST'])
16
- def create_port_list(port_list):
17
- data = request.get_json()
18
- return jsonify(PortManager().create_port_list(port_list, data))
19
-
20
- @api_bp.route('/api/port/list/<port_list>', methods=['PUT'])
21
- def update_port_list(port_list):
22
- data = request.get_json()
23
- return jsonify(PortManager().update_port_list(port_list, data))
24
-
25
- @api_bp.route('/api/port/list/<port_list>', methods=['DELETE'])
26
- def delete_port_list(port_list):
27
- return jsonify(PortManager().delete_port_list(port_list))
@@ -1,69 +0,0 @@
1
- from . import api_bp
2
- from ....libraries.subnet_scan import ScanConfig
3
- from .. import scan_manager
4
-
5
- from flask import request, jsonify
6
- import json
7
- import traceback
8
-
9
- # Subnet Scanner API
10
- ############################################
11
- @api_bp.route('/api/scan', methods=['POST'])
12
- @api_bp.route('/api/scan/threaded', methods=['POST'])
13
- def scan_subnet_threaded():
14
- try:
15
- config = get_scan_config()
16
- scan = scan_manager.new_scan(config)
17
-
18
- return jsonify({'status': 'running', 'scan_id': scan.uid})
19
- except:
20
- return jsonify({'status': 'error', 'traceback': traceback.format_exc()}), 500
21
-
22
-
23
- @api_bp.route('/api/scan/async', methods=['POST'])
24
- def scan_subnet_async():
25
- config = get_scan_config()
26
- scan = scan_manager.new_scan(config)
27
- scan_manager.wait_until_complete(scan.uid)
28
-
29
- return jsonify({'status': 'complete', 'scan_id': scan.uid})
30
-
31
- @api_bp.route('/api/scan/<scan_id>', methods=['GET'])
32
- def get_scan(scan_id):
33
- scan = scan_manager.get_scan(scan_id)
34
- # cast to str and back to handle custom JSON serialization
35
- return jsonify(json.loads(scan.results.export(str)))
36
-
37
- @api_bp.route('/api/scan/<scan_id>/summary',methods=['GET'])
38
- def get_scan_summary(scan_id):
39
- scan = scan_manager.get_scan(scan_id)
40
- if not scan:
41
- return jsonify({'error':'scan not found'}), 404
42
- return jsonify({
43
- 'running': scan.running,
44
- 'percent_complete': scan.calc_percent_complete(),
45
- 'stage': scan.results.stage,
46
- 'runtime': scan.results.get_runtime(),
47
- 'devices': {
48
- 'scanned': scan.results.devices_scanned,
49
- 'alive': len(scan.results.devices),
50
- 'total': scan.results.devices_total
51
- }
52
- })
53
-
54
- @api_bp.route('/api/scan/<scan_id>/terminate', methods=['GET'])
55
- def terminate_scan(scan_id):
56
- scan = scan_manager.get_scan(scan_id)
57
- scan.terminate()
58
- return jsonify({'success': True})
59
-
60
- def get_scan_config():
61
- """
62
- pulls config from the request body
63
- """
64
- data = request.get_json()
65
- return ScanConfig(
66
- subnet = data['subnet'],
67
- port_list= data['port_list'],
68
- t_multiplier=data.get('parallelism',1.0)
69
- )
@@ -1,30 +0,0 @@
1
- from flask import request, jsonify
2
- from . import api_bp
3
- from ....libraries.net_tools import get_all_network_subnets
4
- from ....libraries.ip_parser import parse_ip_input
5
- from ....libraries.errors import SubnetTooLargeError
6
- import traceback
7
-
8
-
9
- @api_bp.route('/api/tools/subnet/test')
10
- def test_subnet():
11
- subnet = request.args.get('subnet')
12
- if not subnet: return jsonify({'valid': False, 'msg': 'Subnet cannot be blank', 'count': -1})
13
- try:
14
- ips = parse_ip_input(subnet)
15
- length = len(ips)
16
- return jsonify({'valid': True, 'msg': f"{length} IP{'s' if length > 1 else ''}", 'count': length})
17
- except SubnetTooLargeError:
18
- return jsonify({'valid': False, 'msg': 'subnet too large', 'error': traceback.format_exc(), 'count': -1})
19
- except:
20
- return jsonify({'valid': False, 'msg': 'invalid subnet', 'error': traceback.format_exc(), 'count': -1})
21
-
22
- @api_bp.route('/api/tools/subnet/list')
23
- def list_subnet():
24
- """
25
- list all interface subets
26
- """
27
- try:
28
- return jsonify(get_all_network_subnets())
29
- except:
30
- return jsonify({'error': traceback.format_exc()})
@@ -1,5 +0,0 @@
1
- from flask import Blueprint
2
-
3
- web_bp = Blueprint('web', __name__)
4
-
5
- from . import routes
@@ -1,74 +0,0 @@
1
- from flask import render_template, request, redirect
2
- from . import web_bp
3
- from ....libraries.subnet_scan import SubnetScanner
4
- from ....libraries.net_tools import (
5
- get_all_network_subnets,
6
- smart_select_primary_subnet
7
- )
8
- from .. import scan_manager, log
9
- import os
10
-
11
- # Template Renderer
12
- ############################################
13
- @web_bp.route('/', methods=['GET'])
14
- def index():
15
- subnets = get_all_network_subnets()
16
- subnet = smart_select_primary_subnet(subnets)
17
-
18
- port_list = 'medium'
19
- parallelism = 1
20
- if scan_id := request.args.get('scan_id'):
21
- if scan := scan_manager.get_scan(scan_id):
22
- subnet = scan.cfg.subnet
23
- port_list = scan.cfg.port_list
24
- parallelism = scan.cfg.t_multiplier
25
-
26
- else:
27
- log.debug(f'Redirecting, scan {scan_id} doesnt exist in memory')
28
- return redirect('/')
29
- return render_template(
30
- 'main.html',
31
- subnet=subnet,
32
- port_list=port_list,
33
- parallelism=parallelism,
34
- alternate_subnets=subnets
35
- )
36
-
37
-
38
- @web_bp.route('/scan/<scan_id>', methods=['GET'])
39
- @web_bp.route('/scan/<scan_id>/<section>', methods=['GET'])
40
- def render_scan(scan_id, section='all'):
41
- if scanner := scan_manager.get_scan(scan_id):
42
- data = scanner.results.export()
43
- filter = request.args.get('filter')
44
- return render_template('scan.html', data=data, section=section, filter=filter)
45
- log.debug(f'Redirecting, scan {scan_id} doesnt exist in memory')
46
- return redirect('/')
47
-
48
- @web_bp.route('/errors/<scan_id>')
49
- def view_errors(scan_id):
50
- if scanner := scan_manager.get_scan(scan_id):
51
- data = scanner.results.export()
52
- return render_template('scan/scan-error.html',data=data)
53
- log.debug(f'Redirecting, scan {scan_id} doesnt exist in memory')
54
- return redirect('/')
55
-
56
- @web_bp.route('/export/<scan_id>')
57
- def export_scan(scan_id):
58
- if scanner := scan_manager.get_scan(scan_id):
59
- export_json = scanner.results.export(str)
60
- return render_template(
61
- 'scan/export.html',
62
- scan=scanner,
63
- export_json=export_json
64
- )
65
- log.debug(f'Redirecting, scan {scan_id} doesnt exist in memory')
66
- return redirect('/')
67
-
68
- @web_bp.route('/shutdown-ui')
69
- def shutdown_ui():
70
- return render_template('shutdown.html')
71
-
72
- @web_bp.route('/info')
73
- def app_info():
74
- return render_template('info.html')