GDPR erasure: private messages

pull/4328/head
Thibault Duplessis 2018-05-04 00:28:52 +02:00
parent 0b439bd578
commit 5da5acf338
5 changed files with 33 additions and 3 deletions

View File

@ -45,6 +45,12 @@ final class Env(
blocks = blocks,
getPref = getPref
)
system.lilaBus.subscribe(system.actorOf(Props(new Actor {
def receive = {
case lila.user.User.GDPRErase(user) => api erase user
}
})), 'gdprErase)
}
object Env {

View File

@ -133,4 +133,10 @@ final class MessageApi(
)
)
}
def erase(user: User) = ThreadRepo.byAndForWithoutIndex(user) flatMap { threads =>
lila.common.Future.applySequentially(threads) { thread =>
coll.update($id(thread.id), thread erase user).void
}
}
}

View File

@ -16,6 +16,8 @@ case class Post(
def isUnRead = !isRead
def similar(other: Post) = text == other.text && isByCreator == other.isByCreator
def erase = copy(text = "<deleted>")
}
object Post {

View File

@ -11,9 +11,9 @@ case class Thread(
createdAt: DateTime,
updatedAt: DateTime,
posts: List[Post],
creatorId: String,
invitedId: String,
visibleByUserIds: List[String],
creatorId: User.ID,
invitedId: User.ID,
visibleByUserIds: List[User.ID],
mod: Option[Boolean]
) {
@ -89,6 +89,14 @@ case class Thread(
def hasPostsWrittenBy(userId: User.ID) = posts exists (_.isByCreator == (creatorId == userId))
def endsWith(post: Post) = posts.lastOption ?? post.similar
def erase(user: User) = copy(
posts = posts.map {
case p if p.isByCreator && user.id == creatorId => p.erase
case p if !p.isByCreator && user.id == invitedId => p.erase
case p => p
}
)
}
object Thread {

View File

@ -1,5 +1,6 @@
package lila.message
import reactivemongo.api.ReadPreference
import lila.db.dsl._
import lila.user.User
@ -22,6 +23,13 @@ object ThreadRepo {
def createdByUser(user: ID): Fu[List[Thread]] =
coll.find(visibleByUserQuery(user) ++ $doc("creatorId" -> user)).list[Thread]()
// super heavy. For GDPR only.
private[message] def byAndForWithoutIndex(user: User): Fu[List[Thread]] =
coll.find($or(
$doc("creatorId" -> user.id),
$doc("invitedId" -> user.id)
)).list[Thread](999, readPreference = ReadPreference.secondaryPreferred)
def setReadFor(user: User)(thread: Thread): Funit = {
val indexes = thread.unreadIndexesBy(user)
indexes.nonEmpty ?? coll.update($id(thread.id), $doc("$set" -> indexes.foldLeft($empty) {