rate limit lobby joins by IP, not socket UID
This commit is contained in:
parent
9d48c224c9
commit
0129c0e7db
|
@ -43,7 +43,7 @@ object Lobby extends LilaController {
|
|||
|
||||
def socket(apiVersion: Int) = SocketOption[JsValue] { implicit ctx =>
|
||||
get("sri") ?? { uid =>
|
||||
Env.lobby.socketHandler(uid = uid, user = ctx.me) map some
|
||||
Env.lobby.socketHandler(uid = uid, ip = ctx.req.remoteAddress, user = ctx.me) map some
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
package lila
|
||||
|
||||
package object common extends PackageObject with WithPlay
|
||||
package object common extends PackageObject with WithPlay
|
||||
|
|
|
@ -36,9 +36,9 @@ private[lobby] final class Socket(
|
|||
history.since(v).fold(resync(m))(_ foreach sendMessage(m))
|
||||
}
|
||||
|
||||
case Join(uid, user, blocks) =>
|
||||
case Join(uid, ip, user, blocks) =>
|
||||
val (enumerator, channel) = Concurrent.broadcast[JsValue]
|
||||
val member = Member(channel, user, blocks, uid)
|
||||
val member = Member(channel, user, blocks, uid, ip)
|
||||
addMember(uid, member)
|
||||
sender ! Connected(enumerator, member)
|
||||
|
||||
|
|
|
@ -27,27 +27,28 @@ private[lobby] final class SocketHandler(
|
|||
uid: String,
|
||||
member: Member): Handler.Controller = {
|
||||
case ("p", o) => o int "v" foreach { v => socket ! PingVersion(uid, v) }
|
||||
case ("join", o) => JoinRateLimit(uid) {
|
||||
case ("join", o) =>
|
||||
o str "d" foreach { id =>
|
||||
lobby ! BiteHook(id, uid, member.user)
|
||||
JoinRateLimit(member.ip, s"hook:$id") {
|
||||
lobby ! BiteHook(id, uid, member.user)
|
||||
}
|
||||
}
|
||||
}
|
||||
case ("cancel", o) => lobby ! CancelHook(uid)
|
||||
case ("joinSeek", o) => JoinRateLimit(uid) {
|
||||
for {
|
||||
case ("joinSeek", o) => for {
|
||||
id <- o str "d"
|
||||
user <- member.user
|
||||
} lobby ! BiteSeek(id, user)
|
||||
}
|
||||
} JoinRateLimit(member.ip, s"seek:$id") {
|
||||
lobby ! BiteSeek(id, user)
|
||||
}
|
||||
case ("cancelSeek", o) => for {
|
||||
id <- o str "d"
|
||||
user <- member.user
|
||||
} lobby ! CancelSeek(id, user)
|
||||
}
|
||||
|
||||
def apply(uid: String, user: Option[User]): Fu[JsSocketHandler] =
|
||||
def apply(uid: String, ip: String, user: Option[User]): Fu[JsSocketHandler] =
|
||||
(user ?? (u => blocking(u.id))) flatMap { blockedUserIds =>
|
||||
val join = Join(uid = uid, user = user, blocking = blockedUserIds)
|
||||
val join = Join(uid = uid, ip = ip, user = user, blocking = blockedUserIds)
|
||||
Handler(hub, socket, uid, join, user map (_.id)) {
|
||||
case Connected(enum, member) =>
|
||||
(controller(socket, uid, member), enum, member)
|
||||
|
|
|
@ -6,13 +6,13 @@ import lila.socket.SocketMember
|
|||
import lila.user.User
|
||||
|
||||
private[lobby] case class LobbyUser(
|
||||
id: String,
|
||||
username: String,
|
||||
troll: Boolean,
|
||||
engine: Boolean,
|
||||
booster: Boolean,
|
||||
ratingMap: Map[String, Int],
|
||||
blocking: Set[String]) {
|
||||
id: String,
|
||||
username: String,
|
||||
troll: Boolean,
|
||||
engine: Boolean,
|
||||
booster: Boolean,
|
||||
ratingMap: Map[String, Int],
|
||||
blocking: Set[String]) {
|
||||
def lame = engine || booster
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,8 @@ private[lobby] object LobbyUser {
|
|||
private[lobby] case class Member(
|
||||
channel: JsChannel,
|
||||
user: Option[LobbyUser],
|
||||
uid: String) extends SocketMember {
|
||||
uid: String,
|
||||
ip: String) extends SocketMember {
|
||||
|
||||
val userId = user map (_.id)
|
||||
val troll = user ?? (_.troll)
|
||||
|
@ -39,10 +40,11 @@ private[lobby] case class Member(
|
|||
|
||||
private[lobby] object Member {
|
||||
|
||||
def apply(channel: JsChannel, user: Option[User], blocking: Set[String], uid: String): Member = Member(
|
||||
def apply(channel: JsChannel, user: Option[User], blocking: Set[String], uid: String, ip: String): Member = Member(
|
||||
channel = channel,
|
||||
user = user map { LobbyUser.make(_, blocking) },
|
||||
uid = uid)
|
||||
uid = uid,
|
||||
ip = ip)
|
||||
}
|
||||
|
||||
private[lobby] case class HookMeta(hookId: Option[String] = None)
|
||||
|
@ -62,7 +64,7 @@ private[lobby] case class BiteHook(hookId: String, uid: String, user: Option[Lob
|
|||
private[lobby] case class BiteSeek(seekId: String, user: LobbyUser)
|
||||
private[lobby] case class JoinHook(uid: String, hook: Hook, game: Game, creatorColor: chess.Color)
|
||||
private[lobby] case class JoinSeek(userId: String, seek: Seek, game: Game, creatorColor: chess.Color)
|
||||
private[lobby] case class Join(uid: String, user: Option[User], blocking: Set[String])
|
||||
private[lobby] case class Join(uid: String, ip: String, user: Option[User], blocking: Set[String])
|
||||
private[lobby] case object Resync
|
||||
private[lobby] case class HookIds(ids: List[String])
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ final class RateLimit(nb: Int, duration: Duration, name: String) {
|
|||
|
||||
logger.info(s"[start] $name ($nb/$duration)")
|
||||
|
||||
def apply[A](key: String)(op: => A)(implicit default: Zero[A]): A =
|
||||
def apply[A](key: String, msg: => String = "")(op: => A)(implicit default: Zero[A]): A =
|
||||
Option(storage getIfPresent key) match {
|
||||
case None =>
|
||||
storage.put(key, 1 -> makeClearAt)
|
||||
|
@ -31,7 +31,7 @@ final class RateLimit(nb: Int, duration: Duration, name: String) {
|
|||
storage.put(key, 1 -> makeClearAt)
|
||||
op
|
||||
case _ =>
|
||||
logger.info(s"$name ($nb/$duration) $key")
|
||||
logger.info(s"$name ($nb/$duration) $msg $key")
|
||||
default.zero
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,5 +3,5 @@ package lila
|
|||
import play.api.libs.iteratee._
|
||||
import play.api.libs.json._
|
||||
|
||||
package object socket
|
||||
extends PackageObject with WithPlay with socket.WithSocket
|
||||
package object socket
|
||||
extends PackageObject with WithPlay with socket.WithSocket
|
||||
|
|
Loading…
Reference in a new issue