Expand test coverage across server, agent, and web; fix bugs found during audit.
Adds hundreds of unit/integration/e2e tests, fixes WS bcrypt auth, config merge, fleet analytics, agent schedule/log tail, and documents stale PROBLEMS items. Updates PROBLEMS.md, README, and test scripts; ignores local spread-kits and coverage dirs.
This commit is contained in:
@@ -216,10 +216,11 @@ func basicAuthMiddleware(next http.Handler) http.Handler {
|
||||
|
||||
path := r.URL.Path
|
||||
|
||||
// Health check and download endpoints are always open.
|
||||
// Health check and one-liner installer endpoints are always open.
|
||||
// NOTE: build download/artifact routes are intentionally NOT in this list —
|
||||
// they require fleet-secret or Basic Auth (see isDownload block below).
|
||||
if path == "/api/v1/health" ||
|
||||
path == "/get" || path == "/install.sh" || path == "/install.ps1" ||
|
||||
(strings.HasPrefix(path, "/api/v1/builds/") && (strings.HasSuffix(path, "/download") || strings.Contains(path, "/artifact/"))) {
|
||||
path == "/get" || path == "/install.sh" || path == "/install.ps1" {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
@@ -227,22 +228,44 @@ func basicAuthMiddleware(next http.Handler) http.Handler {
|
||||
// Agent-facing API endpoints (/api/v1/agent/*) require the fleet secret
|
||||
// in the X-Fleet-Secret header instead of Basic auth. This ensures only
|
||||
// legitimately forged agents can call these endpoints.
|
||||
// A missing or empty fleet secret is always rejected — the server auto-
|
||||
// generates one at startup so this state should never occur in production.
|
||||
if strings.HasPrefix(path, "/api/v1/agent/") {
|
||||
fleetSecretForAgentPathsMu.RLock()
|
||||
secret := fleetSecretForAgentPaths
|
||||
fleetSecretForAgentPathsMu.RUnlock()
|
||||
if secret != "" {
|
||||
provided := r.Header.Get("X-Fleet-Secret")
|
||||
if subtle.ConstantTimeCompare([]byte(provided), []byte(secret)) != 1 {
|
||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
if secret == "" {
|
||||
http.Error(w, "server not ready: fleet secret not configured", http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
provided := r.Header.Get("X-Fleet-Secret")
|
||||
if subtle.ConstantTimeCompare([]byte(provided), []byte(secret)) != 1 {
|
||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
// Secret is empty (first run before config save) or matched — allow through.
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Build download/artifact/uninstall routes: accept fleet secret OR Basic Auth.
|
||||
// This lets forged agents self-upgrade (they have the fleet secret baked in)
|
||||
// while still requiring credentials for unauthenticated callers.
|
||||
isDownload := strings.HasPrefix(path, "/api/v1/builds/") &&
|
||||
(strings.HasSuffix(path, "/download") ||
|
||||
strings.Contains(path, "/artifact/") ||
|
||||
strings.HasSuffix(path, "/uninstall"))
|
||||
if isDownload {
|
||||
fleetSecretForAgentPathsMu.RLock()
|
||||
secret := fleetSecretForAgentPaths
|
||||
fleetSecretForAgentPathsMu.RUnlock()
|
||||
provided := r.Header.Get("X-Fleet-Secret")
|
||||
if secret != "" && subtle.ConstantTimeCompare([]byte(provided), []byte(secret)) == 1 {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
// Fall through to Basic Auth below.
|
||||
}
|
||||
|
||||
user, pass, ok := r.BasicAuth()
|
||||
if !ok {
|
||||
w.Header().Set("WWW-Authenticate", `Basic realm="AetherForge Control Deck"`)
|
||||
|
||||
Reference in New Issue
Block a user