Skip to content

Commit

Permalink
refactor controllers with LilaController.meOrFetch
Browse files Browse the repository at this point in the history
  • Loading branch information
ornicar committed Feb 25, 2024
1 parent 829a2da commit b1a26ba
Show file tree
Hide file tree
Showing 18 changed files with 101 additions and 133 deletions.
19 changes: 9 additions & 10 deletions app/controllers/Account.scala
Original file line number Diff line number Diff line change
Expand Up @@ -366,14 +366,13 @@ final class Account(
}

def data = Auth { _ ?=> me ?=>
val userId: UserId = getUserStr("user")
.map(_.id)
.filter(id => me.is(id) || isGranted(_.Impersonate)) | me.userId
env.user.repo byId userId orNotFound { user =>
if getBool("text") then
apiC.GlobalConcurrencyLimitUser(me)(env.api.personalDataExport(user)): source =>
Ok.chunked(source.map(_ + "\n"))
.pipe(asAttachmentStream(s"lichess_${user.username}.txt"))
else Ok.page(html.account.bits.data(user))
}
meOrFetch(getUserStr("user"))
.map:
_.filter(u => ctx.is(u) || isGrantedOpt(_.Impersonate))
.orNotFound: user =>
if getBool("text") then
apiC.GlobalConcurrencyLimitUser(me)(env.api.personalDataExport(user)): source =>
Ok.chunked(source.map(_ + "\n"))
.pipe(asAttachmentStream(s"lichess_${user.username}.txt"))
else Ok.page(html.account.bits.data(user))
}
26 changes: 10 additions & 16 deletions app/controllers/Api.scala
Original file line number Diff line number Diff line change
Expand Up @@ -207,16 +207,15 @@ final class Api(
}

def tournamentsByOwner(name: UserStr, status: List[Int]) = Anon:
(name.id != lila.user.User.lichessId) so env.user.repo.byId(name) orNotFound { user =>
Found(meOrFetch(name).map(_.filterNot(_ is lila.user.User.lichessId))): user =>
val nb = getInt("nb") | Int.MaxValue
jsonDownload:
env.tournament.api
.byOwnerStream(user, status flatMap lila.tournament.Status.apply, MaxPerSecond(20), nb)
.mapAsync(1)(env.tournament.apiJsonView.fullJson)
}

