diff options
author | Robin Appelman <robin@icewind.nl> | 2021-07-28 17:03:33 +0200 |
---|---|---|
committer | Robin Appelman <robin@icewind.nl> | 2021-07-28 17:21:04 +0200 |
commit | 5c2e7c7d284d92a802a9a673136383a991b36ee6 (patch) | |
tree | 9a7b1f10409fd9ee8c1278d1e1a81c636e968274 /lib/private/Files/Node/Folder.php | |
parent | 3ced8406a0f244d4a46f1feb10531220bd4a86e7 (diff) | |
download | nextcloud-server-5c2e7c7d284d92a802a9a673136383a991b36ee6.tar.gz nextcloud-server-5c2e7c7d284d92a802a9a673136383a991b36ee6.zip |
fix Folder->getById() when a single storage is mounted multiple times
Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'lib/private/Files/Node/Folder.php')
-rw-r--r-- | lib/private/Files/Node/Folder.php | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php index 1f6edfd3bbc..400fd6bedcc 100644 --- a/lib/private/Files/Node/Folder.php +++ b/lib/private/Files/Node/Folder.php @@ -37,7 +37,6 @@ use OC\Files\Search\SearchComparison; use OC\Files\Search\SearchOrder; use OC\Files\Search\SearchQuery; use OCP\Files\Cache\ICacheEntry; -use OCP\Files\Config\ICachedMountInfo; use OCP\Files\FileInfo; use OCP\Files\Mount\IMountPoint; use OCP\Files\NotFoundException; @@ -350,17 +349,28 @@ class Folder extends Node implements \OCP\Files\Folder { $user = null; } $mountsContainingFile = $mountCache->getMountsForFileId((int)$id, $user); + + // when a user has access trough the same storage trough multiple paths + // (such as an external storage that is both mounted for a user and shared to the user) + // the mount cache will only hold a single entry for the storage + // this can lead to issues as the different ways the user has access to a storage can have different permissions + // + // so instead of using the cached entries directly, we instead filter the current mounts by the rootid of the cache entry + + $mountRootIds = array_map(function ($mount) { + return $mount->getRootId(); + }, $mountsContainingFile); + $mountRootPaths = array_map(function ($mount) { + return $mount->getRootInternalPath(); + }, $mountsContainingFile); + $mountRoots = array_combine($mountRootIds, $mountRootPaths); + $mounts = $this->root->getMountsIn($this->path); $mounts[] = $this->root->getMount($this->path); - /** @var IMountPoint[] $folderMounts */ - $folderMounts = array_combine(array_map(function (IMountPoint $mountPoint) { - return $mountPoint->getMountPoint(); - }, $mounts), $mounts); - /** @var ICachedMountInfo[] $mountsContainingFile */ - $mountsContainingFile = array_values(array_filter($mountsContainingFile, function (ICachedMountInfo $cachedMountInfo) use ($folderMounts) { - return isset($folderMounts[$cachedMountInfo->getMountPoint()]); - })); + $mountsContainingFile = array_filter($mounts, function ($mount) use ($mountRoots) { + return isset($mountRoots[$mount->getStorageRootId()]); + }); if (count($mountsContainingFile) === 0) { if ($user === $this->getAppDataDirectoryName()) { @@ -369,18 +379,18 @@ class Folder extends Node implements \OCP\Files\Folder { return []; } - $nodes = array_map(function (ICachedMountInfo $cachedMountInfo) use ($folderMounts, $id) { - $mount = $folderMounts[$cachedMountInfo->getMountPoint()]; + $nodes = array_map(function (IMountPoint $mount) use ($id, $mountRoots) { + $rootInternalPath = $mountRoots[$mount->getStorageRootId()]; $cacheEntry = $mount->getStorage()->getCache()->get((int)$id); if (!$cacheEntry) { return null; } // cache jails will hide the "true" internal path - $internalPath = ltrim($cachedMountInfo->getRootInternalPath() . '/' . $cacheEntry->getPath(), '/'); - $pathRelativeToMount = substr($internalPath, strlen($cachedMountInfo->getRootInternalPath())); + $internalPath = ltrim($rootInternalPath . '/' . $cacheEntry->getPath(), '/'); + $pathRelativeToMount = substr($internalPath, strlen($rootInternalPath)); $pathRelativeToMount = ltrim($pathRelativeToMount, '/'); - $absolutePath = rtrim($cachedMountInfo->getMountPoint() . $pathRelativeToMount, '/'); + $absolutePath = rtrim($mount->getMountPoint() . $pathRelativeToMount, '/'); return $this->root->createNode($absolutePath, new \OC\Files\FileInfo( $absolutePath, $mount->getStorage(), $cacheEntry->getPath(), $cacheEntry, $mount, \OC::$server->getUserManager()->get($mount->getStorage()->getOwner($pathRelativeToMount)) @@ -389,9 +399,13 @@ class Folder extends Node implements \OCP\Files\Folder { $nodes = array_filter($nodes); - return array_filter($nodes, function (Node $node) { + $folders = array_filter($nodes, function (Node $node) { return $this->getRelativePath($node->getPath()); }); + usort($folders, function ($a, $b) { + return $b->getPath() <=> $a->getPath(); + }); + return $folders; } protected function getAppDataDirectoryName(): string { |