diff --git a/apps/dav/appinfo/v2/publicremote.php b/apps/dav/appinfo/v2/publicremote.php index 53e85d556eb9f..0b7480872cb6a 100644 --- a/apps/dav/appinfo/v2/publicremote.php +++ b/apps/dav/appinfo/v2/publicremote.php @@ -73,11 +73,15 @@ $baseuri = $baseuri . $match[0]; $server = $serverFactory->createServer($baseuri, $requestUri, $authPlugin, function (\Sabre\DAV\Server $server) use ($authBackend, $linkCheckPlugin, $filesDropPlugin) { - $isAjax = in_array('XMLHttpRequest', explode(',', $_SERVER['HTTP_X_REQUESTED_WITH'] ?? '')); - $federatedShareProvider = \OCP\Server::get(FederatedShareProvider::class); - if ($federatedShareProvider->isOutgoingServer2serverShareEnabled() === false && !$isAjax) { - // this is what is thrown when trying to access a non-existing share - throw new NotAuthenticated(); + // GET must be allowed for e.g. showing images and allowing Zip downloads + if ($server->httpRequest->getMethod() !== 'GET') { + // If this is *not* a GET request we only allow access to public DAV from AJAX or when Server2Server is allowed + $isAjax = in_array('XMLHttpRequest', explode(',', $_SERVER['HTTP_X_REQUESTED_WITH'] ?? '')); + $federatedShareProvider = \OCP\Server::get(FederatedShareProvider::class); + if ($federatedShareProvider->isOutgoingServer2serverShareEnabled() === false && $isAjax === false) { + // this is what is thrown when trying to access a non-existing share + throw new NotAuthenticated(); + } } $share = $authBackend->getShare(); @@ -132,4 +136,4 @@ $server->addPlugin($filesDropPlugin); // And off we go! -$server->exec(); +$server->start(); diff --git a/build/integration/config/behat.yml b/build/integration/config/behat.yml index 48c2c91aaf306..21e0cdb3309e2 100644 --- a/build/integration/config/behat.yml +++ b/build/integration/config/behat.yml @@ -61,7 +61,7 @@ default: paths: - "%paths.base%/../dav_features" contexts: - - FeatureContext: + - DavFeatureContext: baseUrl: http://localhost:8080/ocs/ admin: - admin diff --git a/build/integration/features/bootstrap/CommandLineContext.php b/build/integration/features/bootstrap/CommandLineContext.php index 47a85885ce414..5ea8d12a970fc 100644 --- a/build/integration/features/bootstrap/CommandLineContext.php +++ b/build/integration/features/bootstrap/CommandLineContext.php @@ -6,6 +6,7 @@ */ require __DIR__ . '/../../vendor/autoload.php'; +use Behat\Behat\Context\Exception\ContextNotFoundException; use Behat\Behat\Hook\Scope\BeforeScenarioScope; use PHPUnit\Framework\Assert; @@ -41,8 +42,12 @@ public function maintenanceModeIsDisabled() { /** @BeforeScenario */ public function gatherContexts(BeforeScenarioScope $scope) { $environment = $scope->getEnvironment(); - // this should really be "WebDavContext" ... - $this->featureContext = $environment->getContext('FeatureContext'); + // this should really be "WebDavContext" + try { + $this->featureContext = $environment->getContext('FeatureContext'); + } catch (ContextNotFoundException) { + $this->featureContext = $environment->getContext('DavFeatureContext'); + } } private function findLastTransferFolderForUser($sourceUser, $targetUser) { diff --git a/build/integration/features/bootstrap/CommentsContext.php b/build/integration/features/bootstrap/CommentsContext.php index 8d7b0fe0c2fa3..22dc53480774f 100644 --- a/build/integration/features/bootstrap/CommentsContext.php +++ b/build/integration/features/bootstrap/CommentsContext.php @@ -29,8 +29,6 @@ public function __construct($baseUrl) { } } - - /** * get a named entry from response instead of picking a random entry from values * diff --git a/build/integration/features/bootstrap/DavFeatureContext.php b/build/integration/features/bootstrap/DavFeatureContext.php new file mode 100644 index 0000000000000..acca52ccafcbd --- /dev/null +++ b/build/integration/features/bootstrap/DavFeatureContext.php @@ -0,0 +1,23 @@ +deleteServerConfig('files_sharing', 'outgoing_server2server_share_enabled'); + } +} diff --git a/build/integration/features/bootstrap/Download.php b/build/integration/features/bootstrap/Download.php index aa10830427aca..92f659338545b 100644 --- a/build/integration/features/bootstrap/Download.php +++ b/build/integration/features/bootstrap/Download.php @@ -120,4 +120,18 @@ public function theDownloadedZipFileContainsAFolderNamed($folderName) { "Local header for folder did not appear once in zip file" ); } + + /** + * @Then the downloaded file has the content of :sourceFilename from :user data + */ + public function theDownloadedFileHasContentOfUserFile($sourceFilename, $user) { + $this->getDownloadedFile(); + $expectedFileContents = file_get_contents($this->getDataDirectory() . "/$user/files" . $sourceFilename); + + // prevent the whole file from being printed in case of error. + Assert::assertEquals( + 0, strcmp($expectedFileContents, $this->downloadedFile), + 'Downloaded file content does not match local file content' + ); + } } diff --git a/build/integration/features/bootstrap/FeatureContext.php b/build/integration/features/bootstrap/FeatureContext.php index 893dc3094bacc..59f1d0068dd92 100644 --- a/build/integration/features/bootstrap/FeatureContext.php +++ b/build/integration/features/bootstrap/FeatureContext.php @@ -9,7 +9,6 @@ require __DIR__ . '/../../vendor/autoload.php'; - /** * Features context. */ diff --git a/build/integration/features/bootstrap/WebDav.php b/build/integration/features/bootstrap/WebDav.php index fff990fc14178..93a44f7c4b697 100644 --- a/build/integration/features/bootstrap/WebDav.php +++ b/build/integration/features/bootstrap/WebDav.php @@ -250,6 +250,42 @@ public function downloadingFile($fileName) { } } + /** + * @When Downloading public file :filename + */ + public function downloadingPublicFile(string $filename) { + $token = $this->lastShareData->data->token; + $fullUrl = substr($this->baseUrl, 0, -4) . "public.php/dav/files/$token/$filename"; + + $client = new GClient(); + $options = [ + 'headers' => [ + 'X-Requested-With' => 'XMLHttpRequest', + ] + ]; + + try { + $this->response = $client->request('GET', $fullUrl, $options); + } catch (\GuzzleHttp\Exception\ClientException $e) { + $this->response = $e->getResponse(); + } + } + + /** + * @When Downloading public file :filename without ajax header + */ + public function downloadingPublicFileWithoutHeader(string $filename) { + $token = $this->lastShareData->data->token; + $fullUrl = substr($this->baseUrl, 0, -4) . "public.php/dav/files/$token/$filename"; + + $client = new GClient(); + try { + $this->response = $client->request('GET', $fullUrl); + } catch (\GuzzleHttp\Exception\ClientException $e) { + $this->response = $e->getResponse(); + } + } + /** * @Then Downloaded content should start with :start * @param int $start