Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\Storage\IStorage;
use OCP\Util;
use OCP\WorkflowEngine\Events\RegisterOperationsEvent;
Expand All @@ -40,13 +41,14 @@ public function addStorageWrapper(): void {
* @param IStorage $storage
* @return StorageWrapper|IStorage
*/
public function addStorageWrapperCallback($mountPoint, IStorage $storage) {
public function addStorageWrapperCallback($mountPoint, IStorage $storage, IMountPoint $mount) {
if (!OC::$CLI && $mountPoint !== '/') {
/** @var Operation $operation */
$operation = $this->getContainer()->get(Operation::class);
return new StorageWrapper([
'storage' => $storage,
'mountPoint' => $mountPoint,
'mount' => $mount,
'operation' => $operation,
]);
}
Expand Down
15 changes: 11 additions & 4 deletions lib/Operation.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,17 @@ public function onEvent(string $eventName, Event $event, IRuleMatcher $ruleMatch
* @param array|ICacheEntry|null $cacheEntry
*/
private function getNode(IStorage $storage, string $path, $cacheEntry = null): ?Node {
/** @var IMountPoint|false $mountPoint */
$mountPoint = current($this->mountManager->findByStorageId($storage->getId()));
if (!$mountPoint) {
return null;
if ($storage->instanceOfStorage(StorageWrapper::class)) {
/** @var StorageWrapper $storage */
$mountPoint = $storage->getMount();
} else {
// fairly sure this branch is never taken, but not 100%

/** @var IMountPoint|false $mountPoint */
$mountPoint = current($this->mountManager->findByStorageId($storage->getId()));
if (!$mountPoint) {
return null;
}
}

$fullPath = $mountPoint->getMountPoint() . $path;
Expand Down
24 changes: 15 additions & 9 deletions lib/StorageWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@

namespace OCA\FilesAccessControl;

use OC\Files\Cache\Cache;
use OC\Files\Storage\Storage;
use OC\Files\Storage\Wrapper\Wrapper;
use OCP\Constants;
use OCP\Files\Cache\ICache;
use OCP\Files\ForbiddenException;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\Storage\IStorage;
use OCP\Files\Storage\IWriteStreamStorage;

class StorageWrapper extends Wrapper implements IWriteStreamStorage {
protected readonly Operation $operation;
public readonly string $mountPoint;
protected readonly int $mask;
private readonly IMountPoint $mount;

/**
* @param array $parameters
Expand All @@ -29,6 +30,7 @@ public function __construct($parameters) {
parent::__construct($parameters);
$this->operation = $parameters['operation'];
$this->mountPoint = $parameters['mountPoint'];
$this->mount = $parameters['mount'];

$this->mask = Constants::PERMISSION_ALL
& ~Constants::PERMISSION_READ
Expand Down Expand Up @@ -152,7 +154,7 @@ public function getPermissions($path): int {
* see http://php.net/manual/en/function.file_get_contents.php
*
* @param string $path
* @return string
* @return string|false
* @throws ForbiddenException
*/
#[\Override]
Expand All @@ -165,12 +167,12 @@ public function file_get_contents($path): string|false {
* see http://php.net/manual/en/function.file_put_contents.php
*
* @param string $path
* @param string $data
* @return bool
* @param mixed $data
* @return int|float|false
* @throws ForbiddenException
*/
#[\Override]
public function file_put_contents($path, $data): int|float|false {
public function file_put_contents(string $path, mixed $data): int|float|false {
$this->checkFileAccess($path, false);
return $this->storage->file_put_contents($path, $data);
}
Expand Down Expand Up @@ -225,7 +227,7 @@ public function copy($source, $target): bool {
*
* @param string $path
* @param string $mode
* @return resource
* @return resource|false
* @throws ForbiddenException
*/
#[\Override]
Expand Down Expand Up @@ -254,7 +256,7 @@ public function touch($path, $mtime = null): bool {
*
* @param string $path
* @param Storage (optional) the storage to pass to the cache
* @return Cache
* @return ICache
*/
#[\Override]
public function getCache($path = '', $storage = null): ICache {
Expand All @@ -271,7 +273,7 @@ public function getCache($path = '', $storage = null): ICache {
* For now the returned array can hold the parameter url - in future more attributes might follow.
*
* @param string $path
* @return array
* @return array|false
* @throws ForbiddenException
*/
#[\Override]
Expand Down Expand Up @@ -323,7 +325,7 @@ public function writeStream(string $path, $stream, ?int $size = null): int {
$this->checkFileAccess($path, false);
}

$result = $this->storage->writeStream($path, $stream, $size);
$result = parent::writeStream($path, $stream, $size);
if (!$this->isPartFile($path)) {
return $result;
}
Expand All @@ -343,4 +345,8 @@ private function isPartFile(string $path): bool {
$extension = pathinfo($path, PATHINFO_EXTENSION);
return $extension === 'part';
}

public function getMount(): IMountPoint {
return $this->mount;
}
}
3 changes: 3 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
<MoreSpecificReturnType errorLevel="error"/>
</issueHandlers>
<stubs>
<file name="tests/stubs/oc_files_cache_cache.php" />
<file name="tests/stubs/oc_hooks_emitter.php" />
<file name="tests/stubs/oc_files_cache_wrapper_cachewrapper.php" />
<file name="tests/stubs/oc_files_storage_wrapper_wrapper.php" />
</stubs>
</psalm>
5 changes: 5 additions & 0 deletions tests/Unit/StorageWrapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use OCA\FilesAccessControl\Operation;
use OCA\FilesAccessControl\StorageWrapper;
use OCP\Files\ForbiddenException;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\Storage\IStorage;
use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
Expand All @@ -27,12 +28,16 @@ protected function setUp(): void {
}

protected function getInstance(array $methods = []): StorageWrapper&MockObject {
$mount = $this->createMock(IMountPoint::class);
$mount->method('getMountPoint')
->willReturn('mountPoint');
return $this->getMockBuilder(StorageWrapper::class)
->setConstructorArgs([
[
'storage' => $this->storage,
'mountPoint' => 'mountPoint',
'operation' => $this->operation,
'mount' => $mount,
]
])
->onlyMethods($methods)
Expand Down
16 changes: 0 additions & 16 deletions tests/psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,10 @@
<code><![CDATA[OC]]></code>
</UndefinedClass>
</file>
<file src="lib/CacheWrapper.php">
<UndefinedClass>
<code><![CDATA[Wrapper]]></code>
</UndefinedClass>
</file>
<file src="lib/Operation.php">
<InvalidArgument>
<code><![CDATA[$this->fileEntity]]></code>
</InvalidArgument>
<MissingDependency>
<code><![CDATA[StorageWrapper]]></code>
</MissingDependency>
<PossiblyUndefinedArrayOffset>
<code><![CDATA[$innerPath]]></code>
</PossiblyUndefinedArrayOffset>
Expand All @@ -31,12 +23,4 @@
<code><![CDATA[protected]]></code>
</UndefinedClass>
</file>
<file src="lib/StorageWrapper.php">
<UndefinedClass>
<code><![CDATA[Wrapper]]></code>
</UndefinedClass>
<UnimplementedInterfaceMethod>
<code><![CDATA[StorageWrapper]]></code>
</UnimplementedInterfaceMethod>
</file>
</files>
77 changes: 77 additions & 0 deletions tests/stubs/oc_files_cache_cache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/

namespace OC\Files\Cache {
use OCP\Files\Cache\ICache;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\IMimeTypeLoader;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchQuery;

class Cache implements ICache {
/**
* @param \OCP\Files\Cache\ICache $cache
*/
public function __construct($cache) {
$this->cache = $cache;
}
public function getNumericStorageId() {
}
public function getIncomplete() {
}
public function getPathById($id) {
}
public function getAll() {
}
public function get($file) {
}
public function getFolderContents($folder) {
}
public function getFolderContentsById($fileId) {
}
public function put($file, array $data) {
}
public function insert($file, array $data) {
}
public function update($id, array $data) {
}
public function getId($file) {
}
public function getParentId($file) {
}
public function inCache($file) {
}
public function remove($file) {
}
public function move($source, $target) {
}
public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
}
public function clear() {
}
public function getStatus($file) {
}
public function search($pattern) {
}
public function searchByMime($mimetype) {
}
public function searchQuery(ISearchQuery $query) {
}
public function correctFolderSize($path, $data = null, $isBackgroundScan = false) {
}
public function copyFromCache(ICache $sourceCache, ICacheEntry $sourceEntry, string $targetPath): int {
}
public function normalize($path) {
}
public function getQueryFilterForStorage(): ISearchOperator {
}
public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEntry {
}
public static function cacheEntryFromData($data, IMimeTypeLoader $mimetypeLoader) {
}
}
}
21 changes: 21 additions & 0 deletions tests/stubs/oc_files_cache_wrapper_cachewrapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/

namespace OC\Files\Cache\Wrapper {

use OCP\Files\Cache\ICacheEntry;

class CacheWrapper extends \OC\Files\Cache\Cache {
/**
* @param ICacheEntry $entry
* @return ICacheEntry|false
*/
protected function formatCacheEntry($entry) {

}
}
}
Loading