Skip to content

Commit 43be97d

Browse files
committed
fix(FileAccess): Use one param for rewriting home dirs and excluding non-user files mounts
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
1 parent 3a96f8e commit 43be97d

3 files changed

Lines changed: 57 additions & 9 deletions

File tree

lib/private/Files/Cache/FileAccess.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,23 @@ public function getByAncestorInStorage(int $storageId, int $folderId, int $fileI
158158
$files->closeCursor();
159159
}
160160

161-
public function getDistinctMounts(array $mountProviders = [], bool $rewriteHomeDirectories = true): \Generator {
161+
public function getDistinctMounts(array $mountProviders = [], bool $onlyUserFilesMounts = true): \Generator {
162162
$qb = $this->connection->getQueryBuilder();
163163
$qb->selectDistinct(['root_id', 'storage_id', 'mount_provider_class'])
164164
->from('mounts');
165+
if ($onlyUserFilesMounts) {
166+
$qb->andWhere(
167+
$qb->expr()->orX(
168+
$qb->expr()->like('mount_point', $qb->createNamedParameter('/%/files/%')),
169+
$qb->expr()->in('mount_provider_class', $qb->createNamedParameter([
170+
\OC\Files\Mount\LocalHomeMountProvider::class,
171+
\OC\Files\Mount\ObjectHomeMountProvider::class,
172+
], IQueryBuilder::PARAM_STR_ARRAY))
173+
)
174+
);
175+
}
165176
if (count($mountProviders) > 0) {
166-
$qb->where($qb->expr()->in('mount_provider_class', $qb->createPositionalParameter($mountProviders, IQueryBuilder::PARAM_STR_ARRAY)));
177+
$qb->andWhere($qb->expr()->in('mount_provider_class', $qb->createNamedParameter($mountProviders, IQueryBuilder::PARAM_STR_ARRAY)));
167178
}
168179
$qb->orderBy('root_id', 'ASC');
169180
$result = $qb->executeQuery();
@@ -177,7 +188,7 @@ public function getDistinctMounts(array $mountProviders = [], bool $rewriteHomeD
177188
$overrideRoot = $rootId;
178189
// LocalHomeMountProvider is the default provider for user home directories
179190
// ObjectHomeMountProvider is the home directory provider for when S3 primary storage is used
180-
if ($rewriteHomeDirectories && in_array($row['mount_provider_class'], [
191+
if ($onlyUserFilesMounts && in_array($row['mount_provider_class'], [
181192
\OC\Files\Mount\LocalHomeMountProvider::class,
182193
\OC\Files\Mount\ObjectHomeMountProvider::class,
183194
], true)) {

lib/public/Files/Cache/IFileAccess.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,11 @@ public function getByAncestorInStorage(int $storageId, int $folderId, int $fileI
104104
* Optionally rewrites home directory root paths to avoid cache and trashbin.
105105
*
106106
* @param list<string> $mountProviders An array of mount provider class names to filter. If empty, all providers will be included.
107-
* @param bool $rewriteHomeDirectories Whether to rewrite the root path IDs for home directories to only include user files.
107+
* @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.
108108
* @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'.
109109
* @throws \OCP\DB\Exception
110110
*
111111
* @since 32.0.0
112112
*/
113-
public function getDistinctMounts(array $mountProviders = [], bool $rewriteHomeDirectories = true): \Generator;
113+
public function getDistinctMounts(array $mountProviders = [], bool $onlyUserFilesMounts = true): \Generator;
114114
}

tests/lib/Files/Cache/FileAccessTest.php

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
/**
34
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
45
* SPDX-License-Identifier: AGPL-3.0-or-later
@@ -71,15 +72,25 @@ private function setUpTestDatabaseForGetDistinctMounts(): void {
7172
'user_id' => $queryBuilder->createNamedParameter('test'),
7273
])
7374
->executeStatement();
75+
76+
$queryBuilder->insert('mounts')
77+
->values([
78+
'storage_id' => $queryBuilder->createNamedParameter(4, IQueryBuilder::PARAM_INT),
79+
'root_id' => $queryBuilder->createNamedParameter(31, IQueryBuilder::PARAM_INT),
80+
'mount_provider_class' => $queryBuilder->createNamedParameter('TestProviderClass2'),
81+
'mount_point' => $queryBuilder->createNamedParameter('/foobar'),
82+
'user_id' => $queryBuilder->createNamedParameter('test'),
83+
])
84+
->executeStatement();
7485
}
7586

7687
/**
7788
* Test that getDistinctMounts returns all mounts without filters
7889
*/
7990
public function testGetDistinctMountsWithoutFilters(): void {
80-
$result = iterator_to_array($this->fileAccess->getDistinctMounts());
91+
$result = iterator_to_array($this->fileAccess->getDistinctMounts([], false));
8192

82-
$this->assertCount(2, $result);
93+
$this->assertCount(3, $result);
8394

8495
$this->assertEquals([
8596
'storage_id' => 1,
@@ -92,13 +103,19 @@ public function testGetDistinctMountsWithoutFilters(): void {
92103
'root_id' => 30,
93104
'overridden_root' => 30,
94105
], $result[1]);
106+
107+
$this->assertEquals([
108+
'storage_id' => 4,
109+
'root_id' => 31,
110+
'overridden_root' => 31,
111+
], $result[2]);
95112
}
96113

97114
/**
98115
* Test that getDistinctMounts applies filtering by mount providers
99116
*/
100117
public function testGetDistinctMountsWithMountProviderFilter(): void {
101-
$result = iterator_to_array($this->fileAccess->getDistinctMounts(['TestProviderClass1']));
118+
$result = iterator_to_array($this->fileAccess->getDistinctMounts(['TestProviderClass1'], false));
102119

103120
$this->assertCount(2, $result);
104121

@@ -131,6 +148,18 @@ public function testGetDistinctMountsWithRewriteHomeDirectories(): void {
131148
])
132149
->executeStatement();
133150

151+
// Add a mount that is mounted in the home directory
152+
$queryBuilder = $this->dbConnection->getQueryBuilder();
153+
$queryBuilder->insert('mounts')
154+
->values([
155+
'storage_id' => $queryBuilder->createNamedParameter(5, IQueryBuilder::PARAM_INT),
156+
'root_id' => $queryBuilder->createNamedParameter(41, IQueryBuilder::PARAM_INT),
157+
'mount_provider_class' => $queryBuilder->createNamedParameter('TestMountProvider3'),
158+
'mount_point' => $queryBuilder->createNamedParameter('/test/files/foobar'),
159+
'user_id' => $queryBuilder->createNamedParameter('test'),
160+
])
161+
->executeStatement();
162+
134163
// Simulate adding a "files" directory to the filecache table
135164
$queryBuilder = $this->dbConnection->getQueryBuilder()->runAcrossAllShards();
136165
$queryBuilder->delete('filecache')->executeStatement();
@@ -148,11 +177,19 @@ public function testGetDistinctMountsWithRewriteHomeDirectories(): void {
148177

149178
$result = iterator_to_array($this->fileAccess->getDistinctMounts());
150179

180+
$this->assertCount(2, $result);
181+
151182
$this->assertEquals([
152183
'storage_id' => 4,
153184
'root_id' => 40,
154185
'overridden_root' => 99,
155-
], end($result));
186+
], $result[0]);
187+
188+
$this->assertEquals([
189+
'storage_id' => 5,
190+
'root_id' => 41,
191+
'overridden_root' => 41,
192+
], $result[1]);
156193
}
157194

158195
private function setUpTestDatabaseForGetByAncestorInStorage(): void {

0 commit comments

Comments
 (0)