From e51fe617d89fd515e9e6836f205f67c613939b41 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 24 Aug 2015 15:57:03 +0200 Subject: [PATCH] copy always file by file to encrypt/decrypt it if needed --- .../files/storage/wrapper/encryption.php | 44 +++++-------- .../lib/files/storage/wrapper/encryption.php | 61 +++---------------- 2 files changed, 23 insertions(+), 82 deletions(-) diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php index 4ba9b21ddb..805a2bc1ad 100644 --- a/lib/private/files/storage/wrapper/encryption.php +++ b/lib/private/files/storage/wrapper/encryption.php @@ -67,7 +67,6 @@ class Encryption extends Wrapper { /** @var IMountPoint */ private $mount; - /** @var IStorage */ private $keyStorage; @@ -300,33 +299,15 @@ class Encryption extends Wrapper { public function copy($path1, $path2) { $source = $this->getFullPath($path1); - $target = $this->getFullPath($path2); if ($this->util->isExcluded($source)) { return $this->storage->copy($path1, $path2); } - $result = $this->storage->copy($path1, $path2); - - if ($result && $this->encryptionManager->isEnabled()) { - $keysCopied = $this->copyKeys($source, $target); - - if ($keysCopied && - dirname($source) !== dirname($target) && - $this->util->isFile($target) - ) { - $this->update->update($target); - } - - $data = $this->getMetaData($path1); - - if (isset($data['encrypted'])) { - $this->getCache()->put($path2, ['encrypted' => $data['encrypted']]); - } - if (isset($data['size'])) { - $this->updateUnencryptedSize($target, $data['size']); - } - } + // need to stream copy file by file in case we copy between a encrypted + // and a unencrypted storage + $this->unlink($path2); + $result = $this->copyFromStorage($this, $path1, $path2); return $result; } @@ -511,12 +492,17 @@ class Encryption extends Wrapper { } } } else { - $source = $sourceStorage->fopen($sourceInternalPath, 'r'); - $target = $this->fopen($targetInternalPath, 'w'); - list(, $result) = \OC_Helper::streamCopy($source, $target); - fclose($source); - fclose($target); - + try { + $source = $sourceStorage->fopen($sourceInternalPath, 'r'); + $target = $this->fopen($targetInternalPath, 'w'); + list(, $result) = \OC_Helper::streamCopy($source, $target); + fclose($source); + fclose($target); + } catch (\Exception $e) { + fclose($source); + fclose($target); + throw $e; + } if($result) { if ($preserveMtime) { $this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath)); diff --git a/tests/lib/files/storage/wrapper/encryption.php b/tests/lib/files/storage/wrapper/encryption.php index 3d1bf1077a..36a5b288c6 100644 --- a/tests/lib/files/storage/wrapper/encryption.php +++ b/tests/lib/files/storage/wrapper/encryption.php @@ -241,59 +241,14 @@ class Encryption extends \Test\Files\Storage\Storage { $this->instance->rename($source, $target); } - /** - * @dataProvider dataTestCopyAndRename - * - * @param string $source - * @param string $target - * @param $encryptionEnabled - * @param boolean $copyKeysReturn - * @param boolean $shouldUpdate - */ - public function testCopyEncryption($source, - $target, - $encryptionEnabled, - $copyKeysReturn, - $shouldUpdate) { - - if ($encryptionEnabled) { - $this->keyStore - ->expects($this->once()) - ->method('copyKeys') - ->willReturn($copyKeysReturn); - $this->cache->expects($this->atLeastOnce()) - ->method('put') - ->willReturnCallback(function($path, $data) { - $this->assertArrayHasKey('encrypted', $data); - $this->assertTrue($data['encrypted']); - }); - } else { - $this->cache->expects($this->never())->method('put'); - $this->keyStore->expects($this->never())->method('copyKeys'); - } - $this->util->expects($this->any()) - ->method('isFile')->willReturn(true); - $this->util->expects($this->any()) - ->method('isExcluded')->willReturn(false); - $this->encryptionManager->expects($this->once()) - ->method('isEnabled')->willReturn($encryptionEnabled); - if ($shouldUpdate) { - $this->update->expects($this->once()) - ->method('update'); - } else { - $this->update->expects($this->never()) - ->method('update'); - } - - $this->instance->mkdir($source); - $this->instance->mkdir(dirname($target)); - $this->instance->copy($source, $target); - - if ($encryptionEnabled) { - $this->assertSame($this->dummySize, - $this->instance->filesize($target) - ); - } + public function testCopyEncryption() { + $this->instance->file_put_contents('source.txt', 'bar'); + $this->instance->copy('source.txt', 'target.txt'); + $this->assertSame('bar', $this->instance->file_get_contents('target.txt')); + $targetMeta = $this->instance->getMetaData('target.txt'); + $sourceMeta = $this->instance->getMetaData('source.txt'); + $this->assertSame($sourceMeta['encrypted'], $targetMeta['encrypted']); + $this->assertSame($sourceMeta['size'], $targetMeta['size']); } /**