diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml
index 5216a3ef43253..cc380846d23ac 100644
--- a/build/psalm-baseline.xml
+++ b/build/psalm-baseline.xml
@@ -3719,17 +3719,12 @@
mountManager->findByNumericId($numericId)]]>
mountManager->findByStorageId($storageId)]]>
mountManager->findIn($mountPoint)]]>
- user]]>
-
-
- user]]>
-
diff --git a/lib/private/Files/Mount/Manager.php b/lib/private/Files/Mount/Manager.php
index b763697387dd7..72b38f38575b7 100644
--- a/lib/private/Files/Mount/Manager.php
+++ b/lib/private/Files/Mount/Manager.php
@@ -230,11 +230,11 @@ public function getSetupManager(): SetupManager {
}
/**
- * Return all mounts in a path from a specific mount provider
+ * Return all mounts in a path from a specific mount provider, indexed by mount point
*
* @param string $path
* @param string[] $mountProviders
- * @return IMountPoint[]
+ * @return array
*/
public function getMountsByMountProvider(string $path, array $mountProviders) {
$this->getSetupManager()->setupForProvider($path, $mountProviders);
diff --git a/lib/private/Files/Node/Root.php b/lib/private/Files/Node/Root.php
index 9b0a48fa296fd..3354e4653f4fe 100644
--- a/lib/private/Files/Node/Root.php
+++ b/lib/private/Files/Node/Root.php
@@ -5,6 +5,7 @@
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
+
namespace OC\Files\Node;
use OC\Files\FileInfo;
@@ -19,6 +20,8 @@
use OCP\Cache\CappedMemoryCache;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Cache\ICacheEntry;
+use OCP\Files\Config\ICachedMountFileInfo;
+use OCP\Files\Config\ICachedMountInfo;
use OCP\Files\Config\IUserMountCache;
use OCP\Files\Events\Node\FilesystemTornDownEvent;
use OCP\Files\IRootFolder;
@@ -82,10 +85,8 @@ public function __construct(
/**
* Get the user for which the filesystem is setup
- *
- * @return \OC\User\User
*/
- public function getUser() {
+ public function getUser(): ?IUser {
return $this->user;
}
@@ -405,17 +406,18 @@ public function getFirstNodeByIdInPath(int $id, string $path): ?INode {
*/
public function getByIdInPath(int $id, string $path): array {
$mountCache = $this->getUserMountCache();
+ $setupManager = $this->mountManager->getSetupManager();
if ($path !== '' && strpos($path, '/', 1) > 0) {
[, $user] = explode('/', $path);
} else {
$user = null;
}
- $mountsContainingFile = $mountCache->getMountsForFileId($id, $user);
+ $mountInfosContainingFiles = $mountCache->getMountsForFileId($id, $user);
// if the mount isn't in the cache yet, perform a setup first, then try again
- if (count($mountsContainingFile) === 0) {
- $this->mountManager->getSetupManager()->setupForPath($path, true);
- $mountsContainingFile = $mountCache->getMountsForFileId($id, $user);
+ if (count($mountInfosContainingFiles) === 0) {
+ $setupManager->setupForPath($path, true);
+ $mountInfosContainingFiles = $mountCache->getMountsForFileId($id, $user);
}
// when a user has access through the same storage through multiple paths
@@ -427,20 +429,31 @@ public function getByIdInPath(int $id, string $path): array {
$mountRootIds = array_map(function ($mount) {
return $mount->getRootId();
- }, $mountsContainingFile);
+ }, $mountInfosContainingFiles);
$mountRootPaths = array_map(function ($mount) {
return $mount->getRootInternalPath();
- }, $mountsContainingFile);
+ }, $mountInfosContainingFiles);
$mountProviders = array_unique(array_map(function ($mount) {
return $mount->getMountProvider();
- }, $mountsContainingFile));
+ }, $mountInfosContainingFiles));
+ $mountPoints = array_map(fn (ICachedMountInfo $mountInfo) => $mountInfo->getMountPoint(), $mountInfosContainingFiles);
$mountRoots = array_combine($mountRootIds, $mountRootPaths);
$mounts = $this->mountManager->getMountsByMountProvider($path, $mountProviders);
+ $mountsContainingFile = array_filter($mounts, fn (IMountPoint $mount) => in_array($mount->getMountPoint(), $mountPoints));
- $mountsContainingFile = array_filter($mounts, function ($mount) use ($mountRoots) {
- return isset($mountRoots[$mount->getStorageRootId()]);
- });
+ if (count($mountsContainingFile) == 0 && count($mountsContainingFile) > 0) {
+ if (!$user) {
+ $user = $this->getUser()?->getUID();
+ }
+ if (!$user) {
+ /** @var ICachedMountFileInfo $firstMount */
+ $firstMount = current($mountInfosContainingFiles);
+ $user = $firstMount->getUser()->getUID();
+ }
+ $mountInfosContainingFiles = array_filter($mountInfosContainingFiles, fn (ICachedMountInfo $mountInfo) => $mountInfo->getUser()->getUID() === $user);
+ $mountsContainingFile = array_filter(array_map($this->mountManager->getMountFromMountInfo(...), $mountInfosContainingFiles));
+ }
if (count($mountsContainingFile) === 0) {
if ($user === $this->getAppDataDirectoryName()) {
diff --git a/lib/private/Files/SetupManager.php b/lib/private/Files/SetupManager.php
index df0fd5a2d52d9..d23314ace2199 100644
--- a/lib/private/Files/SetupManager.php
+++ b/lib/private/Files/SetupManager.php
@@ -434,8 +434,8 @@ public function setupRoot(): void {
* @param string $path
* @return IUser|null
*/
- private function getUserForPath(string $path): ?IUser {
- if ($path === '' || $path === '/') {
+ private function getUserForPath(string $path, bool $includeChildren = false): ?IUser {
+ if (($path === '' || $path === '/') && !$includeChildren) {
return null;
} elseif (str_starts_with($path, '/__groupfolders')) {
return null;
@@ -456,7 +456,7 @@ private function getUserForPath(string $path): ?IUser {
#[Override]
public function setupForPath(string $path, bool $includeChildren = false): void {
- $user = $this->getUserForPath($path);
+ $user = $this->getUserForPath($path, $includeChildren);
if (!$user) {
$this->setupRoot();
return;
diff --git a/tests/lib/Files/Node/FolderTest.php b/tests/lib/Files/Node/FolderTest.php
index ad60cb535558c..e0ed345049bf1 100644
--- a/tests/lib/Files/Node/FolderTest.php
+++ b/tests/lib/Files/Node/FolderTest.php
@@ -29,6 +29,7 @@
use OC\Files\View;
use OCP\Constants;
use OCP\Files\Cache\ICacheEntry;
+use OCP\Files\Config\ICachedMountInfo;
use OCP\Files\InvalidPathException;
use OCP\Files\IRootFolder;
use OCP\Files\Mount\IMountPoint;
@@ -538,6 +539,8 @@ public function testGetById(): void {
->with('/bar/foo')
->willReturn([]);
+ $manager->method('getMountFromMountInfo')
+ ->willReturn($mount);
$manager->method('getMountsByMountProvider')
->willReturn([$mount]);
@@ -583,6 +586,8 @@ public function testGetByIdMountRoot(): void {
->with(1)
->willReturn($fileInfo);
+ $manager->method('getMountFromMountInfo')
+ ->willReturn($mount);
$manager->method('getMountsByMountProvider')
->willReturn([$mount]);
@@ -628,6 +633,8 @@ public function testGetByIdOutsideFolder(): void {
->with(1)
->willReturn($fileInfo);
+ $manager->method('getMountFromMountInfo')
+ ->willReturn($mount);
$manager->method('getMountsByMountProvider')
->willReturn([$mount]);
@@ -668,12 +675,31 @@ public function testGetByIdMultipleStorages(): void {
1,
''
),
+ new CachedMountInfo(
+ $this->user,
+ 1,
+ 0,
+ '/bar/foo/asd/',
+ 'test',
+ 1,
+ ''
+ ),
]);
$cache->method('get')
->with(1)
->willReturn($fileInfo);
+ $manager->method('getMountFromMountInfo')
+ ->willReturnCallback(function (ICachedMountInfo $mountInfo) use ($mount1, $mount2) {
+ if ($mountInfo->getMountPoint() === $mount1->getMountPoint()) {
+ return $mount1;
+ }
+ if ($mountInfo->getMountPoint() === $mount2->getMountPoint()) {
+ return $mount2;
+ }
+ return null;
+ });
$manager->method('getMountsByMountProvider')
->willReturn([$mount1, $mount2]);