rate limit web/mobile user games pagination

ios-push-2
Thibault Duplessis 2016-08-31 20:36:34 +02:00
parent 91eb60bbd6
commit ae5110ad83
2 changed files with 29 additions and 10 deletions

View File

@ -2,12 +2,15 @@ package controllers
import play.api.libs.json._
import play.api.mvc._, Results._
import scala.concurrent.duration._
import lila.api.{ Context, BodyContext }
import lila.app._
import lila.app.mashup.GameFilterMenu
import lila.common.HTTPRequest
import lila.common.paginator.Paginator
import lila.evaluation.{ PlayerAggregateAssessment }
import lila.game.{ GameRepo, Pov }
import lila.game.{ GameRepo, Pov, Game => GameModel }
import lila.rating.PerfType
import lila.user.{ User => UserModel, UserRepo }
import views._
@ -118,19 +121,33 @@ object User extends LilaController {
searchForm = GameFilterMenu.searchForm(userGameSearch, filters.current)(ctx.body)
} yield html.user.show(u, info, pag, filters, searchForm, relation, notes, followable, blocked)
private def userGames(u: UserModel, filterOption: Option[String], page: Int)(implicit ctx: BodyContext[_]) = {
private val UserGamesRateLimitPerIP = new lila.memo.RateLimit(
credits = 500,
duration = 10 minutes,
name = "user games web/mobile per IP")
implicit val userGamesDefault =
ornicar.scalalib.Zero.instance[Fu[Paginator[GameModel]]](fuccess(Paginator.empty[GameModel]))
private def userGames(
u: UserModel,
filterOption: Option[String],
page: Int)(implicit ctx: BodyContext[_]): Fu[(String, Paginator[GameModel])] = {
import lila.app.mashup.GameFilter.{ All, Playing }
filterOption.fold({
Env.simul isHosting u.id map (_.fold(Playing, All).name)
})(fuccess) flatMap { filterName =>
GameFilterMenu.paginatorOf(
userGameSearch = userGameSearch,
user = u,
info = none,
filter = GameFilterMenu.currentOf(GameFilterMenu.all, filterName),
me = ctx.me,
page = page
)(ctx.body) map { filterName -> _ }
val ip = HTTPRequest lastRemoteAddress ctx.req
UserGamesRateLimitPerIP(ip, cost = page, msg = ip) {
GameFilterMenu.paginatorOf(
userGameSearch = userGameSearch,
user = u,
info = none,
filter = GameFilterMenu.currentOf(GameFilterMenu.all, filterName),
me = ctx.me,
page = page
)(ctx.body)
} map { filterName -> _ }
}
}

View File

@ -66,6 +66,8 @@ object Paginator {
maxPerPage: Int = 10): Fu[Paginator[A]] =
validate(adapter, currentPage, maxPerPage) | apply(adapter, 1, maxPerPage)
def empty[A]: Paginator[A] = new Paginator(0, 0, Nil, 0)
def validate[A](
adapter: AdapterLike[A],
currentPage: Int = 1,