def swissGames(id: SwissId) = AnonOrScoped(): ctx ?=>
env.swiss.cache.swissCache byId id orNotFound { swiss =>
Found(env.swiss.cache.swissCache byId id): swiss =>
val config = GameApiV2.BySwissConfig(
swissId = swiss.id,
format = GameApiV2.Format byRequest req,
Expand All @@ -230,7 +229,6 @@ final class Api(
Ok.chunked(source)
.pipe(asAttachmentStream(filename))
.as(gameC gameContentType config)
}

private def gamesPerSecond(me: Option[lila.user.User]) = MaxPerSecond:
30 + me.isDefined.so(20) + me.exists(_.isVerified).so(40)
Expand Down Expand Up @@ -319,10 +317,9 @@ final class Api(
def activity(name: UserStr) = ApiRequest:
UserActivityRateLimitPerIP(req.ipAddress, fuccess(ApiResult.Limited), cost = 1):
lila.mon.api.activity.increment(1)
env.user.repo byId name flatMapz { user =>
env.activity.read.recentAndPreload(user) flatMap {
_.map { env.activity.jsonView(_, user) }.parallel
}
meOrFetch(name).flatMapz { user =>
env.activity.read.recentAndPreload(user) flatMap:
_.traverse(env.activity.jsonView(_, user))
} map toApiResult

private val ApiMoveStreamGlobalConcurrencyLimitPerIP =
Expand All @@ -334,13 +331,10 @@ final class Api(
)

def moveStream(gameId: GameId) = Anon:
env.round.proxyRepo.game(gameId).map {
case None => NotFound
case Some(game) =>
ApiMoveStreamGlobalConcurrencyLimitPerIP(req.ipAddress)(
ndJson.addKeepAlive(env.round.apiMoveStream(game, gameC.delayMovesFromReq))
)(jsOptToNdJson)
}
Found(env.round.proxyRepo.game(gameId)): game =>
ApiMoveStreamGlobalConcurrencyLimitPerIP(req.ipAddress)(
ndJson.addKeepAlive(env.round.apiMoveStream(game, gameC.delayMovesFromReq))
)(jsOptToNdJson)

def perfStat(username: UserStr, perfKey: lila.rating.Perf.Key) = ApiRequest:
env.perfStat.api.data(username, perfKey) map:
Expand Down Expand Up @@ -400,7 +394,7 @@ final class Api(
name = "API concurrency per user",
key = "api.user",
ttl = 1.hour,
maxConcurrency = 1
maxConcurrency = 1 // #TODO allow more for app
)
private[controllers] def GlobalConcurrencyLimitPerUserOption[T](
user: Option[lila.user.User]
Expand Down
13 changes: 6 additions & 7 deletions app/controllers/Appeal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,9 @@ final class Appeal(env: Env, reportC: => report.Report, userC: => User) extends
private def asMod(
username: UserStr
)(f: (AppealModel, Suspect) => Fu[Result])(using Context): Fu[Result] =
env.user.repo byId username flatMapz { user =>
env.appeal.api byId user flatMapz { appeal =>
f(appeal, Suspect(user)) dmap some
}
} flatMap {
_.fold(notFound)(fuccess)
}
meOrFetch(username)
.flatMapz: user =>
env.appeal.api byId user flatMapz: appeal =>
f(appeal, Suspect(user)) dmap some
.flatMap:
_.so(fuccess)
10 changes: 4 additions & 6 deletions app/controllers/Auth.scala
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,10 @@ final class Auth(
.fold(
err => BadRequest.page(html.auth.checkYourEmail(userEmail.some, err.some)),
email =>
env.user.repo.byId(userEmail.username) flatMap {
env.user.repo.byId(userEmail.username) flatMap:
_.fold(Redirect(routes.Auth.signup).toFuccess): user =>
env.user.repo.mustConfirmEmail(user.id) flatMap {
case false => Redirect(routes.Auth.login)
case _ =>
env.user.repo.mustConfirmEmail(user.id) flatMap:
if _ then
val newUserEmail = userEmail.copy(email = email)
EmailConfirmRateLimit(newUserEmail, ctx.req, rateLimited):
lila.mon.email.send.fix.increment()
Expand All @@ -245,8 +244,7 @@ final class Auth(
Redirect(routes.Auth.checkYourEmail).withCookies:
lila.security.EmailConfirm.cookie
.make(env.lilaCookie, user, newUserEmail.email)(using ctx.req)
}
}
else Redirect(routes.Auth.login)
)
}

Expand Down
7 changes: 3 additions & 4 deletions app/controllers/Clas.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,9 @@ final class Clas(env: Env, authC: Auth) extends LilaController(env):
yield res

def teacher(username: UserStr) = Secure(_.Admin) { ctx ?=> _ ?=>
FoundPage(env.user.repo byId username): teacher =>
env.clas.api.clas.of(teacher) map {
FoundPage(meOrFetch(username)): teacher =>
env.clas.api.clas.of(teacher) map:
html.mod.search.teacher(teacher.id, _)
}
}

private def renderHome(using Context) =
Expand Down Expand Up @@ -527,7 +526,7 @@ final class Clas(env: Env, authC: Auth) extends LilaController(env):
private def WithStudent(clas: lila.clas.Clas, username: UserStr)(
f: lila.clas.Student.WithUser => Fu[Result]
)(using Context): Fu[Result] =
Found(env.user.repo byId username): user =>
Found(meOrFetch(username)): user =>
Found(env.clas.api.student.get(clas, user))(f)

private def SafeTeacher(f: => Fu[Result])(using Context): Fu[Result] =
Expand Down
16 changes: 6 additions & 10 deletions app/controllers/Game.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ final class Game(env: Env, apiC: => Api) extends LilaController(env):
def apiExportByUser(username: UserStr) = AnonOrScoped()(handleExport(username))

private def handleExport(username: UserStr)(using ctx: Context) =
env.user.repo byId username flatMap {
meOrFetch(username).flatMap:
_.filter(u => u.enabled.yes || ctx.is(u) || isGrantedOpt(_.GamesModView)) so { user =>
val format = GameApiV2.Format byRequest req
import lila.rating.{ Perf, PerfType }
Expand Down Expand Up @@ -103,7 +103,6 @@ final class Game(env: Env, apiC: => Api) extends LilaController(env):
.as(gameContentType(config))

}
}

private def fileDate = DateTimeFormatter ofPattern "yyyy-MM-dd" print nowInstant

Expand All @@ -129,14 +128,11 @@ final class Game(env: Env, apiC: => Api) extends LilaController(env):
.download(req.ipAddress)(env.api.gameApiV2.exportByIds(config)): source =>
noProxyBuffer(Ok.chunked(source)).as(gameContentType(config))

private def WithVs(f: Option[lila.user.User] => Fu[Result])(using RequestHeader): Fu[Result] =
getUserStr("vs") match
case None => f(none)
case Some(name) =>
env.user.repo byId name flatMap {
case None => notFoundJson(s"No such opponent: $name")
case Some(user) => f(user.some)
}
private def WithVs(f: Option[lila.user.User] => Fu[Result])(using Context): Fu[Result] =
getUserStr("vs").fold(f(none)): name =>
meOrFetch(name).flatMap:
_.fold[Fu[Result]](notFoundJson(s"No such opponent: $name")): user =>
f(user.some)

private[controllers] def requestPgnFlags(extended: Boolean)(using RequestHeader) =
lila.game.PgnDump.WithFlags(
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/GameMod.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ final class GameMod(env: Env)(using akka.stream.Materializer) extends LilaContro
import GameMod.*

def index(username: UserStr) = SecureBody(_.GamesModView) { ctx ?=> _ ?=>
Found(env.user.repo byId username): user =>
Found(meOrFetch(username)): user =>
val form = filterForm.bindFromRequest()
val filter = form.fold(_ => emptyFilter, identity)
for
Expand Down Expand Up @@ -46,7 +46,7 @@ final class GameMod(env: Env)(using akka.stream.Materializer) extends LilaContro
.map(_.toList)

def post(username: UserStr) = SecureBody(_.GamesModView) { ctx ?=> me ?=>
Found(env.user.repo byId username): user =>
Found(meOrFetch(username)): user =>
actionForm
.bindFromRequest()
.fold(
Expand Down
10 changes: 4 additions & 6 deletions app/controllers/Insight.scala
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,13 @@ final class Insight(env: Env) extends LilaController(env):
)

private def Accessible(username: UserStr)(f: User => Fu[Result])(using ctx: Context) =
Found(env.user.repo byId username): u =>
env.insight.share.grant(u) flatMap {
Found(meOrFetch(username)): u =>
env.insight.share.grant(u) flatMap:
if _ then f(u)
else Forbidden.page(html.insight.forbidden(u))
}

private def AccessibleApi(username: UserStr)(f: User => Fu[Result])(using Context) =
Found(env.user.repo byId username): u =>
env.insight.share.grant(u) flatMap {
Found(meOrFetch(username)): u =>
env.insight.share.grant(u) flatMap:
if _ then f(u)
else Forbidden
}
7 changes: 7 additions & 0 deletions app/controllers/LilaController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,13 @@ abstract private[controllers] class LilaController(val env: Env)
.flatMap:
f(using _)

def meOrFetch[U: UserIdOf](id: U)(using ctx: Context): Fu[Option[lila.user.User]] =
if id.isMe then fuccess(ctx.user)
else ctx.user.filter(_ is id).fold(env.user.repo byId id)(u => fuccess(u.some))

def meOrFetch[U: UserIdOf](id: Option[U])(using ctx: Context): Fu[Option[lila.user.User]] =
id.fold(fuccess(ctx.user))(meOrFetch)

given (using req: RequestHeader): lila.chat.AllMessages = lila.chat.AllMessages(HTTPRequest.isLitools(req))

/* We roll our own action, as we don't want to compose play Actions. */
Expand Down
9 changes: 3 additions & 6 deletions app/controllers/Mod.scala
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,8 @@ final class Mod(
}(actionResult(username))

def closeAccount(username: UserStr) = OAuthMod(_.CloseAccount) { _ ?=> me ?=>
env.user.repo byId username flatMapz { user =>
meOrFetch(username).flatMapz: user =>
env.api.accountClosure.close(user) map some
}
}(actionResult(username))

def reopenAccount(username: UserStr) = OAuthMod(_.CloseAccount) { _ ?=> me ?=>
Expand Down Expand Up @@ -137,7 +136,7 @@ final class Mod(
if username == UserName("-") && env.mod.impersonate.isImpersonated(me) then
env.mod.impersonate.stop(me)
Redirect(routes.User.show(me.username))
else if isGranted(_.Impersonate) || (isGranted(_.Admin) && username.id == lila.user.User.lichessId) then
else if isGranted(_.Impersonate) || (isGranted(_.Admin) && username.is(lila.user.User.lichessId)) then
Found(env.user.repo byId username): user =>
env.mod.impersonate.start(me, user)
Redirect(routes.User.show(user.username))
Expand Down Expand Up @@ -217,9 +216,7 @@ final class Mod(
}

private def communications(username: UserStr, priv: Boolean) =
Secure { perms =>
if priv then perms.ViewPrivateComms else perms.Shadowban
} { ctx ?=> me ?=>
Secure(perms => if priv then perms.ViewPrivateComms else perms.Shadowban) { ctx ?=> me ?=>
FoundPage(env.user.repo byId username): user =>
given lila.mod.IpRender.RenderIp = env.mod.ipRender.apply
env.game.gameRepo
Expand Down
3 changes: 1 addition & 2 deletions app/controllers/Puzzle.scala
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,7 @@ final class Puzzle(env: Env, apiC: => Api) extends LilaController(env):

private def DashboardPage(username: Option[UserStr])(f: Context ?=> User => Fu[Result]) =
Auth { ctx ?=> me ?=>
username
.so(env.user.repo.byId)
meOrFetch(username)
.flatMapz: user =>
(fuccess(isGranted(_.CheatHunter)) >>|
user.enabled.yes.so(env.clas.api.clas.isTeacherOf(me, user.id))) map {
Expand Down
8 changes: 3 additions & 5 deletions app/controllers/Relation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -87,22 +87,20 @@ final class Relation(env: Env, apiC: => Api) extends LilaController(env):

def following(username: UserStr, page: Int) = Open:
Reasonable(page, config.Max(20)):
Found(env.user.repo byId username): user =>
RelatedPager(api.followingPaginatorAdapter(user.id), page) flatMap { pag =>
Found(meOrFetch(username)): user =>
RelatedPager(api.followingPaginatorAdapter(user.id), page) flatMap: pag =>
negotiate(
if ctx.is(user) || isGrantedOpt(_.CloseAccount)
then Ok.page(html.relation.bits.friends(user, pag))
else Found(ctx.me)(me => Redirect(routes.Relation.following(me.username))),
Ok(jsonRelatedPaginator(pag))
)
}

def followers(username: UserStr, page: Int) = Open:
negotiateJson:
Reasonable(page, config.Max(20)):
RelatedPager(api.followersPaginatorAdapter(username.id), page) flatMap { pag =>
RelatedPager(api.followersPaginatorAdapter(username.id), page) flatMap: pag =>
Ok(jsonRelatedPaginator(pag))
}

def apiFollowing = Scoped(_.Follow.Read, _.Web.Mobile) { ctx ?=> me ?=>
apiC.jsonDownload:
Expand Down
7 changes: 2 additions & 5 deletions app/controllers/Simul.scala
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,10 @@ final class Simul(env: Env) extends LilaController(env):

def byUser(username: UserStr, page: Int) = Open:
Reasonable(page):
val userOption =
env.user.repo.byId(username).map { _.filter(_.enabled.yes || isGrantedOpt(_.SeeReport)) }
Found(userOption): user =>
Found(meOrFetch(username).map(_.filter(_.enabled.yes || isGrantedOpt(_.SeeReport)))): user =>
Ok.pageAsync:
env.simul.api.hostedByUser(user.id, page).map {
env.simul.api.hostedByUser(user.id, page) map:
html.simul.hosted(user, _)
}

private def AsHost(simulId: SimulId)(f: Sim => Fu[Result])(using ctx: Context): Fu[Result] =
Found(env.simul.repo.find(simulId)): simul =>
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/Study.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ final class Study(
def byOwnerDefault(username: UserStr, page: Int) = byOwner(username, Order.default, page)

def byOwner(username: UserStr, order: Order, page: Int) = Open:
Found(env.user.repo.byId(username)): owner =>
Found(meOrFetch(username)): owner =>
env.study.pager.byOwner(owner, order, page) flatMap: pag =>
preloadMembers(pag) >> negotiate(
Ok.page(html.study.list.byOwner(pag, order, owner)),
Expand Down
Loading

0 comments on commit b1a26ba

Please sign in to comment.