diff --git a/lib/Operation.php b/lib/Operation.php index c5ea8c7d..8865e6f1 100644 --- a/lib/Operation.php +++ b/lib/Operation.php @@ -117,6 +117,7 @@ protected function isBlockablePath(IStorage $storage, string $path): bool { return isset($segment[2]) && in_array($segment[2], [ 'files', 'thumbnails', + 'files_trashbin', 'files_versions', ]); } diff --git a/tests/Integration/features/author.feature b/tests/Integration/features/author.feature index eeb41b1b..0fed2378 100644 --- a/tests/Integration/features/author.feature +++ b/tests/Integration/features/author.feature @@ -59,7 +59,24 @@ Feature: Author When User "test1" deletes file "/foobar.txt" Then The webdav response should have a status code "403" - Scenario: Deleting file inside a shard folder is blocked + Scenario: Downloading a deleted file is blocked + Given User "test1" uploads file "data/textfile.txt" to "/foobar.txt" + And The webdav response should have a status code "201" + When User "test1" deletes file "/foobar.txt" + Then The webdav response should have a status code "204" + Then User "test1" loads file list of trashbin + And user "admin" creates global flow with 200 + | name | Admin flow | + | class | OCA\FilesAccessControl\Operation | + | entity | OCA\WorkflowEngine\Entity\File | + | events | [] | + | operation | deny | + | checks-0 | {"class":"OCA\\WorkflowEngine\\Check\\FileMimeType", "operator": "is", "value": "text/plain"} | + When as user "test1" + When Downloading first trashed file + Then The webdav response should have a status code "403" + + Scenario: Deleting file inside a shared folder is blocked Given User "test1" created a folder "/subdir" Given User "test1" uploads file "data/textfile.txt" to "/subdir/foobar.txt" And The webdav response should have a status code "201" diff --git a/tests/Integration/features/bootstrap/WebDav.php b/tests/Integration/features/bootstrap/WebDav.php index adb2eadb..ac1976d9 100644 --- a/tests/Integration/features/bootstrap/WebDav.php +++ b/tests/Integration/features/bootstrap/WebDav.php @@ -18,6 +18,7 @@ trait WebDav { private $storedETAG = null; /** @var int */ private $storedFileID = null; + private array $trashedFiles = []; /** * @Given /^using dav path "([^"]*)"$/ @@ -55,6 +56,8 @@ public function makeDavRequest($user, $method, $path, $headers, $body = null, $t $fullUrl = $this->baseUrl . $this->getDavFilesPath($user) . "$path"; } elseif ($type === "uploads") { $fullUrl = $this->baseUrl . $this->davPath . "$path"; + } elseif ($type === 'trashbin') { + $fullUrl = $this->baseUrl . ltrim($path, '/'); } else { $fullUrl = $this->baseUrl . $this->davPath . '/' . $type . "$path"; } @@ -221,6 +224,18 @@ public function downloadingFile($fileName) { } } + /** + * @When Downloading first trashed file + * @param string $fileName + */ + public function downloadingTrashedFile() { + try { + $this->response = $this->makeDavRequest($this->currentUser, 'GET', array_shift($this->trashedFiles), [], type: 'trashbin'); + } catch (\GuzzleHttp\Exception\ClientException $e) { + $this->response = $e->getResponse(); + } + } + /** * @Then Downloaded content should start with :start * @param int $start @@ -955,6 +970,24 @@ public function userSeesNoFilesInTheTrashbin($user) { Assert::assertEquals(0, $count); } + /** + * @Then /^User "([^"]*)" loads file list of trashbin$/ + * @param string $user + */ + public function userLoadsFileListOfTrashbin($user) { + $client = $this->getSabreClient($user); + $properties = [ + '{DAV:}getetag' + ]; + + $response = $client->propfind($this->makeSabrePath($user, 'trash', 'trashbin'), $properties, 1); + + // Remove the root entry to only have the directory listing + unset($response['/remote.php/dav/trashbin/' . $user . '/trash/']); + + Assert::assertNotCount(0, $response); + $this->trashedFiles = array_keys($response); + } /**