Skip to content

Add optional local web UI: upload domains, download reports, diff runs (#23)#24

Merged
CallMarcus merged 1 commit into
mainfrom
claude/issues-status-review-ll7hil
Jun 25, 2026
Merged

Add optional local web UI: upload domains, download reports, diff runs (#23)#24
CallMarcus merged 1 commit into
mainfrom
claude/issues-status-review-ll7hil

Conversation

@CallMarcus

Copy link
Copy Markdown
Owner

Implements the MVP scope of #23 — a thin, optional Flask web layer over the existing analysis engine, so a list of domains can be analyzed from the browser without touching the command line. Core analysis logic is untouched; the package stays fully usable without the web extra.

What you get

Install the extra and launch:

pip install "domain-security-analyzer[web]"
domain-analyzer-web --open      # serves http://127.0.0.1:8000

The UI lets you:

  • Upload domains by pasting (one per line, # comments ignored) or dropping a .txt file.
  • Watch progress — analysis runs in a background thread with a live progress bar (the page polls a small JSON status endpoint and stays responsive).
  • Download the standard 29-column CSV for any run.
  • View changes — each run is saved locally; the Changes page diffs the two most recent runs and classifies per-domain deltas into security regressions (SPF/DMARC lost, SRI coverage dropped, HTTPS redirect lost…) vs. improvements, plus domains added/removed.

Binds to 127.0.0.1 only; runs are stored under ~/.domain-security-analyzer/runs/ (override via DSA_DATA_DIR). Single-user local tool by design.

Changes

New domain_security_analyzer/web/ subpackage

  • app.py — Flask app factory, in-memory job registry, routes (/, /run, /run/<id>, /run/<id>/status, /results/<run>, /download/<run>, /changes). Download path is validated against traversal.
  • runs.py — timestamped-CSV storage + the run-diff classifier.
  • cli.py / __main__.py — the domain-analyzer-web launcher (--host/--port/--open/--debug), with a clear message if the web extra isn't installed.
  • templates/ + static/style.css — minimal dark UI.

Engine refactor in analyzer.py (backward compatible)

  • Extracted the inline CSV writing into a reusable write_results_csv() helper + a shared CSV_COLUMNS constant.
  • Added an optional progress_callback(completed, total) to analyze_domains_from_file so the UI gets real progress without scraping stdout. Existing callers/behavior unchanged.

Packaging / CI

  • New [web] extra (flask>=3.0; also added to [dev]); domain-analyzer-web entry point; web templates/static packaged in both wheel and sdist (verified).
  • CI installs .[web] and smoke-tests domain-analyzer-web --help.

Verification

  • 45 tests pass (8 new in tests/test_web.py, all network-free — domain parsing, run-diff classification incl. timestamp-ignore, and the full run → progress → results → download flow with the engine monkeypatched, plus path-traversal rejection).
  • python -m build + twine checkPASSED on wheel and sdist.
  • Live server smoke-tested: /, /changes, and /static/style.css all 200.
  • Both domain-analyzer-web and python -m domain_security_analyzer.web launch.

Out of scope (stays on #23)

Full cross-run history / trend charts / SQLite — this MVP diffs the last two runs only, as agreed.

🤖 Generated with Claude Code


Generated by Claude Code

Add a thin, optional Flask-based web layer over the existing analysis engine
so domain lists can be analyzed from the browser without the command line.

Web UI (domain_security_analyzer/web/, installed via the new [web] extra):
- Upload domains by pasting (one per line, '#' comments ignored) or dropping
  a .txt file.
- Analysis runs in a background thread with a live progress bar (polled via a
  JSON status endpoint); the page stays responsive.
- Download the standard 29-column CSV for any run.
- Changes view diffs the two most recent runs and classifies per-domain field
  deltas into security regressions (e.g. SPF/DMARC lost, SRI coverage dropped)
  vs. improvements, plus domains added/removed.
- Launched with the new `domain-analyzer-web` console command (or
  `python -m domain_security_analyzer.web`); binds to 127.0.0.1 only and stores
  runs under ~/.domain-security-analyzer/runs/ (override via DSA_DATA_DIR).

Engine refactor (backward compatible):
- Extract the inline CSV writing in analyze_domains_from_file into a reusable
  write_results_csv() helper plus a shared CSV_COLUMNS constant.
- Add an optional progress_callback(completed, total) parameter so the web UI
  can drive its progress bar without scraping stdout.

Packaging / CI:
- New optional dependency group [web] = flask>=3.0; flask also added to [dev].
- Register the domain-analyzer-web entry point and package the web templates
  and static assets in both wheel and sdist.
- CI installs the [web] extra and smoke-tests the new entry point.

Tests: add tests/test_web.py (network-free) covering domain parsing, the
run-diff classification, and the full HTTP flow (run -> progress -> results ->
download) with the engine monkeypatched, plus path-traversal rejection. Full
suite: 45 passing.

Implements the MVP scope of #23; cross-run history beyond the last two runs
(SQLite) remains out of scope there.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XYvSCw1sjoG2AHbLPCsX7S
@CallMarcus
CallMarcus merged commit c8e74e3 into main Jun 25, 2026
17 checks passed
@CallMarcus
CallMarcus deleted the claude/issues-status-review-ll7hil branch June 25, 2026 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants