fix(auth): change InternalAuthFilter to use @Singleton and add HTTP tests for secret validation
Build & Test (NowChessSystems) TeamCity build failed

This commit is contained in:
2026-05-03 17:27:30 +02:00
parent 33e5017f51
commit c08d5303eb
3 changed files with 74 additions and 4 deletions
@@ -186,8 +186,11 @@ class InstanceHeartbeatService:
) )
val json = mapper.writeValueAsString(metadata) val json = mapper.writeValueAsString(metadata)
reactiveRedis.value(classOf[String]).setex(key, 5L, json) reactiveRedis
.subscribe().`with`( .value(classOf[String])
.setex(key, 5L, json)
.subscribe()
.`with`(
_ => (), _ => (),
(ex: Throwable) => log.warnf(ex, "Failed to refresh Redis heartbeat"), (ex: Throwable) => log.warnf(ex, "Failed to refresh Redis heartbeat"),
) )
@@ -0,0 +1,67 @@
package de.nowchess.chess.resource
import de.nowchess.chess.grpc.{IoGrpcClientWrapper, RuleSetGrpcAdapter}
import de.nowchess.chess.redis.GameRedisSubscriberManager
import io.quarkus.test.InjectMock
import io.quarkus.test.junit.{QuarkusTest, TestProfile}
import io.quarkus.test.junit.QuarkusTestProfile
import io.restassured.RestAssured
import jakarta.ws.rs.core.MediaType
import org.junit.jupiter.api.{DisplayName, Test}
import java.util.Map as JMap
// scalafix:off
class InternalAuthEnabledProfile extends QuarkusTestProfile:
override def getConfigOverrides(): JMap[String, String] =
JMap.of(
"nowchess.internal.auth.enabled", "true",
"nowchess.internal.secret", "test-secret-123",
)
@QuarkusTest
@TestProfile(classOf[InternalAuthEnabledProfile])
@DisplayName("InternalAuthFilter HTTP")
class InternalAuthFilterHttpTest:
@InjectMock
var ioWrapper: IoGrpcClientWrapper = scala.compiletime.uninitialized
@InjectMock
var ruleAdapter: RuleSetGrpcAdapter = scala.compiletime.uninitialized
@InjectMock
var subscriberManager: GameRedisSubscriberManager = scala.compiletime.uninitialized
@Test
@DisplayName("POST /api/board/game without secret returns 401")
def rejectNoSecret(): Unit =
RestAssured.`given`()
.contentType(MediaType.APPLICATION_JSON)
.body("{}")
.when()
.post("/api/board/game")
.then()
.statusCode(401)
@Test
@DisplayName("POST /api/board/game with wrong secret returns 401")
def rejectWrongSecret(): Unit =
RestAssured.`given`()
.contentType(MediaType.APPLICATION_JSON)
.header("X-Internal-Secret", "wrong-secret")
.body("{}")
.when()
.post("/api/board/game")
.then()
.statusCode(401)
@Test
@DisplayName("GET /api/board/game/{id} without secret returns 404 not 401")
def nonInternalEndpointNotBlocked(): Unit =
RestAssured.`given`()
.when()
.get("/api/board/game/nonexistent")
.then()
.statusCode(404)
// scalafix:on
@@ -1,6 +1,6 @@
package de.nowchess.security package de.nowchess.security
import jakarta.enterprise.context.ApplicationScoped import jakarta.inject.Singleton
import jakarta.ws.rs.container.{ContainerRequestContext, ContainerRequestFilter} import jakarta.ws.rs.container.{ContainerRequestContext, ContainerRequestFilter}
import jakarta.ws.rs.core.Response import jakarta.ws.rs.core.Response
import jakarta.ws.rs.ext.Provider import jakarta.ws.rs.ext.Provider
@@ -9,7 +9,7 @@ import scala.compiletime.uninitialized
@Provider @Provider
@InternalOnly @InternalOnly
@ApplicationScoped @Singleton
class InternalAuthFilter extends ContainerRequestFilter: class InternalAuthFilter extends ContainerRequestFilter:
@ConfigProperty(name = "nowchess.internal.secret", defaultValue = "") @ConfigProperty(name = "nowchess.internal.secret", defaultValue = "")