From 25d92c4e67e356b2f7a305c0bbbe50be3984486b Mon Sep 17 00:00:00 2001 From: Louis Chemineau Date: Wed, 19 Feb 2025 11:55:56 +0100 Subject: [PATCH] fix(files_versions): Do not expire versions newer than min age The auto expire logic does not take into account the min retention age set by the admin. So versions were eagerly deleted. Fix https://github.com/nextcloud/server/issues/19791 Signed-off-by: Louis Chemineau --- apps/files_versions/lib/Expiration.php | 14 ++++++++++++++ apps/files_versions/lib/Storage.php | 10 +++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/files_versions/lib/Expiration.php b/apps/files_versions/lib/Expiration.php index f18a577d80e0f..ba7eb3139a719 100644 --- a/apps/files_versions/lib/Expiration.php +++ b/apps/files_versions/lib/Expiration.php @@ -120,6 +120,20 @@ public function isExpired(int $timestamp, bool $quotaExceeded = false): bool { return $isOlderThanMax || $isMinReached; } + /** + * Get minimal retention obligation as a timestamp + * + * @return int|false + */ + public function getMinAgeAsTimestamp() { + $minAge = false; + if ($this->isEnabled() && $this->minAge !== self::NO_OBLIGATION) { + $time = $this->timeFactory->getTime(); + $minAge = $time - ($this->minAge * 86400); + } + return $minAge; + } + /** * Get maximal retention obligation as a timestamp * diff --git a/apps/files_versions/lib/Storage.php b/apps/files_versions/lib/Storage.php index 48513675d63d4..3ef297a604687 100644 --- a/apps/files_versions/lib/Storage.php +++ b/apps/files_versions/lib/Storage.php @@ -726,7 +726,15 @@ protected static function getExpireList($time, $versions, $quotaExceeded = false $expiration = self::getExpiration(); if ($expiration->shouldAutoExpire()) { - [$toDelete, $size] = self::getAutoExpireList($time, $versions); + // Exclude versions that are newer than the minimum age from the auto expiration logic. + $minAge = $expiration->getMinAgeAsTimestamp(); + if ($minAge !== false) { + $versionsToAutoExpire = array_filter($versions, fn ($version) => $version['version'] < $minAge); + } else { + $versionsToAutoExpire = $versions; + } + + [$toDelete, $size] = self::getAutoExpireList($time, $versionsToAutoExpire); } else { $size = 0; $toDelete = []; // versions we want to delete