Merge pull request #10581 from nextcloud/encryption-s3-fix-stable13

make file cache updates more robust
This commit is contained in:
Roeland Jago Douma 2018-08-10 08:10:03 +02:00 committed by GitHub
commit abef061686
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 3 deletions

View File

@ -254,7 +254,6 @@ class Encryption implements IEncryptionModule {
public function end($path, $position = 0) {
$result = '';
if ($this->isWriteOperation) {
$this->keyManager->setVersion($path, $this->version + 1, new View());
// in case of a part file we remember the new signature versions
// the version will be set later on update.
// This way we make sure that other apps listening to the pre-hooks

View File

@ -102,6 +102,9 @@ class Encryption extends Wrapper {
/** @var array */
protected $expectedContextProperties;
/** @var bool */
protected $fileUpdated;
public function __construct() {
$this->expectedContextProperties = array(
'source',
@ -235,6 +238,7 @@ class Encryption extends Wrapper {
$this->position = 0;
$this->cache = '';
$this->writeFlag = false;
$this->fileUpdated = false;
$this->unencryptedBlockSize = $this->encryptionModule->getUnencryptedBlockSize($this->signed);
if (
@ -313,7 +317,6 @@ class Encryption extends Wrapper {
}
public function stream_write($data) {
$length = 0;
// loop over $data to fit it in 6126 sized unencrypted blocks
while (isset($data[0])) {
@ -333,6 +336,7 @@ class Encryption extends Wrapper {
// switch the writeFlag so flush() will write the block
$this->writeFlag = true;
$this->fileUpdated = true;
// determine the relative position in the current block
$blockPosition = ($this->position % $this->unencryptedBlockSize);
@ -414,7 +418,18 @@ class Encryption extends Wrapper {
}
$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;
}
/**

View File

@ -2,8 +2,10 @@
namespace Test\Files\Stream;
use OC\Files\Cache\CacheEntry;
use OC\Files\View;
use OC\Memcache\ArrayCache;
use OCP\Files\Cache\ICache;
use OCP\IConfig;
class EncryptionTest extends \Test\TestCase {
@ -26,6 +28,7 @@ class EncryptionTest extends \Test\TestCase {
$header = [];
$uid = '';
$this->encryptionModule = $this->buildMockModule();
$cache = $this->createMock(ICache::class);
$storage = $this->getMockBuilder('\OC\Files\Storage\Storage')
->disableOriginalConstructor()->getMock();
$encStorage = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
@ -49,6 +52,13 @@ class EncryptionTest extends \Test\TestCase {
$util->expects($this->any())
->method('getUidAndFilename')
->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,
@ -208,6 +218,7 @@ class EncryptionTest extends \Test\TestCase {
public function testSeek() {
$fileName = tempnam("/tmp", "FOO");
$stream = $this->getStream($fileName, 'w+', 0);
$this->assertEquals(6, fwrite($stream, 'foobar'));
$this->assertEquals(0, fseek($stream, 3));