diff --git a/apps/encryption/lib/Crypto/Encryption.php b/apps/encryption/lib/Crypto/Encryption.php index bd75e4ae10c15..3f6001cab7423 100644 --- a/apps/encryption/lib/Crypto/Encryption.php +++ b/apps/encryption/lib/Crypto/Encryption.php @@ -254,7 +254,6 @@ public function begin($path, $user, $mode, array $header, array $accessList) { 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 65d379c028920..3c884a99ae76b 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 @@ public function stream_open($path, $mode, $options, &$opened_path) { $this->position = 0; $this->cache = ''; $this->writeFlag = false; + $this->fileUpdated = false; $this->unencryptedBlockSize = $this->encryptionModule->getUnencryptedBlockSize($this->signed); if ( @@ -313,7 +317,6 @@ public function stream_read($count) { } 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 @@ public function stream_write($data) { // 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 @@ public function stream_close() { } $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 983428ee51dbc..d7a5554acfdb4 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 @@ protected function getStream($fileName, $mode, $unencryptedSize, $wrapper = '\OC $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 @@ protected function getStream($fileName, $mode, $unencryptedSize, $wrapper = '\OC $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 @@ public function testRewind() { 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));