finer comm control

pull/3585/head
Thibault Duplessis 2017-09-04 12:41:58 -05:00
parent 62fa63c44c
commit 8acab54537
8 changed files with 65 additions and 25 deletions

View File

@ -2,9 +2,9 @@ package controllers
import lila.api.Context
import lila.app._
import lila.chat.Chat
import lila.common.{ IpAddress, EmailAddress }
import lila.user.{ UserRepo, User => UserModel }
import lila.chat.Chat
import views._
import play.api.data._
@ -131,12 +131,18 @@ object Mod extends LilaController {
modLogApi.recent map { html.mod.log(_) }
}
def communication(username: String) = Secure(_.MarkTroll) { implicit ctx => me =>
private def communications(username: String, priv: Boolean) = Secure {
perms => if (priv) perms.ViewPrivateComms else perms.MarkTroll
} { implicit ctx => me =>
OptionFuOk(UserRepo named username) { user =>
lila.game.GameRepo.recentPovsByUserFromSecondary(user, 80) flatMap { povs =>
Env.chat.api.playerChat optionsByOrderedIds povs.map(_.gameId).map(Chat.Id.apply) zip
lila.message.ThreadRepo.visibleByUser(user.id, 60).map {
_ filter (_ hasPostsWrittenBy user.id) take 30
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
}
} zip
(Env.shutup.api getPublicLines user.id) zip
(Env.security userSpy user.id) zip
@ -144,17 +150,20 @@ object Mod extends LilaController {
Env.mod.logApi.userHistory(user.id) zip
Env.report.api.inquiries.ofModId(me.id) map {
case chats ~ threads ~ publicLines ~ spy ~ notes ~ history ~ inquiry =>
Env.slack.api.commlog(mod = me, user = user, inquiry.map(_.createdBy))
if (priv) Env.slack.api.commlog(mod = me, user = user, inquiry.map(_.createdBy))
val povWithChats = (povs zip chats) collect {
case (p, Some(c)) if c.nonEmpty => p -> c
} take 15
val filteredNotes = notes.filter(_.from != "irwin")
html.mod.communication(user, povWithChats, threads, publicLines, spy, filteredNotes, history)
html.mod.communication(user, povWithChats, threads, publicLines, spy, filteredNotes, history, priv)
}
}
}
}
def communicationPublic(username: String) = communications(username, false)
def communicationPrivate(username: String) = communications(username, true)
private[controllers] val ipIntelCache =
Env.memo.asyncCache.multi[IpAddress, Int](
name = "ipIntel",

View File

@ -33,7 +33,7 @@ object Report extends LilaController {
api.inquiries.toggle(me, id) map {
_.fold(Redirect(routes.Report.list)) { report =>
Redirect(report.room match {
case lila.report.Room.Coms => routes.Mod.communication(report.user).url
case lila.report.Room.Coms => routes.Mod.communicationPublic(report.user).url
case _ => routes.User.show(report.user).url + "?mod"
})
}

View File

@ -1,4 +1,4 @@
@(u: User, players: List[(Pov, lila.chat.MixedChat)], threads: List[lila.message.Thread], publicLines: List[String], spy: lila.security.UserSpy, notes: List[lila.user.Note], history: List[lila.mod.Modlog])(implicit ctx: Context)
@(u: User, players: List[(Pov, lila.chat.MixedChat)], threads: List[lila.message.Thread], publicLines: List[String], spy: lila.security.UserSpy, notes: List[lila.user.Note], history: List[lila.mod.Modlog], priv: Boolean)(implicit ctx: Context)
@moreCss = {
@cssTag("mod-communication.css")
@ -17,18 +17,29 @@ side = side.some) {
<div id="communication" class="content_box">
<h1>
<form style="float:right" method="post" action="@routes.Mod.troll(u.username)?set=1&then=reports">
<input class="button@when(u.troll, " active")" type="submit" value="Shadowban" />
</form>
@defining("Warning: Offensive language") { subject =>
<form style="float:right" method="post" action="@routes.Mod.warn(u.username, subject)">
<input class="button" type="submit" value="Warn" title='Sends the "@subject" message'/>
</form>
}
<form style="float:right" method="post" action="@routes.Mod.troll(u.username)?set=0&then=reports">
<input class="button@when(!u.troll, " active")" type="submit" value="OK" />
</form>
@userLink(u) communications
<div class="title">
@userLink(u) communications
</div>
<div class="actions">
@if(isGranted(_.ViewPrivateComms)) {
@if(priv) {
<a class="priv button active" href="@routes.Mod.communicationPublic(u.username)">PMs</a>
} else {
<a class="priv button" href="@routes.Mod.communicationPrivate(u.username)" title="View private messages. This will be logged in #commlog">PMs</a>
}
}
<form method="post" action="@routes.Mod.troll(u.username)?set=1&then=reports">
<input class="button@when(u.troll, " active")" type="submit" value="Shadowban" />
</form>
@defining("Warning: Offensive language") { subject =>
<form method="post" action="@routes.Mod.warn(u.username, subject)">
<input class="button" type="submit" value="Warn" title='Sends the "@subject" message'/>
</form>
}
<form method="post" action="@routes.Mod.troll(u.username)?set=0&then=reports">
<input class="button@when(!u.troll, " active")" type="submit" value="OK" />
</form>
</div>
</h1>
<h2>Dubious public chats</h2>
@if(publicLines.isEmpty) {
@ -63,6 +74,7 @@ side = side.some) {
</div>
}
@if(priv) {
<h2>Recent private chats</h2>
<div class="player_chats">
@players.map {
@ -102,6 +114,7 @@ side = side.some) {
</div>
}
</div>
}
<div class="alternate_accounts">
<h2>Alternate accounts</h2>
@if(spy.otherUsers.size < 1) {

View File

@ -51,7 +51,7 @@
<div class="links">
<a href="@routes.User.games(in.user.id, "search")?players.b=@in.report.createdBy">View<br />Games</a>
@if(isGranted(_.MarkTroll)) {
<a href="@routes.Mod.communication(in.user.id)">View<br />Coms</a>
<a href="@routes.Mod.communicationPublic(in.user.id)">View<br />Comms</a>
}
</div>
<div class="actions">

View File

@ -14,7 +14,7 @@
<input class="button" type="submit" value="Evaluate" />
</form>
@if(isGranted(_.MarkTroll)) {
<a class="button hint--bottom" href="@routes.Mod.communication(u.id)" data-hint="View communications">Coms</a>
<a class="button hint--bottom" href="@routes.Mod.communicationPublic(u.id)" data-hint="View communications">Comms</a>
}
<form method="post" action="@routes.Mod.notifySlack(u.id)" data-hint="Notify slack #tavern" class="hint--bottom">
<input class="button" type="submit" value="Slack" />

View File

@ -354,7 +354,8 @@ POST /mod/:username/close controllers.Mod.closeAccount(username: St
POST /mod/:username/reopen controllers.Mod.reopenAccount(username: String)
POST /mod/:username/title controllers.Mod.setTitle(username: String)
POST /mod/:username/inquiry controllers.Mod.spontaneousInquiry(username: String)
GET /mod/:username/communication controllers.Mod.communication(username: String)
GET /mod/:username/communication controllers.Mod.communicationPublic(username: String)
GET /mod/:username/communication/private controllers.Mod.communicationPrivate(username: String)
POST /mod/:ip/ipban controllers.Mod.ipban(ip: String)
POST /mod/:username/kickFromRankings controllers.Mod.kickFromRankings(username: String)
POST /mod/:username/reportban controllers.Mod.reportban(username: String)

View File

@ -16,6 +16,7 @@ object Permission {
case object ChatTimeout extends Permission("ROLE_CHAT_TIMEOUT")
case object UserSpy extends Permission("ROLE_USER_SPY")
case object UserEvaluate extends Permission("ROLE_USER_EVALUATE")
case object ViewPrivateComms extends Permission("ROLE_VIEW_PRIVATE_COMS")
case object MarkTroll extends Permission("ROLE_CHAT_BAN", List(UserSpy, ChatTimeout))
case object MarkEngine extends Permission("ROLE_ADJUST_CHEATER", List(UserSpy))
case object MarkBooster extends Permission("ROLE_ADJUST_BOOSTER", List(UserSpy))
@ -53,7 +54,7 @@ object Permission {
))
case object Admin extends Permission("ROLE_ADMIN", List(
Hunter, ModerateForum, IpBan, CloseAccount, ReopenAccount,
Hunter, ModerateForum, IpBan, CloseAccount, ReopenAccount, ViewPrivateComms,
ChatTimeout, MarkTroll, SetTitle, SetEmail, ModerateQa, StreamConfig,
MessageAnyone, CloseTeam, TerminateTournament, ManageTournament, ManageEvent,
PreviewCoach, PracticeConfig, RemoveRanking, ReportBan, Beta

View File

@ -1,3 +1,19 @@
#communication h1 {
font-size: 1.5em;
display: flex;
justify-content: space-between;
}
#communication .user_link {
margin-left: -.5em;
}
#communication .actions {
display: flex;
align-items: center;
}
#communication .actions .priv {
margin-right: 5px;
font-weight: normal;
}
#communication h2 {
font-size: 1.6em;
margin-top: 1.6em;