diff options
author | Marcel Klehr <mklehr@gmx.net> | 2025-07-07 15:54:30 +0200 |
---|---|---|
committer | Marcel Klehr <mklehr@gmx.net> | 2025-07-15 09:15:16 +0200 |
commit | 43be97de0846c25b5098d0b355ef1aa8408dbca5 (patch) | |
tree | 174e5e09894865cbf207ff12a326de3feb31ec0e | |
parent | 3a96f8e53345dd578b00119f9bdd541adec12a8e (diff) | |
download | nextcloud-server-43be97de0846c25b5098d0b355ef1aa8408dbca5.tar.gz nextcloud-server-43be97de0846c25b5098d0b355ef1aa8408dbca5.zip |
fix(FileAccess): Use one param for rewriting home dirs and excluding non-user files mountsfeat/getByAncestorInStorage
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
-rw-r--r-- | lib/private/Files/Cache/FileAccess.php | 17 | ||||
-rw-r--r-- | lib/public/Files/Cache/IFileAccess.php | 4 | ||||
-rw-r--r-- | tests/lib/Files/Cache/FileAccessTest.php | 45 |
3 files changed, 57 insertions, 9 deletions
diff --git a/lib/private/Files/Cache/FileAccess.php b/lib/private/Files/Cache/FileAccess.php index a7a6e3a222f..c3f3614f3ca 100644 --- a/lib/private/Files/Cache/FileAccess.php +++ b/lib/private/Files/Cache/FileAccess.php @@ -158,12 +158,23 @@ class FileAccess implements IFileAccess { $files->closeCursor(); } - public function getDistinctMounts(array $mountProviders = [], bool $rewriteHomeDirectories = true): \Generator { + public function getDistinctMounts(array $mountProviders = [], bool $onlyUserFilesMounts = true): \Generator { $qb = $this->connection->getQueryBuilder(); $qb->selectDistinct(['root_id', 'storage_id', 'mount_provider_class']) ->from('mounts'); + if ($onlyUserFilesMounts) { + $qb->andWhere( + $qb->expr()->orX( + $qb->expr()->like('mount_point', $qb->createNamedParameter('/%/files/%')), + $qb->expr()->in('mount_provider_class', $qb->createNamedParameter([ + \OC\Files\Mount\LocalHomeMountProvider::class, + \OC\Files\Mount\ObjectHomeMountProvider::class, + ], IQueryBuilder::PARAM_STR_ARRAY)) + ) + ); + } if (count($mountProviders) > 0) { - $qb->where($qb->expr()->in('mount_provider_class', $qb->createPositionalParameter($mountProviders, IQueryBuilder::PARAM_STR_ARRAY))); + $qb->andWhere($qb->expr()->in('mount_provider_class', $qb->createNamedParameter($mountProviders, IQueryBuilder::PARAM_STR_ARRAY))); } $qb->orderBy('root_id', 'ASC'); $result = $qb->executeQuery(); @@ -177,7 +188,7 @@ class FileAccess implements IFileAccess { $overrideRoot = $rootId; // LocalHomeMountProvider is the default provider for user home directories // ObjectHomeMountProvider is the home directory provider for when S3 primary storage is used - if ($rewriteHomeDirectories && in_array($row['mount_provider_class'], [ + if ($onlyUserFilesMounts && in_array($row['mount_provider_class'], [ \OC\Files\Mount\LocalHomeMountProvider::class, \OC\Files\Mount\ObjectHomeMountProvider::class, ], true)) { diff --git a/lib/public/Files/Cache/IFileAccess.php b/lib/public/Files/Cache/IFileAccess.php index be6257382ad..7a993d81e7a 100644 --- a/lib/public/Files/Cache/IFileAccess.php +++ b/lib/public/Files/Cache/IFileAccess.php @@ -104,11 +104,11 @@ interface IFileAccess { * Optionally rewrites home directory root paths to avoid cache and trashbin. * * @param list<string> $mountProviders An array of mount provider class names to filter. If empty, all providers will be included. - * @param bool $rewriteHomeDirectories Whether to rewrite the root path IDs for home directories to only include user files. + * @param bool $onlyUserFilesMounts Whether to rewrite the root IDs for home directories to only include user files and to only consider mounts with mount points in the user files. * @return \Generator<array{storage_id: int, root_id: int, overridden_root: int}> A generator yielding mount configurations as an array containing 'storage_id', 'root_id', and 'override_root'. * @throws \OCP\DB\Exception * * @since 32.0.0 */ - public function getDistinctMounts(array $mountProviders = [], bool $rewriteHomeDirectories = true): \Generator; + public function getDistinctMounts(array $mountProviders = [], bool $onlyUserFilesMounts = true): \Generator; } diff --git a/tests/lib/Files/Cache/FileAccessTest.php b/tests/lib/Files/Cache/FileAccessTest.php index e856488f176..59fa2494ea8 100644 --- a/tests/lib/Files/Cache/FileAccessTest.php +++ b/tests/lib/Files/Cache/FileAccessTest.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -71,15 +72,25 @@ class FileAccessTest extends TestCase { 'user_id' => $queryBuilder->createNamedParameter('test'), ]) ->executeStatement(); + + $queryBuilder->insert('mounts') + ->values([ + 'storage_id' => $queryBuilder->createNamedParameter(4, IQueryBuilder::PARAM_INT), + 'root_id' => $queryBuilder->createNamedParameter(31, IQueryBuilder::PARAM_INT), + 'mount_provider_class' => $queryBuilder->createNamedParameter('TestProviderClass2'), + 'mount_point' => $queryBuilder->createNamedParameter('/foobar'), + 'user_id' => $queryBuilder->createNamedParameter('test'), + ]) + ->executeStatement(); } /** * Test that getDistinctMounts returns all mounts without filters */ public function testGetDistinctMountsWithoutFilters(): void { - $result = iterator_to_array($this->fileAccess->getDistinctMounts()); + $result = iterator_to_array($this->fileAccess->getDistinctMounts([], false)); - $this->assertCount(2, $result); + $this->assertCount(3, $result); $this->assertEquals([ 'storage_id' => 1, @@ -92,13 +103,19 @@ class FileAccessTest extends TestCase { 'root_id' => 30, 'overridden_root' => 30, ], $result[1]); + + $this->assertEquals([ + 'storage_id' => 4, + 'root_id' => 31, + 'overridden_root' => 31, + ], $result[2]); } /** * Test that getDistinctMounts applies filtering by mount providers */ public function testGetDistinctMountsWithMountProviderFilter(): void { - $result = iterator_to_array($this->fileAccess->getDistinctMounts(['TestProviderClass1'])); + $result = iterator_to_array($this->fileAccess->getDistinctMounts(['TestProviderClass1'], false)); $this->assertCount(2, $result); @@ -131,6 +148,18 @@ class FileAccessTest extends TestCase { ]) ->executeStatement(); + // Add a mount that is mounted in the home directory + $queryBuilder = $this->dbConnection->getQueryBuilder(); + $queryBuilder->insert('mounts') + ->values([ + 'storage_id' => $queryBuilder->createNamedParameter(5, IQueryBuilder::PARAM_INT), + 'root_id' => $queryBuilder->createNamedParameter(41, IQueryBuilder::PARAM_INT), + 'mount_provider_class' => $queryBuilder->createNamedParameter('TestMountProvider3'), + 'mount_point' => $queryBuilder->createNamedParameter('/test/files/foobar'), + 'user_id' => $queryBuilder->createNamedParameter('test'), + ]) + ->executeStatement(); + // Simulate adding a "files" directory to the filecache table $queryBuilder = $this->dbConnection->getQueryBuilder()->runAcrossAllShards(); $queryBuilder->delete('filecache')->executeStatement(); @@ -148,11 +177,19 @@ class FileAccessTest extends TestCase { $result = iterator_to_array($this->fileAccess->getDistinctMounts()); + $this->assertCount(2, $result); + $this->assertEquals([ 'storage_id' => 4, 'root_id' => 40, 'overridden_root' => 99, - ], end($result)); + ], $result[0]); + + $this->assertEquals([ + 'storage_id' => 5, + 'root_id' => 41, + 'overridden_root' => 41, + ], $result[1]); } private function setUpTestDatabaseForGetByAncestorInStorage(): void { |