Skip to content

Commit f826708

Browse files
authored
Merge branch 'lichess-org:master' into patch-7
2 parents 155e1cb + b1f492d commit f826708

File tree

9 files changed

+37
-25
lines changed

9 files changed

+37
-25
lines changed

app/controllers/BulkPairing.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ final class BulkPairing(env: Env) extends LilaController(env):
1212
JsonOk(Json.obj("bulks" -> list.map(SetupBulk.toJson)))
1313
}
1414

15+
def show(id: String) = ScopedBody(_.Challenge.Bulk) { _ ?=> me ?=>
16+
env.challenge.bulk.findBy(id, me) map:
17+
_.fold(notFoundJson()): bulk =>
18+
JsonOk(SetupBulk.toJson(bulk))
19+
}
20+
1521
def delete(id: String) = ScopedBody(_.Challenge.Bulk) { _ ?=> me ?=>
1622
env.challenge.bulk.deleteBy(id, me) flatMap:
1723
if _ then jsonOkResult else notFoundJson()

app/controllers/Game.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,13 @@ final class Game(env: Env, apiC: => Api) extends LilaController(env):
116116
.as(pgnContentType)
117117
}
118118

119-
def exportByIds = AnonBodyOf(parse.tolerantText): body =>
119+
def exportByIds = AnonOrScopedBody(parse.tolerantText)(): ctx ?=>
120+
val (limit, perSec) = if ctx.me.exists(_.isVerifiedOrChallengeAdmin) then (600, 100) else (300, 30)
120121
val config = GameApiV2.ByIdsConfig(
121-
ids = GameId from body.split(',').view.take(300).toSeq,
122+
ids = GameId from ctx.body.body.split(',').view.take(limit).toSeq,
122123
format = GameApiV2.Format byRequest req,
123124
flags = requestPgnFlags(extended = false),
124-
perSecond = MaxPerSecond(30),
125+
perSecond = MaxPerSecond(perSec),
125126
playerFile = get("players")
126127
)
127128
apiC.GlobalConcurrencyLimitPerIP

app/controllers/OAuth.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,16 @@ final class OAuth(env: Env, apiC: => Api) extends LilaController(env):
129129

130130
def challengeTokens = ScopedBody(_.Web.Mod) { ctx ?=> me ?=>
131131
if isGranted(_.ApiChallengeAdmin) then
132-
lila.oauth.OAuthTokenForm.adminChallengeTokens
132+
lila.oauth.OAuthTokenForm
133+
.adminChallengeTokens()
133134
.bindFromRequest()
134135
.fold(
135136
jsonFormError,
136137
data =>
137-
env.oAuth.tokenApi.adminChallengeTokens(data, me).map { tokens =>
138-
JsonOk(tokens.view.mapValues(_.plain).toMap)
139-
}
138+
env.oAuth.tokenApi
139+
.adminChallengeTokens(data, me)
140+
.map: tokens =>
141+
JsonOk(tokens.view.mapValues(_.plain).toMap)
140142
)
141143
else Unauthorized(jsonError("Missing permission"))
142144
}

conf/routes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,7 @@ GET /api/cloud-eval controllers.Api.cloudEval
702702
POST /api/import controllers.Importer.apiSendGame
703703
GET /api/bulk-pairing controllers.BulkPairing.list
704704
POST /api/bulk-pairing controllers.BulkPairing.create
705+
GET /api/bulk-pairing/:id controllers.BulkPairing.show(id)
705706
DELETE /api/bulk-pairing/:id controllers.BulkPairing.delete(id)
706707
POST /api/bulk-pairing/:id/start-clocks controllers.BulkPairing.startClocks(id)
707708

modules/challenge/src/main/ChallengeBulk.scala

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ final class ChallengeBulkApi(
4242
)
4343

4444
def scheduledBy(me: User): Fu[List[ScheduledBulk]] =
45-
coll.list[ScheduledBulk]($doc("by" -> me.id))
45+
coll.find($doc("by" -> me.id)).sort($sort desc "pairAt").cursor[ScheduledBulk]().list(100)
46+
47+
def findBy(id: String, me: User): Fu[Option[ScheduledBulk]] =
48+
coll.one[ScheduledBulk]($doc("_id" -> id, "by" -> me.id))
4649

