"""Compile the gateway configuration: hash any trusted inline script for the CSP. The Site's behaviour now lives in separate files, so normally there is nothing to hash and the policy is simply script-src 'self' — no allowlist to get wrong. The hashing stays because an inline script added later must not silently need 'unsafe-inline'; it is hashed automatically instead. """ import base64 import hashlib import os from pathlib import Path import re root = Path('/build') hashes = [] for html in (root / 'web').glob('*.html'): for attributes, script in re.findall(r']*)>(.*?)', html.read_text(), re.S | re.I): if not re.search(r'\bsrc\s*=', attributes, re.I) and script.strip(): hashes.append("'sha256-" + base64.b64encode(hashlib.sha256(script.encode()).digest()).decode() + "'") template = Path(os.environ.get('NGINX_TEMPLATE', root / 'local/nginx.conf.template')).read_text() rendered = template.replace('@SCRIPT_HASHES@', ' '.join(hashes)) # Collapse the gap an empty hash list leaves behind, so the policy reads cleanly. rendered = re.sub(r"(script-src 'self')\s+;", r'\1;', rendered) (root / 'default.conf.template').write_text(rendered) print(f'CSP script-src: {len(hashes)} inline hash(es)')