/** * @medium */ function testDeleteParentOfMountPoint() { // share to user $fileinfo = $this->view->getFileInfo($this->folder); $result = \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31); $this->assertTrue($result); self::loginHelper(self::TEST_FILES_SHARING_API_USER2); $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); $this->assertTrue($user2View->file_exists($this->folder)); // create a local folder $result = $user2View->mkdir('localfolder'); $this->assertTrue($result); // move mount point to local folder $result = $user2View->rename($this->folder, '/localfolder/' . $this->folder); $this->assertTrue($result); // mount point in the root folder should no longer exist $this->assertFalse($user2View->is_dir($this->folder)); // delete the local folder $result = $user2View->unlink('/localfolder'); $this->assertTrue($result); //enforce reload of the mount points self::loginHelper(self::TEST_FILES_SHARING_API_USER2); //mount point should be back at the root $this->assertTrue($user2View->is_dir($this->folder)); //cleanup self::loginHelper(self::TEST_FILES_SHARING_API_USER1); $this->view->unlink($this->folder); }
/** * test moving a shared file out of the Shared folder */ function testRename() { // login as admin \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // save file with content $cryptedFile = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename, $this->dataShort); // test that data was successfully written $this->assertTrue(is_int($cryptedFile)); // get the file info from previous created file $fileInfo = $this->view->getFileInfo('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); // check if we have a valid file info $this->assertTrue($fileInfo instanceof \OC\Files\FileInfo); // share the file \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, OCP\PERMISSION_ALL); // check if share key for user2 exists $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/' . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); // login as user2 \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename)); // get file contents $retrievedCryptedFile = $this->view->file_get_contents('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename); // check if data is the same as we previously written $this->assertEquals($this->dataShort, $retrievedCryptedFile); // move the file to a subfolder $this->view->rename('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename, '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->folder1 . $this->filename); // check if we can read the moved file $retrievedRenamedFile = $this->view->file_get_contents('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->folder1 . $this->filename); // check if data is the same as we previously written $this->assertEquals($this->dataShort, $retrievedRenamedFile); // cleanup \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); }
function testDescryptAllWithBrokenFiles() { $file1 = "/decryptAll1" . uniqid() . ".txt"; $file2 = "/decryptAll2" . uniqid() . ".txt"; $util = new Encryption\Util($this->view, $this->userId); $this->view->file_put_contents($this->userId . '/files/' . $file1, $this->dataShort); $this->view->file_put_contents($this->userId . '/files/' . $file2, $this->dataShort); $fileInfoEncrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1); $fileInfoEncrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2); $this->assertTrue($fileInfoEncrypted1 instanceof \OC\Files\FileInfo); $this->assertTrue($fileInfoEncrypted2 instanceof \OC\Files\FileInfo); $this->assertEquals($fileInfoEncrypted1['encrypted'], 1); $this->assertEquals($fileInfoEncrypted2['encrypted'], 1); // rename keyfile for file1 so that the decryption for file1 fails // Expected behaviour: decryptAll() returns false, file2 gets decrypted anyway $this->view->rename($this->userId . '/files_encryption/keyfiles/' . $file1 . '.key', $this->userId . '/files_encryption/keyfiles/' . $file1 . '.key.moved'); // decrypt all encrypted files $result = $util->decryptAll(); $this->assertFalse($result); $fileInfoUnencrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1); $fileInfoUnencrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2); $this->assertTrue($fileInfoUnencrypted1 instanceof \OC\Files\FileInfo); $this->assertTrue($fileInfoUnencrypted2 instanceof \OC\Files\FileInfo); // file1 should be still encrypted; file2 should be decrypted $this->assertEquals(1, $fileInfoUnencrypted1['encrypted']); $this->assertEquals(0, $fileInfoUnencrypted2['encrypted']); // keyfiles and share keys should still exist $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/keyfiles/')); $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/share-keys/')); // rename the keyfile for file1 back $this->view->rename($this->userId . '/files_encryption/keyfiles/' . $file1 . '.key.moved', $this->userId . '/files_encryption/keyfiles/' . $file1 . '.key'); // try again to decrypt all encrypted files $result = $util->decryptAll(); $this->assertTrue($result); $fileInfoUnencrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1); $fileInfoUnencrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2); $this->assertTrue($fileInfoUnencrypted1 instanceof \OC\Files\FileInfo); $this->assertTrue($fileInfoUnencrypted2 instanceof \OC\Files\FileInfo); // now both files should be decrypted $this->assertEquals(0, $fileInfoUnencrypted1['encrypted']); $this->assertEquals(0, $fileInfoUnencrypted2['encrypted']); // keyfiles and share keys should be deleted $this->assertFalse($this->view->is_dir($this->userId . '/files_encryption/keyfiles/')); $this->assertFalse($this->view->is_dir($this->userId . '/files_encryption/share-keys/')); //cleanup $this->view->unlink($this->userId . '/files/' . $file1); $this->view->unlink($this->userId . '/files/' . $file2); $this->view->deleteAll($this->userId . '/files_encryption/keyfiles.backup'); $this->view->deleteAll($this->userId . '/files_encryption/share-keys.backup'); }
/** * test deletion of a folder which contains share mount points. Share mount * points should be unshared before the folder gets deleted so * that the mount point doesn't end up at the trash bin */ function testDeleteParentFolder() { $status = \OC_App::isEnabled('files_trashbin'); \OC_App::enable('files_trashbin'); \OCA\Files_Trashbin\Trashbin::registerHooks(); OC_FileProxy::register(new OCA\Files\Share\Proxy()); $fileinfo = \OC\Files\Filesystem::getFileInfo($this->folder); $this->assertTrue($fileinfo instanceof \OC\Files\FileInfo); \OCP\Share::shareItem('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31); $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); $view = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); // check if user2 can see the shared folder $this->assertTrue($view->file_exists($this->folder)); $foldersShared = \OCP\Share::getItemsSharedWith('folder'); $this->assertSame(1, count($foldersShared)); $view->mkdir("localFolder"); $view->file_put_contents("localFolder/localFile.txt", "local file"); $view->rename($this->folder, 'localFolder/' . $this->folder); // share mount point should now be moved to the subfolder $this->assertFalse($view->file_exists($this->folder)); $this->assertTrue($view->file_exists('localFolder/' . $this->folder)); $view->unlink('localFolder'); $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); // shared folder should be unshared $foldersShared = \OCP\Share::getItemsSharedWith('folder'); $this->assertTrue(empty($foldersShared)); // trashbin should contain the local file but not the mount point $rootView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2); $trashContent = \OCA\Files_Trashbin\Helper::getTrashFiles('/', self::TEST_FILES_SHARING_API_USER2); $this->assertSame(1, count($trashContent)); $firstElement = reset($trashContent); $timestamp = $firstElement['mtime']; $this->assertTrue($rootView->file_exists('files_trashbin/files/localFolder.d' . $timestamp . '/localFile.txt')); $this->assertFalse($rootView->file_exists('files_trashbin/files/localFolder.d' . $timestamp . '/' . $this->folder)); //cleanup $rootView->deleteAll('files_trashin'); if ($status === false) { \OC_App::disable('files_trashbin'); } \OC\Files\Filesystem::getLoader()->removeStorageWrapper('oc_trashbin'); }
public function rename($path1, $path2) { // we need the paths relative to data/user/files $relPath1 = $this->getMountPoint() . '/' . $path1; $relPath2 = $this->getMountPoint() . '/' . $path2; $pathinfo = pathinfo($relPath1); $isPartFile = isset($pathinfo['extension']) && $pathinfo['extension'] === 'part'; $targetExists = $this->file_exists($path2); $sameFolder = dirname($relPath1) === dirname($relPath2); if ($targetExists || $sameFolder && !$isPartFile) { // note that renaming a share mount point is always allowed if (!$this->isUpdatable('')) { return false; } } else { if (!$this->isCreatable('')) { return false; } } // for part files we need to ask for the owner and path from the parent directory because // the file cache doesn't return any results for part files if ($isPartFile) { list($user1, $path1) = \OCA\Files_Sharing\Helper::getUidAndFilename($pathinfo['dirname']); $path1 = $path1 . '/' . $pathinfo['basename']; } else { list($user1, $path1) = \OCA\Files_Sharing\Helper::getUidAndFilename($relPath1); } $targetFilename = basename($relPath2); list($user2, $path2) = \OCA\Files_Sharing\Helper::getUidAndFilename(dirname($relPath2)); $rootView = new \OC\Files\View(''); return $rootView->rename('/' . $user1 . '/files/' . $path1, '/' . $user2 . '/files/' . $path2 . '/' . $targetFilename); }
/** * share a folder which contains a share mount point, should be forbidden */ public function testShareFolderWithAMountPoint() { // user 1 shares a folder with user2 \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); $fileInfo = $this->view->getFileInfo($this->folder); $share = $this->share(\OCP\Share::SHARE_TYPE_USER, $this->folder, self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_ALL); // user2 shares a file from the folder as link \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); $view = new \OC\Files\View('/' . \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2 . '/files'); $view->mkdir("localDir"); // move mount point to the folder "localDir" $result = $view->rename($this->folder, 'localDir/' . $this->folder); $this->assertTrue($result !== false); // try to share "localDir" $fileInfo2 = $view->getFileInfo('localDir'); $this->assertTrue($fileInfo2 instanceof \OC\Files\FileInfo); $pass = true; try { $this->share(\OCP\Share::SHARE_TYPE_USER, 'localDir', self::TEST_FILES_SHARING_API_USER2, self::TEST_FILES_SHARING_API_USER3, \OCP\Constants::PERMISSION_ALL); } catch (\Exception $e) { $pass = false; } $this->assertFalse($pass); //cleanup $result = $view->rename('localDir/' . $this->folder, $this->folder); $this->assertTrue($result !== false); $view->unlink('localDir'); \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); $this->shareManager->deleteShare($share); }
public function rename($path1, $path2) { // Check for partial files if (pathinfo($path1, PATHINFO_EXTENSION) === 'part') { if ($oldSource = $this->getSourcePath($path1)) { list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource); $newInternalPath = substr($oldInternalPath, 0, -5); return $storage->rename($oldInternalPath, $newInternalPath); } } else { // Renaming/moving is only allowed within shared folders $pos1 = strpos($path1, '/', 1); $pos2 = strpos($path2, '/', 1); if ($pos1 !== false && $pos2 !== false && ($oldSource = $this->getSourcePath($path1))) { $newSource = $this->getSourcePath(dirname($path2)) . '/' . basename($path2); // Within the same folder, we only need UPDATE permissions if (dirname($path1) == dirname($path2) and $this->isUpdatable($path1)) { list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource); list(, $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource); return $storage->rename($oldInternalPath, $newInternalPath); // otherwise DELETE and CREATE permissions required } elseif ($this->isDeletable($path1) && $this->isCreatable(dirname($path2))) { $rootView = new \OC\Files\View(''); return $rootView->rename($oldSource, $newSource); } } } return false; }
/** * share a folder which contains a share mount point, should be forbidden */ public function testShareFolderWithAMountPoint() { // user 1 shares a folder with user2 \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); $fileInfo = $this->view->getFileInfo($this->folder); $result = \OCP\Share::shareItem('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); $this->assertTrue($result); // user2 shares a file from the folder as link \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); $view = new \OC\Files\View('/' . \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2 . '/files'); $view->mkdir("localDir"); // move mount point to the folder "localDir" $result = $view->rename($this->folder, 'localDir/' . $this->folder); $this->assertTrue($result !== false); // try to share "localDir" $fileInfo2 = $view->getFileInfo('localDir'); $this->assertTrue($fileInfo2 instanceof \OC\Files\FileInfo); try { $result2 = \OCP\Share::shareItem('folder', $fileInfo2['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER3, 31); } catch (\Exception $e) { $result2 = false; } $this->assertFalse($result2); //cleanup $result = $view->rename('localDir/' . $this->folder, $this->folder); $this->assertTrue($result !== false); $view->unlink('localDir'); \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); \OCP\Share::unshare('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); }
/** * @medium */ function testRenamePartFile() { // share to user $fileinfo = $this->view->getFileInfo($this->folder); $result = \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31); $this->assertTrue($result); self::loginHelper(self::TEST_FILES_SHARING_API_USER2); $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); $this->assertTrue($user2View->file_exists($this->folder)); // create part file $result = $user2View->file_put_contents($this->folder . '/foo.txt.part', 'some test data'); $this->assertTrue(is_int($result)); // rename part file to real file $result = $user2View->rename($this->folder . '/foo.txt.part', $this->folder . '/foo.txt'); $this->assertTrue($result); // check if the new file really exists $this->assertTrue($user2View->file_exists($this->folder . '/foo.txt')); // check if the rename also affected the owner self::loginHelper(self::TEST_FILES_SHARING_API_USER1); $this->assertTrue($this->view->file_exists($this->folder . '/foo.txt')); //cleanup \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2); }
/** * @medium */ function testMoveFolder() { $view = new \OC\Files\View('/' . $this->userId . '/files'); $filename = '/tmp-' . uniqid(); $folder = '/folder' . uniqid(); $view->mkdir($folder); // Save long data as encrypted file using stream wrapper $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $folder . $filename, $this->dataLong); // Test that data was successfully written $this->assertTrue(is_int($cryptedFile)); // Get file decrypted contents $decrypt = file_get_contents('crypt:///' . $this->userId . '/files/' . $folder . $filename); $this->assertEquals($this->dataLong, $decrypt); $newFolder = '/newfolder/subfolder' . uniqid(); $view->mkdir('/newfolder'); $view->rename($folder, $newFolder); // Get file decrypted contents $newDecrypt = file_get_contents('crypt:///' . $this->userId . '/files/' . $newFolder . $filename); $this->assertEquals($this->dataLong, $newDecrypt); // tear down $view->unlink($newFolder); $view->unlink('/newfolder'); }
public function rename($path1, $path2) { // we need the paths relative to data/user/files $relPath1 = $this->getMountPoint() . '/' . $path1; $relPath2 = $this->getMountPoint() . '/' . $path2; // check for update permissions on the share if ($this->isUpdatable('')) { $pathinfo = pathinfo($relPath1); // for part files we need to ask for the owner and path from the parent directory because // the file cache doesn't return any results for part files if ($pathinfo['extension'] === 'part') { list($user1, $path1) = \OCA\Files_Sharing\Helper::getUidAndFilename($pathinfo['dirname']); $path1 = $path1 . '/' . $pathinfo['basename']; } else { list($user1, $path1) = \OCA\Files_Sharing\Helper::getUidAndFilename($relPath1); } $targetFilename = basename($relPath2); list($user2, $path2) = \OCA\Files_Sharing\Helper::getUidAndFilename(dirname($relPath2)); $rootView = new \OC\Files\View(''); return $rootView->rename('/' . $user1 . '/files/' . $path1, '/' . $user2 . '/files/' . $path2 . '/' . $targetFilename); } return false; }
/** * rollback to an old version of a file. */ public static function rollback($file, $revision) { if (\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED) == 'true') { list($uid, $filename) = self::getUidAndFilename($file); $users_view = new \OC\Files\View('/' . $uid); $files_view = new \OC\Files\View('/' . \OCP\User::getUser() . '/files'); $versionCreated = false; //first create a new version $version = 'files_versions' . $filename . '.v' . $users_view->filemtime('files' . $filename); if (!$users_view->file_exists($version)) { $users_view->copy('files' . $filename, 'files_versions' . $filename . '.v' . $users_view->filemtime('files' . $filename)); $versionCreated = true; } // rollback if (@$users_view->rename('files_versions' . $filename . '.v' . $revision, 'files' . $filename)) { $files_view->touch($file, $revision); Storage::scheduleExpire($file); return true; } else { if ($versionCreated) { self::deleteVersion($users_view, $version); } } } return false; }
<?php OCP\JSON::checkLoggedIn(); OCP\JSON::callCheck(); $l = \OC::$server->getL10N('settings'); $user = \OC_User::getUser(); $view = new \OC\Files\View('/' . $user . '/files_encryption'); $keyfilesRestored = $view->rename('keyfiles.backup', 'keyfiles'); $sharekeysRestored = $view->rename('share-keys.backup', 'share-keys'); if ($keyfilesRestored && $sharekeysRestored) { \OCP\JSON::success(array('data' => array('message' => $l->t('Backups restored successfully')))); } else { // if one of the move operation was succesful we remove the files back to have a consistent state if ($keyfilesRestored) { $view->rename('keyfiles', 'keyfiles.backup'); } if ($sharekeysRestored) { $view->rename('share-keys', 'share-keys.backup'); } \OCP\JSON::error(array('data' => array('message' => $l->t('Couldn\'t restore your encryption keys, please check your owncloud.log or ask your administrator')))); }
public function testRenameCrossStoragePreserveMtime() { $storage1 = new Temporary(array()); $storage2 = new Temporary(array()); $scanner1 = $storage1->getScanner(); $scanner2 = $storage2->getScanner(); $storage1->mkdir('sub'); $storage1->mkdir('foo'); $storage1->file_put_contents('foo.txt', 'asd'); $storage1->file_put_contents('foo/bar.txt', 'asd'); \OC\Files\Filesystem::mount($storage1, array(), '/test/'); \OC\Files\Filesystem::mount($storage2, array(), '/test/sub/storage'); $view = new \OC\Files\View(''); $time = time() - 200; $view->touch('/test/foo.txt', $time); $view->touch('/test/foo', $time); $view->touch('/test/foo/bar.txt', $time); $view->rename('/test/foo.txt', '/test/sub/storage/foo.txt'); $this->assertEquals($time, $view->filemtime('/test/sub/storage/foo.txt')); $view->rename('/test/foo', '/test/sub/storage/foo'); $this->assertEquals($time, $view->filemtime('/test/sub/storage/foo/bar.txt')); }
/** * @dataProvider dataProviderGetUsersSharingFile * * @param string $groupName name of group to share with * @param bool $includeOwner whether to include the owner in the result * @param bool $includePaths whether to include paths in the result * @param array $expectedResult expected result of the API call */ public function testGetUsersSharingFile($groupName, $includeOwner, $includePaths, $expectedResult) { $fileinfo = $this->view->getFileInfo($this->folder); $result = \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, $groupName, \OCP\Constants::PERMISSION_READ); $this->assertTrue($result); // public share $result = \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null, \OCP\Constants::PERMISSION_READ); $this->assertNotNull($result); // returns the token! // owner renames after sharing $this->view->rename($this->folder, $this->folder . '_owner_renamed'); self::loginHelper(self::TEST_FILES_SHARING_API_USER2); $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); $user2View->rename($this->folder, $this->folder . '_renamed'); $ownerPath = $this->folder . '_owner_renamed'; $owner = self::TEST_FILES_SHARING_API_USER1; $result = \OCP\Share::getUsersSharingFile($ownerPath, $owner, $includeOwner, $includePaths); // sort users to make sure it matches if ($includePaths) { ksort($result); } else { sort($result['users']); } $this->assertEquals($expectedResult, $result); }
/** * restore encryption keys from trash bin * * @param \OC\Files\View $view * @param string $file complete path to file * @param string $filename name of file * @param string $uniqueFilename new file name to restore the file without overwriting existing files * @param string $location location of file * @param int $timestamp deleteion time * */ private static function restoreEncryptionKeys($view, $file, $filename, $uniqueFilename, $location, $timestamp) { // Take care of encryption keys TODO! Get '.key' in file between file name and delete date (also for permanent delete!) if (\OCP\App::isEnabled('files_encryption')) { $user = \OCP\User::getUser(); $rootView = new \OC\Files\View('/'); $target = \OC\Files\Filesystem::normalizePath('/' . $location . '/' . $uniqueFilename); list($owner, $ownerPath) = self::getUidAndFilename($target); $util = new \OCA\Encryption\Util(new \OC\Files\View('/'), $user); if ($util->isSystemWideMountPoint($ownerPath)) { $baseDir = '/files_encryption/'; } else { $baseDir = $owner . '/files_encryption/'; } $path_parts = pathinfo($file); $source_location = $path_parts['dirname']; if ($view->is_dir('/files_trashbin/keyfiles/' . $file)) { if ($source_location != '.') { $keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $source_location . '/' . $filename); $sharekey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $source_location . '/' . $filename); } else { $keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $filename); $sharekey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $filename); } } else { $keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $source_location . '/' . $filename . '.key'); } if ($timestamp) { $keyfile .= '.d' . $timestamp; } // disable proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; if ($rootView->file_exists($keyfile)) { // handle directory if ($rootView->is_dir($keyfile)) { // handle keyfiles $rootView->rename($keyfile, $baseDir . '/keyfiles/' . $ownerPath); // handle share-keys if ($timestamp) { $sharekey .= '.d' . $timestamp; } $rootView->rename($sharekey, $baseDir . '/share-keys/' . $ownerPath); } else { // handle keyfiles $rootView->rename($keyfile, $baseDir . '/keyfiles/' . $ownerPath . '.key'); // handle share-keys $ownerShareKey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $source_location . '/' . $filename . '.' . $user . '.shareKey'); if ($timestamp) { $ownerShareKey .= '.d' . $timestamp; } // move only owners key $rootView->rename($ownerShareKey, $baseDir . '/share-keys/' . $ownerPath . '.' . $user . '.shareKey'); // try to re-share if file is shared $filesystemView = new \OC\Files\View('/'); $session = new \OCA\Encryption\Session($filesystemView); $util = new \OCA\Encryption\Util($filesystemView, $user); // fix the file size $absolutePath = \OC\Files\Filesystem::normalizePath('/' . $owner . '/files/' . $ownerPath); $util->fixFileSize($absolutePath); // get current sharing state $sharingEnabled = \OCP\Share::isEnabled(); // get users sharing this file $usersSharing = $util->getSharingUsersArray($sharingEnabled, $target); // Attempt to set shareKey $util->setSharedFileKeyfiles($session, $usersSharing, $target); } } // enable proxy \OC_FileProxy::$enabled = $proxyStatus; } }
/** * restore encryption keys from trash bin * * @param \OC\Files\View $view * @param string $file complete path to file * @param string $filename name of file * @param string $uniqueFilename new file name to restore the file without overwriting existing files * @param string $location location of file * @param int $timestamp deletion time * @return bool */ private static function restoreEncryptionKeys(\OC\Files\View $view, $file, $filename, $uniqueFilename, $location, $timestamp) { if (\OCP\App::isEnabled('files_encryption')) { $user = \OCP\User::getUser(); $rootView = new \OC\Files\View('/'); $target = \OC\Files\Filesystem::normalizePath('/' . $location . '/' . $uniqueFilename); list($owner, $ownerPath) = self::getUidAndFilename($target); // file has been deleted in between if (empty($ownerPath)) { return false; } $util = new \OCA\Files_Encryption\Util($rootView, $user); $baseDir = '/files_encryption/'; if (!$util->isSystemWideMountPoint($ownerPath)) { $baseDir = $owner . $baseDir; } $source_location = dirname($file); if ($view->is_dir('/files_trashbin/keys/' . $file)) { if ($source_location != '.') { $keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keys/' . $source_location . '/' . $filename); } else { $keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keys/' . $filename); } } if ($timestamp) { $keyfile .= '.d' . $timestamp; } if ($rootView->is_dir($keyfile)) { $rootView->rename($keyfile, $baseDir . '/keys/' . $ownerPath); } } }
public function testGetShareFromOutsideFilesFolder() { \OC_User::setUserId($this->user1); $view = new \OC\Files\View('/' . $this->user1 . '/'); $view->mkdir('files/test'); $view->mkdir('files/test/sub'); $view->mkdir('files_trashbin'); $view->mkdir('files_trashbin/files'); $fileInfo = $view->getFileInfo('files/test/sub'); $this->assertInstanceOf('\\OC\\Files\\FileInfo', $fileInfo); $fileId = $fileInfo->getId(); $this->assertTrue(\OCP\Share::shareItem('folder', $fileId, \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ), 'Failed asserting that user 1 successfully shared "test/sub" with user 2.'); $result = \OCP\Share::getItemShared('folder', $fileId, Backend::FORMAT_SOURCE); $this->assertNotEmpty($result); $result = \OCP\Share::getItemSharedWithUser('folder', $fileId, $this->user2); $this->assertNotEmpty($result); $result = \OCP\Share::getItemsSharedWithUser('folder', $this->user2); $this->assertNotEmpty($result); // move to trash (keeps file id) $view->rename('files/test', 'files_trashbin/files/test'); $result = \OCP\Share::getItemShared('folder', $fileId, Backend::FORMAT_SOURCE); $this->assertEmpty($result, 'Share must not be returned for files outside of "files"'); $result = \OCP\Share::getItemSharedWithUser('folder', $fileId, $this->user2); $this->assertEmpty($result, 'Share must not be returned for files outside of "files"'); $result = \OCP\Share::getItemsSharedWithUser('folder', $this->user2); $this->assertEmpty($result, 'Share must not be returned for files outside of "files"'); }
public function testFopenWithDeleteOnlyPermission() { $this->view->file_put_contents($this->folder . '/existing.txt', 'foo'); $fileinfoFolder = $this->view->getFileInfo($this->folder); $result = \OCP\Share::shareItem('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_DELETE); $this->assertTrue($result); self::loginHelper(self::TEST_FILES_SHARING_API_USER2); $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); // part file should be forbidden $handle = $user2View->fopen($this->folder . '/test.txt.part', 'w'); $this->assertFalse($handle); // regular file forbidden $handle = $user2View->fopen($this->folder . '/test.txt', 'w'); $this->assertFalse($handle); // rename forbidden $this->assertFalse($user2View->rename($this->folder . '/existing.txt', $this->folder . '/existing2.txt')); // delete allowed $this->assertTrue($user2View->unlink($this->folder . '/existing.txt')); //cleanup self::loginHelper(self::TEST_FILES_SHARING_API_USER1); $result = \OCP\Share::unshare('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2); $this->assertTrue($result); }
/** * rollback to an old version of a file. */ public static function rollback($file, $revision) { if (\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED) == 'true') { list($uid, $filename) = self::getUidAndFilename($file); $users_view = new \OC\Files\View('/' . $uid); $files_view = new \OC\Files\View('/' . \OCP\User::getUser() . '/files'); $versionCreated = false; //first create a new version $version = 'files_versions' . $filename . '.v' . $users_view->filemtime('files' . $filename); if (!$users_view->file_exists($version)) { // disable proxy to prevent multiple fopen calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $users_view->copy('files' . $filename, 'files_versions' . $filename . '.v' . $users_view->filemtime('files' . $filename)); // reset proxy state \OC_FileProxy::$enabled = $proxyStatus; $versionCreated = true; } // rollback if (@$users_view->rename('files_versions' . $filename . '.v' . $revision, 'files' . $filename)) { $files_view->touch($file, $revision); Storage::expire($file); return true; } else { if ($versionCreated) { $users_view->unlink($version); } } } return false; }
/** * @medium */ public function testDeleteParentOfMountPoint() { // share to user $share = $this->share(\OCP\Share::SHARE_TYPE_USER, $this->folder, self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_ALL); self::loginHelper(self::TEST_FILES_SHARING_API_USER2); $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); $this->assertTrue($user2View->file_exists($this->folder)); // create a local folder $result = $user2View->mkdir('localfolder'); $this->assertTrue($result); // move mount point to local folder $result = $user2View->rename($this->folder, '/localfolder/' . $this->folder); $this->assertTrue($result); // mount point in the root folder should no longer exist $this->assertFalse($user2View->is_dir($this->folder)); // delete the local folder $result = $user2View->unlink('/localfolder'); $this->assertTrue($result); //enforce reload of the mount points self::loginHelper(self::TEST_FILES_SHARING_API_USER2); //mount point should be back at the root $this->assertTrue($user2View->is_dir($this->folder)); //cleanup self::loginHelper(self::TEST_FILES_SHARING_API_USER1); $this->view->unlink($this->folder); }
/** * Test that moving a mount point into a shared folder is forbidden */ public function testMoveMountPointIntoSharedFolder() { $this->loginAsUser($this->user); list($mount1) = $this->createTestMovableMountPoints([$this->user . '/files/mount1']); $mount1->expects($this->never())->method('moveMount'); $view = new \OC\Files\View('/' . $this->user . '/files/'); $view->mkdir('shareddir'); $view->mkdir('shareddir/sub'); $view->mkdir('shareddir/sub2'); $fileId = $view->getFileInfo('shareddir')->getId(); $userObject = \OC::$server->getUserManager()->createUser('test2', 'IHateNonMockableStaticClasses'); $this->assertTrue(\OCP\Share::shareItem('folder', $fileId, \OCP\Share::SHARE_TYPE_USER, 'test2', \OCP\Constants::PERMISSION_READ)); $this->assertFalse($view->rename('mount1', 'shareddir'), 'Cannot overwrite shared folder'); $this->assertFalse($view->rename('mount1', 'shareddir/sub'), 'Cannot move mount point into shared folder'); $this->assertFalse($view->rename('mount1', 'shareddir/sub/sub2'), 'Cannot move mount point into shared subfolder'); $this->assertTrue(\OCP\Share::unshare('folder', $fileId, \OCP\Share::SHARE_TYPE_USER, 'test2')); $userObject->delete(); }
public function testRenameOverWrite() { $storage = new Temporary(array()); $scanner = $storage->getScanner(); $storage->mkdir('sub'); $storage->mkdir('foo'); $storage->file_put_contents('foo.txt', 'asd'); $storage->file_put_contents('foo/bar.txt', 'asd'); $scanner->scan(''); \OC\Files\Filesystem::mount($storage, array(), '/test/'); $view = new \OC\Files\View(''); $this->assertTrue($view->rename('/test/foo.txt', '/test/foo/bar.txt')); }
/** * @medium */ function testMoveBetweenStorages() { $storage1 = $this->getTestStorage(); $storage2 = $this->getTestStorage(); \OC\Files\Filesystem::mount($storage1, array(), '/'); \OC\Files\Filesystem::mount($storage2, array(), '/substorage'); $rootView = new \OC\Files\View(''); $rootView->rename('foo.txt', 'substorage/folder/foo.txt'); $this->assertFalse($rootView->file_exists('foo.txt')); $this->assertTrue($rootView->file_exists('substorage/folder/foo.txt')); $rootView->rename('substorage/folder', 'anotherfolder'); $this->assertFalse($rootView->is_dir('substorage/folder')); $this->assertTrue($rootView->file_exists('anotherfolder/foo.txt')); $this->assertTrue($rootView->file_exists('anotherfolder/bar.txt')); }
/** * restore versions from trash bin * * @param \OC\Files\View $view file view * @param string $file complete path to file * @param string $filename name of file once it was deleted * @param string $uniqueFilename new file name to restore the file without overwriting existing files * @param string $location location if file * @param int $timestamp deletion time * @return bool */ private static function restoreVersions(\OC\Files\View $view, $file, $filename, $uniqueFilename, $location, $timestamp) { if (\OCP\App::isEnabled('files_versions')) { $user = \OCP\User::getUser(); $rootView = new \OC\Files\View('/'); $target = \OC\Files\Filesystem::normalizePath('/' . $location . '/' . $uniqueFilename); list($owner, $ownerPath) = self::getUidAndFilename($target); // file has been deleted in between if (empty($ownerPath)) { return false; } if ($timestamp) { $versionedFile = $filename; } else { $versionedFile = $file; } if ($view->is_dir('/files_trashbin/versions/' . $file)) { $rootView->rename(\OC\Files\Filesystem::normalizePath($user . '/files_trashbin/versions/' . $file), \OC\Files\Filesystem::normalizePath($owner . '/files_versions/' . $ownerPath)); } else { if ($versions = self::getVersionsFromTrash($versionedFile, $timestamp, $user)) { foreach ($versions as $v) { if ($timestamp) { $rootView->rename($user . '/files_trashbin/versions/' . $versionedFile . '.v' . $v . '.d' . $timestamp, $owner . '/files_versions/' . $ownerPath . '.v' . $v); } else { $rootView->rename($user . '/files_trashbin/versions/' . $versionedFile . '.v' . $v, $owner . '/files_versions/' . $ownerPath . '.v' . $v); } } } } } }