fix: verify dashboard sessions via config API
This commit is contained in:
+15
-14
@@ -29,24 +29,25 @@ class GatewayHttpProbe(
|
||||
bearerToken: String,
|
||||
sessionCookie: String
|
||||
): GatewayProbeResult {
|
||||
// Hermes dashboard auth gates every protected route, including /health.
|
||||
// A successful password login therefore must send its session cookie to
|
||||
// the health probe as well as /v1/models; otherwise the 302-to-login
|
||||
// response is incorrectly presented as a generic offline failure.
|
||||
val healthCookie = if (authMode == ConnectionAuthMode.PasswordLogin) sessionCookie else ""
|
||||
val health = getJson("$baseUrl/health", sessionCookie = healthCookie)
|
||||
// Hermes Dashboard and Hermes API Server are distinct upstream surfaces.
|
||||
// Dashboard /health and /v1/models can legitimately serve the SPA shell,
|
||||
// so they are not a valid dashboard authentication probe. A password
|
||||
// session is verified against the documented JSON dashboard config route.
|
||||
if (authMode == ConnectionAuthMode.PasswordLogin) {
|
||||
return when (val dashboard = getJson("$baseUrl/api/config", sessionCookie = sessionCookie)) {
|
||||
HttpProbeResult.Success -> GatewayProbeResult.Healthy("Dashboard session authentication passed.")
|
||||
else -> dashboard.toGatewayResult("Dashboard session check")
|
||||
}
|
||||
}
|
||||
|
||||
val health = getJson("$baseUrl/health")
|
||||
if (health != HttpProbeResult.Success) return health.toGatewayResult("Health probe")
|
||||
if (authMode == ConnectionAuthMode.None) {
|
||||
return GatewayProbeResult.Healthy("Gateway health check passed.")
|
||||
}
|
||||
val compatibility = when (authMode) {
|
||||
ConnectionAuthMode.None -> error("Anonymous probes return after the health check.")
|
||||
ConnectionAuthMode.BearerToken -> getJson("$baseUrl/v1/models", bearerToken = bearerToken)
|
||||
ConnectionAuthMode.PasswordLogin -> getJson("$baseUrl/v1/models", sessionCookie = sessionCookie)
|
||||
}
|
||||
return when (compatibility) {
|
||||
HttpProbeResult.Success -> GatewayProbeResult.Healthy("Gateway health and authentication checks passed.")
|
||||
else -> compatibility.toGatewayResult("Authenticated compatibility check")
|
||||
return when (val models = getJson("$baseUrl/v1/models", bearerToken = bearerToken)) {
|
||||
HttpProbeResult.Success -> GatewayProbeResult.Healthy("Gateway health and bearer authentication checks passed.")
|
||||
else -> models.toGatewayResult("Authenticated API check")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-5
@@ -56,7 +56,7 @@ class GatewayHttpProbeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun passwordSessionProbeUsesCookieOnlyForAuthenticatedCompatibilityCheck() = runBlocking {
|
||||
fun passwordSessionProbeUsesCookieOnlyForDashboardConfigCheck() = runBlocking {
|
||||
val requests = mutableListOf<Triple<String, String?, String?>>()
|
||||
val probe = GatewayHttpProbe(client { chain ->
|
||||
requests += Triple(
|
||||
@@ -71,10 +71,7 @@ class GatewayHttpProbeTest {
|
||||
|
||||
assertTrue(result is GatewayProbeResult.Healthy)
|
||||
assertEquals(
|
||||
listOf(
|
||||
Triple("/health", null, SESSION_COOKIE),
|
||||
Triple("/v1/models", null, SESSION_COOKIE)
|
||||
),
|
||||
listOf(Triple("/api/config", null, SESSION_COOKIE)),
|
||||
requests
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user