allow reopening marked account, unless closed by a mod

only allow appealing closure when closed by a mod

fixes lichess-org/tavern#88
pull/8571/head
Thibault Duplessis 2021-04-06 19:49:25 +02:00
parent 0d8047f236
commit c4d9322464
5 changed files with 22 additions and 15 deletions

View File

@ -399,7 +399,7 @@ final class Account(
err => BadRequest(renderReopen(err.some, none)).fuccess,
data =>
env.security.reopen
.prepare(data.username, data.realEmail, env.mod.logApi.hasModClose) flatMap {
.prepare(data.username, data.realEmail, env.mod.logApi.closedByMod) flatMap {
case Left((code, msg)) =>
lila.mon.user.auth.reopenRequest(code).increment()
BadRequest(renderReopen(none, msg.some)).fuccess

View File

@ -126,9 +126,10 @@ final class Auth(
case None => InternalServerError("Authentication error").fuccess
case Some(u) if u.disabled =>
negotiate(
html =
if (u.marks.dirty) authenticateAppealUser(u, redirectTo)
else redirectTo(routes.Account.reopen.url).fuccess,
html = (u.marks.dirty ?? env.mod.logApi.closedByMod(u)) flatMap {
case true => authenticateAppealUser(u, redirectTo)
case _ => redirectTo(routes.Account.reopen.url).fuccess
},
api = _ => Unauthorized(jsonError("This account is closed.")).fuccess
)
case Some(u) =>

View File

@ -29,11 +29,6 @@ final class ModlogApi(repo: ModlogRepo, userRepo: UserRepo, slackApi: SlackApi)(
add {
Modlog(mod.user.id, streamerId.some, Modlog.streamerTier, v.toString.some)
}
// BC
def streamerFeature(mod: Mod, streamerId: User.ID, v: Boolean) =
add {
Modlog(mod.user.id, streamerId.some, if (v) Modlog.streamerFeature else Modlog.streamerUnfeature)
}
def practiceConfig(mod: User.ID) =
add {
@ -85,8 +80,8 @@ final class ModlogApi(repo: ModlogRepo, userRepo: UserRepo, slackApi: SlackApi)(
)
}
def hasModClose(user: User.ID): Fu[Boolean] =
coll.exists($doc("user" -> user, "action" -> Modlog.closeAccount))
def closedByMod(user: User): Fu[Boolean] =
fuccess(user.marks.alt) >>| coll.exists($doc("user" -> user.id, "action" -> Modlog.closeAccount))
def reopenAccount(mod: User.ID, user: User.ID) =
add {
@ -293,7 +288,8 @@ final class ModlogApi(repo: ModlogRepo, userRepo: UserRepo, slackApi: SlackApi)(
userRepo.isMonitoredMod(m.mod) flatMap {
_ ?? {
val monitorType = m.action match {
case M.engine | M.unengine | M.booster | M.unbooster | M.closeAccount | M.reopenAccount | M.alt | M.unalt =>
case M.engine | M.unengine | M.booster | M.unbooster | M.closeAccount | M.reopenAccount | M.alt |
M.unalt =>
SlackApi.MonitorType.Hunt
case M.troll | M.untroll | M.chatTimeout | M.closeTopic | M.openTopic | M.disableTeam |
M.enableTeam | M.setKidMode =>

View File

@ -21,7 +21,7 @@ final class Reopen(
def prepare(
username: String,
email: EmailAddress,
hasModClose: User.ID => Fu[Boolean]
closedByMod: User => Fu[Boolean]
): Fu[Either[(String, String), User]] =
userRepo.enabledWithEmail(email.normalize) flatMap {
case Some(_) =>
@ -34,7 +34,7 @@ final class Reopen(
case Some(user) if user.enabled =>
fuccess(Left("alreadyActive" -> "This account is already active."))
case Some(user) =>
userRepo.prevEmail(user.id) flatMap {
userRepo.currentOrPrevEmail(user.id) flatMap {
case None =>
fuccess(
Left("noEmail" -> "That account doesn't have any associated email, and cannot be reopened.")
@ -42,7 +42,7 @@ final class Reopen(
case Some(prevEmail) if !email.similarTo(prevEmail) =>
fuccess(Left("differentEmail" -> "That account has a different email address."))
case _ =>
hasModClose(user.id).map(_ || user.marks.alt) map {
closedByMod(user) map {
case true => Left("nope" -> "Sorry, that account can no longer be reopened.")
case _ => Right(user)
}

View File

@ -469,6 +469,16 @@ final class UserRepo(val coll: Coll)(implicit ec: scala.concurrent.ExecutionCont
def prevEmail(id: ID): Fu[Option[EmailAddress]] =
coll.primitiveOne[EmailAddress]($id(id), F.prevEmail)
def currentOrPrevEmail(id: ID): Fu[Option[EmailAddress]] =
coll
.find($id(id), $doc(F.email -> true, F.verbatimEmail -> true, F.prevEmail -> true).some)
.one[Bdoc]
.map {
_ ?? { doc =>
anyEmail(doc) orElse doc.getAsOpt[EmailAddress](F.prevEmail)
}
}
def withEmails(name: String): Fu[Option[User.WithEmails]] =
coll.find($id(normalize(name))).one[Bdoc].map {
_ ?? { doc =>