mirror of
https://github.com/lichess-org/lila.git
synced 2026-05-26 13:51:00 +00:00
refine AccountInfo/UserModView permissions
This commit is contained in:
@@ -104,7 +104,7 @@ final class Clas(env: Env, authC: Auth) extends LilaController(env):
|
||||
)
|
||||
yield Ok(page),
|
||||
orDefault = _ =>
|
||||
isGranted(_.UserModView).so(FoundPage(env.clas.api.clas.byId(id)): clas =>
|
||||
isGranted(_.AccountInfo).so(FoundPage(env.clas.api.clas.byId(id)): clas =>
|
||||
env.clas.api.student.allWithUsers(clas).flatMap { students =>
|
||||
env.user.api.withPerfsAndEmails(students.map(_.user)).map {
|
||||
views.mod.search.clas(clas, _)
|
||||
|
||||
@@ -163,9 +163,9 @@ final class User(
|
||||
.redirect(username.value)
|
||||
.flatMap:
|
||||
case Some(url) => Redirect(url).toFuccess
|
||||
case None if isGrantedOpt(_.UserModView) => ctx.useMe(modC.searchTerm(username.value))
|
||||
case None if isGrantedOpt(_.AccountInfo) => ctx.useMe(modC.searchTerm(username.value))
|
||||
case None => notFound(true)
|
||||
case Some(u) if u.enabled.yes || isGrantedOpt(_.UserModView) => f(u)
|
||||
case Some(u) if u.enabled.yes || isGrantedOpt(_.AccountInfo) => f(u)
|
||||
case u => notFound(u.isEmpty)
|
||||
|
||||
def showMini(username: UserStr) = Open:
|
||||
@@ -173,7 +173,7 @@ final class User(
|
||||
ctx.userId
|
||||
.so(relationApi.fetchRelation(_, user.id))
|
||||
.flatMap: relation =>
|
||||
if user.enabled.yes || isGrantedOpt(_.UserModView)
|
||||
if user.enabled.yes || isGrantedOpt(_.AccountInfo)
|
||||
then
|
||||
(
|
||||
ctx.userId.so(relationApi.fetchBlocks(user.id, _)),
|
||||
@@ -415,7 +415,8 @@ final class User(
|
||||
.preloadMany(as.games.flatMap(_.userIds))
|
||||
.inject(ui.assessments(user, as))
|
||||
|
||||
val oauthTokens = env.oAuth.tokenApi.modRelevantTokens(user.id).map(views.user.mod.oauthTokens)
|
||||
val oauthTokens = isGranted(_.AccountInfo).so:
|
||||
env.oAuth.tokenApi.modRelevantTokens(user.id).map(views.user.mod.oauthTokens)
|
||||
|
||||
val teacher = isGranted(_.AccountInfo).so:
|
||||
env.clas.api.clas.countOf(user).map(ui.teacher(user))
|
||||
|
||||
@@ -22,7 +22,7 @@ def communication(
|
||||
.js(isGranted(_.UserModView).option(Esm("mod.user"))):
|
||||
main(id := "communication", cls := "box box-pad")(
|
||||
commUi.commsHeader(u, priv),
|
||||
isGranted(_.UserModView).option:
|
||||
isGranted(_.AccountInfo).option:
|
||||
frag(
|
||||
div(cls := "mod-zone mod-zone-full none"),
|
||||
views.user.mod.otherUsers(u, logins, appeals)(cls := "mod-zone communication__logins")
|
||||
|
||||
@@ -144,9 +144,9 @@ object header:
|
||||
case _ =>
|
||||
val profile = u.profileOrDefault
|
||||
val hideTroll = u.marks.troll && ctx.isnt(u)
|
||||
val showProfile = ctx.kid.no && u.kid.no && !hideTroll || isGranted(_.UserModView)
|
||||
val showProfile = ctx.kid.no && u.kid.no && !hideTroll || isGranted(_.AccountInfo)
|
||||
div(id := "us_profile")(
|
||||
if info.ratingChart.isDefined && (!u.lame || ctx.is(u) || isGranted(_.UserModView)) then
|
||||
if info.ratingChart.isDefined && (!u.lame || ctx.is(u) || isGranted(_.AccountInfo)) then
|
||||
views.user.perfStat.ratingHistoryContainer
|
||||
else (ctx.is(u) && u.count.game < 10).option(ui.newPlayer(u)),
|
||||
div(cls := "profile-side")(
|
||||
@@ -162,7 +162,7 @@ object header:
|
||||
.map(strong(cls := List("name" -> true, "muted" -> hideTroll))(_)),
|
||||
info.publicFideId.map: id =>
|
||||
p(a(href := routes.Fide.show(id, u.username.value))("FIDE player #" + id)),
|
||||
(showLinks && showProfile || isGranted(_.UserModView))
|
||||
(showLinks && showProfile || isGranted(_.AccountInfo))
|
||||
.so(profile.nonEmptyBio)
|
||||
.map: bio =>
|
||||
p(cls := List("bio" -> true, "muted" -> hideTroll))(richText(bio, nl2br = true)),
|
||||
|
||||
@@ -34,7 +34,7 @@ object page:
|
||||
)
|
||||
.js(pageModule(info))
|
||||
.js(esModules())
|
||||
.js(isGranted(_.UserModView).option(esmInit("mod.autolink")))
|
||||
.js(isGranted(_.AccountInfo).option(esmInit("mod.autolink")))
|
||||
.css("user.show")
|
||||
.css(isGranted(_.UserModView).option("mod.user"))
|
||||
.flag(_.noRobots, !indexable(u)):
|
||||
|
||||
@@ -12,8 +12,8 @@ final class AppealUi(helpers: Helpers):
|
||||
Page(title)
|
||||
.css("bits.form3")
|
||||
.css("bits.appeal")
|
||||
.css(Granter.opt(_.UserModView).option("mod.user"))
|
||||
.js(esmInitBit("appeal") ++ Granter.opt(_.UserModView).so(Esm("mod.user")))
|
||||
.css(Granter.opt(_.Appeals).option("mod.user"))
|
||||
.js(esmInitBit("appeal") ++ Granter.opt(_.Appeals).so(Esm("mod.user")))
|
||||
|
||||
def renderMark(suspect: User)(using ctx: Context) =
|
||||
val query = Granter.opt(_.Appeals).so(ctx.req.queryString.toMap)
|
||||
|
||||
@@ -48,154 +48,154 @@ final class ModUserUi(helpers: Helpers, modUi: ModUi, mailerEventsUrl: Url):
|
||||
)(using Context, Me): Frag =
|
||||
mzSection("actions")(
|
||||
div(cls := "btn-rack")(
|
||||
Granter.opt(_.ModMessage).option {
|
||||
postForm(action := routes.Mod.spontaneousInquiry(u.username), title := "Start an inquiry")(
|
||||
Granter(_.ModMessage).option:
|
||||
postForm(action := routes.Mod.spontaneousInquiry(u.username), title := "Start an inquiry"):
|
||||
submitButton(cls := "btn-rack__btn inquiry", title := "Hotkey: i")(i)
|
||||
)
|
||||
},
|
||||
Granter.opt(_.UserEvaluate).option {
|
||||
,
|
||||
Granter(_.UserEvaluate).option:
|
||||
postForm(
|
||||
action := routes.Mod.refreshUserAssess(u.username),
|
||||
title := "Collect data and ask irwin and Kaladin",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(cls := "btn-rack__btn")("Evaluate")
|
||||
},
|
||||
Granter.opt(_.GamesModView).option {
|
||||
,
|
||||
Granter(_.GamesModView).option:
|
||||
a(
|
||||
cls := "btn-rack__btn",
|
||||
href := routes.GameMod.index(u.username),
|
||||
title := "View games"
|
||||
)("Games")
|
||||
},
|
||||
Granter.opt(_.Shadowban).option {
|
||||
,
|
||||
Granter(_.Shadowban).option:
|
||||
a(
|
||||
cls := "btn-rack__btn",
|
||||
href := routes.Mod.communicationPublic(u.id),
|
||||
title := "View communications"
|
||||
)("Comms")
|
||||
}
|
||||
),
|
||||
div(cls := "btn-rack")(
|
||||
postForm(
|
||||
action := routes.Mod.alt(u.username, !u.marks.alt),
|
||||
title := "Preemptively close unauthorized alt.",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List(
|
||||
"btn-rack__btn" -> true,
|
||||
"active" -> u.marks.alt
|
||||
),
|
||||
ModUserTableUi.canCloseAlt.not.option(disabled)
|
||||
)("Alt")
|
||||
,
|
||||
postForm(
|
||||
action := routes.Mod.engine(u.username, !u.marks.engine),
|
||||
title := "This user is clearly cheating.",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn" -> true, "active" -> u.marks.engine),
|
||||
Granter.opt(_.MarkEngine).not.option(disabled)
|
||||
)("Engine")
|
||||
,
|
||||
postForm(
|
||||
action := routes.Mod.booster(u.username, !u.marks.boost),
|
||||
title := "Marks the user as a booster or sandbagger.",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn" -> true, "active" -> u.marks.boost),
|
||||
Granter.opt(_.MarkBooster).not.option(disabled)
|
||||
)("Booster")
|
||||
,
|
||||
frag(
|
||||
Granter(_.AccountInfo).option:
|
||||
div(cls := "btn-rack")(
|
||||
postForm(
|
||||
action := routes.Mod.troll(u.username, !u.marks.troll),
|
||||
title := "Enable/disable communication features for this user.",
|
||||
action := routes.Mod.alt(u.username, !u.marks.alt),
|
||||
title := "Preemptively close unauthorized alt.",
|
||||
cls := "xhr"
|
||||
)(
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn" -> true, "active" -> u.marks.troll),
|
||||
Granter.opt(_.Shadowban).not.option(disabled)
|
||||
)("Shadowban")
|
||||
),
|
||||
u.marks.troll.option:
|
||||
frag(
|
||||
postForm(
|
||||
action := routes.Mod.deletePmsAndChats(u.username),
|
||||
title := "Delete all PMs and public chat messages",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := "btn-rack__btn yes-no-confirm",
|
||||
Granter.opt(_.Shadowban).not.option(disabled)
|
||||
cls := List(
|
||||
"btn-rack__btn" -> true,
|
||||
"active" -> u.marks.alt
|
||||
),
|
||||
ModUserTableUi.canCloseAlt.not.option(disabled)
|
||||
)("Alt")
|
||||
,
|
||||
postForm(
|
||||
action := routes.Mod.engine(u.username, !u.marks.engine),
|
||||
title := "This user is clearly cheating.",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn" -> true, "active" -> u.marks.engine),
|
||||
Granter(_.MarkEngine).not.option(disabled)
|
||||
)("Engine")
|
||||
,
|
||||
postForm(
|
||||
action := routes.Mod.booster(u.username, !u.marks.boost),
|
||||
title := "Marks the user as a booster or sandbagger.",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn" -> true, "active" -> u.marks.boost),
|
||||
Granter(_.MarkBooster).not.option(disabled)
|
||||
)("Booster")
|
||||
,
|
||||
frag(
|
||||
postForm(
|
||||
action := routes.Mod.troll(u.username, !u.marks.troll),
|
||||
title := "Enable/disable communication features for this user.",
|
||||
cls := "xhr"
|
||||
)(
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn" -> true, "active" -> u.marks.troll),
|
||||
Granter(_.Shadowban).not.option(disabled)
|
||||
)("Shadowban")
|
||||
),
|
||||
u.marks.troll.option:
|
||||
frag(
|
||||
postForm(
|
||||
action := routes.Mod.deletePmsAndChats(u.username),
|
||||
title := "Delete all PMs and public chat messages",
|
||||
cls := "xhr"
|
||||
):
|
||||
"Clear PMs & chats"
|
||||
,
|
||||
postForm(
|
||||
action := routes.Mod.isolate(u.username, !u.marks.isolate),
|
||||
title := "Isolate user by preventing all PMs, follows and challenges",
|
||||
cls := "xhr"
|
||||
)(
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn yes-no-confirm" -> true, "active" -> u.marks.isolate),
|
||||
Granter.opt(_.Shadowban).not.option(disabled)
|
||||
)("Isolate")
|
||||
submitButton(
|
||||
cls := "btn-rack__btn yes-no-confirm",
|
||||
Granter(_.Shadowban).not.option(disabled)
|
||||
):
|
||||
"Clear PMs & chats"
|
||||
,
|
||||
postForm(
|
||||
action := routes.Mod.isolate(u.username, !u.marks.isolate),
|
||||
title := "Isolate user by preventing all PMs, follows and challenges",
|
||||
cls := "xhr"
|
||||
)(
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn yes-no-confirm" -> true, "active" -> u.marks.isolate),
|
||||
Granter(_.Shadowban).not.option(disabled)
|
||||
)("Isolate")
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
postForm(
|
||||
action := routes.Mod.kid(u.username, !u.kid.value),
|
||||
title := "Activate kid mode if not already the case",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn yes-no-confirm" -> true, "active" -> u.kid.yes),
|
||||
Granter.opt(_.SetKidMode).not.option(disabled)
|
||||
)("Kid")
|
||||
,
|
||||
postForm(
|
||||
action := routes.Mod.rankban(u.username, !u.marks.rankban),
|
||||
title := "Include/exclude this user from the rankings.",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn" -> true, "active" -> u.marks.rankban),
|
||||
Granter.opt(_.RemoveRanking).not.option(disabled)
|
||||
)("Rankban")
|
||||
,
|
||||
postForm(
|
||||
action := routes.Mod.arenaBan(u.username, !u.marks.arenaBan),
|
||||
title := "Enable/disable this user from joining all arenas.",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn" -> true, "active" -> u.marks.arenaBan),
|
||||
Granter.opt(_.ArenaBan).not.option(disabled)
|
||||
)("Arena ban")
|
||||
,
|
||||
postForm(
|
||||
action := routes.Mod.prizeban(u.username, !u.marks.prizeban),
|
||||
title := "Enable/disable this user from joining prized tournaments.",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn" -> true, "active" -> u.marks.prizeban),
|
||||
Granter.opt(_.PrizeBan).not.option(disabled)
|
||||
)("Prizeban")
|
||||
,
|
||||
postForm(
|
||||
action := routes.Mod.reportban(u.username, !u.marks.reportban),
|
||||
title := "Enable/disable the report feature for this user.",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn" -> true, "active" -> u.marks.reportban),
|
||||
Granter.opt(_.ReportBan).not.option(disabled)
|
||||
)("Reportban")
|
||||
),
|
||||
),
|
||||
postForm(
|
||||
action := routes.Mod.kid(u.username, !u.kid.value),
|
||||
title := "Activate kid mode if not already the case",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn yes-no-confirm" -> true, "active" -> u.kid.yes),
|
||||
Granter(_.SetKidMode).not.option(disabled)
|
||||
)("Kid")
|
||||
,
|
||||
postForm(
|
||||
action := routes.Mod.rankban(u.username, !u.marks.rankban),
|
||||
title := "Include/exclude this user from the rankings.",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn" -> true, "active" -> u.marks.rankban),
|
||||
Granter(_.RemoveRanking).not.option(disabled)
|
||||
)("Rankban")
|
||||
,
|
||||
postForm(
|
||||
action := routes.Mod.arenaBan(u.username, !u.marks.arenaBan),
|
||||
title := "Enable/disable this user from joining all arenas.",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn" -> true, "active" -> u.marks.arenaBan),
|
||||
Granter(_.ArenaBan).not.option(disabled)
|
||||
)("Arena ban")
|
||||
,
|
||||
postForm(
|
||||
action := routes.Mod.prizeban(u.username, !u.marks.prizeban),
|
||||
title := "Enable/disable this user from joining prized tournaments.",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn" -> true, "active" -> u.marks.prizeban),
|
||||
Granter(_.PrizeBan).not.option(disabled)
|
||||
)("Prizeban")
|
||||
,
|
||||
postForm(
|
||||
action := routes.Mod.reportban(u.username, !u.marks.reportban),
|
||||
title := "Enable/disable the report feature for this user.",
|
||||
cls := "xhr"
|
||||
):
|
||||
submitButton(
|
||||
cls := List("btn-rack__btn" -> true, "active" -> u.marks.reportban),
|
||||
Granter(_.ReportBan).not.option(disabled)
|
||||
)("Reportban")
|
||||
)
|
||||
,
|
||||
Granter
|
||||
.opt(_.CloseAccount)
|
||||
.option(
|
||||
@@ -219,11 +219,11 @@ final class ModUserUi(helpers: Helpers, modUi: ModUi, mailerEventsUrl: Url):
|
||||
cls := "xhr"
|
||||
)(submitButton(cls := "btn-rack__btn active")("Closed"))
|
||||
,
|
||||
Granter.opt(_.GdprErase).option(gdprEraseForm(u))
|
||||
Granter(_.GdprErase).option(gdprEraseForm(u))
|
||||
)
|
||||
)
|
||||
),
|
||||
(u.totpSecret.isDefined).option:
|
||||
(u.totpSecret.isDefined && Granter(_.AccountInfo)).option:
|
||||
div(cls := "btn-rack")(
|
||||
postForm(
|
||||
action := routes.Mod.disableTwoFactor(u.username),
|
||||
@@ -232,7 +232,7 @@ final class ModUserUi(helpers: Helpers, modUi: ModUi, mailerEventsUrl: Url):
|
||||
):
|
||||
submitButton(
|
||||
cls := "btn-rack__btn yes-no-confirm",
|
||||
Granter.opt(_.DisableTwoFactor).not.option(disabled)
|
||||
Granter(_.DisableTwoFactor).not.option(disabled)
|
||||
)(
|
||||
"Disable 2FA"
|
||||
)
|
||||
@@ -249,7 +249,7 @@ final class ModUserUi(helpers: Helpers, modUi: ModUi, mailerEventsUrl: Url):
|
||||
)
|
||||
)
|
||||
},
|
||||
Granter.opt(_.SetTitle).option {
|
||||
Granter(_.SetTitle).option {
|
||||
postForm(cls := "fide-title", action := routes.Mod.setTitle(u.username))(
|
||||
form3.select(
|
||||
lila.user.UserForm.title.fill(u.title)("title"),
|
||||
@@ -293,7 +293,7 @@ final class ModUserUi(helpers: Helpers, modUi: ModUi, mailerEventsUrl: Url):
|
||||
submitButton(cls := "btn-rack__btn yes-no-confirm")("Blank password")
|
||||
)
|
||||
,
|
||||
Granter.opt(_.FreePatron).option {
|
||||
Granter(_.FreePatron).option {
|
||||
postForm(
|
||||
action := routes.Mod.freePatron(u.username),
|
||||
title := "Give free Patron wings for a month",
|
||||
|
||||
@@ -40,7 +40,7 @@ final class PerfStatApi(
|
||||
.withPerfs(name.id)
|
||||
.flatMap:
|
||||
_.filter: u =>
|
||||
(u.enabled.yes && (!u.lame || me.exists(_.is(u.user)))) || me.soUse(Granter(_.UserModView))
|
||||
(u.enabled.yes && (!u.lame || me.exists(_.is(u.user)))) || me.soUse(Granter(_.AccountInfo))
|
||||
.filter: u =>
|
||||
!u.isBot || (perfKey != PerfKey.ultraBullet)
|
||||
.traverse: u =>
|
||||
|
||||
@@ -126,7 +126,7 @@ final class TeamApi(
|
||||
.teamIdsList(of.id)
|
||||
.map(_.take(Team.maxJoin(of).value))
|
||||
.flatMap: allIds =>
|
||||
if Granter(_.UserModView) then fuccess(allIds)
|
||||
if Granter(_.AccountInfo) then fuccess(allIds)
|
||||
else
|
||||
allIds.nonEmpty.so:
|
||||
teamRepo.filterHideMembers(allIds).flatMap { hiddenIds =>
|
||||
|
||||
@@ -32,8 +32,8 @@ final class TitleModUi(helpers: Helpers)(ui: TitleUi)(using NetDomain):
|
||||
Granter.opt(_.TitleRequest).option(a(href := ui.thumbnail.raw(id))(ui.thumbnail(id.some, 500)))
|
||||
Page(s"${user.username}'s title verification")
|
||||
.css("bits.titleRequest")
|
||||
.css(Granter.opt(_.UserModView).option("mod.user"))
|
||||
.js(esmInitBit("titleRequest") ++ Granter.opt(_.UserModView).so(Esm("mod.user"))):
|
||||
.css(Granter.opt(_.AccountInfo).option("mod.user"))
|
||||
.js(esmInitBit("titleRequest") ++ Granter.opt(_.AccountInfo).so(Esm("mod.user"))):
|
||||
main(cls := "box box-pad page title-mod")(
|
||||
div(cls := "box__top")(
|
||||
h1("Title verification by ", userLink(user), " ", showStatus(req.status)),
|
||||
|
||||
@@ -40,7 +40,7 @@ final class UserShow(helpers: Helpers, bits: UserBits):
|
||||
ping.map(bits.signalBars)
|
||||
),
|
||||
realName.map(div(cls := "upt__info__realname")(_)),
|
||||
if u.lame && ctx.isnt(u) && !Granter.opt(_.UserModView)
|
||||
if u.lame && ctx.isnt(u) && !Granter.opt(_.AccountInfo)
|
||||
then div(cls := "upt__info__warning")(trans.site.thisAccountViolatedTos())
|
||||
else
|
||||
ctx.pref.showRatings.option:
|
||||
@@ -80,7 +80,7 @@ final class UserShow(helpers: Helpers, bits: UserBits):
|
||||
div(cls := "upt__details")(
|
||||
span(trans.site.nbGames.plural(u.count.game, u.count.game.localize)),
|
||||
span(trans.site.joinedX(momentFromNow(u.createdAt))),
|
||||
(Granter.opt(_.UserModView) && (u.lameOrTroll || u.enabled.no || u.marks.rankban))
|
||||
(Granter.opt(_.AccountInfo) && (u.lameOrTroll || u.enabled.no || u.marks.rankban))
|
||||
.option(span(cls := "upt__details__marks")(userMarks))
|
||||
),
|
||||
playing
|
||||
|
||||
@@ -72,7 +72,7 @@ final class UserShowSide(helpers: Helpers):
|
||||
)
|
||||
|
||||
div(cls := "side sub-ratings")(
|
||||
(!u.lame || ctx.is(u) || Granter.opt(_.UserModView)).option(
|
||||
(!u.lame || ctx.is(u) || Granter.opt(_.AccountInfo)).option(
|
||||
frag(
|
||||
showNonEmptyPerf(u.perfs.ultraBullet, PerfKey.ultraBullet),
|
||||
showPerf(u.perfs.bullet, PerfKey.bullet),
|
||||
|
||||
Reference in New Issue
Block a user