summaryrefslogtreecommitdiff
path: root/internal/middleware
diff options
context:
space:
mode:
Diffstat (limited to 'internal/middleware')
-rw-r--r--internal/middleware/ai_auth.go46
1 files changed, 46 insertions, 0 deletions
diff --git a/internal/middleware/ai_auth.go b/internal/middleware/ai_auth.go
new file mode 100644
index 0000000..3c04a37
--- /dev/null
+++ b/internal/middleware/ai_auth.go
@@ -0,0 +1,46 @@
+package middleware
+
+import (
+ "net/http"
+ "strings"
+)
+
+// AIAuthMiddleware validates Bearer token for AI agent access
+func AIAuthMiddleware(validToken string) func(http.Handler) http.Handler {
+ return func(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ // Skip auth if no token configured
+ if validToken == "" {
+ respondError(w, http.StatusServiceUnavailable, "ai_disabled", "AI agent access not configured")
+ return
+ }
+
+ authHeader := r.Header.Get("Authorization")
+
+ if authHeader == "" {
+ respondError(w, http.StatusUnauthorized, "unauthorized", "Missing Authorization header")
+ return
+ }
+
+ if !strings.HasPrefix(authHeader, "Bearer ") {
+ respondError(w, http.StatusUnauthorized, "unauthorized", "Invalid Authorization header format")
+ return
+ }
+
+ token := strings.TrimPrefix(authHeader, "Bearer ")
+ if token != validToken {
+ respondError(w, http.StatusUnauthorized, "unauthorized", "Invalid or missing token")
+ return
+ }
+
+ next.ServeHTTP(w, r)
+ })
+ }
+}
+
+// respondError sends a JSON error response
+func respondError(w http.ResponseWriter, status int, error, message string) {
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(status)
+ w.Write([]byte(`{"error":"` + error + `","message":"` + message + `"}`))
+}