fix(official-bots): configure JWT verification #74
@@ -12,6 +12,12 @@ quarkus:
|
||||
enabled: true
|
||||
log:
|
||||
level: INFO
|
||||
mp:
|
||||
jwt:
|
||||
verify:
|
||||
publickey:
|
||||
location: ${JWT_PUBLIC_KEY_PATH:keys/public.pem}
|
||||
issuer: nowchess
|
||||
|
||||
nowchess:
|
||||
redis:
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxDsnsCAl0vQx7Vu9CLDZ
|
||||
g0SG05NgUzu9T+3DTEaHGq60T2uriO8BenwyvsF3BnDqTbKf4voohZ1DNfzdbT1J
|
||||
Fj8B62FrDmxcO+sp1/b5HUCJP6y2uSRCmzOHe5k7Pk1IEi72FgBpKXSRkFibRlVf
|
||||
634g7mgsPZAQ9PJEsv4Qvm05T9L6+Gmq6N3bMVLKRXs4RhDhaFbYH9GtUg1eI0yH
|
||||
YjGyRfqzW/nqVMstOLHt8CuPouq4p7eMzeDH3YHkxPm4GG5foCXMOd2DZrW0SCcr
|
||||
7dhFeNVWzQ2m53eOhBzNQX+v3pgjVStsePhBRt2LyGfwkNzmqDgqWsMzSHRMY+cn
|
||||
WQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
+1
-1
@@ -20,7 +20,7 @@ object TournamentBotConfig:
|
||||
tournamentId <- env.get("TOURNAMENT_ID").filter(_.nonEmpty)
|
||||
token <- env.get("TOURNAMENT_BOT_TOKEN").filter(_.nonEmpty)
|
||||
botId <- jwtSubject(token)
|
||||
serverUrl = env.getOrElse("TOURNAMENT_SERVER_URL", "http://localhost:8089")
|
||||
serverUrl = env.getOrElse("TOURNAMENT_SERVER_URL", "http://141.37.123.132:8086")
|
||||
difficulty = env.getOrElse("TOURNAMENT_BOT_DIFFICULTY", "medium")
|
||||
yield TournamentBotConfig(serverUrl, tournamentId, token, botId, difficulty)
|
||||
|
||||
|
||||
+34
-3
@@ -39,10 +39,11 @@ class TournamentBotGamePlayer:
|
||||
// scalafix:on DisableSyntax.var
|
||||
|
||||
val defaultServerUrl: String =
|
||||
System.getenv().asScala.getOrElse("TOURNAMENT_SERVER_URL", "http://localhost:8089")
|
||||
System.getenv().asScala.getOrElse("TOURNAMENT_SERVER_URL", "http://141.37.123.132:8086")
|
||||
|
||||
@PostConstruct
|
||||
def initialize(): Unit =
|
||||
parkOnStartup()
|
||||
config match
|
||||
case None =>
|
||||
log.info("Tournament bot disabled — set TOURNAMENT_ID and TOURNAMENT_BOT_TOKEN to enable")
|
||||
@@ -50,6 +51,35 @@ class TournamentBotGamePlayer:
|
||||
log.infof("Tournament bot enabled — server=%s tournament=%s bot=%s", cfg.serverUrl, cfg.tournamentId, cfg.botId)
|
||||
startAsync(cfg)
|
||||
|
||||
private def parkOnStartup(): Unit =
|
||||
park(defaultServerUrl, "expert") match
|
||||
case Some(id) => log.infof("Parked expert bot on %s as id %s", defaultServerUrl, id)
|
||||
case None => log.warnf("Failed to park expert bot on %s", defaultServerUrl)
|
||||
|
||||
private def parkToken(serverUrl: String, difficulty: String): Option[String] =
|
||||
System.getenv().asScala.get("TOURNAMENT_BOT_TOKEN").filter(_.nonEmpty)
|
||||
.orElse(registerBot(serverUrl, difficulty).map(_._2))
|
||||
|
||||
private def park(serverUrl: String, difficulty: String): Option[String] =
|
||||
parkToken(serverUrl, difficulty).flatMap { token =>
|
||||
Try {
|
||||
val body = s"""{"name":"${botName(difficulty)}"}"""
|
||||
val response = client
|
||||
.target(serverUrl)
|
||||
.path("api")
|
||||
.path("bots")
|
||||
.request(MediaType.APPLICATION_JSON)
|
||||
.header("Authorization", s"Bearer $token")
|
||||
.post(Entity.entity(body, MediaType.APPLICATION_JSON))
|
||||
if response.getStatus == 201 || response.getStatus == 200 then
|
||||
val id = objectMapper.readTree(response.readEntity(classOf[String])).path("id").asText()
|
||||
response.close()
|
||||
log.infof("Parked official bot %s as id %s", botName(difficulty), id)
|
||||
Option(id).filter(_.nonEmpty)
|
||||
else { log.warnf("Parking bot %s returned status %d", botName(difficulty), response.getStatus); response.close(); None }
|
||||
}.getOrElse(None)
|
||||
}
|
||||
|
||||
def joinTournament(tournamentId: String, difficulty: String, serverUrl: String): Either[String, String] =
|
||||
registerBot(serverUrl, difficulty) match
|
||||
case None => Left("Failed to register bot with tournament server")
|
||||
@@ -65,10 +95,11 @@ class TournamentBotGamePlayer:
|
||||
thread.setDaemon(true)
|
||||
thread.start()
|
||||
|
||||
private def botName(difficulty: String): String = s"NowChess ${difficulty.capitalize}"
|
||||
|
||||
private def registerBot(serverUrl: String, difficulty: String): Option[(String, String)] =
|
||||
Try {
|
||||
val name = s"NowChess ${difficulty.capitalize}"
|
||||
val body = s"""{"name":"$name","isBot":true}"""
|
||||
val body = s"""{"name":"${botName(difficulty)}","isBot":true}"""
|
||||
val response = client
|
||||
.target(serverUrl)
|
||||
.path("api")
|
||||
|
||||
Reference in New Issue
Block a user