Disallow login from TOR exit nodes

pull/339/head^2
Thibault Duplessis 2015-02-28 15:16:39 +01:00
parent 6b33a117a3
commit 5d8607a3eb
5 changed files with 62 additions and 11 deletions

View File

@ -37,13 +37,24 @@ object Auth extends LilaController {
session + ("sessionId" -> sessionId) - api.AccessUri
}
}
} recoverWith {
case lila.security.Api.AuthFromTorExitNode => negotiate(
html = Unauthorized(html.auth.tor()).fuccess,
api = _ => Unauthorized(Json.obj(
"error" -> "Can't login from TOR exit node"
)).fuccess
)
}
)
}
def login = Open { implicit ctx =>
val referrer = get("referrer")
Ok(html.auth.login(api.loginForm, referrer)).fuccess
if (Env.security.tor isExitNode ctx.req.remoteAddress)
Unauthorized(html.auth.tor()).fuccess
else {
val referrer = get("referrer")
Ok(html.auth.login(api.loginForm, referrer)).fuccess
}
}
def authenticate = OpenBody { implicit ctx =>
@ -54,7 +65,7 @@ object Auth extends LilaController {
html = Unauthorized(html.auth.login(err, get("referrer"))).fuccess,
api = _ => Unauthorized(err.errorsAsJson).fuccess
),
_.fold(InternalServerError("authenticate error").fuccess)(authenticateUser)
_.fold(InternalServerError("Authentication error").fuccess)(authenticateUser)
)
}
}
@ -69,8 +80,12 @@ object Auth extends LilaController {
}
def signup = Open { implicit ctx =>
forms.signup.websiteWithCaptcha map {
case (form, captcha) => Ok(html.auth.signup(form, captcha))
if (Env.security.tor isExitNode ctx.req.remoteAddress)
Unauthorized(html.auth.tor()).fuccess
else {
forms.signup.websiteWithCaptcha map {
case (form, captcha) => Ok(html.auth.signup(form, captcha))
}
}
}
@ -86,7 +101,15 @@ object Auth extends LilaController {
res(user) map {
_ withCookies LilaCookie.session("sessionId", sessionId)
}
} recoverWith {
case lila.security.Api.AuthFromTorExitNode => negotiate(
html = Unauthorized(html.auth.tor()).fuccess,
api = _ => Unauthorized(Json.obj(
"error" -> "Can't register from TOR exit node"
)).fuccess
)
}
}
}

View File

@ -0,0 +1,20 @@
@()(implicit ctx: Context)
@auth.layout(
title = "TOR exit node",
zen = true) {
<div class="content_box small_box signup">
<div class="signup_box">
<h1 class="lichess_title text" data-icon="2">Cannot login from your IP</h1>
<p>
We have detected that you are using TOR to remain anonymous on the Internet.
<br />
<br />
It's a great idea, and we'll make sure you stay Anonymous on lichess as well.
<br />
<br />
As an Anonymous user, you can play, train, and use all lichess features. Enjoy!
</p>
</div>
</div>
}

File diff suppressed because one or more lines are too long

View File

@ -20,10 +20,13 @@ private[security] final class Api(firewall: Firewall, tor: Tor) {
)
def saveAuthentication(id: String, apiVersion: Option[Int])(implicit req: RequestHeader): Fu[String] = {
val sessionId = Random nextStringUppercase 12
Store.save(
sessionId, id, req, apiVersion, tor isExitNode req.remoteAddress
) inject sessionId
if (tor isExitNode req.remoteAddress) fufail(Api.AuthFromTorExitNode)
else {
val sessionId = Random nextStringUppercase 12
Store.save(
sessionId, id, req, apiVersion, tor isExitNode req.remoteAddress
) inject sessionId
}
}
// blocking function, required by Play2 form
@ -57,3 +60,8 @@ private[security] final class Api(firewall: Firewall, tor: Tor) {
}
}
}
object Api {
case object AuthFromTorExitNode extends Exception
}

View File

@ -13,5 +13,5 @@ final class Tor(providerUrl: String) {
}
}
private[security] def isExitNode(ip: String) = ips contains ip
def isExitNode(ip: String) = ips contains ip
}