copy always file by file to encrypt/decrypt it if needed

This commit is contained in:
Bjoern Schiessle 2015-08-24 15:57:03 +02:00
parent 8c08dd0ac2
commit e51fe617d8
2 changed files with 23 additions and 82 deletions

View File

@ -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));

View File

@ -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']);
}
/**