2013-05-06 08:51:19 -06:00
|
|
|
package controllers
|
|
|
|
|
2018-08-20 14:59:56 -06:00
|
|
|
import lila.api.{ Context, BodyContext }
|
2013-05-06 08:51:19 -06:00
|
|
|
import lila.app._
|
2017-09-04 11:41:58 -06:00
|
|
|
import lila.chat.Chat
|
2018-11-04 15:18:10 -07:00
|
|
|
import lila.common.{ IpAddress, EmailAddress, HTTPRequest }
|
2018-02-03 07:30:41 -07:00
|
|
|
import lila.report.{ Suspect, Mod => AsMod, SuspectId }
|
2018-08-20 14:59:56 -06:00
|
|
|
import lila.security.Permission
|
2018-11-13 14:35:37 -07:00
|
|
|
import lila.user.{ UserRepo, User => UserModel, Title }
|
2019-03-20 21:21:47 -06:00
|
|
|
import lila.mod.UserSearch
|
2018-08-20 14:59:56 -06:00
|
|
|
import ornicar.scalalib.Zero
|
2014-02-26 17:18:09 -07:00
|
|
|
import views._
|
2013-05-06 08:51:19 -06:00
|
|
|
|
2017-06-23 04:49:07 -06:00
|
|
|
import play.api.data._
|
|
|
|
import play.api.data.Forms._
|
2013-05-06 08:51:19 -06:00
|
|
|
import play.api.mvc._
|
2017-03-30 04:18:00 -06:00
|
|
|
import scala.concurrent.duration._
|
2013-05-06 08:51:19 -06:00
|
|
|
|
|
|
|
object Mod extends LilaController {
|
|
|
|
|
2013-05-06 10:41:02 -06:00
|
|
|
private def modApi = Env.mod.api
|
|
|
|
private def modLogApi = Env.mod.logApi
|
2015-01-15 04:15:28 -07:00
|
|
|
private def assessApi = Env.mod.assessApi
|
2013-05-06 08:51:19 -06:00
|
|
|
|
2018-08-20 14:59:56 -06:00
|
|
|
def engine(username: String, v: Boolean) = OAuthModBody(_.MarkEngine) { me =>
|
2017-09-11 15:14:36 -06:00
|
|
|
withSuspect(username) { sus =>
|
2017-09-11 23:46:21 -06:00
|
|
|
for {
|
|
|
|
inquiry <- Env.report.api.inquiries ofModId me.id
|
|
|
|
_ <- modApi.setEngine(AsMod(me), sus, v)
|
2018-08-20 14:59:56 -06:00
|
|
|
} yield (inquiry, sus).some
|
2017-09-11 15:14:36 -06:00
|
|
|
}
|
2018-08-20 14:59:56 -06:00
|
|
|
}(ctx => me => {
|
|
|
|
case (inquiry, suspect) => Report.onInquiryClose(inquiry, me, suspect.some)(ctx)
|
|
|
|
})
|
2013-05-10 03:56:34 -06:00
|
|
|
|
2016-10-17 04:01:00 -06:00
|
|
|
def publicChat = Secure(_.ChatTimeout) { implicit ctx => _ =>
|
2017-10-28 14:29:25 -06:00
|
|
|
Env.mod.publicChat.all map {
|
2016-10-17 04:01:00 -06:00
|
|
|
case (tournamentsAndChats, simulsAndChats) =>
|
|
|
|
Ok(html.mod.publicChat(tournamentsAndChats, simulsAndChats))
|
|
|
|
}
|
2016-09-04 07:34:35 -06:00
|
|
|
}
|
|
|
|
|
2018-08-20 14:59:56 -06:00
|
|
|
def booster(username: String, v: Boolean) = OAuthModBody(_.MarkBooster) { me =>
|
2018-03-16 17:18:09 -06:00
|
|
|
withSuspect(username) { prev =>
|
|
|
|
for {
|
|
|
|
inquiry <- Env.report.api.inquiries ofModId me.id
|
|
|
|
suspect <- modApi.setBooster(AsMod(me), prev, v)
|
2018-08-20 14:59:56 -06:00
|
|
|
} yield (inquiry, suspect).some
|
2018-03-16 16:45:54 -06:00
|
|
|
}
|
2018-08-20 14:59:56 -06:00
|
|
|
}(ctx => me => {
|
|
|
|
case (inquiry, suspect) => Report.onInquiryClose(inquiry, me, suspect.some)(ctx)
|
|
|
|
})
|
2015-02-13 07:14:39 -07:00
|
|
|
|
2019-01-19 17:24:36 -07:00
|
|
|
def troll(username: String, v: Boolean) = OAuthModBody(_.Shadowban) { me =>
|
2017-09-11 15:14:36 -06:00
|
|
|
withSuspect(username) { prev =>
|
|
|
|
for {
|
|
|
|
inquiry <- Env.report.api.inquiries ofModId me.id
|
2017-10-28 13:50:20 -06:00
|
|
|
suspect <- modApi.setTroll(AsMod(me), prev, v)
|
2018-08-20 14:59:56 -06:00
|
|
|
} yield (inquiry, suspect).some
|
2016-10-17 04:01:00 -06:00
|
|
|
}
|
2018-08-20 14:59:56 -06:00
|
|
|
}(ctx => me => {
|
|
|
|
case (inquiry, suspect) => Report.onInquiryClose(inquiry, me, suspect.some)(ctx)
|
|
|
|
})
|
2016-10-17 04:01:00 -06:00
|
|
|
|
2018-08-20 14:59:56 -06:00
|
|
|
def warn(username: String, subject: String) = OAuthModBody(_.ModMessage) { me =>
|
|
|
|
lila.message.ModPreset.bySubject(subject) ?? { preset =>
|
2017-10-28 13:50:20 -06:00
|
|
|
withSuspect(username) { prev =>
|
2017-09-11 15:14:36 -06:00
|
|
|
for {
|
|
|
|
inquiry <- Env.report.api.inquiries ofModId me.id
|
2017-10-28 13:50:20 -06:00
|
|
|
suspect <- modApi.setTroll(AsMod(me), prev, prev.user.troll)
|
|
|
|
thread <- Env.message.api.sendPreset(me, suspect.user, preset)
|
2017-09-11 15:14:36 -06:00
|
|
|
_ <- Env.mod.logApi.modMessage(thread.creatorId, thread.invitedId, thread.name)
|
2018-08-20 14:59:56 -06:00
|
|
|
} yield (inquiry, suspect).some
|
2017-03-30 10:21:52 -06:00
|
|
|
}
|
|
|
|
}
|
2018-08-20 14:59:56 -06:00
|
|
|
}(ctx => me => {
|
|
|
|
case (inquiry, suspect) => Report.onInquiryClose(inquiry, me, suspect.some)(ctx)
|
|
|
|
})
|
2017-03-30 10:21:52 -06:00
|
|
|
|
2018-08-20 14:59:56 -06:00
|
|
|
def ban(username: String, v: Boolean) = OAuthMod(_.IpBan) { _ => me =>
|
2017-09-11 15:14:36 -06:00
|
|
|
withSuspect(username) { sus =>
|
2018-08-20 14:59:56 -06:00
|
|
|
modApi.setBan(AsMod(me), sus, v) map some
|
2018-03-16 16:45:54 -06:00
|
|
|
}
|
2018-11-04 15:18:10 -07:00
|
|
|
}(actionResult(username))
|
2013-05-10 03:56:34 -06:00
|
|
|
|
2019-01-19 17:24:36 -07:00
|
|
|
def deletePmsAndChats(username: String) = OAuthMod(_.Shadowban) { _ => me =>
|
2017-10-31 10:13:37 -06:00
|
|
|
withSuspect(username) { sus =>
|
|
|
|
Env.mod.publicChat.delete(sus) >>
|
2018-08-20 14:59:56 -06:00
|
|
|
Env.message.api.deleteThreadsBy(sus.user) map some
|
2018-03-16 16:45:54 -06:00
|
|
|
}
|
2018-11-04 15:18:10 -07:00
|
|
|
}(actionResult(username))
|
2017-10-28 14:29:25 -06:00
|
|
|
|
2018-05-06 04:03:28 -06:00
|
|
|
def disableTwoFactor(username: String) = Secure(_.DisableTwoFactor) { implicit ctx => me =>
|
|
|
|
modApi.disableTwoFactor(me.id, username) >> User.modZoneOrRedirect(username, me)
|
|
|
|
}
|
|
|
|
|
2018-08-20 14:59:56 -06:00
|
|
|
def closeAccount(username: String) = OAuthMod(_.CloseAccount) { _ => me =>
|
2018-03-16 15:49:57 -06:00
|
|
|
modApi.closeAccount(me.id, username).flatMap {
|
2018-03-16 16:45:54 -06:00
|
|
|
_.?? { user =>
|
2018-08-20 14:59:56 -06:00
|
|
|
Env.current.closeAccount(user.id, self = false) map some
|
|
|
|
}
|
2018-03-16 16:45:54 -06:00
|
|
|
}
|
2018-11-04 15:18:10 -07:00
|
|
|
}(actionResult(username))
|
2013-05-06 08:51:19 -06:00
|
|
|
|
2018-08-20 14:59:56 -06:00
|
|
|
def reopenAccount(username: String) = OAuthMod(_.ReopenAccount) { _ => me =>
|
|
|
|
modApi.reopenAccount(me.id, username) map some
|
2018-11-04 15:18:10 -07:00
|
|
|
}(actionResult(username))
|
2014-02-01 06:13:22 -07:00
|
|
|
|
2018-08-20 14:59:56 -06:00
|
|
|
def reportban(username: String, v: Boolean) = OAuthMod(_.ReportBan) { _ => me =>
|
2017-09-11 15:14:36 -06:00
|
|
|
withSuspect(username) { sus =>
|
2018-08-20 14:59:56 -06:00
|
|
|
modApi.setReportban(AsMod(me), sus, v) map some
|
2018-03-16 16:45:54 -06:00
|
|
|
}
|
2018-11-04 15:18:10 -07:00
|
|
|
}(actionResult(username))
|
2017-07-05 16:15:46 -06:00
|
|
|
|
2018-08-20 14:59:56 -06:00
|
|
|
def rankban(username: String, v: Boolean) = OAuthMod(_.RemoveRanking) { _ => me =>
|
2018-01-30 10:27:32 -07:00
|
|
|
withSuspect(username) { sus =>
|
2018-08-20 14:59:56 -06:00
|
|
|
modApi.setRankban(AsMod(me), sus, v) map some
|
2018-03-16 16:45:54 -06:00
|
|
|
}
|
2018-11-04 15:18:10 -07:00
|
|
|
}(actionResult(username))
|
2018-01-30 10:27:32 -07:00
|
|
|
|
2017-08-03 04:43:29 -06:00
|
|
|
def impersonate(username: String) = Auth { implicit ctx => me =>
|
|
|
|
if (username == "-" && lila.mod.Impersonate.isImpersonated(me)) fuccess {
|
|
|
|
lila.mod.Impersonate.stop(me)
|
|
|
|
Redirect(routes.User.show(me.username))
|
|
|
|
}
|
|
|
|
else if (isGranted(_.Impersonate)) OptionFuRedirect(UserRepo named username) { user =>
|
|
|
|
lila.mod.Impersonate.start(me, user)
|
|
|
|
fuccess(routes.User.show(user.username))
|
|
|
|
}
|
|
|
|
else notFound
|
|
|
|
}
|
|
|
|
|
2016-10-17 04:01:00 -06:00
|
|
|
def setTitle(username: String) = SecureBody(_.SetTitle) { implicit ctx => me =>
|
|
|
|
implicit def req = ctx.body
|
|
|
|
lila.user.DataForm.title.bindFromRequest.fold(
|
|
|
|
err => fuccess(redirect(username, mod = true)),
|
2018-11-13 14:35:37 -07:00
|
|
|
title => modApi.setTitle(me.id, username, title map Title.apply) >>
|
2017-12-20 07:18:00 -07:00
|
|
|
Env.security.automaticEmail.onTitleSet(username) >>-
|
2016-10-17 04:01:00 -06:00
|
|
|
Env.user.uncacheLightUser(UserModel normalize username) inject
|
|
|
|
redirect(username, mod = false)
|
|
|
|
)
|
2013-09-11 04:38:16 -06:00
|
|
|
}
|
|
|
|
|
2016-10-17 04:01:00 -06:00
|
|
|
def setEmail(username: String) = SecureBody(_.SetEmail) { implicit ctx => me =>
|
|
|
|
implicit def req = ctx.body
|
|
|
|
OptionFuResult(UserRepo named username) { user =>
|
|
|
|
Env.security.forms.modEmail(user).bindFromRequest.fold(
|
|
|
|
err => BadRequest(err.toString).fuccess,
|
|
|
|
rawEmail => {
|
2017-04-14 04:23:23 -06:00
|
|
|
val email = Env.security.emailAddressValidator.validate(EmailAddress(rawEmail)) err s"Invalid email ${rawEmail}"
|
2019-02-19 04:09:44 -07:00
|
|
|
modApi.setEmail(me.id, user.id, email.acceptable) inject redirect(user.username, mod = true)
|
2016-10-17 04:01:00 -06:00
|
|
|
}
|
2016-06-20 10:44:30 -06:00
|
|
|
)
|
2016-10-17 04:01:00 -06:00
|
|
|
}
|
2014-02-26 17:18:09 -07:00
|
|
|
}
|
|
|
|
|
2018-08-20 14:59:56 -06:00
|
|
|
def notifySlack(username: String) = OAuthMod(_.ModNote) { _ => me =>
|
|
|
|
withSuspect(username) { sus =>
|
|
|
|
Env.slack.api.userMod(user = sus.user, mod = me) map some
|
2018-03-16 16:45:54 -06:00
|
|
|
}
|
2018-11-04 15:18:10 -07:00
|
|
|
}(actionResult(username))
|
2015-08-12 05:17:16 -06:00
|
|
|
|
2018-04-05 07:44:44 -06:00
|
|
|
def log = Secure(_.ModLog) { implicit ctx => me =>
|
2016-10-19 08:55:32 -06:00
|
|
|
modLogApi.recent map { html.mod.log(_) }
|
2013-05-10 03:56:34 -06:00
|
|
|
}
|
2014-01-16 01:46:01 -07:00
|
|
|
|
2017-09-04 11:41:58 -06:00
|
|
|
private def communications(username: String, priv: Boolean) = Secure {
|
2019-01-19 17:24:36 -07:00
|
|
|
perms => if (priv) perms.ViewPrivateComms else perms.Shadowban
|
2017-09-04 11:41:58 -06:00
|
|
|
} { implicit ctx => me =>
|
2016-10-17 04:01:00 -06:00
|
|
|
OptionFuOk(UserRepo named username) { user =>
|
2017-03-30 04:18:00 -06:00
|
|
|
lila.game.GameRepo.recentPovsByUserFromSecondary(user, 80) flatMap { povs =>
|
2017-09-04 11:41:58 -06:00
|
|
|
priv.?? {
|
|
|
|
Env.chat.api.playerChat optionsByOrderedIds povs.map(_.gameId).map(Chat.Id.apply)
|
|
|
|
} zip
|
|
|
|
priv.?? {
|
|
|
|
lila.message.ThreadRepo.visibleByUser(user.id, 60).map {
|
|
|
|
_ filter (_ hasPostsWrittenBy user.id) take 30
|
|
|
|
}
|
2017-03-30 04:18:00 -06:00
|
|
|
} zip
|
|
|
|
(Env.shutup.api getPublicLines user.id) zip
|
2017-11-10 09:28:17 -07:00
|
|
|
(Env.security userSpy user) zip
|
2017-03-30 10:01:38 -06:00
|
|
|
Env.user.noteApi.forMod(user.id) zip
|
2017-09-03 16:31:16 -06:00
|
|
|
Env.mod.logApi.userHistory(user.id) zip
|
|
|
|
Env.report.api.inquiries.ofModId(me.id) map {
|
|
|
|
case chats ~ threads ~ publicLines ~ spy ~ notes ~ history ~ inquiry =>
|
2017-09-11 23:46:34 -06:00
|
|
|
if (priv && !inquiry.??(_.isRecentCommOf(Suspect(user))))
|
2017-11-30 22:22:12 -07:00
|
|
|
Env.slack.api.commlog(mod = me, user = user, inquiry.map(_.oldestAtom.by.value))
|
2017-03-30 04:18:00 -06:00
|
|
|
val povWithChats = (povs zip chats) collect {
|
|
|
|
case (p, Some(c)) if c.nonEmpty => p -> c
|
2017-08-29 21:30:14 -06:00
|
|
|
} take 15
|
2017-03-30 10:01:38 -06:00
|
|
|
val filteredNotes = notes.filter(_.from != "irwin")
|
2017-09-04 11:41:58 -06:00
|
|
|
html.mod.communication(user, povWithChats, threads, publicLines, spy, filteredNotes, history, priv)
|
2014-05-22 13:01:54 -06:00
|
|
|
}
|
2017-03-30 04:18:00 -06:00
|
|
|
}
|
2016-10-17 04:01:00 -06:00
|
|
|
}
|
2014-05-22 13:01:54 -06:00
|
|
|
}
|
|
|
|
|
2017-09-04 11:41:58 -06:00
|
|
|
def communicationPublic(username: String) = communications(username, false)
|
|
|
|
def communicationPrivate(username: String) = communications(username, true)
|
|
|
|
|
2016-10-17 04:01:00 -06:00
|
|
|
def ipIntel(ip: String) = Secure(_.IpBan) { ctx => me =>
|
2017-11-10 09:28:17 -07:00
|
|
|
Env.security.ipIntel.failable(IpAddress(ip)).map { Ok(_) }.recover {
|
2016-10-17 04:01:00 -06:00
|
|
|
case e: Exception => InternalServerError(e.getMessage)
|
|
|
|
}
|
2015-08-20 16:39:32 -06:00
|
|
|
}
|
|
|
|
|
2017-05-02 08:40:37 -06:00
|
|
|
protected[controllers] def redirect(username: String, mod: Boolean = true) =
|
2016-10-19 08:55:32 -06:00
|
|
|
Redirect(routes.User.show(username).url + mod.??("?mod"))
|
2015-01-13 03:44:12 -07:00
|
|
|
|
2016-10-19 08:55:32 -06:00
|
|
|
def refreshUserAssess(username: String) = Secure(_.MarkEngine) { implicit ctx => me =>
|
2018-08-22 08:55:07 -06:00
|
|
|
OptionFuResult(UserRepo named username) { user =>
|
|
|
|
assessApi.refreshAssessByUsername(username) >>
|
|
|
|
Env.irwin.api.requests.fromMod(Suspect(user), AsMod(me)) >>
|
2018-11-04 15:18:10 -07:00
|
|
|
User.renderModZoneActions(username)
|
2018-08-22 08:55:07 -06:00
|
|
|
}
|
2015-02-22 23:12:25 -07:00
|
|
|
}
|
2016-01-10 21:09:37 -07:00
|
|
|
|
2017-05-10 17:07:04 -06:00
|
|
|
def spontaneousInquiry(username: String) = Secure(_.SeeReport) { implicit ctx => me =>
|
|
|
|
OptionFuResult(UserRepo named username) { user =>
|
2017-10-28 13:50:20 -06:00
|
|
|
Env.report.api.inquiries.spontaneous(AsMod(me), Suspect(user)) inject redirect(user.username, true)
|
2017-05-10 17:07:04 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-17 04:01:00 -06:00
|
|
|
def gamify = Secure(_.SeeReport) { implicit ctx => me =>
|
|
|
|
Env.mod.gamify.leaderboards zip
|
|
|
|
Env.mod.gamify.history(orCompute = true) map {
|
|
|
|
case (leaderboards, history) => Ok(html.mod.gamify.index(leaderboards, history))
|
|
|
|
}
|
2016-01-10 22:18:26 -07:00
|
|
|
}
|
2016-10-17 04:01:00 -06:00
|
|
|
def gamifyPeriod(periodStr: String) = Secure(_.SeeReport) { implicit ctx => me =>
|
|
|
|
lila.mod.Gamify.Period(periodStr).fold(notFound) { period =>
|
|
|
|
Env.mod.gamify.leaderboards map { leaderboards =>
|
|
|
|
Ok(html.mod.gamify.period(leaderboards, period))
|
2016-01-10 21:09:37 -07:00
|
|
|
}
|
2016-10-17 04:01:00 -06:00
|
|
|
}
|
2016-01-10 21:09:37 -07:00
|
|
|
}
|
2016-01-11 20:16:20 -07:00
|
|
|
|
2019-03-20 20:32:20 -06:00
|
|
|
def search = SecureBody(_.UserSearch) { implicit ctx => me =>
|
|
|
|
implicit def req = ctx.body
|
2019-03-20 21:21:47 -06:00
|
|
|
val f = UserSearch.form
|
2019-03-20 20:32:20 -06:00
|
|
|
f.bindFromRequest.fold(
|
|
|
|
err => BadRequest(html.mod.search(err, Nil)).fuccess,
|
|
|
|
query => Env.mod.search(query) map { html.mod.search(f.fill(query), _) }
|
|
|
|
)
|
2016-01-11 20:16:20 -07:00
|
|
|
}
|
2016-06-10 18:13:57 -06:00
|
|
|
|
2019-03-20 21:21:47 -06:00
|
|
|
protected[controllers] def searchTerm(q: String)(implicit ctx: Context) = {
|
|
|
|
val query = UserSearch exact q
|
|
|
|
Env.mod.search(query) map { users => Ok(html.mod.search(UserSearch.form fill query, users)) }
|
|
|
|
}
|
2019-02-12 23:58:56 -07:00
|
|
|
|
2016-10-17 04:01:00 -06:00
|
|
|
def chatUser(username: String) = Secure(_.ChatTimeout) { implicit ctx => me =>
|
2017-01-25 04:33:04 -07:00
|
|
|
implicit val lightUser = Env.user.lightUserSync _
|
2016-10-17 04:01:00 -06:00
|
|
|
JsonOptionOk {
|
|
|
|
Env.chat.api.userChat userModInfo username map2 lila.chat.JsonView.userModInfo
|
|
|
|
}
|
2016-06-10 18:13:57 -06:00
|
|
|
}
|
2016-06-20 10:44:30 -06:00
|
|
|
|
2017-01-14 08:42:26 -07:00
|
|
|
def permissions(username: String) = Secure(_.ChangePermission) { implicit ctx => me =>
|
2016-10-17 04:01:00 -06:00
|
|
|
OptionOk(UserRepo named username) { user =>
|
2017-01-14 08:42:26 -07:00
|
|
|
html.mod.permissions(user)
|
2016-10-17 04:01:00 -06:00
|
|
|
}
|
2016-06-20 10:44:30 -06:00
|
|
|
}
|
|
|
|
|
2017-01-14 08:42:26 -07:00
|
|
|
def savePermissions(username: String) = SecureBody(_.ChangePermission) { implicit ctx => me =>
|
2016-10-17 04:01:00 -06:00
|
|
|
implicit def req = ctx.body
|
2017-01-14 08:58:24 -07:00
|
|
|
import lila.security.Permission
|
2016-10-17 04:01:00 -06:00
|
|
|
OptionFuResult(UserRepo named username) { user =>
|
|
|
|
Form(single(
|
2018-12-04 03:38:50 -07:00
|
|
|
"permissions" -> list(text.verifying { str =>
|
2017-01-14 08:58:24 -07:00
|
|
|
Permission.allButSuperAdmin.exists(_.name == str)
|
2016-10-17 04:01:00 -06:00
|
|
|
})
|
|
|
|
)).bindFromRequest.fold(
|
2017-01-14 08:42:26 -07:00
|
|
|
err => BadRequest(html.mod.permissions(user)).fuccess,
|
2016-10-17 04:01:00 -06:00
|
|
|
permissions =>
|
2017-12-20 07:18:00 -07:00
|
|
|
modApi.setPermissions(me.id, user.username, Permission(permissions)) >> {
|
2017-12-27 09:46:50 -07:00
|
|
|
(Permission(permissions) diff Permission(user.roles) contains Permission.Coach) ??
|
2017-12-20 07:18:00 -07:00
|
|
|
Env.security.automaticEmail.onBecomeCoach(user)
|
2018-04-11 17:34:14 -06:00
|
|
|
} >> {
|
|
|
|
Permission(permissions).exists(_ is Permission.SeeReport) ?? Env.plan.api.setLifetime(user)
|
2017-12-20 07:18:00 -07:00
|
|
|
} inject redirect(user.username, true)
|
2016-10-17 04:01:00 -06:00
|
|
|
)
|
|
|
|
}
|
2016-06-20 10:44:30 -06:00
|
|
|
}
|
2017-06-23 04:49:07 -06:00
|
|
|
|
|
|
|
def emailConfirm = SecureBody(_.SetEmail) { implicit ctx => me =>
|
2017-08-15 07:50:47 -06:00
|
|
|
get("q") match {
|
|
|
|
case None => Ok(html.mod.emailConfirm("", none, none)).fuccess
|
|
|
|
case Some(rawQuery) =>
|
2017-06-23 04:49:07 -06:00
|
|
|
val query = rawQuery.trim.split(' ').toList
|
|
|
|
val email = query.headOption.map(EmailAddress.apply) flatMap Env.security.emailAddressValidator.validate
|
|
|
|
val username = query lift 1
|
2019-03-20 20:32:20 -06:00
|
|
|
def tryWith(setEmail: EmailAddress, q: String): Fu[Option[Result]] =
|
2019-03-20 21:21:47 -06:00
|
|
|
Env.mod.search(UserSearch.exact(q)) flatMap {
|
2019-03-20 20:32:20 -06:00
|
|
|
case List(UserModel.WithEmails(user, _)) => (!user.everLoggedIn).?? {
|
|
|
|
lila.mon.user.register.modConfirmEmail()
|
|
|
|
modApi.setEmail(me.id, user.id, setEmail)
|
|
|
|
} >>
|
|
|
|
UserRepo.email(user.id) map { email =>
|
|
|
|
Ok(html.mod.emailConfirm("", user.some, email)).some
|
|
|
|
}
|
|
|
|
case _ => fuccess(none)
|
|
|
|
}
|
2017-06-23 04:49:07 -06:00
|
|
|
email.?? { em =>
|
2019-02-19 04:09:44 -07:00
|
|
|
tryWith(em.acceptable, em.acceptable.value) orElse {
|
|
|
|
username ?? { tryWith(em.acceptable, _) }
|
2017-06-23 04:49:07 -06:00
|
|
|
}
|
|
|
|
} getOrElse BadRequest(html.mod.emailConfirm(rawQuery, none, none)).fuccess
|
2017-08-15 07:50:47 -06:00
|
|
|
}
|
2017-06-23 04:49:07 -06:00
|
|
|
}
|
2017-09-11 15:14:36 -06:00
|
|
|
|
2019-01-19 17:24:36 -07:00
|
|
|
def chatPanic = Secure(_.Shadowban) { implicit ctx => me =>
|
2017-10-28 15:40:52 -06:00
|
|
|
Ok(html.mod.chatPanic(Env.chat.panic.get)).fuccess
|
|
|
|
}
|
|
|
|
|
2019-01-19 17:24:36 -07:00
|
|
|
def chatPanicPost = OAuthMod(_.Shadowban) { req => me =>
|
2018-08-20 14:59:56 -06:00
|
|
|
val v = getBool("v", req)
|
2017-10-28 15:58:24 -06:00
|
|
|
Env.chat.panic.set(v)
|
|
|
|
Env.slack.api.chatPanic(me, v)
|
2018-08-20 14:59:56 -06:00
|
|
|
fuccess(().some)
|
|
|
|
}(ctx => me => _ => Redirect(routes.Mod.chatPanic).fuccess)
|
2017-10-28 15:40:52 -06:00
|
|
|
|
2018-07-29 23:01:25 -06:00
|
|
|
def eventStream = OAuthSecure(_.Admin) { req => me =>
|
2019-01-21 20:16:32 -07:00
|
|
|
noProxyBuffer(Ok.chunked(Env.mod.stream.enumerator)).fuccess
|
2018-07-29 23:01:25 -06:00
|
|
|
}
|
|
|
|
|
2018-08-20 14:59:56 -06:00
|
|
|
private def withSuspect[A](username: String)(f: Suspect => Fu[A])(implicit zero: Zero[A]): Fu[A] =
|
2017-09-11 15:14:36 -06:00
|
|
|
Env.report.api getSuspect username flatMap {
|
2018-08-20 14:59:56 -06:00
|
|
|
_ ?? f
|
2017-09-11 15:14:36 -06:00
|
|
|
}
|
2018-08-20 14:59:56 -06:00
|
|
|
|
|
|
|
private def OAuthMod[A](perm: Permission.Selector)(f: RequestHeader => UserModel => Fu[Option[A]])(
|
|
|
|
secure: Context => UserModel => A => Fu[Result]
|
|
|
|
): Action[Unit] = SecureOrScoped(perm)(
|
|
|
|
secure = ctx => me => f(ctx.req)(me) flatMap { _ ?? secure(ctx)(me) },
|
|
|
|
scoped = req => me => f(req)(me) flatMap { res =>
|
|
|
|
res.isDefined ?? fuccess(jsonOkResult)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
private def OAuthModBody[A](perm: Permission.Selector)(f: UserModel => Fu[Option[A]])(
|
|
|
|
secure: BodyContext[_] => UserModel => A => Fu[Result]
|
|
|
|
): Action[AnyContent] = SecureOrScopedBody(perm)(
|
|
|
|
secure = ctx => me => f(me) flatMap { _ ?? secure(ctx)(me) },
|
|
|
|
scoped = _ => me => f(me) flatMap { res =>
|
|
|
|
res.isDefined ?? fuccess(jsonOkResult)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2018-11-04 15:18:10 -07:00
|
|
|
private def actionResult(username: String)(ctx: Context)(me: UserModel)(res: Any) =
|
|
|
|
if (HTTPRequest isSynchronousHttp ctx.req) fuccess(Mod.redirect(username))
|
|
|
|
else User.renderModZoneActions(username)(ctx)
|
2013-05-06 08:51:19 -06:00
|
|
|
}
|