Sanitize codebase, reorganize docs, and add missing deploy files

Remove dead code identified in docs/SANITIZATION-REVIEW.md:
- app/blueprints/content_old.py and app/blueprints/playlist.py
- app/models/group.py, app/utils/nginx_config_reader.py
- orphaned templates (content_list, edit_content, upload_content,
  player_page) and the related group/Template references

Result: 6 blueprints, 82 routes, no dead modules or orphan templates.

Add files that deploy.sh and docker-entrypoint.sh already require but
which were never tracked:
- https_manager.py       (referenced by deploy.sh, migrate_network.sh,
                          docker-entrypoint.sh)
- Caddyfile.example      (seeded by deploy.sh; its absence aborts deploy)

Relocate generated Graphify artifacts from graphify-out/ to
docs/graphify-out/ (110 files, no content change) and archive the
superseded docs under docs/.

Ignore hygiene:
- ignore ad-hoc .env backups (.env.bak*) — they contain live secrets
- keep the pre-sanitization snapshots (docs/legacy code/,
  docs/old_code_documentation/) on disk but out of the repo

Fix .env.example: drop a duplicated config block, genericize the
hardcoded host IP, and document HOSTNAME_INTERNAL.
This commit is contained in:
2026-09-11 12:18:34 +03:00
parent 1c5186463a
commit 46602f1933
226 changed files with 3999 additions and 15737 deletions
+96
View File
@@ -0,0 +1,96 @@
"""Verify every Caddyfile mode against the real `caddy validate` binary.
Also asserts the structural guarantees required for the deployment model:
* ONE HTTP endpoint that answers regardless of Host header (catch-all :80)
* explicit per-name HTTP blocks for both IP and hostname
* HTTPS on 443 only when enabled, using the internal CA for intranet names
Run: PYTHONPATH=$(pwd) ./.venv/bin/python docs/tools/verify_caddyfile_modes.py
"""
import subprocess
import sys
from app.utils.caddy_manager import CaddyConfigGenerator as G
class Cfg:
def __init__(self, **kw):
self.email = kw.get('email', 'admin@example.com')
self.https_enabled = kw.get('https_enabled', False)
self.domain = kw.get('domain', '')
self.ip_address = kw.get('ip_address', '')
self.hostname = kw.get('hostname', '')
self.port = kw.get('port', 443)
def validate(text):
path = '/tmp/_caddyfile_check'
open(path, 'w').write(text)
r = subprocess.run(
['docker', 'run', '--rm', '-v', f'{path}:/etc/caddy/Caddyfile:ro',
'caddy:2-alpine', 'caddy', 'validate', '--config', '/etc/caddy/Caddyfile'],
capture_output=True, text=True)
return (r.returncode == 0 and 'Valid configuration' in (r.stdout + r.stderr),
(r.stdout + r.stderr))
CASES = [
('1. Nothing configured -> HTTP only on :80',
Cfg(), True, {}),
('2. HTTPS on, IP only -> internal CA + HTTP fallback',
Cfg(https_enabled=True, ip_address='192.168.0.152'), True,
{'tls internal', 'http://192.168.0.152', 'https://192.168.0.152', ':80'}),
('3. HTTPS on, IP + hostname -> both served',
Cfg(https_enabled=True, ip_address='192.168.0.152', hostname='digiserver'),
True,
{'http://digiserver', 'https://digiserver', 'http://192.168.0.152'}),
('4. HTTPS on, redirect-only -> 301 to published port',
Cfg(https_enabled=True, ip_address='192.168.0.152'), False,
{'redir https://192.168.0.152{uri} 301', ':80'}),
('5. HTTPS on, public domain -> ACME (no tls internal)',
Cfg(https_enabled=True, domain='example.com',
ip_address='192.168.0.152'), True,
{'https://example.com', 'tls internal'}),
('6. HTTP only even though IP known (HTTPS disabled) -> :80 only',
Cfg(https_enabled=False, ip_address='192.168.0.152'), True,
{':80'}),
]
failures = []
for label, cfg, fallback, must_contain in CASES:
text = G.generate_caddyfile(cfg, http_fallback=fallback)
ok, raw = validate(text)
missing = sorted(s for s in must_contain if s not in text)
if missing:
ok = False
print(f'[{"OK " if ok else "FAIL"}] {label}')
blocks = [ln.strip() for ln in text.splitlines()
if ln.strip().startswith(('http://', 'https://', ':80'))]
print(f' blocks: {blocks}')
if missing:
print(f' MISSING: {missing}')
if not ok:
failures.append(label)
print(' ', raw.strip()[-400:])
print()
# Extra guarantees that are easy to regress silently.
text_https = G.generate_caddyfile(
Cfg(https_enabled=True, ip_address='192.168.0.152', hostname='digiserver'),
http_fallback=True)
assert ':80 {' in text_https, 'catch-all :80 block missing'
assert 'https://digiserver {' in text_https, 'hostname TLS block missing'
assert text_https.count(':80 {') == 1, 'exactly one catch-all :80 expected'
text_http = G.generate_caddyfile(Cfg(https_enabled=False))
assert 'https://' not in text_http, 'no TLS should be emitted when disabled'
assert ':80 {' in text_http
print('Structural guarantees hold (catch-all :80, per-name blocks, TLS only when enabled)')
if failures:
print(f'FAILED: {failures}')
sys.exit(1)
print('All Caddyfile modes are VALID')