From f5ae389eea0886933ae3c5d90815933ec7e2516f Mon Sep 17 00:00:00 2001
From: Eike Kettner <eike.kettner@posteo.de>
Date: Fri, 4 Dec 2020 00:59:08 +0100
Subject: [PATCH] Cleanup remember-me tokens periodically

---
 .../joex/src/main/resources/reference.conf    | 11 ++++++++
 .../joex/hk/CleanupRememberMeTask.scala       | 25 +++++++++++++++++++
 .../docspell/joex/hk/HouseKeepingConfig.scala |  5 +++-
 .../docspell/joex/hk/HouseKeepingTask.scala   |  1 +
 4 files changed, 41 insertions(+), 1 deletion(-)
 create mode 100644 modules/joex/src/main/scala/docspell/joex/hk/CleanupRememberMeTask.scala

diff --git a/modules/joex/src/main/resources/reference.conf b/modules/joex/src/main/resources/reference.conf
index f8deb8e7..8437982d 100644
--- a/modules/joex/src/main/resources/reference.conf
+++ b/modules/joex/src/main/resources/reference.conf
@@ -142,6 +142,17 @@ docspell.joex {
       older-than = "30 days"
     }
 
+    # This task removes expired remember-me tokens. The timespan
+    # should be greater than the `valid` time in the restserver
+    # config.
+    cleanup-remember-me = {
+      # Whether the job is enabled.
+      enabled = true
+
+      # The minimum age of tokens to be deleted.
+      older-than = "30 days"
+    }
+
     # Jobs store their log output in the database. Normally this data
     # is only interesting for some period of time. The processing logs
     # of old files can be removed eventually.
diff --git a/modules/joex/src/main/scala/docspell/joex/hk/CleanupRememberMeTask.scala b/modules/joex/src/main/scala/docspell/joex/hk/CleanupRememberMeTask.scala
new file mode 100644
index 00000000..05568e8f
--- /dev/null
+++ b/modules/joex/src/main/scala/docspell/joex/hk/CleanupRememberMeTask.scala
@@ -0,0 +1,25 @@
+package docspell.joex.hk
+
+import cats.effect._
+import cats.implicits._
+
+import docspell.common._
+import docspell.joex.scheduler.Task
+import docspell.store.records._
+
+object CleanupRememberMeTask {
+
+  def apply[F[_]: Sync](cfg: HouseKeepingConfig.CleanupRememberMe): Task[F, Unit, Unit] =
+    Task { ctx =>
+      if (cfg.enabled)
+        for {
+          now <- Timestamp.current[F]
+          ts = now - cfg.olderThan
+          _ <- ctx.logger.info(s"Cleanup remember-me tokens older than $ts")
+          n <- ctx.store.transact(RRememberMe.deleteOlderThan(ts))
+          _ <- ctx.logger.info(s"Removed $n tokens")
+        } yield ()
+      else
+        ctx.logger.info("CleanupRememberMe task is disabled in the configuration")
+    }
+}
diff --git a/modules/joex/src/main/scala/docspell/joex/hk/HouseKeepingConfig.scala b/modules/joex/src/main/scala/docspell/joex/hk/HouseKeepingConfig.scala
index be0f3f5e..a76cc520 100644
--- a/modules/joex/src/main/scala/docspell/joex/hk/HouseKeepingConfig.scala
+++ b/modules/joex/src/main/scala/docspell/joex/hk/HouseKeepingConfig.scala
@@ -8,7 +8,8 @@ import com.github.eikek.calev.CalEvent
 case class HouseKeepingConfig(
     schedule: CalEvent,
     cleanupInvites: CleanupInvites,
-    cleanupJobs: CleanupJobs
+    cleanupJobs: CleanupJobs,
+    cleanupRememberMe: CleanupRememberMe
 )
 
 object HouseKeepingConfig {
@@ -17,4 +18,6 @@ object HouseKeepingConfig {
 
   case class CleanupJobs(enabled: Boolean, olderThan: Duration, deleteBatch: Int)
 
+  case class CleanupRememberMe(enabled: Boolean, olderThan: Duration)
+
 }
diff --git a/modules/joex/src/main/scala/docspell/joex/hk/HouseKeepingTask.scala b/modules/joex/src/main/scala/docspell/joex/hk/HouseKeepingTask.scala
index c124717f..aa5281ab 100644
--- a/modules/joex/src/main/scala/docspell/joex/hk/HouseKeepingTask.scala
+++ b/modules/joex/src/main/scala/docspell/joex/hk/HouseKeepingTask.scala
@@ -19,6 +19,7 @@ object HouseKeepingTask {
     Task
       .log[F, Unit](_.info(s"Running house-keeping task now"))
       .flatMap(_ => CleanupInvitesTask(cfg.houseKeeping.cleanupInvites))
+      .flatMap(_ => CleanupRememberMeTask(cfg.houseKeeping.cleanupRememberMe))
       .flatMap(_ => CleanupJobsTask(cfg.houseKeeping.cleanupJobs))
 
   def onCancel[F[_]: Sync]: Task[F, Unit, Unit] =