Skip to content

Commit 8da1a9b

Browse files
icewind1991nickvergessen
authored andcommitted
fix(operation): Improve getNode logic
Signed-off-by: Robin Appelman <robin@icewind.nl>
1 parent 97f204d commit 8da1a9b

4 files changed

Lines changed: 42 additions & 45 deletions

File tree

‎lib/CacheWrapper.php‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
namespace OCA\FilesAccessControl;
1010

1111
use OC\Files\Cache\Wrapper\CacheWrapper as Wrapper;
12+
use OC\Files\Storage\Wrapper\Jail;
1213
use OCP\Constants;
1314
use OCP\Files\Cache\ICache;
1415
use OCP\Files\ForbiddenException;
@@ -17,14 +18,15 @@
1718

1819
class CacheWrapper extends Wrapper {
1920
protected readonly int $mask;
21+
protected readonly IStorage $storage;
2022

2123
public function __construct(
2224
ICache $cache,
23-
protected readonly IStorage $storage,
2425
protected readonly IMountPoint $mountPoint,
2526
protected readonly Operation $operation,
2627
) {
2728
parent::__construct($cache);
29+
$this->storage = $mountPoint->getStorage();
2830
$this->mask = Constants::PERMISSION_ALL
2931
& ~Constants::PERMISSION_READ
3032
& ~Constants::PERMISSION_CREATE
@@ -36,7 +38,13 @@ public function __construct(
3638
protected function formatCacheEntry($entry) {
3739
if (isset($entry['path']) && isset($entry['permissions'])) {
3840
try {
39-
$this->operation->checkFileAccess($this->storage, $entry['path'], $this->mountPoint, $entry['mimetype'] === 'httpd/unix-directory', $entry);
41+
$storage = $this->storage;
42+
$path = $entry['path'];
43+
if ($storage->instanceOfStorage(Jail::class)) {
44+
/** @var Jail $storage */
45+
$path = $storage->getJailedPath($path);
46+
}
47+
$this->operation->checkFileAccess($path, $this->mountPoint, $entry['mimetype'] === 'httpd/unix-directory', $entry);
4048
} catch (ForbiddenException) {
4149
$entry['permissions'] &= $this->mask;
4250
}

‎lib/Operation.php‎

Lines changed: 19 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,14 @@ public function __construct(
5050
* @param array|ICacheEntry|null $cacheEntry
5151
* @throws ForbiddenException
5252
*/
53-
public function checkFileAccess(IStorage $storage, string $path, IMountPoint $mountPoint, bool $isDir, $cacheEntry = null): void {
54-
if (!$this->isBlockablePath($storage, $path) || $this->isCreatingSkeletonFiles() || $this->nestingLevel !== 0) {
53+
public function checkFileAccess(string $path, IMountPoint $mountPoint, bool $isDir, $cacheEntry = null): void {
54+
if (!$this->isBlockablePath($mountPoint, $path) || $this->isCreatingSkeletonFiles() || $this->nestingLevel !== 0) {
5555
// Allow creating skeletons and theming
5656
// https://github.com/nextcloud/files_accesscontrol/issues/5
5757
// https://github.com/nextcloud/files_accesscontrol/issues/12
5858
return;
5959
}
60+
$storage = $mountPoint->getStorage();
6061

6162
$this->nestingLevel++;
6263

@@ -80,24 +81,8 @@ public function checkFileAccess(IStorage $storage, string $path, IMountPoint $mo
8081
}
8182
}
8283

83-
protected function isBlockablePath(IStorage $storage, string $path): bool {
84-
if (property_exists($storage, 'mountPoint')) {
85-
$hasMountPoint = $storage instanceof StorageWrapper;
86-
if (!$hasMountPoint) {
87-
$ref = new ReflectionClass($storage);
88-
$prop = $ref->getProperty('mountPoint');
89-
$hasMountPoint = $prop->isPublic();
90-
}
91-
92-
if ($hasMountPoint) {
93-
/** @var StorageWrapper $storage */
94-
$fullPath = $storage->mountPoint . ltrim($path, '/');
95-
} else {
96-
$fullPath = $path;
97-
}
98-
} else {
99-
$fullPath = $path;
100-
}
84+
protected function isBlockablePath(IMountPoint $mountPoint, string $path): bool {
85+
$fullPath = $mountPoint->getMountPoint() . ltrim($path, '/');
10186

10287
if (substr_count($fullPath, '/') < 3) {
10388
return false;
@@ -299,22 +284,20 @@ public function onEvent(string $eventName, Event $event, IRuleMatcher $ruleMatch
299284

300285
private function getNode(string $path, IMountPoint $mountPoint, ICacheEntry|array|null $cacheEntry = null): ?Node {
301286
$fullPath = $mountPoint->getMountPoint() . $path;
302-
if ($cacheEntry) {
303-
// todo: LazyNode?
304-
$info = new FileInfo($fullPath, $mountPoint->getStorage(), $path, $cacheEntry, $mountPoint);
305-
$isDir = $info->getType() === \OCP\Files\FileInfo::TYPE_FOLDER;
306-
$view = new View('');
307-
if ($isDir) {
308-
return new Folder($this->rootFolder, $view, $path, $info);
309-
} else {
310-
return new \OC\Files\Node\File($this->rootFolder, $view, $path, $info);
311-
}
312-
} else {
313-
try {
314-
return $this->rootFolder->get($fullPath);
315-
} catch (NotFoundException) {
316-
return null;
317-
}
287+
if (!$cacheEntry) {
288+
$cacheEntry = $mountPoint->getStorage()->getCache()->get($path);
289+
}
290+
if (!$cacheEntry) {
291+
return null;
292+
}
293+
294+
// todo: LazyNode?
295+
$info = new FileInfo($fullPath, $mountPoint->getStorage(), $path, $cacheEntry, $mountPoint);
296+
$isDir = $info->getType() === FileInfo::TYPE_FOLDER;
297+
$view = new View('');
298+
if ($isDir) {
299+
return new Folder($this->rootFolder, $view, $path, $info);
318300
}
301+
return new \OC\Files\Node\File($this->rootFolder, $view, $path, $info);
319302
}
320303
}

‎lib/StorageWrapper.php‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function __construct($parameters) {
4343
* @throws ForbiddenException
4444
*/
4545
protected function checkFileAccess(string $path, ?bool $isDir = null): void {
46-
$this->operation->checkFileAccess($this, $path, $this->mount, is_bool($isDir) ? $isDir : $this->is_dir($path));
46+
$this->operation->checkFileAccess($path, $this->mount, is_bool($isDir) ? $isDir : $this->is_dir($path));
4747
}
4848

4949
/*
@@ -264,7 +264,7 @@ public function getCache($path = '', $storage = null): ICache {
264264
$storage = $this;
265265
}
266266
$cache = $this->storage->getCache($path, $storage);
267-
return new CacheWrapper($cache, $storage, $this->operation, $this->mount);
267+
return new CacheWrapper($cache, $this->operation, $this->mount);
268268
}
269269

270270
/**

‎tests/Unit/StorageWrapperTest.php‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,30 @@ class StorageWrapperTest extends TestCase {
2020
protected IStorage&MockObject $storage;
2121
protected Operation&MockObject $operation;
2222

23+
/** @var IMountPoint|MockObject */
24+
protected $mountPoint;
25+
2326
protected function setUp(): void {
2427
parent::setUp();
2528

2629
$this->storage = $this->createMock(IStorage::class);
2730
$this->operation = $this->createMock(Operation::class);
31+
32+
$this->mountPoint = $this->createMock(IMountPoint::class);
33+
$this->mountPoint->method('getMountPoint')
34+
->willReturn('mountPoint');
35+
$this->mountPoint->method('getStorage')
36+
->willReturn($this->storage);
2837
}
2938

3039
protected function getInstance(array $methods = []): StorageWrapper&MockObject {
31-
$mount = $this->createMock(IMountPoint::class);
32-
$mount->method('getMountPoint')
33-
->willReturn('mountPoint');
3440
return $this->getMockBuilder(StorageWrapper::class)
3541
->setConstructorArgs([
3642
[
3743
'storage' => $this->storage,
3844
'mountPoint' => 'mountPoint',
45+
'mount' => $this->mountPoint,
3946
'operation' => $this->operation,
40-
'mount' => $mount,
4147
]
4248
])
4349
->onlyMethods($methods)
@@ -59,7 +65,7 @@ public function testCheckFileAccess(string $path, bool $isDir): void {
5965

6066
$this->operation->expects($this->once())
6167
->method('checkFileAccess')
62-
->with($storage, $path, $this->createMock(IMountPoint::class), false);
68+
->with($path, $this->mountPoint, $isDir);
6369

6470
self::invokePrivate($storage, 'checkFileAccess', [$path, $isDir]);
6571
}

0 commit comments

Comments
 (0)