diff --git a/apps/files/lib/Command/TransferOwnership.php b/apps/files/lib/Command/TransferOwnership.php index 85c5f898f894..058e67b440f8 100644 --- a/apps/files/lib/Command/TransferOwnership.php +++ b/apps/files/lib/Command/TransferOwnership.php @@ -24,10 +24,12 @@ namespace OCA\Files\Command; +use OC\Encryption\Manager; use OC\Files\Filesystem; use OC\Files\View; use OCP\Files\FileInfo; use OCP\Files\Mount\IMountManager; +use OCP\ILogger; use OCP\IUserManager; use OCP\Share\IManager; use OCP\Share\IShare; @@ -49,6 +51,12 @@ class TransferOwnership extends Command { /** @var IMountManager */ private $mountManager; + /** @var Manager */ + private $encryptionManager; + + /** @var ILogger */ + private $logger; + /** @var FileInfo[] */ private $allFiles = []; @@ -70,10 +78,12 @@ class TransferOwnership extends Command { /** @var string */ private $finalTarget; - public function __construct(IUserManager $userManager, IManager $shareManager, IMountManager $mountManager) { + public function __construct(IUserManager $userManager, IManager $shareManager, IMountManager $mountManager, Manager $encryptionManager, ILogger $logger) { $this->userManager = $userManager; $this->shareManager = $shareManager; $this->mountManager = $mountManager; + $this->encryptionManager = $encryptionManager; + $this->logger = $logger; parent::__construct(); } @@ -260,7 +270,9 @@ protected function transfer(OutputInterface $output) { $this->finalTarget = $this->finalTarget . '/' . basename($sourcePath); } } + $view->rename($sourcePath, $this->finalTarget); + if (!is_dir("$this->sourceUser/files")) { // because the files folder is moved away we need to recreate it $view->mkdir("$this->sourceUser/files"); diff --git a/lib/private/Files/Storage/Wrapper/Encryption.php b/lib/private/Files/Storage/Wrapper/Encryption.php index b4c270bb8d51..e1b5049d1fda 100644 --- a/lib/private/Files/Storage/Wrapper/Encryption.php +++ b/lib/private/Files/Storage/Wrapper/Encryption.php @@ -86,6 +86,11 @@ class Encryption extends Wrapper { /** @var ArrayCache */ private $arrayCache; + /** @var array which has information of sourcePath during rename operation */ + private $sourcePath; + + private static $disableWriteEncryption = false; + /** * @param array $parameters * @param IManager $encryptionManager @@ -201,16 +206,18 @@ public function getMetaData($path) { */ public function file_get_contents($path) { - $encryptionModule = $this->getEncryptionModule($path); + if ($this->encryptionManager->isEnabled() !== false) { + $encryptionModule = $this->getEncryptionModule($path); - if ($encryptionModule) { - $handle = $this->fopen($path, "r"); - if (!$handle) { - return false; + if ($encryptionModule) { + $handle = $this->fopen($path, "r"); + if (!$handle) { + return false; + } + $data = stream_get_contents($handle); + fclose($handle); + return $data; } - $data = stream_get_contents($handle); - fclose($handle); - return $data; } return $this->storage->file_get_contents($path); } @@ -358,12 +365,11 @@ public function copy($path1, $path2) { * * @param string $path * @param string $mode - * @param string|null $sourceFileOfRename * @return resource|bool * @throws GenericEncryptionException * @throws ModuleDoesNotExistsException */ - public function fopen($path, $mode, $sourceFileOfRename = null) { + public function fopen($path, $mode) { // check if the file is stored in the array cache, this means that we // copy a file over to the versions folder, in this case we don't want to @@ -451,14 +457,33 @@ public function fopen($path, $mode, $sourceFileOfRename = null) { } if ($shouldEncrypt === true && $encryptionModule !== null) { + /** + * The check of $disableWriteEncryption, required to get the file in the decrypted state. + * It will help us get the normal file handler. And hence we can re-encrypt + * the file when necessary, later. The true/false of $getDecryptedFile decides whether + * to keep the file decrypted or not. The intention is to get the data decrypt + * for write mode. + */ + if (self::$disableWriteEncryption && ($mode !== 'r')) { + return $this->getWrapperStorage()->fopen($path, $mode); + } + $headerSize = $this->getHeaderSize($path); $source = $this->storage->fopen($path, $mode); if (!is_resource($source)) { return false; } + + if (isset($this->sourcePath[$path])) { + $sourceFileOfRename = $this->sourcePath[$path]; + } else { + $sourceFileOfRename = null; + } $handle = \OC\Files\Stream\Encryption::wrap($source, $path, $fullPath, $header, $this->uid, $encryptionModule, $this->storage, $this, $this->util, $this->fileHelper, $mode, $size, $unencryptedSize, $headerSize, $signed, $sourceFileOfRename); + unset($this->sourcePath[$path]); + return $handle; } @@ -622,6 +647,15 @@ public function moveFromStorage(Storage $sourceStorage, $sourceInternalPath, $ta return $result; } + /** + * Set the flag to true, so that the file would be + * in the decrypted state. + * + * @param $isDisabled bool + */ + public static function setDisableWriteEncryption($isDisabled) { + self::$disableWriteEncryption = $isDisabled; + } /** * @param Storage $sourceStorage @@ -748,10 +782,11 @@ private function copyBetweenStorage(Storage $sourceStorage, $sourceInternalPath, $source = $sourceStorage->fopen($sourceInternalPath, 'r'); if ($isRename) { $absSourcePath = Filesystem::normalizePath($sourceStorage->getOwner($sourceInternalPath). '/' . $sourceInternalPath); - $target = $this->fopen($targetInternalPath, 'w', $absSourcePath); + $this->sourcePath[$targetInternalPath] = $absSourcePath; } else { - $target = $this->fopen($targetInternalPath, 'w'); + unset($this->sourcePath[$targetInternalPath]); } + $target = $this->fopen($targetInternalPath, 'w'); list(, $result) = \OC_Helper::streamCopy($source, $target); fclose($source); fclose($target); diff --git a/lib/private/Files/Stream/Encryption.php b/lib/private/Files/Stream/Encryption.php index 72f47e5f33b0..03845e79281b 100644 --- a/lib/private/Files/Stream/Encryption.php +++ b/lib/private/Files/Stream/Encryption.php @@ -139,6 +139,7 @@ public function __construct() { * @param int $unencryptedSize * @param int $headerSize * @param bool $signed + * @param null|string $sourceFileOfRename * @param string $wrapper stream wrapper class * @return resource *