/**
  * @return string the mount point of the mount for the user
  */
 public function getMountPoint()
 {
     if (!$this->mountPoint) {
         $this->mountPoint = $this->mount->getMountPoint();
     }
     return parent::getMountPoint();
 }
Example #2
0
 public function testGetStorage()
 {
     $return = $this->getMockBuilder('OC\\Files\\Storage\\Storage')->disableOriginalConstructor()->getMock();
     $path = '/foo/bar.txt';
     $this->filesMock->expects($this->once())->method('getMount')->with($path)->willReturn($this->mountMock);
     $this->mountMock->expects($this->once())->method('getStorage')->willReturn($return);
     $this->assertEquals($return, $this->instance->getStorage($path));
 }
Example #3
0
 /**
  * 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 {
         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));
             }
             $isEncrypted = $this->encryptionManager->isEnabled() && $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;
 }
Example #4
0
 /**
  * see http://php.net/manual/en/function.fopen.php
  *
  * @param string $path
  * @param string $mode
  * @return resource
  */
 public function fopen($path, $mode)
 {
     $encryptionEnabled = $this->encryptionManager->isEnabled();
     $shouldEncrypt = false;
     $encryptionModule = null;
     $header = $this->getHeader($path);
     $fullPath = $this->getFullPath($path);
     $encryptionModuleId = $this->util->getEncryptionModuleId($header);
     $size = $unencryptedSize = 0;
     $targetExists = $this->file_exists($path);
     $targetIsEncrypted = false;
     if ($targetExists) {
         // in case the file exists we require the explicit module as
         // specified in the file header - otherwise we need to fail hard to
         // prevent data loss on client side
         if (!empty($encryptionModuleId)) {
             $targetIsEncrypted = true;
             $encryptionModule = $this->encryptionManager->getEncryptionModule($encryptionModuleId);
         }
         $size = $this->storage->filesize($path);
         $unencryptedSize = $this->filesize($path);
     }
     try {
         if ($mode === 'w' || $mode === 'w+' || $mode === 'wb' || $mode === 'wb+') {
             if (!empty($encryptionModuleId)) {
                 $encryptionModule = $this->encryptionManager->getEncryptionModule($encryptionModuleId);
                 $shouldEncrypt = $encryptionModule->shouldEncrypt($fullPath);
             } elseif ($encryptionEnabled) {
                 $encryptionModule = $this->encryptionManager->getDefaultEncryptionModule();
                 $shouldEncrypt = $encryptionModule->shouldEncrypt($fullPath);
             }
         } else {
             // only get encryption module if we found one in the header
             if (!empty($encryptionModuleId)) {
                 $encryptionModule = $this->encryptionManager->getEncryptionModule($encryptionModuleId);
                 $shouldEncrypt = true;
             }
         }
     } catch (ModuleDoesNotExistsException $e) {
         $this->logger->warning('Encryption module "' . $encryptionModuleId . '" not found, file will be stored unencrypted (' . $e->getMessage() . ')');
     }
     // encryption disabled on write of new file and write to existing unencrypted file -> don't encrypt
     if (!$encryptionEnabled || !$this->mount->getOption('encrypt', true)) {
         if (!$targetExists || !$targetIsEncrypted) {
             $shouldEncrypt = false;
         }
     }
     if ($shouldEncrypt === true && !$this->util->isExcluded($fullPath) && $encryptionModule !== null) {
         $source = $this->storage->fopen($path, $mode);
         $handle = \OC\Files\Stream\Encryption::wrap($source, $path, $fullPath, $header, $this->uid, $encryptionModule, $this->storage, $this, $this->util, $this->fileHelper, $mode, $size, $unencryptedSize);
         return $handle;
     } else {
         return $this->storage->fopen($path, $mode);
     }
 }
Example #5
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);
     }
 }
Example #6
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);
     }
 }
Example #7
0
 /**
  * @param IMountPoint $mount
  */
 public function addMount(IMountPoint $mount)
 {
     $this->mounts[$mount->getMountPoint()] = $mount;
 }