mirror of
https://github.com/nextcloud/server.git
synced 2026-02-18 18:28:50 -05:00
fix(dav): Public WebDAV endpoint should allow GET requests
`GET` should be allowed even without Ajax header to allow downloading files, or show files in the viewer. All other requests could be guarded, but this should not. Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
parent
3d74ed3762
commit
bbc5d32c8e
9 changed files with 127 additions and 12 deletions
|
|
@ -73,11 +73,15 @@ preg_match('/(^files\/\w+)/i', substr($requestUri, strlen($baseuri)), $match);
|
|||
$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($linkCheckPlugin);
|
|||
$server->addPlugin($filesDropPlugin);
|
||||
|
||||
// And off we go!
|
||||
$server->exec();
|
||||
$server->start();
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ default:
|
|||
paths:
|
||||
- "%paths.base%/../dav_features"
|
||||
contexts:
|
||||
- FeatureContext:
|
||||
- DavFeatureContext:
|
||||
baseUrl: http://localhost:8080/ocs/
|
||||
admin:
|
||||
- admin
|
||||
|
|
|
|||
|
|
@ -21,6 +21,42 @@ Feature: dav-v2-public
|
|||
When Requesting share note on dav endpoint
|
||||
Then the single response should contain a property "{http://nextcloud.org/ns}note" with value "Hello"
|
||||
|
||||
Scenario: Downloading a file from public share with Ajax header
|
||||
Given using new dav path
|
||||
And As an "admin"
|
||||
And user "user0" exists
|
||||
And user "user1" exists
|
||||
And As an "user1"
|
||||
And user "user1" created a folder "/testshare"
|
||||
When User "user1" uploads file "data/green-square-256.png" to "/testshare/image.png"
|
||||
And as "user1" creating a share with
|
||||
| path | testshare |
|
||||
| shareType | 3 |
|
||||
| permissions | 1 |
|
||||
And As an "user0"
|
||||
Given using new public dav path
|
||||
When Downloading public file "/image.png"
|
||||
Then the downloaded file has the content of "/testshare/image.png" from "user1" data
|
||||
|
||||
# Test that downloading files work to ensure e.g. the viewer works or files can be downloaded
|
||||
Scenario: Downloading a file from public share without Ajax header and disabled s2s share
|
||||
Given using new dav path
|
||||
And As an "admin"
|
||||
And user "user0" exists
|
||||
And user "user1" exists
|
||||
And As an "user1"
|
||||
And user "user1" created a folder "/testshare"
|
||||
When User "user1" uploads file "data/green-square-256.png" to "/testshare/image.png"
|
||||
And as "user1" creating a share with
|
||||
| path | testshare |
|
||||
| shareType | 3 |
|
||||
| permissions | 1 |
|
||||
And As an "user0"
|
||||
Given parameter "outgoing_server2server_share_enabled" of app "files_sharing" is set to "no"
|
||||
Given using new public dav path
|
||||
When Downloading public file "/image.png" without ajax header
|
||||
Then the downloaded file has the content of "/testshare/image.png" from "user1" data
|
||||
|
||||
Scenario: Download a folder
|
||||
Given using new dav path
|
||||
And As an "admin"
|
||||
|
|
|
|||
|
|
@ -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 @@ class CommandLineContext implements \Behat\Behat\Context\Context {
|
|||
/** @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) {
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@ class CommentsContext implements \Behat\Behat\Context\Context {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* get a named entry from response instead of picking a random entry from values
|
||||
*
|
||||
|
|
|
|||
23
build/integration/features/bootstrap/DavFeatureContext.php
Normal file
23
build/integration/features/bootstrap/DavFeatureContext.php
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Behat\Behat\Context\SnippetAcceptingContext;
|
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
class DavFeatureContext implements Context, SnippetAcceptingContext {
|
||||
use AppConfiguration;
|
||||
use ContactsMenu;
|
||||
use ExternalStorage;
|
||||
use Search;
|
||||
use WebDav;
|
||||
use Trashbin;
|
||||
|
||||
protected function resetAppConfigs() {
|
||||
$this->deleteServerConfig('files_sharing', 'outgoing_server2server_share_enabled');
|
||||
}
|
||||
}
|
||||
|
|
@ -137,4 +137,18 @@ trait Download {
|
|||
'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'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ use Behat\Behat\Context\SnippetAcceptingContext;
|
|||
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
|
||||
/**
|
||||
* Features context.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -277,6 +277,42 @@ trait WebDav {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
|
|
|||
Loading…
Reference in a new issue