4750
def deleteBy(id: String, me: User): Fu[Boolean] =
4851
coll.delete.one($doc("_id" -> id, "by" -> me.id)).map(_.n == 1)
@@ -72,10 +75,12 @@ final class ChallengeBulkApi(
7275
makePairings(bulk).void
7376

7477
private def checkForClocks: Funit =
75-
coll.one[ScheduledBulk]($doc("startClocksAt" $lte nowInstant, "pairedAt" $exists true)) flatMapz: bulk =>
78+
coll.one[ScheduledBulk](
79+
$doc("startClocksAt" $lte nowInstant, "startedClocksAt" $exists false, "pairedAt" $exists true)
80+
) flatMapz: bulk =>
7681
workQueue(bulk.by):
77-
fuccess:
78-
Bus.publish(TellMany(bulk.games.map(_.id.value), StartClock), "roundSocket")
82+
Bus.publish(TellMany(bulk.games.map(_.id.value), StartClock), "roundSocket")
83+
coll.updateField($id(bulk.id), "startedClocksAt", nowInstant).void
7984

8085
private def makePairings(bulk: ScheduledBulk): Funit =
8186
def timeControl =

modules/game/src/main/GamesByUsersStream.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@ import lila.common.Bus
88
import lila.common.Json.given
99
import lila.db.dsl.given
1010

11-
final class GamesByUsersStream(gameRepo: lila.game.GameRepo)(using
12-
mat: akka.stream.Materializer,
13-
ec: Executor
14-
):
11+
final class GamesByUsersStream(gameRepo: lila.game.GameRepo)(using akka.stream.Materializer, Executor):
1512

1613
private val chans = List("startGame", "finishGame")
1714

modules/oauth/src/main/OAuthTokenForm.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@ object OAuthTokenForm:
2121

2222
case class Data(description: String, scopes: List[String])
2323

24-
def adminChallengeTokens = Form(
24+
def adminChallengeTokens(max: Int = 1000) = Form(
2525
mapping(
2626
"description" -> descriptionField,
27-
"users" -> cleanText
28-
.verifying("No more than 500 users", _.split(',').size <= 500)
27+
"users" -> cleanText.verifying(s"No more than $max users", _.split(',').sizeIs <= max)
2928
)(AdminChallengeTokensData.apply)(unapply)
3029
)
3130

modules/setup/src/main/SetupBulk.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ object SetupBulk:
5151
mapping(
5252
"players" -> nonEmptyText
5353
.verifying("Not enough tokens", t => extractTokenPairs(t).nonEmpty)
54-
.verifying(s"Too many tokens (max: ${maxGames * 2})", t => extractTokenPairs(t).sizeIs < maxGames),
54+
.verifying(s"Too many tokens (max: ${maxGames * 2})", t => extractTokenPairs(t).sizeIs <= maxGames),
5555
SetupForm.api.variant,
5656
SetupForm.api.clock,
5757
SetupForm.api.optionalDays,
@@ -225,7 +225,7 @@ final class SetupBulkApi(oauthServer: OAuthServer, idGenerator: IdGenerator)(usi
225225
.collect { case List(w, b) => (w, b) }
226226
.toList
227227
val nbGames = pairs.size
228-
val cost = nbGames * (if me.isVerified || me.isApiHog then 1 else 3)
228+
val cost = nbGames * (if me.isVerifiedOrChallengeAdmin || me.isApiHog then 1 else 3)
229229
rateLimit(me.id, fuccess(Left(ScheduleError.RateLimited)), cost = cost):
230230
lila.mon.api.challenge.bulk.scheduleNb(me.id.value).increment(nbGames)
231231
idGenerator

modules/user/src/main/User.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,12 @@ case class User(
9191

9292
def addRole(role: String) = copy(roles = role :: roles)
9393

94-
def isVerified = roles.exists(_ contains "ROLE_VERIFIED")
95-
def isSuperAdmin = roles.exists(_ contains "ROLE_SUPER_ADMIN")
96-
def isAdmin = roles.exists(_ contains "ROLE_ADMIN") || isSuperAdmin
97-
def isApiHog = roles.exists(_ contains "ROLE_API_HOG")
98-
def isVerifiedOrAdmin = isVerified || isAdmin
94+
def isVerified = roles.exists(_ contains "ROLE_VERIFIED")
95+
def isSuperAdmin = roles.exists(_ contains "ROLE_SUPER_ADMIN")
96+
def isAdmin = roles.exists(_ contains "ROLE_ADMIN") || isSuperAdmin
97+
def isApiHog = roles.exists(_ contains "ROLE_API_HOG")
98+
def isVerifiedOrAdmin = isVerified || isAdmin
99+
def isVerifiedOrChallengeAdmin = isVerifiedOrAdmin || roles.exists(_ contains "ROLE_CHALLENGE_ADMIN")
99100

100101
def has2fa = totpSecret.isDefined
101102

0 commit comments

Comments
 (0)