Skip to content

Commit

Permalink
Merge branch 'master' into paypal-api
Browse files Browse the repository at this point in the history
* master: (103 commits)
  New Crowdin updates (#10718)
  move challenge button back to relation/actions
  eslint
  ui/analyse: Fix 2nd slice param in uciToLastMove - after 9fadded
  remove PostView.topicLastPage in model.scala
  Update specs2-core to 4.15.0
  ui/chart/ratingHistory
  refactor ui/chart division & movetime
  bump actions/cache to v3
  rewrite ratingDistribution.js as ui/chart/src/ratingDistribution.ts
  rewrite chart JS as ui/chart TS - WIP
  upgrade ui deps
  don't read data.treeParts - closes #10658
  Improve the proportions of the flag of Latvia
  ui/analyse refactoring
  allow up to 128 user study topics
  always show swiss tournament creator - closes #10716
  Update team forum setting description
  Allow team forum to be seen by everyone again
  rename "if logged in" to "if registered" (also rename variables)
  ...
  • Loading branch information
ornicar committed Mar 29, 2022
2 parents 211875c + 83a87ca commit 6c972b4
Show file tree
Hide file tree
Showing 274 changed files with 3,142 additions and 2,481 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.sbt
Expand Down
17 changes: 1 addition & 16 deletions app/controllers/Coordinate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,7 @@ final class Coordinate(env: Env) extends LilaController(env) {
.bindFromRequest()
.fold(
_ => fuccess(BadRequest),
data => env.coordinate.api.addScore(me.id, data.isWhite, data.score) inject Ok(())
)
}

def color =
AuthBody { implicit ctx => me =>
implicit val req = ctx.body
env.coordinate.forms.color
.bindFromRequest()
.fold(
_ => fuccess(BadRequest),
value =>
env.pref.api.setPref(
me,
(p: lila.pref.Pref) => p.copy(coordColor = value)
) inject Ok(())
data => env.coordinate.api.addScore(me.id, data.mode, data.color, data.score) inject Ok(())
)
}
}
3 changes: 1 addition & 2 deletions app/controllers/Dev.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ final class Dev(env: Env) extends LilaController(env) {
env.prizeTournamentMakers,
env.pieceImageExternal,
env.evalCache.enable,
env.tournament.reloadEndpointSetting,
env.tournament.lilaHttpTourIdSetting
env.tournament.reloadEndpointSetting
)

