From 46b1825f2d4263a03108efb863a3ba2fa19be2df 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 b84756212e4c6..5ef749ad115f5 100644 --- a/apps/files_versions/lib/Expiration.php +++ b/apps/files_versions/lib/Expiration.php @@ -98,6 +98,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 11e6bff6b6b12..dcf39a5e47717 100644 --- a/apps/files_versions/lib/Storage.php +++ b/apps/files_versions/lib/Storage.php @@ -696,7 +696,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