mirror of
https://github.com/nextcloud/server.git
synced 2026-06-09 08:44:07 -04:00
refactor(Stream\Encryption): Migrate to strong types
Signed-off-by: provokateurin <kate@provokateurin.de>
This commit is contained in:
parent
bbb6cb2eb0
commit
d1977b8d25
2 changed files with 80 additions and 100 deletions
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
|
|
@ -9,81 +11,42 @@ namespace OC\Files\Stream;
|
|||
|
||||
use Icewind\Streams\Wrapper;
|
||||
use OC\Encryption\Exceptions\EncryptionHeaderKeyExistsException;
|
||||
use OC\Encryption\File;
|
||||
use OC\Encryption\Util;
|
||||
use OC\Files\Storage\Storage;
|
||||
use OCP\Encryption\IEncryptionModule;
|
||||
use function is_array;
|
||||
use function stream_context_create;
|
||||
|
||||
class Encryption extends Wrapper {
|
||||
/** @var \OC\Encryption\Util */
|
||||
protected $util;
|
||||
|
||||
/** @var \OC\Encryption\File */
|
||||
protected $file;
|
||||
|
||||
/** @var \OCP\Encryption\IEncryptionModule */
|
||||
protected $encryptionModule;
|
||||
|
||||
/** @var \OC\Files\Storage\Storage */
|
||||
protected $storage;
|
||||
|
||||
/** @var \OC\Files\Storage\Wrapper\Encryption */
|
||||
protected $encryptionStorage;
|
||||
|
||||
/** @var string */
|
||||
protected $internalPath;
|
||||
|
||||
/** @var string */
|
||||
protected $cache;
|
||||
|
||||
/** @var integer */
|
||||
protected $size;
|
||||
|
||||
/** @var integer */
|
||||
protected $position;
|
||||
|
||||
/** @var integer */
|
||||
protected $unencryptedSize;
|
||||
|
||||
/** @var integer */
|
||||
protected $headerSize;
|
||||
|
||||
/** @var integer */
|
||||
protected $unencryptedBlockSize;
|
||||
|
||||
/** @var array */
|
||||
protected $header;
|
||||
|
||||
/** @var string */
|
||||
protected $fullPath;
|
||||
|
||||
/** @var bool */
|
||||
protected $signed;
|
||||
|
||||
protected Util $util;
|
||||
protected File $file;
|
||||
protected IEncryptionModule $encryptionModule;
|
||||
protected Storage $storage;
|
||||
protected \OC\Files\Storage\Wrapper\Encryption $encryptionStorage;
|
||||
protected string $internalPath;
|
||||
protected string $cache;
|
||||
protected ?int $size = null;
|
||||
protected int $position;
|
||||
protected ?int $unencryptedSize = null;
|
||||
protected int $headerSize;
|
||||
protected int $unencryptedBlockSize;
|
||||
protected array $header;
|
||||
protected string $fullPath;
|
||||
protected bool $signed;
|
||||
/**
|
||||
* header data returned by the encryption module, will be written to the file
|
||||
* in case of a write operation
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $newHeader;
|
||||
|
||||
protected array $newHeader;
|
||||
/**
|
||||
* user who perform the read/write operation null for public access
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $uid;
|
||||
|
||||
/** @var bool */
|
||||
protected $readOnly;
|
||||
|
||||
/** @var bool */
|
||||
protected $writeFlag;
|
||||
|
||||
/** @var array */
|
||||
protected $expectedContextProperties;
|
||||
|
||||
/** @var bool */
|
||||
protected $fileUpdated;
|
||||
protected string $uid;
|
||||
protected bool $readOnly;
|
||||
protected bool $writeFlag;
|
||||
protected array $expectedContextProperties;
|
||||
protected bool $fileUpdated;
|
||||
|
||||
public function __construct() {
|
||||
$this->expectedContextProperties = [
|
||||
|
|
@ -113,11 +76,11 @@ class Encryption extends Wrapper {
|
|||
* @param string $fullPath relative to data/
|
||||
* @param array $header
|
||||
* @param string $uid
|
||||
* @param \OCP\Encryption\IEncryptionModule $encryptionModule
|
||||
* @param \OC\Files\Storage\Storage $storage
|
||||
* @param IEncryptionModule $encryptionModule
|
||||
* @param Storage $storage
|
||||
* @param \OC\Files\Storage\Wrapper\Encryption $encStorage
|
||||
* @param \OC\Encryption\Util $util
|
||||
* @param \OC\Encryption\File $file
|
||||
* @param Util $util
|
||||
* @param File $file
|
||||
* @param string $mode
|
||||
* @param int|float $size
|
||||
* @param int|float $unencryptedSize
|
||||
|
|
@ -128,19 +91,24 @@ class Encryption extends Wrapper {
|
|||
*
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
public static function wrap($source, $internalPath, $fullPath, array $header,
|
||||
public static function wrap(
|
||||
$source,
|
||||
$internalPath,
|
||||
$fullPath,
|
||||
array $header,
|
||||
$uid,
|
||||
\OCP\Encryption\IEncryptionModule $encryptionModule,
|
||||
\OC\Files\Storage\Storage $storage,
|
||||
IEncryptionModule $encryptionModule,
|
||||
Storage $storage,
|
||||
\OC\Files\Storage\Wrapper\Encryption $encStorage,
|
||||
\OC\Encryption\Util $util,
|
||||
\OC\Encryption\File $file,
|
||||
Util $util,
|
||||
File $file,
|
||||
$mode,
|
||||
$size,
|
||||
$unencryptedSize,
|
||||
$headerSize,
|
||||
$signed,
|
||||
$wrapper = Encryption::class) {
|
||||
$wrapper = Encryption::class,
|
||||
) {
|
||||
$context = stream_context_create([
|
||||
'ocencryption' => [
|
||||
'source' => $source,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
|
||||
|
|
@ -7,27 +10,27 @@
|
|||
namespace Test\Files\Stream;
|
||||
|
||||
use OC\Files\Cache\CacheEntry;
|
||||
use OC\Files\Storage\Wrapper\Wrapper;
|
||||
use OC\Files\View;
|
||||
use OC\Memcache\ArrayCache;
|
||||
use OCP\Encryption\IEncryptionModule;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\Cache\ICache;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IConfig;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class EncryptionTest extends \Test\TestCase {
|
||||
public const DEFAULT_WRAPPER = '\OC\Files\Stream\Encryption';
|
||||
|
||||
/** @var \OCP\Encryption\IEncryptionModule | \PHPUnit\Framework\MockObject\MockObject */
|
||||
private $encryptionModule;
|
||||
private IEncryptionModule&MockObject $encryptionModule;
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
* @param string $mode
|
||||
* @param integer $unencryptedSize
|
||||
* @param class-string<Wrapper> $wrapper
|
||||
* @return resource
|
||||
*/
|
||||
protected function getStream($fileName, $mode, $unencryptedSize, $wrapper = self::DEFAULT_WRAPPER, $unencryptedSizeOnClose = 0) {
|
||||
protected function getStream(string $fileName, string $mode, int $unencryptedSize, string $wrapper = self::DEFAULT_WRAPPER, int $unencryptedSizeOnClose = 0) {
|
||||
clearstatcache();
|
||||
$size = filesize($fileName);
|
||||
$source = fopen($fileName, $mode);
|
||||
|
|
@ -74,23 +77,39 @@ class EncryptionTest extends \Test\TestCase {
|
|||
$cache->expects($this->any())->method('get')->willReturn($entry);
|
||||
$cache->expects($this->any())->method('update')->with(5, ['encrypted' => 3, 'encryptedVersion' => 3, 'unencrypted_size' => $unencryptedSizeOnClose]);
|
||||
|
||||
|
||||
return $wrapper::wrap($source, $internalPath,
|
||||
$fullPath, $header, $uid, $this->encryptionModule, $storage, $encStorage,
|
||||
$util, $file, $mode, $size, $unencryptedSize, 8192, $wrapper);
|
||||
return $wrapper::wrap(
|
||||
$source,
|
||||
$internalPath,
|
||||
$fullPath,
|
||||
$header,
|
||||
$uid,
|
||||
$this->encryptionModule,
|
||||
$storage,
|
||||
$encStorage,
|
||||
$util,
|
||||
$file,
|
||||
$mode,
|
||||
$size,
|
||||
$unencryptedSize,
|
||||
8192,
|
||||
true,
|
||||
$wrapper,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProviderStreamOpen()
|
||||
*/
|
||||
public function testStreamOpen($isMasterKeyUsed,
|
||||
public function testStreamOpen(
|
||||
$isMasterKeyUsed,
|
||||
$mode,
|
||||
$fullPath,
|
||||
$fileExists,
|
||||
$expectedSharePath,
|
||||
$expectedSize,
|
||||
$expectedUnencryptedSize,
|
||||
$expectedReadOnly): void {
|
||||
$expectedReadOnly,
|
||||
): void {
|
||||
// build mocks
|
||||
$encryptionModuleMock = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule')
|
||||
->disableOriginalConstructor()->getMock();
|
||||
|
|
@ -98,7 +117,7 @@ class EncryptionTest extends \Test\TestCase {
|
|||
$encryptionModuleMock->expects($this->once())
|
||||
->method('getUnencryptedBlockSize')->willReturn(99);
|
||||
$encryptionModuleMock->expects($this->once())
|
||||
->method('begin')->willReturn(true);
|
||||
->method('begin')->willReturn([]);
|
||||
|
||||
$storageMock = $this->getMockBuilder('\OC\Files\Storage\Storage')
|
||||
->disableOriginalConstructor()->getMock();
|
||||
|
|
@ -152,6 +171,8 @@ class EncryptionTest extends \Test\TestCase {
|
|||
$header->setValue($streamWrapper, []);
|
||||
$header->setAccessible(false);
|
||||
$this->invokePrivate($streamWrapper, 'signed', [true]);
|
||||
$this->invokePrivate($streamWrapper, 'internalPath', [$fullPath]);
|
||||
$this->invokePrivate($streamWrapper, 'uid', ['test']);
|
||||
|
||||
// call stream_open, that's the method we want to test
|
||||
$dummyVar = 'foo';
|
||||
|
|
@ -160,23 +181,17 @@ class EncryptionTest extends \Test\TestCase {
|
|||
// check internal properties
|
||||
$size = $stream->getProperty('size');
|
||||
$size->setAccessible(true);
|
||||
$this->assertSame($expectedSize,
|
||||
$size->getValue($streamWrapper)
|
||||
);
|
||||
$this->assertSame($expectedSize, $size->getValue($streamWrapper));
|
||||
$size->setAccessible(false);
|
||||
|
||||
$unencryptedSize = $stream->getProperty('unencryptedSize');
|
||||
$unencryptedSize->setAccessible(true);
|
||||
$this->assertSame($expectedUnencryptedSize,
|
||||
$unencryptedSize->getValue($streamWrapper)
|
||||
);
|
||||
$this->assertSame($expectedUnencryptedSize, $unencryptedSize->getValue($streamWrapper));
|
||||
$unencryptedSize->setAccessible(false);
|
||||
|
||||
$readOnly = $stream->getProperty('readOnly');
|
||||
$readOnly->setAccessible(true);
|
||||
$this->assertSame($expectedReadOnly,
|
||||
$readOnly->getValue($streamWrapper)
|
||||
);
|
||||
$this->assertSame($expectedReadOnly, $readOnly->getValue($streamWrapper));
|
||||
$readOnly->setAccessible(false);
|
||||
}
|
||||
|
||||
|
|
@ -335,10 +350,7 @@ class EncryptionTest extends \Test\TestCase {
|
|||
unlink($fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \PHPUnit\Framework\MockObject\MockObject
|
||||
*/
|
||||
protected function buildMockModule() {
|
||||
protected function buildMockModule(): IEncryptionModule&MockObject {
|
||||
$encryptionModule = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize', 'isReadable', 'encryptAll', 'prepareDecryptAll', 'isReadyForUser', 'needDetailedAccessList'])
|
||||
|
|
|
|||
Loading…
Reference in a new issue