/** * @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(); }
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)); }
/** * 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; }
/** * 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); } }
/** * 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); } }
/** * 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); } }
/** * @param IMountPoint $mount */ public function addMount(IMountPoint $mount) { $this->mounts[$mount->getMountPoint()] = $mount; }