fix(official-bots): register with tournament server directly to get correct token
Build & Test (NowChessSystems) TeamCity build finished
Build & Test (NowChessSystems) TeamCity build finished
The TOURNAMENT_SERVICE_URL points to the NowChessTools tournament server
which uses its own HMAC-HS256 JWTs issued by POST /api/auth/register.
Tokens from the NowChessSystems account service (RS256) are rejected
with 401 by that server.
resolveToken now first calls POST {tournamentServiceUrl}/api/auth/register
(public endpoint, idempotent — finds existing identity by name or creates).
This returns the correct HMAC-HS256 token for the target server and is
stored in Redis. Falls back to the account service path for deployments
where TOURNAMENT_SERVICE_URL points to the NowChessSystems tournament module.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+18
-2
@@ -62,10 +62,11 @@ class TournamentBotGamePlayer:
|
||||
private def resolveToken(difficulty: String): Option[String] =
|
||||
val name = botName(difficulty)
|
||||
val redisKey = s"${redisConfig.prefix}:tournament-bot:token:$name"
|
||||
fetchTokenFromAccountService(name)
|
||||
registerWithTournamentServer(name)
|
||||
.orElse(fetchTokenFromAccountService(name))
|
||||
.map { token =>
|
||||
redis.value(classOf[String]).set(redisKey, token)
|
||||
log.infof("Fetched fresh bot token for %s from account service", name)
|
||||
log.infof("Refreshed bot token for %s — stored in Redis", name)
|
||||
token
|
||||
}
|
||||
.orElse {
|
||||
@@ -81,6 +82,21 @@ class TournamentBotGamePlayer:
|
||||
}
|
||||
}
|
||||
|
||||
private def registerWithTournamentServer(name: String): Option[String] =
|
||||
Try {
|
||||
val body = s"""{"name":"${name.replace("\"", "\\\"")}","isBot":true}"""
|
||||
val response = client.target(tournamentServiceUrl)
|
||||
.path("api").path("auth").path("register")
|
||||
.request(MediaType.APPLICATION_JSON)
|
||||
.post(Entity.entity(body, MediaType.APPLICATION_JSON))
|
||||
val status = response.getStatus
|
||||
if status == 200 || status == 201 then
|
||||
val token = objectMapper.readTree(response.readEntity(classOf[String])).path("token").asText()
|
||||
response.close()
|
||||
Option(token).filter(_.nonEmpty)
|
||||
else { response.close(); None }
|
||||
}.toOption.flatten
|
||||
|
||||
private def fetchTokenFromAccountService(name: String): Option[String] =
|
||||
Try(accountServiceClient.getBotToken(name).token).toOption.filter(_.nonEmpty)
|
||||
.orElse {
|
||||
|
||||
Reference in New Issue
Block a user