Merge pull request #10397 from nextcloud/encryption-s3-fix
make file cache updates more robust
This commit is contained in:
commit
11e99859ef
3 changed files with 28 additions and 3 deletions
|
@ -254,7 +254,6 @@ class Encryption implements IEncryptionModule {
|
||||||
public function end($path, $position = 0) {
|
public function end($path, $position = 0) {
|
||||||
$result = '';
|
$result = '';
|
||||||
if ($this->isWriteOperation) {
|
if ($this->isWriteOperation) {
|
||||||
$this->keyManager->setVersion($path, $this->version + 1, new View());
|
|
||||||
// in case of a part file we remember the new signature versions
|
// in case of a part file we remember the new signature versions
|
||||||
// the version will be set later on update.
|
// the version will be set later on update.
|
||||||
// This way we make sure that other apps listening to the pre-hooks
|
// This way we make sure that other apps listening to the pre-hooks
|
||||||
|
|
|
@ -102,6 +102,9 @@ class Encryption extends Wrapper {
|
||||||
/** @var array */
|
/** @var array */
|
||||||
protected $expectedContextProperties;
|
protected $expectedContextProperties;
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
protected $fileUpdated;
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
$this->expectedContextProperties = array(
|
$this->expectedContextProperties = array(
|
||||||
'source',
|
'source',
|
||||||
|
@ -235,6 +238,7 @@ class Encryption extends Wrapper {
|
||||||
$this->position = 0;
|
$this->position = 0;
|
||||||
$this->cache = '';
|
$this->cache = '';
|
||||||
$this->writeFlag = false;
|
$this->writeFlag = false;
|
||||||
|
$this->fileUpdated = false;
|
||||||
$this->unencryptedBlockSize = $this->encryptionModule->getUnencryptedBlockSize($this->signed);
|
$this->unencryptedBlockSize = $this->encryptionModule->getUnencryptedBlockSize($this->signed);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -313,7 +317,6 @@ class Encryption extends Wrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stream_write($data) {
|
public function stream_write($data) {
|
||||||
|
|
||||||
$length = 0;
|
$length = 0;
|
||||||
// loop over $data to fit it in 6126 sized unencrypted blocks
|
// loop over $data to fit it in 6126 sized unencrypted blocks
|
||||||
while (isset($data[0])) {
|
while (isset($data[0])) {
|
||||||
|
@ -333,6 +336,7 @@ class Encryption extends Wrapper {
|
||||||
|
|
||||||
// switch the writeFlag so flush() will write the block
|
// switch the writeFlag so flush() will write the block
|
||||||
$this->writeFlag = true;
|
$this->writeFlag = true;
|
||||||
|
$this->fileUpdated = true;
|
||||||
|
|
||||||
// determine the relative position in the current block
|
// determine the relative position in the current block
|
||||||
$blockPosition = ($this->position % $this->unencryptedBlockSize);
|
$blockPosition = ($this->position % $this->unencryptedBlockSize);
|
||||||
|
@ -414,7 +418,18 @@ class Encryption extends Wrapper {
|
||||||
}
|
}
|
||||||
$this->encryptionStorage->updateUnencryptedSize($this->fullPath, $this->unencryptedSize);
|
$this->encryptionStorage->updateUnencryptedSize($this->fullPath, $this->unencryptedSize);
|
||||||
}
|
}
|
||||||
return parent::stream_close();
|
$result = parent::stream_close();
|
||||||
|
|
||||||
|
if ($this->fileUpdated) {
|
||||||
|
$cache = $this->storage->getCache();
|
||||||
|
$cacheEntry = $cache->get($this->internalPath);
|
||||||
|
if ($cacheEntry) {
|
||||||
|
$version = $cacheEntry['encryptedVersion'] + 1;
|
||||||
|
$cache->update($cacheEntry->getId(), ['encrypted' => $version, 'encryptedVersion' => $version]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
|
|
||||||
namespace Test\Files\Stream;
|
namespace Test\Files\Stream;
|
||||||
|
|
||||||
|
use OC\Files\Cache\CacheEntry;
|
||||||
use OC\Files\View;
|
use OC\Files\View;
|
||||||
use OC\Memcache\ArrayCache;
|
use OC\Memcache\ArrayCache;
|
||||||
|
use OCP\Files\Cache\ICache;
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
|
|
||||||
class EncryptionTest extends \Test\TestCase {
|
class EncryptionTest extends \Test\TestCase {
|
||||||
|
@ -26,6 +28,7 @@ class EncryptionTest extends \Test\TestCase {
|
||||||
$header = [];
|
$header = [];
|
||||||
$uid = '';
|
$uid = '';
|
||||||
$this->encryptionModule = $this->buildMockModule();
|
$this->encryptionModule = $this->buildMockModule();
|
||||||
|
$cache = $this->createMock(ICache::class);
|
||||||
$storage = $this->getMockBuilder('\OC\Files\Storage\Storage')
|
$storage = $this->getMockBuilder('\OC\Files\Storage\Storage')
|
||||||
->disableOriginalConstructor()->getMock();
|
->disableOriginalConstructor()->getMock();
|
||||||
$encStorage = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
|
$encStorage = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
|
||||||
|
@ -49,6 +52,13 @@ class EncryptionTest extends \Test\TestCase {
|
||||||
$util->expects($this->any())
|
$util->expects($this->any())
|
||||||
->method('getUidAndFilename')
|
->method('getUidAndFilename')
|
||||||
->willReturn(['user1', $internalPath]);
|
->willReturn(['user1', $internalPath]);
|
||||||
|
$storage->expects($this->any())->method('getCache')->willReturn($cache);
|
||||||
|
$entry = new CacheEntry([
|
||||||
|
'fileid' => 5,
|
||||||
|
'encryptedVersion' => 2,
|
||||||
|
]);
|
||||||
|
$cache->expects($this->any())->method('get')->willReturn($entry );
|
||||||
|
$cache->expects($this->any())->method('update')->with(5, ['encrypted' => 3, 'encryptedVersion' => 3]);
|
||||||
|
|
||||||
|
|
||||||
return $wrapper::wrap($source, $internalPath,
|
return $wrapper::wrap($source, $internalPath,
|
||||||
|
@ -208,6 +218,7 @@ class EncryptionTest extends \Test\TestCase {
|
||||||
|
|
||||||
public function testSeek() {
|
public function testSeek() {
|
||||||
$fileName = tempnam("/tmp", "FOO");
|
$fileName = tempnam("/tmp", "FOO");
|
||||||
|
|
||||||
$stream = $this->getStream($fileName, 'w+', 0);
|
$stream = $this->getStream($fileName, 'w+', 0);
|
||||||
$this->assertEquals(6, fwrite($stream, 'foobar'));
|
$this->assertEquals(6, fwrite($stream, 'foobar'));
|
||||||
$this->assertEquals(0, fseek($stream, 3));
|
$this->assertEquals(0, fseek($stream, 3));
|
||||||
|
|
Loading…
Reference in a new issue