/** * @param $argument * @throws \Exception */ protected function run($argument) { $maxAge = $this->expiration->getMaxAgeAsTimestamp(); if (!$maxAge) { return; } $this->userManager->callForAllUsers(function (IUser $user) { $uid = $user->getUID(); if (!$this->setupFS($uid)) { return; } $dirContent = Helper::getTrashFiles('/', $uid, 'mtime'); Trashbin::deleteExpiredFiles($dirContent, $uid); }); \OC_Util::tearDownFS(); }
/** * 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'); }
<?php OCP\JSON::checkLoggedIn(); \OC::$server->getSession()->close(); // Load the files $dir = isset($_GET['dir']) ? $_GET['dir'] : ''; $sortAttribute = isset($_GET['sort']) ? $_GET['sort'] : 'name'; $sortDirection = isset($_GET['sortdirection']) ? $_GET['sortdirection'] === 'desc' : false; $data = array(); // make filelist try { $files = \OCA\Files_Trashbin\Helper::getTrashFiles($dir, \OCP\User::getUser(), $sortAttribute, $sortDirection); } catch (Exception $e) { header("HTTP/1.0 404 Not Found"); exit; } $encodedDir = \OCP\Util::encodePath($dir); $data['permissions'] = 0; $data['directory'] = $dir; $data['files'] = \OCA\Files_Trashbin\Helper::formatFileInfos($files); OCP\JSON::success(array('data' => $data));
/** * clean up the trash bin * * @param int $trashBinSize current size of the trash bin * @param string $user */ public static function expire($trashBinSize, $user) { $availableSpace = self::calculateFreeSpace($trashBinSize, $user); $size = 0; $retention_obligation = \OC_Config::getValue('trashbin_retention_obligation', self::DEFAULT_RETENTION_OBLIGATION); $limit = time() - $retention_obligation * 86400; $dirContent = Helper::getTrashFiles('/', $user, 'mtime'); // delete all files older then $retention_obligation list($delSize, $count) = self::deleteExpiredFiles($dirContent, $user, $limit, $retention_obligation); $size += $delSize; $availableSpace += $size; // delete files from trash until we meet the trash bin size limit again $size += self::deleteFiles(array_slice($dirContent, $count), $user, $availableSpace); }
/** * clean up the trash bin * * @param string $user */ public static function expire($user) { $trashBinSize = self::getTrashbinSize($user); $availableSpace = self::calculateFreeSpace($trashBinSize, $user); $dirContent = Helper::getTrashFiles('/', $user, 'mtime'); // delete all files older then $retention_obligation list($delSize, $count) = self::deleteExpiredFiles($dirContent, $user); $availableSpace += $delSize; // delete files from trash until we meet the trash bin size limit again self::deleteFiles(array_slice($dirContent, $count), $user, $availableSpace); }
/** * @param $argument * @throws \Exception */ protected function run($argument) { $maxAge = $this->expiration->getMaxAgeAsTimestamp(); if (!$maxAge) { return; } $offset = $this->config->getAppValue('files_trashbin', 'cronjob_user_offset', 0); $users = $this->userManager->search('', self::USERS_PER_SESSION, $offset); if (!count($users)) { // No users found, reset offset and retry $offset = 0; $users = $this->userManager->search('', self::USERS_PER_SESSION); } $offset += self::USERS_PER_SESSION; $this->config->setAppValue('files_trashbin', 'cronjob_user_offset', $offset); foreach ($users as $user) { $uid = $user->getUID(); if (!$this->setupFS($uid)) { continue; } $dirContent = Helper::getTrashFiles('/', $uid, 'mtime'); Trashbin::deleteExpiredFiles($dirContent, $uid); } \OC_Util::tearDownFS(); }
/** * Gets information about trashed notes * * @NoAdminRequired * @NoCSRFRequired * @CORS * * @return string */ public function getTrashedNotes() { $dir = $this->request->getParam("dir", ""); $customFileExtensions = $this->request->getParam("extensions", array()); if (!is_array($customFileExtensions)) { $customFileExtensions = array(); } $noteFileExtensions = array_merge(array("md", "txt"), $customFileExtensions); // remove leading "/" if (substr($dir, 0, 1) === "/") { $dir = substr($dir, 1); } // remove trailing "/" if (substr($dir, -1) === "/") { $dir = substr($dir, 0, -1); } $sortAttribute = $this->request->getParam("sort", "mtime"); $sortDirectionParam = $this->request->getParam("sortdirection", ""); $sortDirection = $sortDirectionParam !== "" ? $sortDirectionParam === 'desc' : true; $filesInfo = array(); // generate the file list try { $files = Helper::getTrashFiles("/", $this->user, $sortAttribute, $sortDirection); $filesInfo = Helper::formatFileInfos($files); } catch (Exception $e) { } // only return notes (with extension ".txt", ".md" and the custom extensions) in the $dir directory $resultFilesInfo = array(); foreach ($filesInfo as $fileInfo) { $pathParts = pathinfo($fileInfo["name"]); // if $fileInfo["extraData"] is not set we will have to show the note files from all folders in QOwnNotes $isInDir = isset($fileInfo["extraData"]) ? strpos($fileInfo["extraData"], $dir . "/" . $fileInfo["name"]) === 0 : true; $isNoteFile = in_array($pathParts["extension"], $noteFileExtensions); if ($isInDir && $isNoteFile) { $timestamp = (int) ($fileInfo["mtime"] / 1000); $fileName = '/files_trashbin/files/' . $fileInfo["name"] . ".d{$timestamp}"; $view = new \OC\Files\View('/' . $this->user); $data = ""; // load the file data $handle = $view->fopen($fileName, 'rb'); if ($handle) { $chunkSize = 8192; // 8 kB chunks while (!feof($handle)) { $data .= fread($handle, $chunkSize); } } $resultFilesInfo[] = ["noteName" => $pathParts["filename"], "fileName" => $fileInfo["name"], "timestamp" => $timestamp, "dateString" => $fileInfo["date"], "data" => $data]; } } $data = array(); $data['directory'] = $dir; $data['notes'] = $resultFilesInfo; return $data; }
OCP\JSON::checkLoggedIn(); // Load the files $dir = isset($_GET['dir']) ? $_GET['dir'] : ''; $doBreadcrumb = isset($_GET['breadcrumb']) ? true : false; $data = array(); // Make breadcrumb if ($doBreadcrumb) { $breadcrumb = \OCA\Files_Trashbin\Helper::makeBreadcrumb($dir); $breadcrumbNav = new OCP\Template('files_trashbin', 'part.breadcrumb', ''); $breadcrumbNav->assign('breadcrumb', $breadcrumb, false); $breadcrumbNav->assign('baseURL', OCP\Util::linkTo('files_trashbin', 'index.php') . '?dir='); $breadcrumbNav->assign('home', OCP\Util::linkTo('files', 'index.php')); $data['breadcrumb'] = $breadcrumbNav->fetchPage(); } // make filelist $files = \OCA\Files_Trashbin\Helper::getTrashFiles($dir); if ($files === null) { header("HTTP/1.0 404 Not Found"); exit; } $dirlisting = false; if ($dir && $dir !== '/') { $dirlisting = true; } $encodedDir = \OCP\Util::encodePath($dir); $list = new OCP\Template('files_trashbin', 'part.list', ''); $list->assign('files', $files, false); $list->assign('baseURL', OCP\Util::linkTo('files_trashbin', 'index.php') . '?dir=' . $encodedDir); $list->assign('downloadURL', OCP\Util::linkToRoute('download', array('file' => '/'))); $list->assign('dirlisting', $dirlisting); $list->assign('disableDownloadActions', true);
/** * @medium * test restore file */ function testRestoreFile() { // generate filename $filename = 'tmp-' . $this->getUniqueID() . '.txt'; $filename2 = $filename . '.backup'; // a second file with similar name // save file with content file_put_contents('crypt:///' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename, $this->dataShort); file_put_contents('crypt:///' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename2, $this->dataShort); // delete both files \OC\Files\Filesystem::unlink($filename); \OC\Files\Filesystem::unlink($filename2); $trashFiles = \OCA\Files_Trashbin\Helper::getTrashFiles('/', self::TEST_ENCRYPTION_TRASHBIN_USER1); // find created file with timestamp $timestamp = null; foreach ($trashFiles as $file) { if ($file['name'] === $filename) { $timestamp = $file['mtime']; break; } } // make sure that we have a timestamp $this->assertNotNull($timestamp); // before calling the restore operation the keys shouldn't be there $this->assertFalse($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename . '/fileKey')); $this->assertFalse($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // restore first file $this->assertTrue(\OCA\Files_Trashbin\Trashbin::restore($filename . '.d' . $timestamp, $filename, $timestamp)); // check if file exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename)); // check if key for admin exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename . '/fileKey')); // check if share key for admin exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // check that second file was NOT restored $this->assertFalse($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename2)); // check if key for admin exists $this->assertFalse($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename2 . '/fileKey')); // check if share key for admin exists $this->assertFalse($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename2 . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); }
if (!$isIE8) { $files = \OCA\Files_Trashbin\Helper::getTrashFiles($dir); } else { $files = array(); $ajaxLoad = true; } // Redirect if directory does not exist if ($files === null) { header('Location: ' . OCP\Util::linkTo('files_trashbin', 'index.php')); exit; } $dirlisting = false; if ($dir && $dir !== '/') { $dirlisting = true; } $breadcrumb = \OCA\Files_Trashbin\Helper::makeBreadcrumb($dir); $breadcrumbNav = new OCP\Template('files_trashbin', 'part.breadcrumb', ''); $breadcrumbNav->assign('breadcrumb', $breadcrumb); $breadcrumbNav->assign('baseURL', OCP\Util::linkTo('files_trashbin', 'index.php') . '?dir='); $breadcrumbNav->assign('home', OCP\Util::linkTo('files', 'index.php')); $list = new OCP\Template('files_trashbin', 'part.list', ''); $list->assign('files', $files); $encodedDir = \OCP\Util::encodePath($dir); $list->assign('baseURL', OCP\Util::linkTo('files_trashbin', 'index.php') . '?dir=' . $encodedDir); $list->assign('downloadURL', OCP\Util::linkTo('files_trashbin', 'download.php') . '?file=' . $encodedDir); $list->assign('dirlisting', $dirlisting); $list->assign('disableDownloadActions', true); $tmpl->assign('dirlisting', $dirlisting); $tmpl->assign('breadcrumb', $breadcrumbNav->fetchPage()); $tmpl->assign('fileList', $list->fetchPage()); $tmpl->assign('files', $files);