feat(template): install HardeningKitty audit view

This commit is contained in:
PierreCsn committed 2026-10-30 09:12:53 +01:00
1 parent f60d102233
commit eb4ca133d1
7 files changed
+243 -232

No files matched your search

+32 -6
View File
@@ -34,6 +34,7 @@ setuphelpers_stub.system32 = lambda: os.path.join(os.environ.get('SystemRoot', '
setuphelpers_stub.run = lambda *args, **kwargs: ''
setuphelpers_stub.wget = lambda *args, **kwargs: (_ for _ in ()).throw(
AssertionError('unexpected network download in synthetic tests'))
setuphelpers_stub.programfiles32 = '/synthetic/Program Files (x86)'
sys.modules.setdefault('setuphelpers', setuphelpers_stub)
spec = importlib.util.spec_from_file_location('wapt_hardeningkitty_setup', ROOT / 'setup.py')
pkg = importlib.util.module_from_spec(spec)
@@ -75,6 +76,9 @@ def make_source(root):
(root / 'setup.py').write_text('# synthetic setup\n', encoding='utf-8')
(root / 'runner.ps1').write_text('Invoke-HardeningKitty -Mode Audit\n', encoding='utf-8')
(root / 'audit_config.json').write_text('{}\n', encoding='utf-8')
template = root / pkg.CONSOLE_TEMPLATE
template.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(ROOT / pkg.CONSOLE_TEMPLATE, template)
asset_root = root / 'vendor'
assets = {x: ('sample ' + x).encode('utf-8') for x in vendor.REQUIRED}
assets['HardeningKitty.psd1'] = b"@{\n ModuleVersion = '0.9.5'\n}\n"
@@ -344,14 +348,34 @@ class PackageTests(unittest.TestCase):
def test_console_template_matches_schema_and_uses_escaped_tags(self):
template = (ROOT / 'console-templates' /
'host_audit_hardeningkitty_hardeningkitty.html').read_text(encoding='utf-8')
self.assertIn('{{#Items categories}}', template)
self.assertIn('{{#Items controls}}', template)
self.assertIn('{{error.code}}', template)
self.assertIn('{{error.description}}', template)
self.assertIn('{{summary.expected}}', template)
# WAPT wraps the audit JSON under `value`; host metadata stays at root.
self.assertIn('{{#value.summary}}', template)
self.assertIn('{{#Items value.categories}}', template)
self.assertIn('{{#Items value.controls}}', template)
self.assertIn('{{#value.error}}', template)
self.assertIn('{{code}}', template)
self.assertIn('{{description}}', template)
self.assertIn('{{checked}}', template)
self.assertIn('{{computer_fqdn}}', template)
self.assertNotIn('{{{', template)
self.assertNotIn('<script', template.lower())
def test_windows_install_copies_console_template_using_wapt_path(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
source = make_source(root / 'package')
prior = (pkg._IS_WINDOWS, pkg.programfiles32)
try:
pkg._IS_WINDOWS = True
pkg.programfiles32 = str(root / 'Program Files (x86)')
pkg._install_console_template(str(source))
installed = (root / 'Program Files (x86)' / 'wapt' / 'templates' /
'host_audit_hardeningkitty_hardeningkitty.html')
self.assertEqual(installed.read_bytes(),
(source / pkg.CONSOLE_TEMPLATE).read_bytes())
finally:
pkg._IS_WINDOWS, pkg.programfiles32 = prior
def test_structured_error_does_not_publish_exception_details(self):
events = []
class FakeWapt:
@@ -540,7 +564,9 @@ class PackageTests(unittest.TestCase):
verify.verify_source(source)
archive = Path(tmp, 'synthetic.wapt')
with zipfile.ZipFile(archive, 'w') as zf:
for name in ('setup.py', 'runner.ps1', 'audit_config.json', 'package-manifest.json'):
for name in ('setup.py', 'runner.ps1', 'audit_config.json',
'console-templates/host_audit_hardeningkitty_hardeningkitty.html',
'package-manifest.json'):
zf.write(source / name, name)
zf.write(source / 'WAPT' / 'control', 'WAPT/control')
for path in (source / 'vendor').rglob('*'):
+3
View File
@@ -114,6 +114,9 @@ class AuditWaptTest(unittest.TestCase):
'publish_to_wapt':True,'retain_audit_runs':3,'timeout_seconds':120,
'max_findings_in_log':10,
}))
template = self.source/'console-templates'/'host_audit_hardeningkitty_hardeningkitty.html'
template.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(WORK/'console-templates'/'host_audit_hardeningkitty_hardeningkitty.html', template)
self.source.joinpath('package-manifest.json').write_text('{"stale":true}')
(self.source/'setup.py').write_text('# synthetic setup\n')
(self.source/'tools').mkdir()