summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoeland Jago Douma <rullzer@users.noreply.github.com>2018-08-10 08:10:03 +0200
committerGitHub <noreply@github.com>2018-08-10 08:10:03 +0200
commitabef061686533e3a6310eab7b7a99969f14f24fd (patch)
tree6fff510d1d0fc1a907514bbe9ef881274b42fcdb
parent93df97f1bf2abbad3f0d7cecfd6b232f9f3de9be (diff)
parentbe172cc6f25ad7d1da383da06f90b834b62c0855 (diff)
downloadnextcloud-server-abef061686533e3a6310eab7b7a99969f14f24fd.tar.gz
nextcloud-server-abef061686533e3a6310eab7b7a99969f14f24fd.zip
Merge pull request #10581 from nextcloud/encryption-s3-fix-stable13
make file cache updates more robust
-rw-r--r--apps/encryption/lib/Crypto/Encryption.php1
-rw-r--r--lib/private/Files/Stream/Encryption.php19
-rw-r--r--tests/lib/Files/Stream/EncryptionTest.php11
3 files changed, 28 insertions, 3 deletions
diff --git a/apps/encryption/lib/Crypto/Encryption.php b/apps/encryption/lib/Crypto/Encryption.php
index bd75e4ae10c..3f6001cab74 100644
--- a/apps/encryption/lib/Crypto/Encryption.php
+++ b/apps/encryption/lib/Crypto/Encryption.php
@@ -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
diff --git a/lib/private/Files/Stream/Encryption.php b/lib/private/Files/Stream/Encryption.php
index d76ba85aa62..7d6642be104 100644
--- a/lib/private/Files/Stream/Encryption.php
+++ b/lib/private/Files/Stream/Encryption.php
@@ -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;
}
/**
diff --git a/tests/lib/Files/Stream/EncryptionTest.php b/tests/lib/Files/Stream/EncryptionTest.php
index 983428ee51d..d7a5554acfd 100644
--- a/tests/lib/Files/Stream/EncryptionTest.php
+++ b/tests/lib/Files/Stream/EncryptionTest.php
@@ -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));