/** * @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); }
/** * @medium */ function testDeleteFileKeyFolder() { $this->view->mkdir('/' . Test_Encryption_Keymanager::TEST_USER . '/files/folder1'); $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files/folder1/existingFile.txt', 'data'); // create folder structure for some dummy file key files $this->view->mkdir('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/keyfiles/folder1'); // create dummy keyfile $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/keyfiles/folder1/dummyFile.txt.key', 'data'); // recursive delete share keys from user1 and user2 $result = Encryption\Keymanager::deleteFileKey($this->view, '/folder1'); $this->assertFalse($result); // all file keys should still exists if we try to delete a folder with keys for which some files still exists $this->assertTrue($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/keyfiles/folder1/dummyFile.txt.key')); $this->assertTrue($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/keyfiles/folder1/existingFile.txt.key')); // delete folder $this->view->unlink('/' . Test_Encryption_Keymanager::TEST_USER . '/files/folder1'); // create dummy keyfile $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/keyfiles/folder1/dummyFile.txt.key', 'data'); // now file keys should be deleted since the folder no longer exists $result = Encryption\Keymanager::deleteFileKey($this->view, '/folder1'); $this->assertTrue($result); $this->assertFalse($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/keyfiles/folder1')); // cleanup $this->view->deleteAll('/' . Test_Encryption_Keymanager::TEST_USER . '/files/folder1'); }
/** * unshare shared items below the deleted folder * * @param string $path */ private function unshareChildren($path) { $view = new \OC\Files\View('/'); // find share mount points within $path and unmount them $mountManager = \OC\Files\Filesystem::getMountManager(); $mountedShares = $mountManager->findIn($path); foreach ($mountedShares as $mount) { if ($mount->getStorage()->instanceOfStorage('OCA\\Files_Sharing\\ISharedStorage')) { $mountPoint = $mount->getMountPoint(); $view->unlink($mountPoint); } } }
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'); }
/** * Tests that filterShareReadyUsers() returns the correct list of * users that are ready or not ready for encryption */ public function testFilterShareReadyUsers() { $appConfig = \OC::$server->getAppConfig(); $publicShareKeyId = $appConfig->getValue('files_encryption', 'publicShareKeyId'); $recoveryKeyId = $appConfig->getValue('files_encryption', 'recoveryKeyId'); $usersToTest = array('readyUser', 'notReadyUser', 'nonExistingUser', $publicShareKeyId, $recoveryKeyId); \Test_Encryption_Util::loginHelper('readyUser', true); \Test_Encryption_Util::loginHelper('notReadyUser', true); // delete encryption dir to make it not ready $this->view->unlink('notReadyUser/files_encryption/'); // login as user1 \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1); $result = $this->util->filterShareReadyUsers($usersToTest); $this->assertEquals(array('readyUser', $publicShareKeyId, $recoveryKeyId), $result['ready']); $this->assertEquals(array('notReadyUser', 'nonExistingUser'), $result['unready']); \OC_User::deleteUser('readyUser'); }
/** * 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'); }
/** * Test clearing orphaned files */ public function testClearFiles() { $input = $this->getMockBuilder('Symfony\\Component\\Console\\Input\\InputInterface')->disableOriginalConstructor()->getMock(); $output = $this->getMockBuilder('Symfony\\Component\\Console\\Output\\OutputInterface')->disableOriginalConstructor()->getMock(); $this->loginAsUser($this->user1); $view = new \OC\Files\View('/' . $this->user1 . '/'); $view->mkdir('files/test'); $fileInfo = $view->getFileInfo('files/test'); $storageId = $fileInfo->getStorage()->getId(); $this->assertCount(1, $this->getFile($fileInfo->getId()), 'Asserts that file is available'); $this->command->execute($input, $output); $this->assertCount(1, $this->getFile($fileInfo->getId()), 'Asserts that file is still available'); $deletedRows = $this->connection->executeUpdate('DELETE FROM `*PREFIX*storages` WHERE `id` = ?', [$storageId]); $this->assertNotNull($deletedRows, 'Asserts that storage got deleted'); $this->assertSame(1, $deletedRows, 'Asserts that storage got deleted'); // parent folder, `files`, ´test` and `welcome.txt` => 4 elements $output->expects($this->once())->method('writeln')->with('4 orphaned file cache entries deleted'); $this->command->execute($input, $output); $this->assertCount(0, $this->getFile($fileInfo->getId()), 'Asserts that file gets cleaned up'); $view->unlink('files/test'); }
/** * 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; }
public function testDeleteGhostFile() { $storage = new Temporary(array()); $scanner = $storage->getScanner(); $cache = $storage->getCache(); $storage->file_put_contents('foo.txt', 'bar'); \OC\Files\Filesystem::mount($storage, array(), '/test/'); $scanner->scan(''); $storage->unlink('foo.txt'); $this->assertTrue($cache->inCache('foo.txt')); $view = new \OC\Files\View('/test'); $rootInfo = $view->getFileInfo(''); $this->assertEquals(3, $rootInfo->getSize()); $view->unlink('foo.txt'); $newInfo = $view->getFileInfo(''); $this->assertFalse($cache->inCache('foo.txt')); $this->assertNotEquals($rootInfo->getEtag(), $newInfo->getEtag()); $this->assertEquals(0, $newInfo->getSize()); }
/** * if the file was really deleted we remove the encryption keys * @param array $params * @return boolean|null */ public static function postDelete($params) { $path = $params[\OC\Files\Filesystem::signal_param_path]; if (!isset(self::$deleteFiles[$path])) { return true; } $deletedFile = self::$deleteFiles[$path]; $keyPath = $deletedFile['keyPath']; // we don't need to remember the file any longer unset(self::$deleteFiles[$path]); $view = new \OC\Files\View('/'); // return if the file still exists and wasn't deleted correctly if ($view->file_exists('/' . \OCP\User::getUser() . '/files/' . $path)) { return true; } // Delete keyfile & shareKey so it isn't orphaned $view->unlink($keyPath); }
/** * @medium */ function testFopenFile() { $filename = '/tmp-' . uniqid(); $view = new \OC\Files\View('/' . $this->userId . '/files'); // Save short data as encrypted file using stream wrapper $cryptedFile = $view->file_put_contents($filename, $this->dataShort); // Test that data was successfully written $this->assertTrue(is_int($cryptedFile)); $handle = $view->fopen($filename, 'r'); // Get file decrypted contents $decrypt = fgets($handle); $this->assertEquals($this->dataShort, $decrypt); // tear down $view->unlink($filename); }
/** * 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); }
function testStreamSetWriteBuffer() { $filename = '/tmp-' . time(); $view = new \OC\Files\View('/' . $this->userId . '/files'); // Save short data as encrypted file using stream wrapper $cryptedFile = $view->file_put_contents($filename, $this->dataShort); // Test that data was successfully written $this->assertTrue(is_int($cryptedFile)); $handle = $view->fopen($filename, 'r'); // set stream options $this->assertEquals(0, stream_set_write_buffer($handle, 1024)); // tear down $view->unlink($filename); }
/** * @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); }
public function testDeleteFailKeepCache() { /** * @var \PHPUnit_Framework_MockObject_MockObject | \OC\Files\Storage\Temporary $storage */ $storage = $this->getMockBuilder('\\OC\\Files\\Storage\\Temporary')->setConstructorArgs(array(array()))->setMethods(array('unlink'))->getMock(); $storage->expects($this->once())->method('unlink')->will($this->returnValue(false)); $scanner = $storage->getScanner(); $cache = $storage->getCache(); $storage->file_put_contents('foo.txt', 'asd'); $scanner->scan(''); \OC\Files\Filesystem::mount($storage, array(), '/test/'); $view = new \OC\Files\View('/test'); $this->assertFalse($view->unlink('foo.txt')); $this->assertTrue($cache->inCache('foo.txt')); }
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); }
/** * cleanup encryption backend upon user deleted * @note This method should never be called for users using client side encryption */ public static function postDeleteUser($params) { if (\OCP\App::isEnabled('files_encryption')) { $view = new \OC\Files\View('/'); // cleanup public key $publicKey = '/public-keys/' . $params['uid'] . '.public.key'; // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $view->unlink($publicKey); \OC_FileProxy::$enabled = $proxyStatus; } }
/** * 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); }
/** * Test clearing orphaned shares */ public function testClearShares() { $this->loginAsUser($this->user1); $view = new \OC\Files\View('/' . $this->user1 . '/'); $view->mkdir('files/test'); $view->mkdir('files/test/sub'); $fileInfo = $view->getFileInfo('files/test/sub'); $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.'); $this->assertCount(1, $this->getShares()); $this->job->run([]); $this->assertCount(1, $this->getShares(), 'Linked shares not deleted'); $view->unlink('files/test'); $this->job->run([]); $this->assertCount(0, $this->getShares(), 'Orphaned shares deleted'); }
/** * move file to the trash bin * * @param string $file_path path to the deleted file/directory relative to the files root directory */ public static function move2trash($file_path) { // get the user for which the filesystem is setup $root = Filesystem::getRoot(); list(, $user) = explode('/', $root); $size = 0; list($owner, $ownerPath) = self::getUidAndFilename($file_path); $view = new \OC\Files\View('/' . $user); // file has been deleted in between if (!$view->file_exists('/files/' . $file_path)) { return true; } self::setUpTrash($user); $path_parts = pathinfo($file_path); $filename = $path_parts['basename']; $location = $path_parts['dirname']; $timestamp = time(); $userTrashSize = self::getTrashbinSize($user); // disable proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $trashPath = '/files_trashbin/files/' . $filename . '.d' . $timestamp; try { $sizeOfAddedFiles = $view->filesize('/files/' . $file_path); if ($view->file_exists($trashPath)) { $view->unlink($trashPath); } $view->rename('/files/' . $file_path, $trashPath); } catch (\OCA\Files_Trashbin\Exceptions\CopyRecursiveException $e) { $sizeOfAddedFiles = false; if ($view->file_exists($trashPath)) { $view->deleteAll($trashPath); } \OC_Log::write('files_trashbin', 'Couldn\'t move ' . $file_path . ' to the trash bin', \OC_log::ERROR); } \OC_FileProxy::$enabled = $proxyStatus; if ($view->file_exists('/files/' . $file_path)) { // failed to delete the original file, abort $view->unlink($trashPath); return false; } if ($sizeOfAddedFiles !== false) { $size = $sizeOfAddedFiles; $query = \OC_DB::prepare("INSERT INTO `*PREFIX*files_trash` (`id`,`timestamp`,`location`,`user`) VALUES (?,?,?,?)"); $result = $query->execute(array($filename, $timestamp, $location, $user)); if (!$result) { \OC_Log::write('files_trashbin', 'trash bin database couldn\'t be updated', \OC_log::ERROR); } \OCP\Util::emitHook('\\OCA\\Files_Trashbin\\Trashbin', 'post_moveToTrash', array('filePath' => \OC\Files\Filesystem::normalizePath($file_path), 'trashPath' => \OC\Files\Filesystem::normalizePath($filename . '.d' . $timestamp))); $size += self::retainVersions($file_path, $filename, $timestamp); $size += self::retainEncryptionKeys($file_path, $filename, $timestamp); // if owner !== user we need to also add a copy to the owners trash if ($user !== $owner) { self::copyFilesToOwner($file_path, $owner, $ownerPath, $timestamp); } } $userTrashSize += $size; $userTrashSize -= self::expire($userTrashSize, $user); // if owner !== user we also need to update the owners trash size if ($owner !== $user) { $ownerTrashSize = self::getTrashbinSize($owner); $ownerTrashSize += $size; $ownerTrashSize -= self::expire($ownerTrashSize, $owner); } return $sizeOfAddedFiles === false ? false : true; }
/** * @medium */ function testUnlinkRootMustFail() { $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->file_put_contents('/foo.txt', 'asd'); $rootView->file_put_contents('/substorage/bar.txt', 'asd'); $this->assertFalse($rootView->unlink('')); $this->assertFalse($rootView->unlink('/')); $this->assertFalse($rootView->unlink('substorage')); $this->assertFalse($rootView->unlink('/substorage')); }
/** * Test that deleted versions properly land in the trashbin when deleting as share recipient. */ public function testDeleteVersionsOfFileAsRecipient() { \OCA\Files_Versions\Hooks::connectHooks(); $this->userView->mkdir('share'); // trigger a version (multiple would not work because of the expire logic) $this->userView->file_put_contents('share/test.txt', 'v1'); $this->userView->file_put_contents('share/test.txt', 'v2'); $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/share/'); $this->assertEquals(1, count($results)); $recipientUser = $this->getUniqueId('recipient_'); \OC::$server->getUserManager()->createUser($recipientUser, $recipientUser); $fileinfo = $this->userView->getFileInfo('share'); $this->assertTrue(\OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, $recipientUser, 31)); $this->loginAsUser($recipientUser); // delete as recipient $recipientView = new \OC\Files\View('/' . $recipientUser . '/files'); $recipientView->unlink('share/test.txt'); // rescan trash storage for both users list($rootStorage, ) = $this->rootView->resolvePath($this->user . '/files_trashbin'); $rootStorage->getScanner()->scan(''); // check if versions are in trashbin for both users $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/versions'); $this->assertEquals(1, count($results), 'Versions in owner\'s trashbin'); $name = $results[0]->getName(); $this->assertEquals('test.txt.v', substr($name, 0, strlen('test.txt.v'))); $results = $this->rootView->getDirectoryContent($recipientUser . '/files_trashbin/versions'); $this->assertEquals(1, count($results), 'Versions in recipient\'s trashbin'); $name = $results[0]->getName(); $this->assertEquals('test.txt.v', substr($name, 0, strlen('test.txt.v'))); // versions deleted $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/share/'); $this->assertEquals(0, count($results)); }