def settings =
Expand Down
10 changes: 7 additions & 3 deletions app/controllers/ForumCateg.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,16 @@ final class ForumCateg(env: Env) extends LilaController(env) with ForumControlle
Open { implicit ctx =>
NotForKids {
Reasonable(page, 50, errorPage = notFound) {
OptionFuOk(categApi.show(slug, page, ctx.me)) { case (categ, topics) =>
OptionFuResult(categApi.show(slug, page, ctx.me)) { case (categ, topics) =>
for {
canWrite <- isGrantedWrite(categ.slug)
canRead <- access.isGrantedRead(categ.slug)
canWrite <- access.isGrantedWrite(categ.slug)
stickyPosts <- (page == 1) ?? env.forum.topicApi.getSticky(categ, ctx.me)
_ <- env.user.lightUserApi preloadMany topics.currentPageResults.flatMap(_.lastPostUserId)
} yield html.forum.categ.show(categ, topics, canWrite, stickyPosts)
res <-
if (canRead) Ok(html.forum.categ.show(categ, topics, canWrite, stickyPosts)).fuccess
else notFound
} yield res
}
}
}
Expand Down
22 changes: 8 additions & 14 deletions app/controllers/ForumController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,27 @@ import lila.api.Context
import lila.app._
import lila.forum

private[controllers] trait ForumController extends forum.Granter { self: LilaController =>

protected def categApi = env.forum.categApi
protected def topicApi = env.forum.topicApi
protected def postApi = env.forum.postApi
protected def forms = env.forum.forms
private[controllers] trait ForumController { self: LilaController =>

protected def categApi = env.forum.categApi
protected def topicApi = env.forum.topicApi
protected def postApi = env.forum.postApi
protected def forms = env.forum.forms
protected def access = env.api.forumAccess
protected def teamCache = env.team.cached

protected def userBelongsToTeam(teamId: String, userId: String): Fu[Boolean] =
env.team.api.belongsTo(teamId, userId)

protected def userOwnsTeam(teamId: String, userId: String): Fu[Boolean] =
env.team.api.leads(teamId, userId)

protected def CategGrantWrite[A <: Result](
categSlug: String
)(a: => Fu[A])(implicit ctx: Context): Fu[Result] =
isGrantedWrite(categSlug) flatMap { granted =>
access.isGrantedWrite(categSlug) flatMap { granted =>
if (granted) a
else fuccess(Forbidden("You cannot post to this category"))
}

protected def CategGrantMod[A <: Result](
categSlug: String
)(a: => Fu[A])(implicit ctx: Context): Fu[Result] =
isGrantedMod(categSlug) flatMap { granted =>
access.isGrantedMod(categSlug) flatMap { granted =>
if (granted | isGranted(_.ModerateForum)) a
else fuccess(Forbidden("You cannot post to this category"))
}
Expand Down
8 changes: 6 additions & 2 deletions app/controllers/ForumPost.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ final class ForumPost(env: Env) extends LilaController(env) with ForumController
OpenBody { implicit ctx =>
NotForKids {
if (text.trim.isEmpty) Redirect(routes.ForumCateg.index).fuccess
else env.forumSearch(text, page, ctx.troll) map { html.forum.search(text, _) }
else
for {
teamIds <- ctx.userId ?? env.team.cached.teamIdsSet
posts <- env.forumSearch(text, page, ctx.troll)
} yield html.forum.search(text, posts, teamIds)
}
}

Expand All @@ -38,7 +42,7 @@ final class ForumPost(env: Env) extends LilaController(env) with ForumController
for {
captcha <- forms.anyCaptcha
unsub <- env.timeline.status(s"forum:${topic.id}")(me.id)
canModCateg <- isGrantedMod(categ.slug)
canModCateg <- access.isGrantedMod(categ.slug)
} yield BadRequest(
html.forum.topic
.show(categ, topic, posts, Some(err -> captcha), unsub, canModCateg = canModCateg)
Expand Down
17 changes: 11 additions & 6 deletions app/controllers/ForumTopic.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,24 @@ final class ForumTopic(env: Env) extends LilaController(env) with ForumControlle
def show(categSlug: String, slug: String, page: Int) =
Open { implicit ctx =>
NotForKids {
OptionFuOk(topicApi.show(categSlug, slug, page, ctx.me)) { case (categ, topic, posts) =>
OptionFuResult(topicApi.show(categSlug, slug, page, ctx.me)) { case (categ, topic, posts) =>
for {
unsub <- ctx.userId ?? env.timeline.status(s"forum:${topic.id}")
canWrite <- isGrantedWrite(categSlug)
unsub <- ctx.userId ?? env.timeline.status(s"forum:${topic.id}")
canRead <- access.isGrantedRead(categ.slug)
canWrite <- access.isGrantedWrite(categ.slug)
canModCateg <- access.isGrantedMod(categ.slug)
inOwnTeam <- ~(categ.team, ctx.me).mapN { case (teamId, me) =>
env.team.cached.isLeader(teamId, me.id)
}
form <- ctx.me.ifTrue(
canWrite && topic.open && !topic.isOld
) ?? { me => forms.postWithCaptcha(me, inOwnTeam) map some }
canModCateg <- isGrantedMod(categ.slug)
_ <- env.user.lightUserApi preloadMany posts.currentPageResults.flatMap(_.userId)
} yield html.forum.topic.show(categ, topic, posts, form, unsub, canModCateg = canModCateg)
_ <- env.user.lightUserApi preloadMany posts.currentPageResults.flatMap(_.userId)
res <-
if (canRead)
Ok(html.forum.topic.show(categ, topic, posts, form, unsub, canModCateg = canModCateg)).fuccess
else notFound
} yield res
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions app/controllers/Game.scala
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ final class Game(
user = user,
format = format,
vs = vs,
since = getLong("since", req) map { new DateTime(_) },
until = getLong("until", req) map { new DateTime(_) },
since = getTimestamp("since", req),
until = getTimestamp("until", req),
max = getInt("max", req) map (_ atLeast 1),
rated = getBoolOpt("rated", req),
perfType = (~get("perfType", req) split "," flatMap { lila.rating.PerfType(_) }).toSet,
Expand All @@ -104,7 +104,7 @@ final class Game(
.as(gameContentType(config))
.fuccess
else {
val date = DateTimeFormat forPattern "yyyy-MM-dd" print new DateTime
val date = DateTimeFormat forPattern "yyyy-MM-dd" print DateTime.now
apiC
.GlobalConcurrencyLimitPerIpAndUserOption(req, me)(env.api.gameApiV2.exportByUser(config)) {
source =>
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/LilaController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ abstract private[controllers] class LilaController(val env: Env)
scoped: RequestHeader => Holder => Fu[Result]
): Action[Unit] =
Action.async(parse.empty) { req =>
if (HTTPRequest isOAuth req) SecuredScoped(perm)(scoped)(req)
if (HTTPRequest isOAuth req) SecureScoped(perm)(scoped)(req)
else Secure(parse.empty)(perm(Permission))(secure)(req)
}

Expand All @@ -280,7 +280,7 @@ abstract private[controllers] class LilaController(val env: Env)
else SecureBody(parse.anyContent)(perm(Permission))(secure)(req)
}

protected def SecuredScoped(perm: Permission.Selector)(
protected def SecureScoped(perm: Permission.Selector)(
f: RequestHeader => Holder => Fu[Result]
) =
Scoped() { req => me =>
Expand Down
29 changes: 25 additions & 4 deletions app/controllers/Mod.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package controllers
import ornicar.scalalib.Zero
import play.api.data._
import play.api.data.Forms._
import play.api.libs.json.Json
import play.api.mvc._
import scala.annotation.nowarn
import views._
Expand All @@ -23,7 +24,6 @@ final class Mod(
) extends LilaController(env) {

private def modApi = env.mod.api
private def modLogApi = env.mod.logApi
private def assessApi = env.mod.assessApi

implicit private def asMod(holder: Holder) = AsMod(holder.user)
Expand Down Expand Up @@ -567,11 +567,32 @@ final class Mod(
}
}

private def withSuspect[A](username: String)(f: Suspect => Fu[A])(implicit zero: Zero[A]): Fu[A] =
env.report.api getSuspect username flatMap {
_ ?? f
def apiUserLog(username: String) =
SecureScoped(_.ModLog) { implicit req => me =>
import lila.common.Json._
env.user.repo named username flatMap {
_ ?? { user =>
for {
logs <- env.mod.logApi.userHistory(user.id)
notes <- env.socialInfo.fetchNotes(user, me.user)
notesJson <- lila.user.JsonView.notes(notes)(env.user.lightUserApi)
} yield JsonOk(
Json.obj(
"logs" -> Json.arr(logs.map { log =>
Json
.obj("mod" -> log.mod, "action" -> log.action, "date" -> log.date)
.add("details", log.details)
}),
"notes" -> notesJson
)
)
}
}
}

private def withSuspect[A](username: String)(f: Suspect => Fu[A])(implicit zero: Zero[A]): Fu[A] =
env.report.api getSuspect username flatMap { _ ?? f }

private def OAuthMod[A](perm: Permission.Selector)(f: RequestHeader => Holder => Fu[Option[A]])(
secure: Context => Holder => A => Fu[Result]
): Action[Unit] =
Expand Down
4 changes: 4 additions & 0 deletions app/controllers/RequestGetter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import lila.common.Form.trueish
import lila.common.IsMobile

import play.api.mvc.RequestHeader
import org.joda.time.DateTime

trait RequestGetter {

Expand All @@ -25,6 +26,9 @@ trait RequestGetter {
protected def getLong(name: String, req: RequestHeader) =
get(name, req) flatMap (_.toLongOption)

protected def getTimestamp(name: String, req: RequestHeader) =
getLong(name, req) map { new DateTime(_) }

protected def getBool(name: String)(implicit ctx: UserContext) =
(getInt(name) exists trueish) || (get(name) exists trueish)

Expand Down
1 change: 1 addition & 0 deletions app/controllers/Team.scala
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ final class Team(
ctx: Context
): Boolean =
team.enabled && !team.isForumFor(_.NONE) && ctx.noKid && {
team.isForumFor(_.EVERYONE) ||
(team.isForumFor(_.LEADERS) && ctx.userId.exists(team.leaders)) ||
(team.isForumFor(_.MEMBERS) && isMember) ||
(isGranted(_.ModerateForum) && requestModView)
Expand Down
13 changes: 12 additions & 1 deletion app/controllers/User.scala
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ final class User(
}
}
private def renderShow(u: UserModel, status: Results.Status = Results.Ok)(implicit ctx: Context) =
if (HTTPRequest.isSynchronousHttp(ctx.req)) {
if (HTTPRequest isSynchronousHttp ctx.req) {
for {
as <- env.activity.read.recent(u)
nbs <- env.userNbGames(u, ctx, withCrosstable = false)
Expand Down Expand Up @@ -476,6 +476,17 @@ final class User(
)(ctx.body)
}

def apiReadNote(username: String) =
Scoped() { implicit req => me =>
env.user.repo named username flatMap {
_ ?? {
env.socialInfo.fetchNotes(_, me) flatMap {
lila.user.JsonView.notes(_)(env.user.lightUserApi)
} map JsonOk
}
}
}

def apiWriteNote(username: String) =
ScopedBody() { implicit req => me =>
doWriteNote(username, me)(
Expand Down
9 changes: 7 additions & 2 deletions app/mashup/UserInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import lila.relation.RelationApi
import lila.security.Granter
import lila.ublog.{ UblogApi, UblogPost }
import lila.user.{ Trophies, TrophyApi, User }
import scala.concurrent.ExecutionContext

case class UserInfo(
user: User,
Expand Down Expand Up @@ -80,7 +81,11 @@ object UserInfo {
}

def fetchNotes(u: User, me: User) =
noteApi.get(u, me, Granter(_.ModNote)(me))
noteApi.get(u, me, Granter(_.ModNote)(me)) dmap {
_.filter { n =>
(!n.dox || Granter(_.Admin)(me))
}
}
}

case class NbGames(
Expand Down Expand Up @@ -130,7 +135,7 @@ object UserInfo {
coachApi: lila.coach.CoachApi,
insightShare: lila.insight.Share,
playbanApi: lila.playban.PlaybanApi
)(implicit ec: scala.concurrent.ExecutionContext) {
)(implicit ec: ExecutionContext) {
def apply(user: User, nbs: NbGames, ctx: Context): Fu[UserInfo] =
((ctx.noBlind && ctx.pref.showRatings) ?? ratingChartApi(user)).mon(_.user segment "ratingChart") zip
relationApi.countFollowers(user.id).mon(_.user segment "nbFollowers") zip
Expand Down
1 change: 0 additions & 1 deletion app/templating/Environment.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ object Environment
with AiHelper
with GameHelper
with UserHelper
with ForumHelper
with I18nHelper
with SecurityHelper
with TeamHelper
Expand Down
33 changes: 0 additions & 33 deletions app/templating/ForumHelper.scala

This file was deleted.

1 change: 1 addition & 0 deletions app/templating/SetupHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ trait SetupHelper { self: I18nHelper =>
trans.ifRatingIsPlusMinusX.txt(lila.pref.Pref.Challenge.ratingThreshold)
),
(Pref.Challenge.FRIEND, trans.onlyFriends.txt()),
(Pref.Challenge.REGISTERED, trans.ifRegistered.txt()),
(Pref.Challenge.ALWAYS, trans.always.txt())
)

Expand Down
Loading

0 comments on commit 6c972b4

Please sign in to comment.