From e5535f447a1840c360ba2bca775208522e592cdd Mon Sep 17 00:00:00 2001 From: ProgramFOX Date: Thu, 6 Jul 2017 00:15:46 +0200 Subject: [PATCH 1/3] Implement reportban Shadowbanned people can now still report Reportbanned people can not report, but they can use the other communications. --- app/controllers/Mod.scala | 4 ++++ app/views/user/mod.scala.html | 5 +++++ conf/routes | 1 + modules/mod/src/main/ModApi.scala | 10 ++++++++++ modules/mod/src/main/Modlog.scala | 4 ++++ modules/mod/src/main/ModlogApi.scala | 4 ++++ modules/report/src/main/ReportApi.scala | 2 +- modules/security/src/main/Permission.scala | 5 +++-- modules/user/src/main/User.scala | 10 +++++++--- modules/user/src/main/UserRepo.scala | 2 ++ 10 files changed, 41 insertions(+), 6 deletions(-) diff --git a/app/controllers/Mod.scala b/app/controllers/Mod.scala index 45f2b0d7a4..f7475d6aac 100644 --- a/app/controllers/Mod.scala +++ b/app/controllers/Mod.scala @@ -81,6 +81,10 @@ object Mod extends LilaController { modApi.kickFromRankings(me.id, username) inject redirect(username) } + def reportban(username: String) = Secure(_.ReportBan) { implicit ctx => me => + modApi.toggleReportban(me.id, username) inject redirect(username) + } + def setTitle(username: String) = SecureBody(_.SetTitle) { implicit ctx => me => implicit def req = ctx.body lila.user.DataForm.title.bindFromRequest.fold( diff --git a/app/views/user/mod.scala.html b/app/views/user/mod.scala.html index 59d628f1e3..21be551827 100644 --- a/app/views/user/mod.scala.html +++ b/app/views/user/mod.scala.html @@ -59,6 +59,11 @@ } + @if(isGranted(_.ReportBan)) { +
+ +
+ } @if(isGranted(_.SetTitle)) {

diff --git a/conf/routes b/conf/routes index 55124f09e8..83b469f429 100644 --- a/conf/routes +++ b/conf/routes @@ -356,6 +356,7 @@ POST /mod/:username/inquiry controllers.Mod.spontaneousInquiry(userna GET /mod/:username/communication controllers.Mod.communication(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) GET /mod/log controllers.Mod.log POST /mod/:username/refreshUserAssess controllers.Mod.refreshUserAssess(username: String) POST /mod/:username/email controllers.Mod.setEmail(username: String) diff --git a/modules/mod/src/main/ModApi.scala b/modules/mod/src/main/ModApi.scala index 0bd88e72e6..8039b1a765 100644 --- a/modules/mod/src/main/ModApi.scala +++ b/modules/mod/src/main/ModApi.scala @@ -124,6 +124,16 @@ final class ModApi( logApi.kickFromRankings(mod, user.id) } + def toggleReportban(mod: String, username: String): Funit = withUser(username) { user => + setReportban(mod, username, !user.reportban) + } + + def setReportban(mod: String, username: String, v: Boolean): Funit = withUser(username) { user => + (user.reportban != v) ?? { + UserRepo.setReportban(user.id, v) >>- logApi.reportban(mod, user.id, v) + } + } + private def withUser[A](username: String)(op: User => Fu[A]): Fu[A] = UserRepo named username flatten "[mod] missing user " + username flatMap op diff --git a/modules/mod/src/main/Modlog.scala b/modules/mod/src/main/Modlog.scala index 0f4657ccc2..069da0f34c 100644 --- a/modules/mod/src/main/Modlog.scala +++ b/modules/mod/src/main/Modlog.scala @@ -40,6 +40,8 @@ case class Modlog( case Modlog.untroll => "un-shadowban" case Modlog.permissions => "set permissions" case Modlog.kickFromRankings => "kick from rankings" + case Modlog.reportban => "reportban" + case Modlog.unreportban => "un-reportban" case Modlog.modMessage => "send message" case a => a } @@ -78,5 +80,7 @@ object Modlog { val terminateTournament = "terminateTournament " val chatTimeout = "chatTimeout " val kickFromRankings = "kickFromRankings" + val reportban = "reportban" + val unreportban = "unreportban" val modMessage = "modMessage" } diff --git a/modules/mod/src/main/ModlogApi.scala b/modules/mod/src/main/ModlogApi.scala index cc6de2f6a0..b5b9a3eef0 100644 --- a/modules/mod/src/main/ModlogApi.scala +++ b/modules/mod/src/main/ModlogApi.scala @@ -103,6 +103,10 @@ final class ModlogApi(coll: Coll) { Modlog(mod, user.some, Modlog.kickFromRankings) } + def reportban(mod: String, user: String, v: Boolean) = add { + Modlog(mod, user.some, v.fold(Modlog.reportban, Modlog.unreportban)) + } + def modMessage(mod: String, user: String, subject: String) = add { Modlog(mod, user.some, Modlog.modMessage, details = subject.some) } diff --git a/modules/report/src/main/ReportApi.scala b/modules/report/src/main/ReportApi.scala index 79d1bbf0ea..e4771e547c 100644 --- a/modules/report/src/main/ReportApi.scala +++ b/modules/report/src/main/ReportApi.scala @@ -31,7 +31,7 @@ final class ReportApi( createdBy = by ), setup.user, by) - def create(report: Report, reported: User, by: User): Funit = !by.troll ?? { + def create(report: Report, reported: User, by: User): Funit = !by.reportban ?? { !isAlreadySlain(report, reported) ?? { lila.mon.mod.report.create(report.reason.key)() diff --git a/modules/security/src/main/Permission.scala b/modules/security/src/main/Permission.scala index a61fae8b57..1883cb1d52 100644 --- a/modules/security/src/main/Permission.scala +++ b/modules/security/src/main/Permission.scala @@ -43,6 +43,7 @@ object Permission { case object PreviewCoach extends Permission("ROLE_PREVIEW_COACH") case object ModNote extends Permission("ROLE_MOD_NOTE") case object RemoveRanking extends Permission("ROLE_REMOVE_RANKING") + case object ReportBan extends Permission("ROLE_REPORT_BAN") case object ModMessage extends Permission("ROLE_MOD_MESSAGE") case object Hunter extends Permission("ROLE_HUNTER", List( @@ -55,7 +56,7 @@ object Permission { Hunter, ModerateForum, IpBan, CloseAccount, ReopenAccount, ChatTimeout, MarkTroll, SetTitle, SetEmail, ModerateQa, StreamConfig, MessageAnyone, CloseTeam, TerminateTournament, ManageTournament, ManageEvent, - PreviewCoach, PracticeConfig, RemoveRanking + PreviewCoach, PracticeConfig, RemoveRanking, ReportBan )) case object SuperAdmin extends Permission("ROLE_SUPER_ADMIN", List( @@ -66,7 +67,7 @@ object Permission { Admin, Hunter, MarkTroll, ChatTimeout, ChangePermission, ViewBlurs, StaffForum, ModerateForum, UserSpy, MarkEngine, MarkBooster, IpBan, ModerateQa, StreamConfig, PracticeConfig, Beta, MessageAnyone, UserSearch, CloseTeam, TerminateTournament, ManageTournament, ManageEvent, - PublicMod, Developer, Coach, PreviewCoach, GuineaPig, ModNote + PublicMod, Developer, Coach, PreviewCoach, GuineaPig, ModNote, RemoveRanking, ReportBan ) lazy private val all: List[Permission] = SuperAdmin :: allButSuperAdmin diff --git a/modules/user/src/main/User.scala b/modules/user/src/main/User.scala index 4265913772..b8a7da0600 100644 --- a/modules/user/src/main/User.scala +++ b/modules/user/src/main/User.scala @@ -26,7 +26,8 @@ case class User( seenAt: Option[DateTime], kid: Boolean, lang: Option[String], - plan: Plan + plan: Plan, + reportban: Boolean = false ) extends Ordered[User] { override def equals(other: Any) = other match { @@ -188,6 +189,7 @@ object User { val prevEmail = "prevEmail" val colorIt = "colorIt" val plan = "plan" + val reportban = "reportban" } import lila.db.BSON @@ -221,7 +223,8 @@ object User { kid = r boolD kid, lang = r strO lang, title = r strO title, - plan = r.getO[Plan](plan) | Plan.empty + plan = r.getO[Plan](plan) | Plan.empty, + reportban = r boolD reportban ) def writes(w: BSON.Writer, o: User) = BSONDocument( @@ -243,7 +246,8 @@ object User { kid -> w.boolO(o.kid), lang -> o.lang, title -> o.title, - plan -> o.plan.nonEmpty + plan -> o.plan.nonEmpty, + reportban -> w.boolO(o.reportban) ) } } diff --git a/modules/user/src/main/UserRepo.scala b/modules/user/src/main/UserRepo.scala index 49c833674d..c4b749a28b 100644 --- a/modules/user/src/main/UserRepo.scala +++ b/modules/user/src/main/UserRepo.scala @@ -303,6 +303,8 @@ object UserRepo { def setBooster(id: ID, v: Boolean): Funit = coll.updateField($id(id), "booster", v).void + def setReportban(id: ID, v: Boolean): Funit = coll.updateField($id(id), "reportban", v).void + def toggleIpBan(id: ID) = coll.fetchUpdate[User]($id(id)) { u => $set("ipBan" -> !u.ipBan) } def toggleKid(user: User) = coll.updateField($id(user.id), "kid", !user.kid) From 7a01846d293910da7a9b0af3a3fd3acefa8a49e7 Mon Sep 17 00:00:00 2001 From: ProgramFOX Date: Thu, 6 Jul 2017 00:24:33 +0200 Subject: [PATCH 2/3] Add styling for second row of mod action buttons The new 'Reportban' button would automatically be on a second row in the mod actions view, but that's not sufficient for two reasons: a) tooltips break, b) it looks better with a bit of margin between the two rows I also explicitly added the 'Kick from rankings' button to this second row. Normally, it would fit on the first row, but when the "IP Ban" button text is too long, it would go on a second row, and the same problems would occur as described above. This commit resolves those layout problems. --- app/views/user/mod.scala.html | 2 ++ public/stylesheets/user-mod.css | 3 +++ 2 files changed, 5 insertions(+) diff --git a/app/views/user/mod.scala.html b/app/views/user/mod.scala.html index 21be551827..0817fa1ea5 100644 --- a/app/views/user/mod.scala.html +++ b/app/views/user/mod.scala.html @@ -54,6 +54,7 @@ } } +
@if(isGranted(_.RemoveRanking)) {
@@ -64,6 +65,7 @@
} +
@if(isGranted(_.SetTitle)) {

diff --git a/public/stylesheets/user-mod.css b/public/stylesheets/user-mod.css index fe126c927f..1554c3e27d 100644 --- a/public/stylesheets/user-mod.css +++ b/public/stylesheets/user-mod.css @@ -16,6 +16,9 @@ border: 0; vertical-align: top; } +.mod_zone .second_mod_button_row { + margin-top: 5px; +} .mod_zone .neural, .mod_zone .mod_roles { padding: 10px 0; From 33eceb195989a4426d87e3b7431d7d5d590f4c38 Mon Sep 17 00:00:00 2001 From: ProgramFOX Date: Thu, 6 Jul 2017 00:30:25 +0200 Subject: [PATCH 3/3] Show Reportban icon in mod table for related users I chose the "!" icon, consistent with the icon next to "Reports sent by" and "Reports concerning". --- app/views/user/mod.scala.html | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/user/mod.scala.html b/app/views/user/mod.scala.html index 0817fa1ea5..2de74edd40 100644 --- a/app/views/user/mod.scala.html +++ b/app/views/user/mod.scala.html @@ -282,6 +282,7 @@ @if(o.engine){} @if(o.ipBan){} @if(o.disabled){} + @if(o.reportban){} @momentFromNow(o.createdAt) @o.seenAt.map(momentFromNow)