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] =
|
private def resolveToken(difficulty: String): Option[String] =
|
||||||
val name = botName(difficulty)
|
val name = botName(difficulty)
|
||||||
val redisKey = s"${redisConfig.prefix}:tournament-bot:token:$name"
|
val redisKey = s"${redisConfig.prefix}:tournament-bot:token:$name"
|
||||||
fetchTokenFromAccountService(name)
|
registerWithTournamentServer(name)
|
||||||
|
.orElse(fetchTokenFromAccountService(name))
|
||||||
.map { token =>
|
.map { token =>
|
||||||
redis.value(classOf[String]).set(redisKey, 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
|
token
|
||||||
}
|
}
|
||||||
.orElse {
|
.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] =
|
private def fetchTokenFromAccountService(name: String): Option[String] =
|
||||||
Try(accountServiceClient.getBotToken(name).token).toOption.filter(_.nonEmpty)
|
Try(accountServiceClient.getBotToken(name).token).toOption.filter(_.nonEmpty)
|
||||||
.orElse {
|
.orElse {
|
||||||
|
|||||||
Reference in New Issue
Block a user