/**
  * Wraps the given storage when it is not a shared storage
  *
  * @param string $mountPoint
  * @param Storage $storage
  * @param IMountPoint $mount
  * @return Encryption|Storage
  */
 public function wrapStorage($mountPoint, Storage $storage, IMountPoint $mount)
 {
     $parameters = ['storage' => $storage, 'mountPoint' => $mountPoint, 'mount' => $mount];
     if (!$storage->instanceOfStorage('OC\\Files\\Storage\\Shared') && !$storage->instanceOfStorage('OCA\\Files_Sharing\\External\\Storage') && !$storage->instanceOfStorage('OC\\Files\\Storage\\OwnCloud')) {
         $user = \OC::$server->getUserSession()->getUser();
         $mountManager = Filesystem::getMountManager();
         $uid = $user ? $user->getUID() : null;
         $fileHelper = \OC::$server->getEncryptionFilesHelper();
         $keyStorage = \OC::$server->getEncryptionKeyStorage();
         $util = new Util(new View(), \OC::$server->getUserManager(), \OC::$server->getGroupManager(), \OC::$server->getConfig());
         $update = new Update(new View(), $util, Filesystem::getMountManager(), $this->manager, $fileHelper, $uid);
         return new Encryption($parameters, $this->manager, $util, $this->logger, $fileHelper, $uid, $keyStorage, $update, $mountManager, $this->arrayCache);
     } else {
         return $storage;
     }
 }
 /**
  * by default the encryption module should encrypt regular files, files in
  * files_versions and files in files_trashbin
  *
  * @dataProvider dataTestShouldEncrypt
  */
 public function testShouldEncrypt($path, $shouldEncryptHomeStorage, $isHomeStorage, $expected)
 {
     $this->utilMock->expects($this->once())->method('shouldEncryptHomeStorage')->willReturn($shouldEncryptHomeStorage);
     if ($shouldEncryptHomeStorage === false) {
         $this->storageMock->expects($this->once())->method('instanceOfStorage')->with('\\OCP\\Files\\IHomeStorage')->willReturn($isHomeStorage);
         $this->utilMock->expects($this->once())->method('getStorage')->with($path)->willReturn($this->storageMock);
     }
     $this->assertSame($expected, $this->instance->shouldEncrypt($path));
 }
Exemple #3
0
	/**
	 * Returns whether a part file is needed for the given storage
	 * or whether the file can be assembled/uploaded directly on the
	 * target storage.
	 *
	 * @param \OCP\Files\Storage $storage
	 * @return bool true if the storage needs part file handling
	 */
	private function needsPartFile($storage) {
		// TODO: in the future use ChunkHandler provided by storage
		// and/or add method on Storage called "needsPartFile()"
		return !$storage->instanceOfStorage('OCA\Files_Sharing\External\Storage') &&
		!$storage->instanceOfStorage('OC\Files\Storage\OwnCloud');
	}
Exemple #4
0
	/**
	 * @param \OCP\Files\Storage $sourceStorage
	 * @param string $sourceInternalPath
	 * @param string $targetInternalPath
	 * @return bool
	 */
	public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
		if ($sourceStorage->instanceOfStorage('\OC\Files\Storage\Local')) {
			/**
			 * @var \OC\Files\Storage\Local $sourceStorage
			 */
			$rootStorage = new Local(['datadir' => '/']);
			return $rootStorage->rename($sourceStorage->getSourcePath($sourceInternalPath), $this->getSourcePath($targetInternalPath));
		} else {
			return parent::moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
		}
	}
Exemple #5
0
 /**
  * @param \OCP\Files\Storage $sourceStorage
  * @param string $sourceInternalPath
  * @param string $targetInternalPath
  * @param bool $preserveMtime
  * @return bool
  */
 public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false)
 {
     if ($sourceStorage === $this) {
         return $this->copy($sourceInternalPath, $targetInternalPath);
     }
     if ($sourceStorage->is_dir($sourceInternalPath)) {
         $dh = $sourceStorage->opendir($sourceInternalPath);
         $result = $this->mkdir($targetInternalPath);
         if (is_resource($dh)) {
             while ($result and ($file = readdir($dh)) !== false) {
                 if (!Filesystem::isIgnoredDir($file)) {
                     $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file);
                 }
             }
         }
     } else {
         $source = $sourceStorage->fopen($sourceInternalPath, 'r');
         // TODO: call fopen in a way that we execute again all storage wrappers
         // to avoid that we bypass storage wrappers which perform important actions
         // for this operation. Same is true for all other operations which
         // are not the same as the original one.Once this is fixed we also
         // need to adjust the encryption wrapper.
         $target = $this->fopen($targetInternalPath, 'w');
         list(, $result) = \OC_Helper::streamCopy($source, $target);
         if ($result and $preserveMtime) {
             $this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath));
         }
         fclose($source);
         fclose($target);
         if (!$result) {
             // delete partially written target file
             $this->unlink($targetInternalPath);
             // delete cache entry that was created by fopen
             $this->getCache()->remove($targetInternalPath);
         }
     }
     return (bool) $result;
 }
 /**
  * copy file between two storages
  *
  * @param Storage $sourceStorage
  * @param string $sourceInternalPath
  * @param string $targetInternalPath
  * @param bool $preserveMtime
  * @param bool $isRename
  * @return bool
  */
 private function copyBetweenStorage(Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime, $isRename)
 {
     // first copy the keys that we reuse the existing file key on the target location
     // and don't create a new one which would break versions for example.
     $mount = $this->mountManager->findByStorageId($sourceStorage->getId());
     if (count($mount) === 1) {
         $mountPoint = $mount[0]->getMountPoint();
         $source = $mountPoint . '/' . $sourceInternalPath;
         $target = $this->getFullPath($targetInternalPath);
         $this->copyKeys($source, $target);
     } else {
         $this->logger->error('Could not find mount point, can\'t keep encryption keys');
     }
     if ($sourceStorage->is_dir($sourceInternalPath)) {
         $dh = $sourceStorage->opendir($sourceInternalPath);
         $result = $this->mkdir($targetInternalPath);
         if (is_resource($dh)) {
             while ($result and ($file = readdir($dh)) !== false) {
                 if (!Filesystem::isIgnoredDir($file)) {
                     $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file);
                 }
             }
         }
     } else {
         $source = $sourceStorage->fopen($sourceInternalPath, 'r');
         $target = $this->fopen($targetInternalPath, 'w');
         list(, $result) = \OC_Helper::streamCopy($source, $target);
         fclose($source);
         fclose($target);
         if ($result) {
             if ($preserveMtime) {
                 $this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath));
             }
             $isEncrypted = $this->mount->getOption('encrypt', true) ? 1 : 0;
             // in case of a rename we need to manipulate the source cache because
             // this information will be kept for the new target
             if ($isRename) {
                 $sourceStorage->getCache()->put($sourceInternalPath, ['encrypted' => $isEncrypted]);
             } else {
                 $this->getCache()->put($targetInternalPath, ['encrypted' => $isEncrypted]);
             }
         } else {
             // delete partially written target file
             $this->unlink($targetInternalPath);
             // delete cache entry that was created by fopen
             $this->getCache()->remove($targetInternalPath);
         }
     }
     return (bool) $result;
 }
