Shared backend auth validator#3857
Closed
timmo001 wants to merge 1 commit into
Closed
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
There was a problem hiding this comment.
Pull request overview
This PR centralizes backend API token authentication into a new reusable backend/auth package, then refactors HTTP, WebSocket, and MCP endpoints to use the shared token extraction + validation helpers, with new unit/integration tests to cover the updated auth flows.
Changes:
- Added
backend/authwith aValidator, token extraction helpers (Bearer + legacy headers + optional query token), and standardized JSON auth error writers. - Refactored HTTP data/media handlers, MCP transport auth, and WebSocket message auth to use the new validator/utilities.
- Added focused tests covering token extraction precedence and endpoint-level authorization behavior.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| backend/auth/auth.go | New centralized auth validator, token extraction utilities, and standardized JSON error helpers. |
| backend/auth/auth_test.go | Unit tests for token parsing/extraction precedence and validator behavior. |
| backend/backend.go | Wires shared validator into HTTP handlers and updates media/data route registration. |
| backend/http/data.go | Uses centralized auth utilities for module data endpoint authorization. |
| backend/http/data_test.go | Adds authorization and error-shape tests for the module data endpoint. |
| backend/http/media.go | Converts media handler to a validator-based handler factory and uses centralized token extraction. |
| backend/http/media_test.go | Adds authorization-path tests for media endpoint (Bearer + legacy query token). |
| backend/mcp/server.go | Replaces raw token storage with centralized validator usage. |
| backend/mcp/transport.go | Uses centralized token extraction + standardized unauthorized response for MCP WebSocket auth. |
| backend/mcp/transport_test.go | Adds auth rejection tests for MCP connection handling. |
| backend/websocket/websocket.go | Replaces stored token with centralized validator instance in WebSocket server. |
| backend/websocket/handlers.go | Uses validator-based token validation for incoming WebSocket messages. |
Comment on lines
+66
to
+70
| func writeJSONError(w http.ResponseWriter, status int, message string) { | ||
| w.Header().Set("Content-Type", "application/json") | ||
| w.WriteHeader(status) | ||
| _ = json.NewEncoder(w).Encode(map[string]string{"error": message}) | ||
| } |
Comment on lines
+44
to
48
| token := backend_auth.TokenFromRequest(r, backend_auth.RequestTokenOptions{AllowQuery: true}) | ||
| if !validator.ValidateToken(token) { | ||
| backend_auth.WriteUnauthorized(w) | ||
| return | ||
| } |
Comment on lines
+15
to
20
| func GetModuleDataHandler(dataStore *data.DataStore, validator *backend_auth.Validator) http.HandlerFunc { | ||
| return func(w http.ResponseWriter, r *http.Request) { | ||
| expectedToken, err := utils.LoadToken() | ||
| if err != nil { | ||
| slog.Error("Failed to load token for authentication", "error", err) | ||
| w.Header().Set("Content-Type", "application/json") | ||
| w.WriteHeader(http.StatusInternalServerError) | ||
| if err := json.NewEncoder(w).Encode(map[string]string{"error": "Authentication error"}); err != nil { | ||
| slog.Error("Failed to encode response", "error", err) | ||
| } | ||
| return | ||
| } | ||
|
|
||
| // Check for API token in both X-API-Token and token headers | ||
| token := r.Header.Get("X-API-Token") | ||
| if token == "" { | ||
| token = r.Header.Get("token") | ||
| } | ||
| if token != expectedToken { | ||
| w.Header().Set("Content-Type", "application/json") | ||
| w.WriteHeader(http.StatusUnauthorized) | ||
| if err := json.NewEncoder(w).Encode(map[string]string{"error": "Invalid API token"}); err != nil { | ||
| slog.Error("Failed to encode response", "error", err) | ||
| } | ||
| token := backend_auth.TokenFromRequest(r, backend_auth.RequestTokenOptions{}) | ||
| if !validator.ValidateToken(token) { | ||
| backend_auth.WriteUnauthorized(w) | ||
| return |
Comment on lines
59
to
63
| // Validate token | ||
| if msg.Token != ws.token { | ||
| if !ws.validator.ValidateToken(msg.Token) { | ||
| slog.Error("Invalid token received") | ||
| ws.SendError(conn, msg, "BAD_TOKEN", "Invalid token") | ||
| continue |
| if err := json.NewEncoder(w).Encode(map[string]string{"error": "Method not allowed"}); err != nil { | ||
| slog.Error("Failed to encode response", "error", err) | ||
| func ServeMediaFileDataHandler(validator *backend_auth.Validator) http.HandlerFunc { | ||
| return func(w http.ResponseWriter, r *http.Request) { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
The following is an LLM summary
This pull request introduces a unified API token authentication mechanism across the backend by creating a reusable
authpackage and refactoring all HTTP and WebSocket endpoints to use it. The authentication logic is now centralized, making it easier to maintain and extend. Comprehensive tests have been added for the new authentication flows.The most important changes are:
Authentication Refactor and Centralization:
authpackage that provides aValidatortype, token extraction utilities (supporting Bearer, legacy headers, and query tokens), and standardized error responses. All authentication logic is now handled through this package (backend/auth/auth.go,backend/auth/auth_test.go). [1] [2]Validatorfor token validation, replacing previous scattered and duplicated logic (backend/backend.go,backend/http/data.go,backend/http/media.go,backend/mcp/server.go,backend/mcp/transport.go,backend/websocket/websocket.go,backend/websocket/handlers.go). [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]Improved Token Extraction:
backend/auth/auth.go).Testing Enhancements:
backend/auth/auth_test.go,backend/http/data_test.go,backend/http/media_test.go,backend/mcp/transport_test.go). [1] [2] [3] [4]Consistent Error Handling:
backend/auth/auth.go, refactored handlers).Simplification and Code Cleanup:
authpackage (backend/http/data.go,backend/http/media.go). [1] [2]These changes make authentication more robust, maintainable, and easier to test across the backend.