protected function setUp() { parent::setUp(); self::loginHelper(self::TEST_FILES_SHARING_API_USER1); // prepare user1's dir structure $textData = "dummy file data\n"; $this->view->mkdir('container'); $this->view->mkdir('container/shareddir'); $this->view->mkdir('container/shareddir/subdir'); $this->view->mkdir('container/shareddirrestricted'); $this->view->mkdir('container/shareddirrestricted/subdir'); $this->view->file_put_contents('container/shareddir/textfile.txt', $textData); $this->view->file_put_contents('container/shareddirrestricted/textfile1.txt', $textData); list($this->ownerStorage, $internalPath) = $this->view->resolvePath(''); $this->ownerCache = $this->ownerStorage->getCache(); $this->ownerStorage->getScanner()->scan(''); // share "shareddir" with user2 $rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1); $node = $rootFolder->get('container/shareddir'); $share = $this->shareManager->newShare(); $share->setNode($node)->setShareType(\OCP\Share::SHARE_TYPE_USER)->setSharedWith(self::TEST_FILES_SHARING_API_USER2)->setSharedBy(self::TEST_FILES_SHARING_API_USER1)->setPermissions(\OCP\Constants::PERMISSION_ALL); $this->shareManager->createShare($share); $node = $rootFolder->get('container/shareddirrestricted'); $share = $this->shareManager->newShare(); $share->setNode($node)->setShareType(\OCP\Share::SHARE_TYPE_USER)->setSharedWith(self::TEST_FILES_SHARING_API_USER2)->setSharedBy(self::TEST_FILES_SHARING_API_USER1)->setPermissions(\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE); $this->shareManager->createShare($share); // login as user2 self::loginHelper(self::TEST_FILES_SHARING_API_USER2); // retrieve the shared storage $this->secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2); list($this->sharedStorage, $internalPath) = $this->secondView->resolvePath('files/shareddir'); list($this->sharedStorageRestrictedShare, $internalPath) = $this->secondView->resolvePath('files/shareddirrestricted'); $this->sharedCache = $this->sharedStorage->getCache(); $this->sharedCacheRestrictedShare = $this->sharedStorageRestrictedShare->getCache(); }
protected function setUp() { parent::setUp(); self::loginHelper(self::TEST_FILES_SHARING_API_USER1); // prepare user1's dir structure $textData = "dummy file data\n"; $this->view->mkdir('container'); $this->view->mkdir('container/shareddir'); $this->view->mkdir('container/shareddir/subdir'); $this->view->mkdir('container/shareddirrestricted'); $this->view->mkdir('container/shareddirrestricted/subdir'); $this->view->file_put_contents('container/shareddir/textfile.txt', $textData); $this->view->file_put_contents('container/shareddirrestricted/textfile1.txt', $textData); list($this->ownerStorage, $internalPath) = $this->view->resolvePath(''); $this->ownerCache = $this->ownerStorage->getCache(); $this->ownerStorage->getScanner()->scan(''); // share "shareddir" with user2 $fileinfo = $this->view->getFileInfo('container/shareddir'); \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31); $fileinfo2 = $this->view->getFileInfo('container/shareddirrestricted'); \OCP\Share::shareItem('folder', $fileinfo2['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 7); // login as user2 self::loginHelper(self::TEST_FILES_SHARING_API_USER2); // retrieve the shared storage $this->secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2); list($this->sharedStorage, $internalPath) = $this->secondView->resolvePath('files/shareddir'); list($this->sharedStorageRestrictedShare, $internalPath) = $this->secondView->resolvePath('files/shareddirrestricted'); $this->sharedCache = $this->sharedStorage->getCache(); $this->sharedCacheRestrictedShare = $this->sharedStorageRestrictedShare->getCache(); }
/** * Test that versions are not auto-trashed when moving a file between * storages. This is because rename() between storages would call * unlink() which should NOT trigger the version deletion logic. */ public function testKeepFileAndVersionsWhenMovingFolderBetweenStorages() { \OCA\Files_Versions\Hooks::connectHooks(); $storage2 = new Temporary(array()); \OC\Files\Filesystem::mount($storage2, array(), $this->user . '/files/substorage'); // trigger a version (multiple would not work because of the expire logic) $this->userView->file_put_contents('folder/inside.txt', 'v1'); $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files'); $this->assertEquals(0, count($results)); $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/folder/'); $this->assertEquals(1, count($results)); // move to another storage $this->userView->rename('folder', 'substorage/folder'); $this->assertTrue($this->userView->file_exists('substorage/folder/inside.txt')); // rescan trash storage list($rootStorage, ) = $this->rootView->resolvePath($this->user . '/files_trashbin'); $rootStorage->getScanner()->scan(''); // versions were moved too $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/substorage/folder/'); $this->assertEquals(1, count($results)); // check that nothing got trashed by the rename's unlink() call $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files'); $this->assertEquals(0, count($results)); // check that versions were moved and not trashed $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/versions/'); $this->assertEquals(0, count($results)); }
/** * Test restoring a file into a read-only folder, will restore * the file to root instead */ public function testRestoreFileIntoReadOnlySourceFolder() { $userFolder = \OC::$server->getUserFolder(); $folder = $userFolder->newFolder('folder'); $file = $folder->newFile('file1.txt'); $file->putContent('foo'); $this->assertTrue($userFolder->nodeExists('folder/file1.txt')); $file->delete(); $this->assertFalse($userFolder->nodeExists('folder/file1.txt')); $filesInTrash = OCA\Files_Trashbin\Helper::getTrashFiles('/', self::TEST_TRASHBIN_USER1, 'mtime'); $this->assertCount(1, $filesInTrash); /** @var \OCP\Files\FileInfo */ $trashedFile = $filesInTrash[0]; // delete source folder list($storage, $internalPath) = $this->rootView->resolvePath('/' . self::TEST_TRASHBIN_USER1 . '/files/folder'); if ($storage instanceof \OC\Files\Storage\Local) { $folderAbsPath = $storage->getSourcePath($internalPath); // make folder read-only chmod($folderAbsPath, 0555); $this->assertTrue(OCA\Files_Trashbin\Trashbin::restore('file1.txt.d' . $trashedFile->getMtime(), $trashedFile->getName(), $trashedFile->getMtime())); $file = $userFolder->get('file1.txt'); $this->assertEquals('foo', $file->getContent()); chmod($folderAbsPath, 0755); } }
public function isLocal() { $this->init(); $ownerPath = $this->ownerView->getPath($this->share['item_source']); list($targetStorage) = $this->ownerView->resolvePath($ownerPath); return $targetStorage->isLocal(); }
/** * propagate the registered changes to their parent folders * * @param int $time (optional) the mtime to set for the folders, if not set the current time is used */ public function propagateChanges($time = null) { $parents = $this->getAllParents(); $this->changedFiles = array(); if (!$time) { $time = time(); } foreach ($parents as $parent) { /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ list($storage, $internalPath) = $this->view->resolvePath($parent); $cache = $storage->getCache(); $id = $cache->getId($internalPath); $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath))); } }
function setUp() { // reset backend \OC_User::useBackend('database'); // set user id \OC_User::setUserId(\Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1); $this->userId = \Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1; $this->pass = \Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1; // init filesystem view $this->view = new \OC\Files\View('/'); list($this->storage, ) = $this->view->resolvePath('/'); // init short data $this->dataShort = 'hats'; // remember files_trashbin state $this->stateFilesTrashbin = OC_App::isEnabled('files_trashbin'); // we don't want to tests with app files_trashbin enabled \OC_App::disable('files_trashbin'); // create test user \Test_Encryption_Util::loginHelper(\Test_Encryption_Webdav::TEST_ENCRYPTION_WEBDAV_USER1); }
/** * propagate the registered changes to their parent folders * * @param int $time (optional) the mtime to set for the folders, if not set the current time is used */ public function propagateChanges($time = null) { $parents = $this->getAllParents(); $this->changedFiles = array(); if (!$time) { $time = time(); } foreach ($parents as $parent) { /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ list($storage, $internalPath) = $this->view->resolvePath($parent); if ($storage) { $cache = $storage->getCache(); $entry = $cache->get($internalPath); $cache->update($entry['fileid'], array('mtime' => max($time, $entry['mtime']), 'etag' => $storage->getETag($internalPath))); $this->emit('\\OC\\Files', 'propagate', [$parent, $entry]); } } }
/** * @param \OC\Files\View $view * @param string $path */ private function createAndCheckVersions(\OC\Files\View $view, $path) { $view->file_put_contents($path, 'test file'); $view->file_put_contents($path, 'version 1'); $view->file_put_contents($path, 'version 2'); $this->loginAsUser(self::TEST_VERSIONS_USER); // need to scan for the versions list($rootStorage, ) = $this->rootView->resolvePath(self::TEST_VERSIONS_USER . '/files_versions'); $rootStorage->getScanner()->scan('files_versions'); $versions = \OCA\Files_Versions\Storage::getVersions(self::TEST_VERSIONS_USER, '/' . $path); // note: we cannot predict how many versions are created due to // test run timing $this->assertGreaterThan(0, count($versions)); }
private function init() { if ($this->initialized) { return; } $this->initialized = true; try { Filesystem::initMountPoints($this->superShare->getShareOwner()); $sourcePath = $this->ownerView->getPath($this->superShare->getNodeId()); list($this->sourceStorage, $sourceInternalPath) = $this->ownerView->resolvePath($sourcePath); $this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath); } catch (\Exception $e) { $this->logger->logException($e); } }
/** * read key from hard disk * * @param string $path to key * @param \OC\Files\View $view * @return string|bool either the key or false */ private static function getKey($path, $view) { $key = false; if (isset(self::$key_cache[$path])) { $key = self::$key_cache[$path]; } else { /** @var \OCP\Files\Storage $storage */ list($storage, $internalPath) = $view->resolvePath($path); if ($storage->file_exists($internalPath)) { $key = $storage->file_get_contents($internalPath); self::$key_cache[$path] = $key; } } return $key; }
/** * Rename a file or folder in the cache and update the size, etag and mtime of the parent folders * * @param string $source * @param string $target */ public function rename($source, $target) { if (!$this->enabled or Scanner::isPartialFile($source) or Scanner::isPartialFile($target)) { return; } /** * @var \OC\Files\Storage\Storage $sourceStorage * @var \OC\Files\Storage\Storage $targetStorage * @var string $sourceInternalPath * @var string $targetInternalPath */ list($sourceStorage, $sourceInternalPath) = $this->view->resolvePath($source); // if it's a moved mountpoint we dont need to do anything if ($sourceInternalPath === '') { return; } list($targetStorage, $targetInternalPath) = $this->view->resolvePath($target); if ($sourceStorage && $targetStorage) { $targetCache = $targetStorage->getCache($sourceInternalPath); if ($sourceStorage->getCache($sourceInternalPath)->inCache($sourceInternalPath)) { if ($targetCache->inCache($targetInternalPath)) { $targetCache->remove($targetInternalPath); } if ($sourceStorage === $targetStorage) { $targetCache->move($sourceInternalPath, $targetInternalPath); } else { $targetCache->moveFromCache($sourceStorage->getCache(), $sourceInternalPath, $targetInternalPath); } } if (pathinfo($sourceInternalPath, PATHINFO_EXTENSION) !== pathinfo($targetInternalPath, PATHINFO_EXTENSION)) { // handle mime type change $mimeType = $targetStorage->getMimeType($targetInternalPath); $fileId = $targetCache->getId($targetInternalPath); $targetCache->update($fileId, array('mimetype' => $mimeType)); } $targetCache->correctFolderSize($sourceInternalPath); $targetCache->correctFolderSize($targetInternalPath); $this->correctParentStorageMtime($sourceStorage, $sourceInternalPath); $this->correctParentStorageMtime($targetStorage, $targetInternalPath); $this->propagator->addChange($this->getPropagatorPath($source)); $this->propagator->addChange($this->getPropagatorPath($target)); $this->propagator->propagateChanges(); } }
/** * Stream copy file contents from $path1 to $path2 * * @param \OC\Files\View $view view to use for copying * @param string $path1 source file to copy * @param string $path2 target file * * @return bool true for success, false otherwise */ private static function copyFileContents($view, $path1, $path2) { /** @var \OC\Files\Storage\Storage $storage1 */ list($storage1, $internalPath1) = $view->resolvePath($path1); /** @var \OC\Files\Storage\Storage $storage2 */ list($storage2, $internalPath2) = $view->resolvePath($path2); $view->lockFile($path1, ILockingProvider::LOCK_EXCLUSIVE); $view->lockFile($path2, ILockingProvider::LOCK_EXCLUSIVE); $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2); $view->unlockFile($path1, ILockingProvider::LOCK_EXCLUSIVE); $view->unlockFile($path2, ILockingProvider::LOCK_EXCLUSIVE); return $result !== false; }
/** * @return string */ public function getInternalPath() { list(, $internalPath) = $this->view->resolvePath($this->path); return $internalPath; }
/** * Stream copy file contents from $path1 to $path2 * * @param \OC\Files\View $view view to use for copying * @param string $path1 source file to copy * @param string $path2 target file * * @return bool true for success, false otherwise */ private static function copyFileContents($view, $path1, $path2) { list($storage1, $internalPath1) = $view->resolvePath($path1); list($storage2, $internalPath2) = $view->resolvePath($path2); $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2); return $result !== false; }
public function setUp() { $app = new Application(); $container = $app->getContainer(); // reset backend $um = $container->getServer()->getUserManager(); $this->userSession = $container->getServer()->getUserSession(); $um->clearBackends(); $um->registerBackend(new \OC_User_Database()); // create test user $this->userName = '******'; \OC_User::deleteUser($this->userName); $um->createUser($this->userName, $this->userName); \OC_Util::tearDownFS(); $this->userSession->setUser(null); Filesystem::tearDown(); \OC_Util::setupFS($this->userName); $this->userSession->setUser($um->get($this->userName)); $view = new \OC\Files\View('/' . $this->userName . '/files'); // setup files $filesToCopy = array('documents' => array('document.pdf', 'document.docx', 'document.odt', 'document.txt')); $count = 0; foreach ($filesToCopy as $folder => $files) { foreach ($files as $file) { $imgData = file_get_contents(__DIR__ . '/data/' . $file); $view->mkdir($folder); $path = $folder . '/' . $file; $view->file_put_contents($path, $imgData); // set mtime to get fixed sorting with respect to recentFiles $count++; $view->touch($path, 1000 + $count); } } list($storage, ) = $view->resolvePath(''); /** @var $storage Storage */ $this->storage = $storage; $this->scanner = $storage->getScanner(); $this->scanner->scan(''); }
/** * delete the version from the storage and cache * * @param \OC\Files\View $view * @param string $path */ protected static function deleteVersion($view, $path) { $view->unlink($path); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ list($storage, $internalPath) = $view->resolvePath($path); $cache = $storage->getCache($internalPath); $cache->remove($internalPath); }
/** * find all versions which belong to the file we want to restore * * @param string $filename name of the file which should be restored * @param int $timestamp timestamp when the file was deleted * @return array */ private static function getVersionsFromTrash($filename, $timestamp, $user) { $view = new \OC\Files\View('/' . $user . '/files_trashbin/versions'); $versions = array(); //force rescan of versions, local storage may not have updated the cache if (!self::$scannedVersions) { /** @var \OC\Files\Storage\Storage $storage */ list($storage, ) = $view->resolvePath('/'); $storage->getScanner()->scan('files_trashbin/versions'); self::$scannedVersions = true; } if ($timestamp) { // fetch for old versions $matches = $view->searchRaw($filename . '.v%.d' . $timestamp); $offset = -strlen($timestamp) - 2; } else { $matches = $view->searchRaw($filename . '.v%'); } if (is_array($matches)) { foreach ($matches as $ma) { if ($timestamp) { $parts = explode('.v', substr($ma['path'], 0, $offset)); $versions[] = end($parts); } else { $parts = explode('.v', $ma); $versions[] = end($parts); } } } return $versions; }
/** * Copy a file or folder on storage level * * @param View $view * @param string $source * @param string $target * @return bool */ private static function copy(View $view, $source, $target) { /** @var \OC\Files\Storage\Storage $sourceStorage */ list($sourceStorage, $sourceInternalPath) = $view->resolvePath($source); /** @var \OC\Files\Storage\Storage $targetStorage */ list($targetStorage, $targetInternalPath) = $view->resolvePath($target); /** @var \OC\Files\Storage\Storage $ownerTrashStorage */ $result = $targetStorage->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); if ($result) { $view->getUpdater()->update($target); } return $result; }
/** * Stream copy file contents from $path1 to $path2 * * @param View $view view to use for copying * @param string $path1 source file to copy * @param string $path2 target file * * @return bool true for success, false otherwise */ private static function copyFileContents($view, $path1, $path2) { /** @var \OC\Files\Storage\Storage $storage1 */ list($storage1, $internalPath1) = $view->resolvePath($path1); /** @var \OC\Files\Storage\Storage $storage2 */ list($storage2, $internalPath2) = $view->resolvePath($path2); $view->lockFile($path1, ILockingProvider::LOCK_EXCLUSIVE); $view->lockFile($path2, ILockingProvider::LOCK_EXCLUSIVE); // TODO add a proper way of overwriting a file while maintaining file ids if ($storage1->instanceOfStorage('\\OC\\Files\\ObjectStore\\ObjectStoreStorage') || $storage2->instanceOfStorage('\\OC\\Files\\ObjectStore\\ObjectStoreStorage')) { $source = $storage1->fopen($internalPath1, 'r'); $target = $storage2->fopen($internalPath2, 'w'); list(, $result) = \OC_Helper::streamCopy($source, $target); fclose($source); fclose($target); if ($result !== false) { $storage1->unlink($internalPath1); } } else { $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2); } $view->unlockFile($path1, ILockingProvider::LOCK_EXCLUSIVE); $view->unlockFile($path2, ILockingProvider::LOCK_EXCLUSIVE); return $result !== false; }