lint: adopt org-standard .golangci.yml and golangci-lint v2.12.2 (closes #14)
check / check (push) Failing after 1s

The old backend/.golangci.yml declared version "2" but used v1 schema
keys, so under v2 it never validated and its thresholds were inert: the
linter ran at defaults. Replace it verbatim with the org-standard file,
repin the Dockerfile.backend lint stage to golangci-lint v2.12.2, and
assert the config's sha256 as the first step of the backend lint target
so it cannot silently drift again -- a local hash check, no network.

The standard config surfaces findings only in the tests: the repeated
IP literals in middleware_test.go become named constants (goconst) and
its request switches to NewRequestWithContext (noctx). reportbuf.go's
gosec suppression gains a plain justification comment. The rest of the
backend, including the fx-based server lifecycle, is already clean.
TODO.md updated.

Model: opus-4-8
This commit was merged in pull request #31.
This commit is contained in:
2026-09-21 19:30:06 +02:00
parent d7cf010e00
commit 7a1ee6e5a8
6 changed files with 81 additions and 34 deletions
+21 -12
View File
@@ -9,6 +9,15 @@ import (
"sneak.berlin/go/netwatch/internal/middleware"
)
const (
// loopbackPeer is a remote address inside the trusted-proxy allowlist.
loopbackPeer = "127.0.0.1:5000"
// forwardedIP is the client address presented via X-Forwarded-For.
forwardedIP = "203.0.113.7"
// realIP is the client address presented via X-Real-IP.
realIP = "203.0.113.9"
)
func mustPrefixes(t *testing.T, cidrs ...string) []netip.Prefix {
t.Helper()
@@ -41,32 +50,32 @@ func clientIPCases() []clientIPCase {
return []clientIPCase{
{
name: "trusted proxy uses forwarded-for",
remoteAddr: "127.0.0.1:5000",
xff: "203.0.113.7",
want: "203.0.113.7",
remoteAddr: loopbackPeer,
xff: forwardedIP,
want: forwardedIP,
},
{
name: "trusted proxy uses left-most of chain",
remoteAddr: "10.1.2.3:5000",
xff: "203.0.113.7, 10.1.2.3",
want: "203.0.113.7",
xff: forwardedIP + ", 10.1.2.3",
want: forwardedIP,
},
{
name: "trusted proxy falls back to x-real-ip",
remoteAddr: "127.0.0.1:5000",
xRealIP: "203.0.113.9",
want: "203.0.113.9",
remoteAddr: loopbackPeer,
xRealIP: realIP,
want: realIP,
},
{
name: "untrusted peer ignores forwarded-for",
remoteAddr: "198.51.100.4:5000",
xff: "203.0.113.7",
xff: forwardedIP,
want: "198.51.100.4",
},
{
name: "untrusted peer ignores x-real-ip",
remoteAddr: "198.51.100.4:5000",
xRealIP: "203.0.113.9",
xRealIP: realIP,
want: "198.51.100.4",
},
{
@@ -76,7 +85,7 @@ func clientIPCases() []clientIPCase {
},
{
name: "trusted proxy with garbage header uses peer",
remoteAddr: "127.0.0.1:5000",
remoteAddr: loopbackPeer,
xff: "not-an-ip",
want: "127.0.0.1",
},
@@ -119,7 +128,7 @@ func TestSecurityHeaders(t *testing.T) {
)
rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/", http.NoBody)
req := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/", http.NoBody)
handler.ServeHTTP(rec, req)
want := map[string]string{