Exemple #7
0
	/**
	 * Wraps the given storage when it is not a shared storage
	 *
	 * @param string $mountPoint
	 * @param Storage $storage
	 * @param IMountPoint $mount
	 * @return Encryption|Storage
	 */
	public function wrapStorage($mountPoint, Storage $storage, IMountPoint $mount) {
		$parameters = [
			'storage' => $storage,
			'mountPoint' => $mountPoint,
			'mount' => $mount];

		if (!$storage->instanceOfStorage('OC\Files\Storage\Shared')
			&& !$storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')
			&& !$storage->instanceOfStorage('OC\Files\Storage\OwnCloud')) {

			$manager = \OC::$server->getEncryptionManager();
			$user = \OC::$server->getUserSession()->getUser();
			$logger = \OC::$server->getLogger();
			$mountManager = Filesystem::getMountManager();
			$uid = $user ? $user->getUID() : null;
			$fileHelper = \OC::$server->getEncryptionFilesHelper();
			$keyStorage = \OC::$server->getEncryptionKeyStorage();
			$update = new Update(
				new View(),
				$this,
				Filesystem::getMountManager(),
				$manager,
				$fileHelper,
				$uid
			);
			return new Encryption(
				$parameters,
				$manager,
				$this,
				$logger,
				$fileHelper,
				$uid,
				$keyStorage,
				$update,
				$mountManager
			);
		} else {
			return $storage;
		}
	}
Exemple #8
0
 /**
  * Update the encrypted cache version in the database
  *
  * @param Storage $sourceStorage
  * @param string $sourceInternalPath
  * @param string $targetInternalPath
  * @param bool $isRename
  */
 private function updateEncryptedVersion(Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $isRename)
 {
     $isEncrypted = $this->encryptionManager->isEnabled() && $this->mount->getOption('encrypt', true) ? 1 : 0;
     $cacheInformation = ['encrypted' => (bool) $isEncrypted];
     if ($isEncrypted === 1) {
         $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
     // this information will be kept for the new target
     if ($isRename) {
         $sourceStorage->getCache()->put($sourceInternalPath, $cacheInformation);
     } else {
         $this->getCache()->put($targetInternalPath, $cacheInformation);
     }
 }
Exemple #9
0
 /**
  * @param \OCP\Files\Storage $sourceStorage
  * @param string $sourceInternalPath
  * @param string $targetInternalPath
  * @return bool
  */
 public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath)
 {
     if ($sourceStorage === $this) {
         return $this->rename($sourceInternalPath, $targetInternalPath);
     }
     if (!$sourceStorage->isDeletable($sourceInternalPath)) {
         return false;
     }
     $result = $this->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, true);
     if ($result) {
         if ($sourceStorage->is_dir($sourceInternalPath)) {
             $result &= $sourceStorage->rmdir($sourceInternalPath);
         } else {
             $result &= $sourceStorage->unlink($sourceInternalPath);
         }
     }
     return $result;
 }
Exemple #10
0
 /**
  * Update the encrypted cache version in the database
  *
  * @param Storage $sourceStorage
  * @param string $sourceInternalPath
  * @param string $targetInternalPath
  * @param bool $isRename
  */
 private function updateEncryptedVersion(Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $isRename)
 {
     $isEncrypted = $this->encryptionManager->isEnabled() && $this->mount->getOption('encrypt', true) ? 1 : 0;
     $cacheInformation = ['encrypted' => (bool) $isEncrypted];
     if ($isEncrypted === 1) {
         $cacheInformation['encryptedVersion'] = $sourceStorage->getCache()->get($sourceInternalPath)['encryptedVersion'];
     }
     // in case of a rename we need to manipulate the source cache because
     // this information will be kept for the new target
     if ($isRename) {
         $sourceStorage->getCache()->put($sourceInternalPath, $cacheInformation);
     } else {
         $this->getCache()->put($targetInternalPath, $cacheInformation);
     }
 }