fix(auth): typed context keys and real sentinel errors #4

Merged
nsatoshi merged 1 commits from devin/1776538999-fix-auth-context-keys-and-errors into master 2026-04-18 19:35:57 +00:00
Owner

Summary

PR #4 of the 11-PR completion sequence. Fixes the go vet SA1029 class of bug in the auth middleware and stops abusing http.ErrMissingFile as an auth sentinel.

backend/api/middleware/context.go (new)

<ref_snippet file="/home/ubuntu/repos/explorer-monorepo/backend/api/middleware/context.go" lines="1-60" />

  • Unexported ctxKey type + three constants (ctxKeyUserAddress, ctxKeyUserTrack, ctxKeyAuthenticated) replace the bare string keys "user_address" / "user_track" / "authenticated".
  • Helpers: ContextWithAuth, UserAddress, UserTrack, IsAuthenticated.
  • New sentinel ErrMissingAuthorization replaces misuse of http.ErrMissingFile (which belongs to multipart/form-data parsing) as an "auth header missing" signal.

Call sites migrated

  • backend/api/middleware/auth.goRequireAuth, OptionalAuth, RequireTrack, extractAuth all use the typed helpers. Unused context import dropped.
  • backend/api/track4/operator_scripts.go, backend/api/track4/endpoints.go, backend/api/rest/features.go — read address / track via middleware.UserAddress() / middleware.UserTrack().
  • backend/api/track4/operator_scripts_test.go — four fixtures now seed the context through middleware.ContextWithAuth(..., 4, true) instead of context.WithValue with a bare string key. This is load-bearing: a bare string key no longer reaches the middleware helpers, so anyone regressing the type discipline will fail these tests immediately.

Tests

<ref_file file="/home/ubuntu/repos/explorer-monorepo/backend/api/middleware/context_test.go" />

  • TestContextWithAuthRoundTrip — address / track / authenticated round-trip.
  • TestUserTrackDefaultsToTrack1OnBareContext — Track 1 is the safe default for an un-seeded context.
  • TestUserAddressEmptyOnBareContext, TestIsAuthenticatedFalseOnBareContext — default-deny defaults.
  • TestContextKeyIsolation — a caller that writes context.WithValue(ctx, "user_address", "injected") with a bare string must NOT be visible to UserAddress(ctx). This specifically catches SA1029-class collisions.
  • TestErrMissingAuthorizationIsSentinelerrors.Is smoke test for the new sentinel.

Verification

  • go build ./... — clean.
  • go vet ./... — clean (SA1029 hits on the old bare keys are gone).
  • go test ./api/middleware/... ./api/track4/... ./api/rest/... — all PASS.

Completion criterion advanced

3. Auth correctness — "No bare-string context keys in backend/api/middleware or its callers; the auth-missing sentinel is a package-local errors.New, not http.ErrMissingFile."

