Skip to content

Commit bd6220d

Browse files
committed
removing auth from metrics endpoint
1 parent 59f69b9 commit bd6220d

File tree

2 files changed

+41
-45
lines changed

2 files changed

+41
-45
lines changed

main.go

Lines changed: 7 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -392,51 +392,13 @@ func (s *server) authenticateToken(
392392
return true, "authenticated", nil
393393
}
394394

395-
// securedMetricsHandler creates a secured metrics endpoint that requires authentication
396-
func (s *server) securedMetricsHandler() http.Handler {
395+
// metricsHandler creates a public metrics endpoint (no authentication required).
396+
// Serving metrics is often useful to allow external monitoring systems to scrape
397+
// this endpoint without requiring credentials. If you want to restrict access
398+
// again later, add appropriate auth checks here.
399+
func (s *server) metricsHandler() http.Handler {
397400
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
398-
// Get Authorization header or token from query parameter
399-
token := r.Header.Get("Authorization")
400-
if token == "" {
401-
token = r.URL.Query().Get("token")
402-
}
403-
404-
// Handle different Authorization header formats
405-
if strings.HasPrefix(token, "Bearer ") {
406-
token = strings.TrimPrefix(token, "Bearer ")
407-
} else if strings.HasPrefix(token, "token ") {
408-
token = strings.TrimPrefix(token, "token ")
409-
}
410-
411-
// Check if this is a local request (from localhost or 127.0.0.1)
412-
clientIP := getClientIP(r)
413-
isLocal := clientIP == "127.0.0.1" || clientIP == "::1" || clientIP == "localhost"
414-
415-
// Allow local requests without authentication (for monitoring tools on same machine)
416-
if isLocal {
417-
s.logger.Debug("Metrics access granted for local request", "client_ip", clientIP)
418-
promhttp.HandlerFor(s.metrics.GetRegistry(), promhttp.HandlerOpts{}).ServeHTTP(w, r)
419-
return
420-
}
421-
422-
// For remote requests, require authentication with a special metrics token
423-
if token == "" {
424-
s.logger.Info("Metrics access denied - no token provided", "client_ip", clientIP)
425-
http.Error(w, "Authentication required for metrics endpoint", http.StatusUnauthorized)
426-
return
427-
}
428-
429-
// We need to check if this token is from an admin user with metrics access
430-
// Since we don't have a username for metrics endpoint, we'll check against the Forgejo token
431-
// This is a simple approach - in production you might want a dedicated metrics token
432-
if token == s.forgejoToken {
433-
s.logger.Info("Metrics access granted with server token", "client_ip", clientIP)
434-
promhttp.HandlerFor(s.metrics.GetRegistry(), promhttp.HandlerOpts{}).ServeHTTP(w, r)
435-
return
436-
}
437-
438-
s.logger.Info("Metrics access denied - invalid token", "client_ip", clientIP)
439-
http.Error(w, "Invalid authentication token", http.StatusForbidden)
401+
promhttp.HandlerFor(s.metrics.GetRegistry(), promhttp.HandlerOpts{}).ServeHTTP(w, r)
440402
})
441403
}
442404

@@ -2610,7 +2572,7 @@ func getHTTPServer(logger *slog.Logger, ctx context.Context, port int) *http.Ser
26102572

26112573
router.HandleFunc("/healthz", server.statusHandler)
26122574
router.HandleFunc("/status", server.statusHandler)
2613-
router.Handle("/metrics", server.securedMetricsHandler())
2575+
router.Handle("/metrics", server.metricsHandler())
26142576

26152577
router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
26162578
// Read the template content

main_metrics_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package main
2+
3+
import (
4+
"net/http/httptest"
5+
"strings"
6+
"testing"
7+
)
8+
9+
func TestMetricsHandlerPublic(t *testing.T) {
10+
server := createTestMainServer()
11+
12+
// Record a sample metric so the exposition contains the HTTP requests metric
13+
server.metrics.RecordHTTPRequest("GET", "public", "200")
14+
15+
handler := server.metricsHandler()
16+
17+
req := httptest.NewRequest("GET", "/metrics", nil)
18+
w := httptest.NewRecorder()
19+
20+
handler.ServeHTTP(w, req)
21+
22+
if w.Code != 200 {
23+
t.Fatalf("Expected status 200, got %d", w.Code)
24+
}
25+
26+
body := w.Body.String()
27+
if !strings.Contains(body, "patchwork_http_requests_total") {
28+
t.Errorf("Expected metrics output to contain 'patchwork_http_requests_total', got: %s", body)
29+
}
30+
31+
if !strings.Contains(body, "# HELP") || !strings.Contains(body, "# TYPE") {
32+
t.Errorf("Expected metrics exposition to contain HELP/TYPE comments, got: %s", body)
33+
}
34+
}

0 commit comments

Comments
 (0)