fix: getById: don't setup for all users with access by default

Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
Robin Appelman 2026-01-30 17:38:56 +01:00
parent be2c26a75b
commit 72150d6deb
No known key found for this signature in database
GPG key ID: 42B69D8A64526EFB
2 changed files with 34 additions and 12 deletions

View file

@ -230,11 +230,11 @@ class Manager implements IMountManager {
}
/**
* 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<string, IMountPoint>
*/
public function getMountsByMountProvider(string $path, array $mountProviders) {
$this->getSetupManager()->setupForProvider($path, $mountProviders);

View file

@ -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 OCA\Files\ConfigLexicon;
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 @@ class Root extends Folder implements IRootFolder {
/**
* Get the user for which the filesystem is setup
*
* @return \OC\User\User
*/
public function getUser() {
public function getUser(): ?IUser {
return $this->user;
}
@ -411,12 +412,12 @@ class Root extends Folder implements IRootFolder {
} 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) {
if (count($mountInfosContainingFiles) === 0) {
$setupManager->setupForPath($path, true);
$mountsContainingFile = $mountCache->getMountsForFileId($id, $user);
$mountInfosContainingFiles = $mountCache->getMountsForFileId($id, $user);
}
// when a user has access through the same storage through multiple paths
@ -428,16 +429,37 @@ class Root extends Folder implements IRootFolder {
$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);
$mountsContainingFile = array_filter(array_map($this->mountManager->getMountFromMountInfo(...), $mountsContainingFile));
$mounts = $this->mountManager->getMountsByMountProvider($path, $mountProviders);
$mountsContainingFile = array_filter($mounts, fn (IMountPoint $mount) => in_array($mount->getMountPoint(), $mountPoints));
// if we haven't found a relevant mount that is setup, but we do have relevant mount infos
// we try to load them from the mount info.
if (count($mountsContainingFile) === 0 && count($mountInfosContainingFiles) > 0) {
// in order to minimize the cost of this, we only use the mount infos from one user.
if (!$user) {
// if we don't have a user from the path, use the user from the current filesystem setup
$user = $this->getUser()?->getUID();
}
if (!$user) {
// if there also isn't a current filesystem user, just use the user from the first mount info
/** @var ICachedMountFileInfo $firstMount */
$firstMount = current($mountInfosContainingFiles);
$user = $firstMount->getUser()->getUID();
}
// get the mount infos for the user we picked, and get the mounts for it
$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()) {