Disallow login from TOR exit nodes
parent
6b33a117a3
commit
5d8607a3eb
|
@ -37,13 +37,24 @@ object Auth extends LilaController {
|
||||||
session + ("sessionId" -> sessionId) - api.AccessUri
|
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 =>
|
def login = Open { implicit ctx =>
|
||||||
val referrer = get("referrer")
|
if (Env.security.tor isExitNode ctx.req.remoteAddress)
|
||||||
Ok(html.auth.login(api.loginForm, referrer)).fuccess
|
Unauthorized(html.auth.tor()).fuccess
|
||||||
|
else {
|
||||||
|
val referrer = get("referrer")
|
||||||
|
Ok(html.auth.login(api.loginForm, referrer)).fuccess
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def authenticate = OpenBody { implicit ctx =>
|
def authenticate = OpenBody { implicit ctx =>
|
||||||
|
@ -54,7 +65,7 @@ object Auth extends LilaController {
|
||||||
html = Unauthorized(html.auth.login(err, get("referrer"))).fuccess,
|
html = Unauthorized(html.auth.login(err, get("referrer"))).fuccess,
|
||||||
api = _ => Unauthorized(err.errorsAsJson).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 =>
|
def signup = Open { implicit ctx =>
|
||||||
forms.signup.websiteWithCaptcha map {
|
if (Env.security.tor isExitNode ctx.req.remoteAddress)
|
||||||
case (form, captcha) => Ok(html.auth.signup(form, captcha))
|
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 {
|
res(user) map {
|
||||||
_ withCookies LilaCookie.session("sessionId", sessionId)
|
_ 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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
@ -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] = {
|
def saveAuthentication(id: String, apiVersion: Option[Int])(implicit req: RequestHeader): Fu[String] = {
|
||||||
val sessionId = Random nextStringUppercase 12
|
if (tor isExitNode req.remoteAddress) fufail(Api.AuthFromTorExitNode)
|
||||||
Store.save(
|
else {
|
||||||
sessionId, id, req, apiVersion, tor isExitNode req.remoteAddress
|
val sessionId = Random nextStringUppercase 12
|
||||||
) inject sessionId
|
Store.save(
|
||||||
|
sessionId, id, req, apiVersion, tor isExitNode req.remoteAddress
|
||||||
|
) inject sessionId
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// blocking function, required by Play2 form
|
// 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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue