From 8b9798884abd617abbcdd2e95ecbf4acc4361c58 Mon Sep 17 00:00:00 2001 From: Mix Date: Wed, 14 Oct 2026 13:55:12 +0300 Subject: [PATCH] staticcheck: the four items of the audit (stage 0) - handlers/authz.go: domainIDSet removed, nothing called it (U1000). - handlers_outbound_pages_test.go: two refusals whose status code was assigned and never read (SA4006) now check it is 400 - a custom DMARC report mode without an address, export passwords that differ. - view/pages_test.go: !strings.Contains for a missing box (S1003). - Audit plan line ticked, roadmap 6/61. No CHANGELOG line: nothing an operator sees changes. staticcheck ./... clean afterwards. Evidence on the test server: see the previous commit (same tree run). Co-Authored-By: Claude Opus 5.5 --- docs/audit-2026-10-12.md | 2 +- docs/roadmap.md | 2 +- internal/web/handlers/authz.go | 13 ------------- .../web/handlers/handlers_outbound_pages_test.go | 6 ++++++ internal/web/view/pages_test.go | 2 +- 5 files changed, 9 insertions(+), 16 deletions(-) diff --git a/docs/audit-2026-10-12.md b/docs/audit-2026-10-12.md index ddf7d1e..1235325 100644 --- a/docs/audit-2026-10-12.md +++ b/docs/audit-2026-10-12.md @@ -562,7 +562,7 @@ has already run is never edited — the next file is added; the published - [x] **Toolchain and deps**: `modernc.org/sqlite`, `x/crypto`, `x/sys`; note in development.md that the image is rebuilt after each Go patch release (`golang:1.26-bookworm` floats, so a rebuild suffices). — **Haiku** -- [ ] The four `staticcheck` items. — **Haiku** +- [x] The four `staticcheck` items. — **Haiku** - [ ] **A negative e2e case passes only on the refusal it is about** (owner, 2026-10-14; seen, not found by the audit). `negative_level1_ratelimit` sends up to sixty messages and waits for one to be refused; it once diff --git a/docs/roadmap.md b/docs/roadmap.md index 2e145eb..b46473b 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -42,7 +42,7 @@ in `git log` and [CHANGELOG.md](../CHANGELOG.md). | from-header-binding | Hold a message's `From:` header against the application that sends it | shipped `2.4.0` | 9/9 | [plans/from-header-binding.md](plans/from-header-binding.md) | | panel-redesign | Panel redesign (accepted mockups, design contract) | shipped `2.0.0` | 27/27 | [plans/panel-redesign.md](plans/panel-redesign.md) | | schema-squash | Squash SQLite migrations into a 2.x baseline | built in panel-redesign (stage 1) | — | [plans/panel-redesign.md](plans/panel-redesign.md) | -| audit-2026-10-12 | Follow-ups of the 2026-10-12 full-tree code audit, seven stages | agreed (2026-10-12: stage 0 first, then 1+2; the rest after) | 5/61 | [audit-2026-10-12.md](audit-2026-10-12.md) | +| audit-2026-10-12 | Follow-ups of the 2026-10-12 full-tree code audit, seven stages | agreed (2026-10-12: stage 0 first, then 1+2; the rest after) | 6/61 | [audit-2026-10-12.md](audit-2026-10-12.md) | **Recommended order** (not binding; owner, 2026-10-09: feature order follows development convenience): **panel-redesign** shipped as `2.0.0` (2026-10-11) and diff --git a/internal/web/handlers/authz.go b/internal/web/handlers/authz.go index 327083f..5b2fd20 100644 --- a/internal/web/handlers/authz.go +++ b/internal/web/handlers/authz.go @@ -57,16 +57,3 @@ func domainNameSet(domains []store.Domain) map[string]bool { } return m } - -// domainIDSet is the set of sending domains a principal is limited to; nil -// means no limit (the global role, or a domain user with All). -func domainIDSet(p auth.Principal) map[int64]bool { - if p.IsGlobal() || p.AllDomains { - return nil - } - m := make(map[int64]bool, len(p.Domains)) - for _, id := range p.Domains { - m[id] = true - } - return m -} diff --git a/internal/web/handlers/handlers_outbound_pages_test.go b/internal/web/handlers/handlers_outbound_pages_test.go index f180c41..820766e 100644 --- a/internal/web/handlers/handlers_outbound_pages_test.go +++ b/internal/web/handlers/handlers_outbound_pages_test.go @@ -172,6 +172,9 @@ func TestDomainSettingsRefusalsStayOnTheSettingsPage(t *testing.T) { lacks(t, "report address refusal", body, ``) code, body = post(s.h.HandleDomainDMARC, "reports", url.Values{"dmarc_rua_mode": {"custom"}}) + if code != http.StatusBadRequest { + t.Fatalf("a custom mode without an address = %d", code) + } has(t, "report address refusal", body, `Enter the report address or choose another option.`) code, body = post(s.h.HandleDomainDMARC, "reports", url.Values{"dmarc_rua_mode": {"hosted"}}) @@ -192,6 +195,9 @@ func TestDomainSettingsRefusalsStayOnTheSettingsPage(t *testing.T) { } has(t, "export refusal", body, `The encryption password must be at least 12 characters.`, `

Domain settings

`) code, body = post(s.h.HandleExportDomain, "export", url.Values{"encrypt": {"1"}, "password": {"long-enough-password"}, "password_confirm": {"another-one-entirely"}}) + if code != http.StatusBadRequest { + t.Fatalf("export passwords that differ = %d", code) + } has(t, "export refusal", body, `The two passwords do not match.`) } diff --git a/internal/web/view/pages_test.go b/internal/web/view/pages_test.go index cc0d514..f9acc76 100644 --- a/internal/web/view/pages_test.go +++ b/internal/web/view/pages_test.go @@ -167,7 +167,7 @@ func TestHealthShowsEveryCheckAndBothActions(t *testing.T) { order := []string{`id="processes"`, `id="sender-check"`, `id="hostname"`, `id="machine"`, `id="sockets"`, `id="certificate"`, `id="notification-mail"`, `id="configuration"`} for i := 1; i < len(order); i++ { - if strings.Index(out, order[i-1]) < 0 || strings.Index(out, order[i]) < strings.Index(out, order[i-1]) { + if !strings.Contains(out, order[i-1]) || strings.Index(out, order[i]) < strings.Index(out, order[i-1]) { t.Errorf("%s does not come after %s", order[i], order[i-1]) } }