Skip to content

Commit

Permalink
Merge branch 'master' into piece-adjustments
Browse files Browse the repository at this point in the history
  • Loading branch information
johndoknjas authored Jan 19, 2025
2 parents 0a08b55 + 9e4ccc0 commit 1839fa3
Show file tree
Hide file tree
Showing 164 changed files with 1,791 additions and 820 deletions.
37 changes: 31 additions & 6 deletions app/controllers/Account.scala
Original file line number Diff line number Diff line change
Expand Up @@ -239,23 +239,48 @@ final class Account(
}

def close = Auth { _ ?=> me ?=>
env.clas.api.student.isManaged(me).flatMap { managed =>
env.security.forms.closeAccount.flatMap: form =>
Ok.page(pages.close(form, managed))
}
for
managed <- env.clas.api.student.isManaged(me)
form <- env.security.forms.closeAccount
res <- Ok.page(pages.close(form, managed))
yield res
}

def closeConfirm = AuthBody { ctx ?=> me ?=>
NotManaged:
auth.HasherRateLimit:
env.security.forms.closeAccount.flatMap: form =>
FormFuResult(form)(err => renderPage(pages.close(err, managed = false))): _ =>
env.api.accountClosure
.close(me.value)
env.api.accountTermination
.disable(me.value)
.inject:
Redirect(routes.User.show(me.username)).withCookies(env.security.lilaCookie.newSession)
}

def delete = Auth { _ ?=> me ?=>
for
managed <- env.clas.api.student.isManaged(me)
form <- env.security.forms.deleteAccount
res <- Ok.page(pages.delete(form, managed))
yield res
}

def deleteConfirm = AuthBody { ctx ?=> me ?=>
NotManaged:
auth.HasherRateLimit:
env.security.forms.deleteAccount.flatMap: form =>
FormFuResult(form)(err => renderPage(pages.delete(err, managed = false))): _ =>
env.api.accountTermination
.scheduleDelete(me.value)
.inject:
Redirect(routes.Account.deleteDone).withCookies(env.security.lilaCookie.newSession)
}

def deleteDone = Open { ctx ?=>
if ctx.isAuth then Redirect(routes.Lobby.home)
else FoundPage(env.cms.renderKey("delete-done"))(views.site.page.lone)
}

