180 lines
5.7 KiB
Scala
180 lines
5.7 KiB
Scala
package controllers
|
|
|
|
import play.api.mvc._, Results._
|
|
|
|
import lila.api.Context
|
|
import lila.app._
|
|
import lila.common.LilaCookie
|
|
import lila.common.PimpedJson._
|
|
import lila.security.Permission
|
|
import lila.user.{ User => UserModel, UserRepo }
|
|
import views._
|
|
|
|
object Account extends LilaController {
|
|
|
|
private def env = Env.user
|
|
private def relationEnv = Env.relation
|
|
private def forms = lila.user.DataForm
|
|
|
|
def profile = Auth { implicit ctx =>
|
|
me =>
|
|
Ok(html.account.profile(me, forms profileOf me)).fuccess
|
|
}
|
|
|
|
def profileApply = AuthBody { implicit ctx =>
|
|
me =>
|
|
implicit val req: Request[_] = ctx.body
|
|
FormFuResult(forms.profile) { err =>
|
|
fuccess(html.account.profile(me, err))
|
|
} { profile =>
|
|
UserRepo.setProfile(me.id, profile) inject Redirect(routes.User show me.username)
|
|
}
|
|
}
|
|
|
|
def info = Open { implicit ctx =>
|
|
negotiate(
|
|
html = notFound,
|
|
api = _ => ctx.me match {
|
|
case None => fuccess(unauthorizedApiResult)
|
|
case Some(me) =>
|
|
relationEnv.api.countFollowers(me.id) zip
|
|
relationEnv.api.countFollowing(me.id) zip
|
|
Env.pref.api.getPref(me) zip
|
|
lila.game.GameRepo.urgentGames(me) zip
|
|
Env.challenge.api.countInFor(me.id) map {
|
|
case ((((nbFollowers, nbFollowing), prefs), povs), nbChallenges) =>
|
|
Env.current.bus.publish(lila.user.User.Active(me), 'userActive)
|
|
Ok {
|
|
import play.api.libs.json._
|
|
import lila.pref.JsonView._
|
|
Env.user.jsonView(me) ++ Json.obj(
|
|
"prefs" -> prefs,
|
|
"nowPlaying" -> JsArray(povs take 20 map Env.api.lobbyApi.nowPlaying),
|
|
"nbFollowing" -> nbFollowing,
|
|
"nbFollowers" -> nbFollowers,
|
|
"kid" -> me.kid.option(true),
|
|
"troll" -> me.troll.option(true),
|
|
"nbChallenges" -> nbChallenges
|
|
).noNull
|
|
}
|
|
}
|
|
}
|
|
) map ensureSessionId(ctx.req)
|
|
}
|
|
|
|
def passwd = Auth { implicit ctx =>
|
|
me =>
|
|
Ok(html.account.passwd(me, forms.passwd)).fuccess
|
|
}
|
|
|
|
def passwdApply = AuthBody { implicit ctx =>
|
|
me =>
|
|
implicit val req = ctx.body
|
|
FormFuResult(forms.passwd) { err =>
|
|
fuccess(html.account.passwd(me, err))
|
|
} { data =>
|
|
for {
|
|
ok ← UserRepo.authenticateById(me.id, data.oldPasswd).map(_.isDefined)
|
|
_ ← ok ?? UserRepo.passwd(me.id, data.newPasswd1)
|
|
} yield {
|
|
val content = html.account.passwd(me, forms.passwd.fill(data), ok.some)
|
|
ok.fold(Ok(content), BadRequest(content))
|
|
}
|
|
}
|
|
}
|
|
|
|
private def emailForm(user: UserModel) = UserRepo email user.id map { email =>
|
|
Env.security.forms.changeEmail(user).fill(
|
|
lila.security.DataForm.ChangeEmail(~email, ""))
|
|
}
|
|
|
|
def email = Auth { implicit ctx =>
|
|
me =>
|
|
emailForm(me) map { form =>
|
|
Ok(html.account.email(me, form))
|
|
}
|
|
}
|
|
|
|
def emailApply = AuthBody { implicit ctx =>
|
|
me =>
|
|
UserRepo hasEmail me.id flatMap {
|
|
case true => notFound
|
|
case false =>
|
|
implicit val req = ctx.body
|
|
FormFuResult(Env.security.forms.changeEmail(me)) { err =>
|
|
fuccess(html.account.email(me, err))
|
|
} { data =>
|
|
val email = Env.security.emailAddress.validate(data.email) err s"Invalid email ${data.email}"
|
|
for {
|
|
ok ← UserRepo.authenticateById(me.id, data.passwd).map(_.isDefined)
|
|
_ ← ok ?? UserRepo.email(me.id, email)
|
|
form <- emailForm(me)
|
|
} yield {
|
|
val content = html.account.email(me, form, ok.some)
|
|
ok.fold(Ok(content), BadRequest(content))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
def close = Auth { implicit ctx =>
|
|
me =>
|
|
Ok(html.account.close(me, Env.security.forms.closeAccount)).fuccess
|
|
}
|
|
|
|
def closeConfirm = AuthBody { implicit ctx =>
|
|
me =>
|
|
implicit val req = ctx.body
|
|
FormFuResult(Env.security.forms.closeAccount) { err =>
|
|
fuccess(html.account.close(me, err))
|
|
} { password =>
|
|
UserRepo.authenticateById(me.id, password).map(_.isDefined) flatMap {
|
|
case false => BadRequest(html.account.close(me, Env.security.forms.closeAccount)).fuccess
|
|
case true => doClose(me) inject {
|
|
Redirect(routes.User show me.username) withCookies LilaCookie.newSession
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private[controllers] def doClose(user: UserModel) =
|
|
(UserRepo disable user) >>-
|
|
env.onlineUserIdMemo.remove(user.id) >>
|
|
relationEnv.api.unfollowAll(user.id) >>
|
|
Env.team.api.quitAll(user.id) >>-
|
|
Env.challenge.api.removeByUserId(user.id) >>-
|
|
Env.tournament.api.withdrawAll(user) >>
|
|
(Env.security disconnect user.id)
|
|
|
|
def kid = Auth { implicit ctx =>
|
|
me =>
|
|
Ok(html.account.kid(me)).fuccess
|
|
}
|
|
|
|
def kidConfirm = Auth { ctx =>
|
|
me =>
|
|
implicit val req = ctx.req
|
|
(UserRepo toggleKid me) inject Redirect(routes.Account.kid)
|
|
}
|
|
|
|
private def currentSessionId(implicit ctx: Context) =
|
|
~Env.security.api.reqSessionId(ctx.req)
|
|
|
|
def security = Auth { implicit ctx =>
|
|
me =>
|
|
Env.security.api.dedup(me.id, ctx.req) >>
|
|
Env.security.api.locatedOpenSessions(me.id, 50) map { sessions =>
|
|
Ok(html.account.security(me, sessions, currentSessionId))
|
|
}
|
|
}
|
|
|
|
def signout(sessionId: String) = Auth { implicit ctx =>
|
|
me =>
|
|
if (sessionId == "all")
|
|
lila.security.Store.closeUserExceptSessionId(me.id, currentSessionId) inject
|
|
Redirect(routes.Account.security)
|
|
else
|
|
lila.security.Store.closeUserAndSessionId(me.id, sessionId)
|
|
}
|
|
}
|