From f9ad57ee523db315e49f08ae4d28b592d32cc8c9 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 10 Mar 2016 15:58:24 +0100 Subject: [PATCH] Ensure that stored version is at least 1 for cross-storage copy In case of a move operation from an unencrypted to an encrypted storage the old encrypted version would stay with "0" while the correct value would be "1". Thus we manually set the value to "1" for those cases. See also https://github.com/owncloud/core/issues/23078 --- .../files/storage/wrapper/encryption.php | 13 +++++- .../lib/files/storage/wrapper/encryption.php | 42 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php index 0b4816174b..81eea9944f 100644 --- a/lib/private/files/storage/wrapper/encryption.php +++ b/lib/private/files/storage/wrapper/encryption.php @@ -634,7 +634,18 @@ class Encryption extends Wrapper { 'encrypted' => (bool)$isEncrypted, ]; if($isEncrypted === 1) { - $cacheInformation['encryptedVersion'] = $sourceStorage->getCache()->get($sourceInternalPath)['encryptedVersion']; + $encryptedVersion = $sourceStorage->getCache()->get($sourceInternalPath)['encryptedVersion']; + + // In case of a move operation from an unencrypted to an encrypted + // storage the old encrypted version would stay with "0" while the + // correct value would be "1". Thus we manually set the value to "1" + // for those cases. + // See also https://github.com/owncloud/core/issues/23078 + if($encryptedVersion === 0) { + $encryptedVersion = 1; + } + + $cacheInformation['encryptedVersion'] = $encryptedVersion; } // in case of a rename we need to manipulate the source cache because diff --git a/tests/lib/files/storage/wrapper/encryption.php b/tests/lib/files/storage/wrapper/encryption.php index b5ec15b12b..bde920e440 100644 --- a/tests/lib/files/storage/wrapper/encryption.php +++ b/tests/lib/files/storage/wrapper/encryption.php @@ -672,6 +672,48 @@ class Encryption extends Storage { ]; } + public function testCopyBetweenStorageMinimumEncryptedVersion() { + $storage2 = $this->getMockBuilder('OCP\Files\Storage') + ->disableOriginalConstructor() + ->getMock(); + + $sourceInternalPath = $targetInternalPath = 'file.txt'; + $preserveMtime = $isRename = false; + + $storage2->expects($this->any()) + ->method('fopen') + ->willReturnCallback(function($path, $mode) { + $temp = \OC::$server->getTempManager(); + return fopen($temp->getTemporaryFile(), $mode); + }); + $cache = $this->getMock('\OCP\Files\Cache\ICache'); + $cache->expects($this->once()) + ->method('get') + ->with($sourceInternalPath) + ->willReturn(['encryptedVersion' => 0]); + $storage2->expects($this->once()) + ->method('getCache') + ->willReturn($cache); + $this->encryptionManager->expects($this->any()) + ->method('isEnabled') + ->willReturn(true); + global $mockedMountPointEncryptionEnabled; + $mockedMountPointEncryptionEnabled = true; + + $expectedCachePut = [ + 'encrypted' => true, + ]; + $expectedCachePut['encryptedVersion'] = 1; + + $this->cache->expects($this->once()) + ->method('put') + ->with($sourceInternalPath, $expectedCachePut); + + $this->invokePrivate($this->instance, 'copyBetweenStorage', [$storage2, $sourceInternalPath, $targetInternalPath, $preserveMtime, $isRename]); + + $this->assertFalse(false); + } + /** * @dataProvider dataCopyBetweenStorage *