def kid = Auth { _ ?=> me ?=>
for
managed <- env.clas.api.student.isManaged(me)
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/Clas.scala
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ final class Clas(env: Env, authC: Auth) extends LilaController(env):
WithStudent(clas, username): s =>
if s.student.managed then
(env.clas.api.student.closeAccount(s) >>
env.api.accountClosure.close(s.user)).inject(redirectTo(clas).flashSuccess)
env.api.accountTermination.disable(s.user)).inject(redirectTo(clas).flashSuccess)
else if s.student.isArchived then
env.clas.api.student.closeAccount(s) >>
redirectTo(clas).flashSuccess
Expand Down
19 changes: 8 additions & 11 deletions app/controllers/Mod.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class Mod(
withSuspect(username): sus =>
for
_ <- api.setAlt(sus, v)
_ <- (v && sus.user.enabled.yes).so(env.api.accountClosure.close(sus.user))
_ <- (v && sus.user.enabled.yes).so(env.api.accountTermination.disable(sus.user))
_ <- (!v && sus.user.enabled.no).so(api.reopenAccount(sus.user.id))
yield sus.some
}(reportC.onModAction)
Expand All @@ -40,7 +40,7 @@ final class Mod(
Source(ctx.body.body.split(' ').toList.flatMap(UserStr.read))
.mapAsync(1): username =>
withSuspect(username): sus =>
api.setAlt(sus, true) >> (sus.user.enabled.yes.so(env.api.accountClosure.close(sus.user)))
api.setAlt(sus, true) >> (sus.user.enabled.yes.so(env.api.accountTermination.disable(sus.user)))
.runWith(Sink.ignore)
.void
.inject(NoContent)
Expand Down Expand Up @@ -114,7 +114,7 @@ final class Mod(

def closeAccount(username: UserStr) = OAuthMod(_.CloseAccount) { _ ?=> me ?=>
meOrFetch(username).flatMapz: user =>
env.api.accountClosure.close(user).map(some)
env.api.accountTermination.disable(user).map(some)
}(actionResult(username))

def reopenAccount(username: UserStr) = OAuthMod(_.CloseAccount) { _ ?=> me ?=>
Expand Down Expand Up @@ -380,13 +380,10 @@ final class Mod(
env.user.noteApi.search(q.trim, page, withDox = true).map(views.mod.search.notes(q, _))
}

def gdprErase(username: UserStr) = Secure(_.GdprErase) { _ ?=> me ?=>
val res = Redirect(routes.User.show(username))
env.api.accountClosure
.closeThenErase(username)
.map:
case Right(msg) => res.flashSuccess(msg)
case Left(err) => res.flashFailure(err)
def gdprErase(username: UserStr) = Secure(_.GdprErase) { _ ?=> _ ?=>
Found(env.user.repo.byId(username)): user =>
for _ <- env.api.accountTermination.scheduleErase(user)
yield Redirect(routes.User.show(username)).flashSuccess("Erasure scheduled")
}

protected[controllers] def searchTerm(query: String)(using Context, Me) =
Expand All @@ -411,7 +408,7 @@ final class Mod(

def printBan(v: Boolean, fh: String) = Secure(_.PrintBan) { _ ?=> me ?=>
val hash = FingerHash(fh)
env.security.printBan.toggle(hash, v).inject(Redirect(routes.Mod.print(fh)))
for _ <- env.security.printBan.toggle(hash, v) yield Redirect(routes.Mod.print(fh))
}

def singleIp(ip: String) = SecureBody(_.ViewPrintNoIP) { ctx ?=> me ?=>
Expand Down
8 changes: 4 additions & 4 deletions app/controllers/User.scala
Original file line number Diff line number Diff line change
Expand Up @@ -396,8 +396,8 @@ final class User(
.map(ui.showRageSitAndPlaybans)
)

val actions = env.user.repo.isErased(user).map { erased =>
ui.actions(user, emails, erased, env.mod.presets.getPmPresets)
val actions = env.user.repo.isDeleted(user).map { deleted =>
ui.actions(user, emails, deleted, env.mod.presets.getPmPresets)
}

val userLoginsFu = env.security.userLogins(user, nbOthers)
Expand Down Expand Up @@ -458,12 +458,12 @@ final class User(
protected[controllers] def renderModZoneActions(username: UserStr)(using ctx: Context) =
env.user.api.withPerfsAndEmails(username).orFail(s"No such user $username").flatMap {
case WithPerfsAndEmails(user, emails) =>
env.user.repo.isErased(user).flatMap { erased =>
env.user.repo.isDeleted(user).flatMap { deleted =>
Ok.snip:
views.mod.user.actions(
user,
emails,
erased,
deleted,
env.mod.presets.getPmPresetsOpt
)
}
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/UserTournament.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ final class UserTournament(env: Env, apiC: => Api) extends LilaController(env):
apiC.jsonDownload:
env.tournament.leaderboardApi
.byPlayerStream(
user,
user.id,
withPerformance = getBool("performance"),
maxPerSecond(name),
getInt("nb") | Int.MaxValue
Expand Down
2 changes: 1 addition & 1 deletion app/views/user/show/page.scala
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ object page:
h1(cls := "box__top")("No such player"),
div(
p("This username doesn't match any Lichess player."),
(!canCreate).option(p("It cannot be used to create a new account."))
canCreate.not.option(p("It cannot be used to create a new account."))
)
)

Expand Down
26 changes: 26 additions & 0 deletions bin/mongodb/analysis-requester-cleanup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
count = 0;
db.analysis_requester.find().forEach(function (doc) {
const entries = Object.entries(doc);
const reduced = entries.filter(([key]) => !key.includes('-') || key.startsWith('2025-'));
if (entries.length !== reduced.length) {
const newDoc = Object.fromEntries(reduced);
db.analysis_requester.replaceOne({ _id: doc._id }, newDoc);
}
if (count % 1000 === 0) print(count);
count++;
});

print(count, 'documents processed');

/*
size: 2710719734,
count: 6218537,
storageSize: 627077120,
totalIndexSize: 178106368,
totalSize: 805183488,
indexSizes: { 'total_-1': 51482624, _id_: 126623744 },
avgObjSize: 435,
ns: 'lichess.analysis_requester',
nindexes: 2,
scaleFactor: 1
*/
5 changes: 4 additions & 1 deletion bin/mongodb/indexes.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ db.user4.createIndex({ title: 1 }, { sparse: true });
db.user4.createIndex({ email: 1 }, { unique: true, sparse: 1 });
db.user4.createIndex({ roles: 1 }, { background: 1, partialFilterExpression: { roles: { $exists: 1 } } });
db.user4.createIndex({ prevEmail: 1 }, { sparse: 1, background: 1 });
db.user4.createIndex({ eraseAt: 1 }, { partialFilterExpression: { eraseAt: { $exists: true } } });
db.user4.createIndex(
{ 'delete.scheduled': 1 },
{ partialFilterExpression: { 'delete.scheduled': { $exists: 1 }, 'delete.done': false } },
);
db.f_topic.createIndex({ categId: 1, troll: 1 });
db.f_topic.createIndex({ categId: 1, updatedAt: -1, troll: 1 });
db.f_topic.createIndex({ categId: 1, slug: 1 });
Expand Down
5 changes: 4 additions & 1 deletion conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,10 @@ POST /account/email controllers.Account.emailApply
GET /contact/email-confirm/help controllers.Account.emailConfirmHelp
GET /account/email/confirm/:token controllers.Account.emailConfirm(token)
GET /account/close controllers.Account.close
POST /account/closeConfirm controllers.Account.closeConfirm
POST /account/close controllers.Account.closeConfirm
GET /account/delete controllers.Account.delete
POST /account/delete controllers.Account.deleteConfirm
GET /account/delete/done controllers.Account.deleteDone
GET /account/profile controllers.Account.profile
POST /account/profile controllers.Account.profileApply
GET /account/username controllers.Account.username
Expand Down
2 changes: 2 additions & 0 deletions modules/activity/src/main/ActivityWriteApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ final class ActivityWriteApi(
import BSONHandlers.{ *, given }
import activities.*

def deleteAll(u: User): Funit = withColl(_.delete.one(regexId(u.id)).void)

def game(game: Game): Funit =
(for
userId <- game.userIds
Expand Down
4 changes: 3 additions & 1 deletion modules/analyse/src/main/AnalyseBsonHandlers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import lila.tree.{ Analysis, Info }

object AnalyseBsonHandlers:

given BSONWriter[Analysis.Id] = BSONWriter(id => BSONString(id.value))

given BSON[Analysis] with
def reads(r: BSON.Reader) =
val startPly = Ply(r.intD("ply"))
Expand All @@ -28,7 +30,7 @@ object AnalyseBsonHandlers:
)
def writes(w: BSON.Writer, a: Analysis) =
BSONDocument(
"_id" -> a.id.value,
"_id" -> a.id,
"studyId" -> a.studyId,
"data" -> Info.encodeList(a.infos),
"ply" -> w.intO(a.startPly.value),
Expand Down
11 changes: 7 additions & 4 deletions modules/analyse/src/main/AnalysisRepo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,31 @@ package lila.analyse

import lila.db.dsl.*
import lila.tree.Analysis
import reactivemongo.api.bson.*

final class AnalysisRepo(val coll: Coll)(using Executor):

import AnalyseBsonHandlers.given

def save(analysis: Analysis) = coll.insert.one(analysis).void

def byId(id: Analysis.Id): Fu[Option[Analysis]] = coll.byId[Analysis](id.value)
def byId(id: Analysis.Id): Fu[Option[Analysis]] = coll.byId[Analysis](id)

def byGame(game: Game): Fu[Option[Analysis]] =
game.metadata.analysed.so(byId(Analysis.Id(game.id)))

def byIds(ids: Seq[Analysis.Id]): Fu[Seq[Option[Analysis]]] =
coll.optionsByOrderedIds[Analysis, String](ids.map(_.value))(_.id.value)
coll.optionsByOrderedIds[Analysis, Analysis.Id](ids)(_.id)

def associateToGames(games: List[Game]): Fu[List[(Game, Analysis)]] =
byIds(games.map(g => Analysis.Id(g.id))).map: as =>
games.zip(as).collect { case (game, Some(analysis)) =>
game -> analysis
}

def remove(id: GameId) = coll.delete.one($id(Analysis.Id(id).value))
def remove(id: GameId) = coll.delete.one($id(Analysis.Id(id)))

def exists(id: GameId) = coll.exists($id(id.value))
def remove(ids: List[GameId]) = coll.delete.one($inIds(ids.map(Analysis.Id(_))))

def exists(id: GameId) = coll.exists($id(Analysis.Id(id)))
def chapterExists(id: StudyChapterId) = coll.exists($id(id.value))
9 changes: 5 additions & 4 deletions modules/analyse/src/main/RequesterApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,16 @@ final class RequesterApi(coll: Coll)(using Executor):
coll
.one(
$id(userId),
$doc {
$doc:
(7 to 0 by -1).toList.map(now.minusDays).map(formatter.print).map(_ -> BSONBoolean(true))
}
)
.map { doc =>
.map: doc =>
val daily = doc.flatMap(_.int(formatter.print(now)))
val weekly = doc.so:
_.values.foldLeft(0):
case (acc, BSONInteger(v)) => acc + v
case (acc, _) => acc
(~daily, weekly)
}

lila.common.Bus.sub[lila.core.user.UserDelete]: del =>
coll.delete.one($id(del.id)).void
82 changes: 0 additions & 82 deletions modules/api/src/main/AccountClosure.scala

This file was deleted.

Loading

0 comments on commit 1839fa3

Please sign in to comment.