diff --git a/tests/acceptance/bootstrap/ArchiverContext.php b/tests/acceptance/bootstrap/ArchiverContext.php index c2384a5f901..43a528dd221 100644 --- a/tests/acceptance/bootstrap/ArchiverContext.php +++ b/tests/acceptance/bootstrap/ArchiverContext.php @@ -247,13 +247,41 @@ public function userDownloadsTheArchiveOfTheseItems( } $queryString = \join('&', $queryString); + $data = $this->featureContext->getPublicLinkData(); + + $fileIds = $data['fileIds']; + $signature = $data['signature']; + $expiration = $data['expiration']; + + $token = $this->featureContext->isUsingSharingNG() + ? $this->featureContext->shareNgGetLastCreatedLinkShareToken() + : $this->featureContext->getLastCreatedPublicShareToken(); + + $queryParts = []; + + $queryParts[] = "public-token=" . urlencode($token); + + foreach ($fileIds as $fileId) { + $queryParts[] = "id=" . urlencode($fileId); + } + + $queryParts[] = "signature=" . urlencode($signature); + $queryParts[] = "expiration=" . urlencode($expiration); + + $queryString = implode('&', $queryParts); + + $url = $this->featureContext->getBaseUrl() . "/archiver?" . $queryString; + $this->featureContext->setResponse( HttpRequestHelper::get( - $this->getArchiverUrl($queryString), + $url, $user, $this->featureContext->getPasswordForUser($user), ), ); + file_put_contents('archive.zip', $this->featureContext->getResponse()->getBody()->getContents()); + + var_dump($this->featureContext->getResponse()->getBody()->getContents(), "archive urllllll: " . $this->getArchiverUrl($queryString)); } /** diff --git a/tests/acceptance/bootstrap/FeatureContext.php b/tests/acceptance/bootstrap/FeatureContext.php index f06330b1cfa..9b022b6f903 100644 --- a/tests/acceptance/bootstrap/FeatureContext.php +++ b/tests/acceptance/bootstrap/FeatureContext.php @@ -1753,6 +1753,25 @@ public function mkDirOnServer(string $dirPathFromServerRoot): void { ); } + private string $propfindResponseBody = ''; + private array $publicLinkData = []; + + public function setPropfindResponseBody(string $body): void { + $this->propfindResponseBody = $body; + } + + public function getPropfindResponseBody(): string { + return $this->propfindResponseBody; + } + + public function setPublicLinkData(array $data): void { + $this->publicLinkData = $data; + } + + public function getPublicLinkData(): array { + return $this->publicLinkData; + } + /** * @return string */ diff --git a/tests/acceptance/bootstrap/PublicWebDavContext.php b/tests/acceptance/bootstrap/PublicWebDavContext.php index d9ba3c3644a..e3d1a8b3034 100644 --- a/tests/acceptance/bootstrap/PublicWebDavContext.php +++ b/tests/acceptance/bootstrap/PublicWebDavContext.php @@ -548,6 +548,27 @@ public function thePublicUploadsFileWithContentUsingThePublicWebDavApi( $this->featureContext->pushToLastStatusCodesArrays(); } + /** + * @When /^the public uploads the following files using the public WebDAV API:$/ + * + * @param \Behat\Gherkin\Node\TableNode $table table with filename and content + * + * @return void + */ + public function thePublicUploadsTheFollowingFilesUsingThePublicWebDavApi( + \Behat\Gherkin\Node\TableNode $table, + ): void { + foreach ($table->getHash() as $row) { + $filename = $row['filename']; + $content = $row['content'] ?? 'test'; + + $response = $this->publicUploadContent($filename, '', $content); + + $this->featureContext->setResponse($response); + $this->featureContext->pushToLastStatusCodesArrays(); + } + } + /** * @Given the public has uploaded file :filename with content :body * @@ -1212,6 +1233,43 @@ public function before(BeforeScenarioScope $scope): void { $this->featureContext = BehatHelper::getContext($scope, $environment, 'FeatureContext'); } + private function extractPublicLinkData(string $xml): array { + $doc = new \SimpleXMLElement($xml); + + $doc->registerXPathNamespace('d', 'DAV:'); + $doc->registerXPathNamespace('oc', 'http://owncloud.org/ns'); + + $fileIds = []; + $signature = null; + $expiration = null; + + foreach ($doc->xpath('//d:response') as $response) { + $type = $response->xpath('.//oc:public-link-item-type'); + $fileId = $response->xpath('.//oc:fileid'); + $sig = $response->xpath('.//oc:signature'); + $exp = $response->xpath('.//oc:expiration'); + + // only files + if (!empty($type) && (string)$type[0] === 'file' && !empty($fileId)) { + $fileIds[] = (string)$fileId[0]; + } + + if ($signature === null && !empty($sig)) { + $signature = (string)$sig[0]; + } + + if ($expiration === null && !empty($exp)) { + $expiration = (string)$exp[0]; + } + } + + return [ + 'fileIds' => $fileIds, + 'signature' => $signature, + 'expiration' => $expiration, + ]; + } + /** * @When /^the public sends "([^"]*)" request to the last public link share using the public WebDAV API(?: with password "([^"]*)")?$/ * @@ -1224,41 +1282,83 @@ public function before(BeforeScenarioScope $scope): void { public function publicSendsRequestToLastPublicShare(string $method, ?string $password = ''): void { if ($method === "PROPFIND") { $body = ' - - - - - - - - - - '; + + + + + + + + + + + + + + '; } else { $body = null; } - $token = ($this->featureContext->isUsingSharingNG()) + + $token = $this->featureContext->isUsingSharingNG() ? $this->featureContext->shareNgGetLastCreatedLinkShareToken() : $this->featureContext->getLastCreatedPublicShareToken(); + var_dump("tokennnnnnnnnnnnnnnnnnnnn", $token); + var_dump( + "token bothhhhhhhhhhh", + $this->featureContext->shareNgGetLastCreatedLinkShareToken(), + ); $davPath = WebDavHelper::getDavPath( WebDavHelper::DAV_VERSION_NEW, $token, "public-files", ); + var_dump("davPathhhhhhhhhhhhhhhhhhhh", $davPath); $password = $this->featureContext->getActualPassword($password); $username = $this->getUsernameForPublicWebdavApi( $token, $password, ); - $fullUrl = $this->featureContext->getBaseUrl() . "/$davPath"; + var_dump("username", $username); + + $fullUrl = $this->featureContext->getBaseUrl() . "/dav/public-files/$token"; + // $fullUrl = $this->featureContext->getBaseUrl() . "/remote.php/dav/public-files/$token/"; + + var_dump("fullURL issssssssssssssss", $fullUrl); + + $headers = [ + "Depth" => "1", + "OCS-APIRequest" => "true", + "public-token" => $token, + "Content-Type" => "application/xml; charset=utf-8", + "Authorization" => "Basic " . base64_encode("public:$password"), + ]; + var_dump("headersssssss", $headers['Authorization']); $response = HttpRequestHelper::sendRequest( $fullUrl, $method, - $username, - $password, null, + null, + $headers, $body, ); + + $responseBody = $response->getBody()->getContents(); + + var_dump("responsseeeeeeeeeeeeeeeeeeeeeeee", $responseBody); + $this->featureContext->setResponse($response); + + // Debug output + var_dump("fullURL lasttttt", $fullUrl, "body", $body); + var_dump("response yeeeeeeeeeeeee", $response->getBody()->getContents()); + + // store raw XML + $this->featureContext->setPropfindResponseBody($responseBody); + + $data = $this->extractPublicLinkData($responseBody); + + // store structured data + $this->featureContext->setPublicLinkData($data); } } diff --git a/tests/acceptance/bootstrap/SharingNgContext.php b/tests/acceptance/bootstrap/SharingNgContext.php index d5721da94ba..31e1cdea253 100644 --- a/tests/acceptance/bootstrap/SharingNgContext.php +++ b/tests/acceptance/bootstrap/SharingNgContext.php @@ -934,7 +934,8 @@ public function userHasCreatedTheFollowingResourceLinkShare(string $user, TableN "'resource' should be provided in the data-table while sharing a resource", ); $response = $this->createLinkShare($user, $body); - $this->featureContext->theHTTPStatusCodeShouldBe(200, "Failed while creating public share link!", $response); + $this->featureContext->theHTTPStatusCodeShouldBe(200, "Failed while creating public + share link!", $response); } /** diff --git a/tests/acceptance/bootstrap/SpacesContext.php b/tests/acceptance/bootstrap/SpacesContext.php index ed050677f2e..148c4d1ec39 100644 --- a/tests/acceptance/bootstrap/SpacesContext.php +++ b/tests/acceptance/bootstrap/SpacesContext.php @@ -4702,7 +4702,7 @@ public function publicDownloadsTheFolderFromTheLastCreatedPublicLink(string $res '', '', ), - ); + ); } /** diff --git a/tests/acceptance/features/apiSpacesShares/publicLinkDownload.feature b/tests/acceptance/features/apiSpacesShares/publicLinkDownload.feature index ed7b1f5534f..a1a36110835 100644 --- a/tests/acceptance/features/apiSpacesShares/publicLinkDownload.feature +++ b/tests/acceptance/features/apiSpacesShares/publicLinkDownload.feature @@ -45,3 +45,24 @@ Feature: Public can download folders from project space public link And the downloaded zip archive should contain these files: | name | content | | folder/test.txt | some content | + + @env-config + Scenario: public tries to download multiple files from a public link of a folder inside a space + Given the config "SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD" has been set to "false" for "sharing" service + And using SharingNG + And user "Alice" has created a folder "project-folder" in space "new-space" + And user "Alice" has uploaded a file inside space "new-space" with content "some content1" to "project-folder/test1.txt" + And user "Alice" has uploaded a file inside space "new-space" with content "some content2" to "project-folder/test2.txt" + And user "Alice" has uploaded a file inside space "new-space" with content "some content3" to "project-folder/test3.txt" + And user "Alice" has created the following resource link share: + | resource | project-folder | + | space | new-space | + | permissionsRole | View | + | password | %public% | + When the public sends "PROPFIND" request to the last public link share using the public WebDAV API with password "%public%" + Then the HTTP status code should be "207" + When user "Alice" downloads the archive of these items using the resource ids + | project-folder/test1.txt | + | project-folder/test2.txt | + | project-folder/test3.txt | + Then the HTTP status code should be "200"