GDPR erasure: private messages

This commit is contained in:
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, blocks = blocks,
getPref = getPref getPref = getPref
) )
system.lilaBus.subscribe(system.actorOf(Props(new Actor {
def receive = {
case lila.user.User.GDPRErase(user) => api erase user
}
})), 'gdprErase)
} }
object Env { 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 isUnRead = !isRead
def similar(other: Post) = text == other.text && isByCreator == other.isByCreator def similar(other: Post) = text == other.text && isByCreator == other.isByCreator
def erase = copy(text = "<deleted>")
} }
object Post { object Post {

View file

@ -11,9 +11,9 @@ case class Thread(
createdAt: DateTime, createdAt: DateTime,
updatedAt: DateTime, updatedAt: DateTime,
posts: List[Post], posts: List[Post],
creatorId: String, creatorId: User.ID,
invitedId: String, invitedId: User.ID,
visibleByUserIds: List[String], visibleByUserIds: List[User.ID],
mod: Option[Boolean] mod: Option[Boolean]
) { ) {
@ -89,6 +89,14 @@ case class Thread(
def hasPostsWrittenBy(userId: User.ID) = posts exists (_.isByCreator == (creatorId == userId)) def hasPostsWrittenBy(userId: User.ID) = posts exists (_.isByCreator == (creatorId == userId))
def endsWith(post: Post) = posts.lastOption ?? post.similar 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 { object Thread {

View file

@ -1,5 +1,6 @@
package lila.message package lila.message
import reactivemongo.api.ReadPreference
import lila.db.dsl._ import lila.db.dsl._
import lila.user.User import lila.user.User
@ -22,6 +23,13 @@ object ThreadRepo {
def createdByUser(user: ID): Fu[List[Thread]] = def createdByUser(user: ID): Fu[List[Thread]] =
coll.find(visibleByUserQuery(user) ++ $doc("creatorId" -> user)).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 = { def setReadFor(user: User)(thread: Thread): Funit = {
val indexes = thread.unreadIndexesBy(user) val indexes = thread.unreadIndexesBy(user)
indexes.nonEmpty ?? coll.update($id(thread.id), $doc("$set" -> indexes.foldLeft($empty) { indexes.nonEmpty ?? coll.update($id(thread.id), $doc("$set" -> indexes.foldLeft($empty) {