lint: adopt org-standard .golangci.yml and golangci-lint v2.12.2 (closes #14)
check / check (push) Failing after 1s
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. Fix every finding the standard config surfaces in the Go source: wrap over-long lines, drop a dead //nolint:wsl, hoist the repeated test IP literals in middleware_test.go to named constants (goconst), and switch its request to NewRequestWithContext (noctx). TODO.md updated. Model: opus-4-8
This commit is contained in:
@@ -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{
|
||||
|
||||
@@ -163,7 +163,9 @@ func (b *Buffer) writeFile(data []byte) {
|
||||
name := fmt.Sprintf("reports-%s.jsonl.zst", ts)
|
||||
path := filepath.Join(b.dataDir, name)
|
||||
|
||||
f, err := os.OpenFile( //nolint:gosec // path built from controlled dataDir + timestamp
|
||||
// path is built from the operator-supplied dataDir plus a
|
||||
// generated timestamp, so it carries no external input.
|
||||
f, err := os.OpenFile( //nolint:gosec // see comment above
|
||||
path,
|
||||
os.O_WRONLY|os.O_CREATE|os.O_EXCL,
|
||||
filePerms,
|
||||
|
||||
@@ -62,7 +62,10 @@ func New(
|
||||
OnStart: func(_ context.Context) error {
|
||||
s.startupTime = time.Now().UTC()
|
||||
|
||||
go func() { //nolint:contextcheck // fx OnStart ctx is startup-only; run() creates its own
|
||||
// The fx OnStart context is scoped to startup and is
|
||||
// cancelled once the hook returns; run() derives its
|
||||
// own context instead of inheriting this one.
|
||||
go func() { //nolint:contextcheck // see comment above
|
||||
s.run()
|
||||
}()
|
||||
|
||||
@@ -94,7 +97,7 @@ func (s *Server) run() {
|
||||
}
|
||||
|
||||
func (s *Server) serve() int {
|
||||
var ctx context.Context //nolint:wsl // ctx must be declared before multi-assign
|
||||
var ctx context.Context
|
||||
|
||||
ctx, s.cancelFunc = context.WithCancel(
|
||||
context.Background(),
|
||||
|
||||
Reference in New Issue
Block a user