diff options
Diffstat (limited to 'internal/server/server.go')
| -rw-r--r-- | internal/server/server.go | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/internal/server/server.go b/internal/server/server.go index 92b0f09..b0192a4 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -65,9 +65,11 @@ func New(cfg *config.Config, store *storage.Storage, sched *monitor.Scheduler, l // Pages mux.HandleFunc("GET /", s.handleIndex) - mux.HandleFunc("GET /api/status", s.handleAPIStatus) - mux.HandleFunc("GET /api/monitor/{name}", s.handleAPIMonitor) - mux.HandleFunc("GET /api/history/{name}", s.handleAPIHistory) + + // API endpoints (protected by API access control) + mux.HandleFunc("GET /api/status", s.withAPIAuth(s.handleAPIStatus)) + mux.HandleFunc("GET /api/monitor/{name}", s.withAPIAuth(s.handleAPIMonitor)) + mux.HandleFunc("GET /api/history/{name}", s.withAPIAuth(s.handleAPIHistory)) // Create HTTP server s.server = &http.Server{ @@ -115,6 +117,49 @@ func (s *Server) withMiddleware(next http.Handler) http.Handler { }) } +// withAPIAuth wraps an API handler with access control based on config.API.Access +func (s *Server) withAPIAuth(handler http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + switch s.config.API.Access { + case "private": + // API is disabled + s.jsonError(w, "API access is disabled", http.StatusForbidden) + return + + case "authenticated": + // Check for API key in header or query param + apiKey := r.Header.Get("X-API-Key") + if apiKey == "" { + apiKey = r.URL.Query().Get("api_key") + } + + if apiKey == "" { + w.Header().Set("WWW-Authenticate", "API-Key") + s.jsonError(w, "API key required", http.StatusUnauthorized) + return + } + + // Check if key is valid + valid := false + for _, key := range s.config.API.Keys { + if key == apiKey { + valid = true + break + } + } + + if !valid { + s.jsonError(w, "Invalid API key", http.StatusUnauthorized) + return + } + + // case "public" or default: allow access + } + + handler(w, r) + } +} + // PageData contains data for rendering the status page type PageData struct { Site config.SiteConfig |