## Summary PR #4 of the 11-PR completion sequence. Fixes the `go vet` SA1029 class of bug in the auth middleware and stops abusing `http.ErrMissingFile` as an auth sentinel. ## `backend/api/middleware/context.go` (new) <ref_snippet file="/home/ubuntu/repos/explorer-monorepo/backend/api/middleware/context.go" lines="1-60" /> - Unexported `ctxKey` type + three constants (`ctxKeyUserAddress`, `ctxKeyUserTrack`, `ctxKeyAuthenticated`) replace the bare string keys `"user_address"` / `"user_track"` / `"authenticated"`. - Helpers: `ContextWithAuth`, `UserAddress`, `UserTrack`, `IsAuthenticated`. - New sentinel `ErrMissingAuthorization` replaces misuse of `http.ErrMissingFile` (which belongs to `multipart/form-data` parsing) as an "auth header missing" signal. ## Call sites migrated - `backend/api/middleware/auth.go` — `RequireAuth`, `OptionalAuth`, `RequireTrack`, `extractAuth` all use the typed helpers. Unused `context` import dropped. - `backend/api/track4/operator_scripts.go`, `backend/api/track4/endpoints.go`, `backend/api/rest/features.go` — read address / track via `middleware.UserAddress()` / `middleware.UserTrack()`. - `backend/api/track4/operator_scripts_test.go` — four fixtures now seed the context through `middleware.ContextWithAuth(..., 4, true)` instead of `context.WithValue` with a bare string key. This is load-bearing: a bare string key no longer reaches the middleware helpers, so anyone regressing the type discipline will fail these tests immediately. ## Tests <ref_file file="/home/ubuntu/repos/explorer-monorepo/backend/api/middleware/context_test.go" /> - `TestContextWithAuthRoundTrip` — address / track / authenticated round-trip. - `TestUserTrackDefaultsToTrack1OnBareContext` — Track 1 is the safe default for an un-seeded context. - `TestUserAddressEmptyOnBareContext`, `TestIsAuthenticatedFalseOnBareContext` — default-deny defaults. - `TestContextKeyIsolation` — a caller that writes `context.WithValue(ctx, "user_address", "injected")` with a bare string must NOT be visible to `UserAddress(ctx)`. This specifically catches SA1029-class collisions. - `TestErrMissingAuthorizationIsSentinel` — `errors.Is` smoke test for the new sentinel. ## Verification - `go build ./...` — clean. - `go vet ./...` — clean (SA1029 hits on the old bare keys are gone). - `go test ./api/middleware/... ./api/track4/... ./api/rest/...` — all PASS. ## Completion criterion advanced > **3. Auth correctness** — "No bare-string context keys in `backend/api/middleware` or its callers; the auth-missing sentinel is a package-local `errors.New`, not `http.ErrMissingFile`."
nsatoshi added 1 commit 2026-04-18 19:05:49 +00:00
backend/api/middleware/context.go (new):
- Introduces an unexported ctxKey type and three constants
  (ctxKeyUserAddress, ctxKeyUserTrack, ctxKeyAuthenticated) that
  replace the bare string keys 'user_address', 'user_track', and
  'authenticated'. Bare strings trigger go vet's SA1029 and collide
  with keys from any other package that happens to share the name.
- Helpers: ContextWithAuth, UserAddress, UserTrack, IsAuthenticated.
- Sentinel: ErrMissingAuthorization replaces the misuse of
  http.ErrMissingFile as an auth-missing signal. (http.ErrMissingFile
  belongs to multipart form parsing and was semantically wrong.)

backend/api/middleware/auth.go:
- RequireAuth, OptionalAuth, RequireTrack now all read/write via the
  helpers; no more string literals for context keys in this file.
- extractAuth returns ErrMissingAuthorization instead of
  http.ErrMissingFile.
- Dropped now-unused 'context' import.

backend/api/track4/operator_scripts.go, backend/api/track4/endpoints.go,
backend/api/rest/features.go:
- Read user address / track via middleware.UserAddress() and
  middleware.UserTrack() instead of a raw context lookup with a bare
  string key.
- Import 'github.com/explorer/backend/api/middleware'.

backend/api/track4/operator_scripts_test.go:
- Four test fixtures updated to seed the request context through
  middleware.ContextWithAuth (track 4, authenticated) instead of
  context.WithValue with a bare 'user_address' string. This is the
  load-bearing change that proves typed keys are required: a bare
  string key no longer wakes up the middleware helpers.

backend/api/middleware/context_test.go (new):
- Round-trip test for ContextWithAuth + UserAddress + UserTrack +
  IsAuthenticated.
- Defaults: UserTrack=1, UserAddress="", IsAuthenticated=false on a
  bare context.
- TestContextKeyIsolation: an outside caller that inserts
  'user_address' as a bare string key must NOT be visible to
  UserAddress; proves the type discipline.
- ErrMissingAuthorization sentinel smoke test.

Verification:
- go build ./... clean.
- go vet ./... clean (removes SA1029 on the old bare keys).
- go test ./api/middleware/... ./api/track4/... ./api/rest/... PASS.

Advances completion criterion 3 (Auth correctness).
nsatoshi merged commit 44a12722cf into master 2026-04-18 19:35:57 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: d-bis/explorer-monorepo#4