Skip to content

Commit 2a69cf7

Browse files
Merge pull request #48631 from nextcloud/backport/dav-get
2 parents c03ff3c + eae69cb commit 2a69cf7

9 files changed

Lines changed: 140 additions & 12 deletions

File tree

apps/dav/appinfo/v2/publicremote.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,15 @@
9696
$baseuri = $baseuri . $match[0];
9797

9898
$server = $serverFactory->createServer($baseuri, $requestUri, $authPlugin, function (\Sabre\DAV\Server $server) use ($authBackend, $linkCheckPlugin, $filesDropPlugin) {
99-
$isAjax = in_array('XMLHttpRequest', explode(',', $_SERVER['HTTP_X_REQUESTED_WITH'] ?? ''));
100-
$federatedShareProvider = \OCP\Server::get(FederatedShareProvider::class);
101-
if ($federatedShareProvider->isOutgoingServer2serverShareEnabled() === false && !$isAjax) {
102-
// this is what is thrown when trying to access a non-existing share
103-
throw new NotAuthenticated();
99+
// GET must be allowed for e.g. showing images and allowing Zip downloads
100+
if ($server->httpRequest->getMethod() !== 'GET') {
101+
// If this is *not* a GET request we only allow access to public DAV from AJAX or when Server2Server is allowed
102+
$isAjax = in_array('XMLHttpRequest', explode(',', $_SERVER['HTTP_X_REQUESTED_WITH'] ?? ''));
103+
$federatedShareProvider = \OCP\Server::get(FederatedShareProvider::class);
104+
if ($federatedShareProvider->isOutgoingServer2serverShareEnabled() === false && $isAjax === false) {
105+
// this is what is thrown when trying to access a non-existing share
106+
throw new NotAuthenticated();
107+
}
104108
}
105109

106110
$share = $authBackend->getShare();
@@ -152,4 +156,4 @@
152156
$server->addPlugin($filesDropPlugin);
153157

154158
// And off we go!
155-
$server->exec();
159+
$server->start();

build/integration/config/behat.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ default:
5858
paths:
5959
- "%paths.base%/../dav_features"
6060
contexts:
61-
- FeatureContext:
61+
- DavFeatureContext:
6262
baseUrl: http://localhost:8080/ocs/
6363
admin:
6464
- admin
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
2+
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
Feature: dav-v2-public
4+
Background:
5+
Given using api version "1"
6+
7+
Scenario: Downloading a file from public share with Ajax header
8+
Given using new dav path
9+
And As an "admin"
10+
And user "user0" exists
11+
And user "user1" exists
12+
And As an "user1"
13+
And user "user1" created a folder "/testshare"
14+
When User "user1" uploads file "data/green-square-256.png" to "/testshare/image.png"
15+
And as "user1" creating a share with
16+
| path | testshare |
17+
| shareType | 3 |
18+
| permissions | 1 |
19+
And As an "user0"
20+
Given using new public dav path
21+
When Downloading public file "/image.png"
22+
Then the downloaded file has the content of "/testshare/image.png" from "user1" data
23+
24+
# Test that downloading files work to ensure e.g. the viewer works or files can be downloaded
25+
Scenario: Downloading a file from public share without Ajax header and disabled s2s share
26+
Given using new dav path
27+
And As an "admin"
28+
And user "user0" exists
29+
And user "user1" exists
30+
And As an "user1"
31+
And user "user1" created a folder "/testshare"
32+
When User "user1" uploads file "data/green-square-256.png" to "/testshare/image.png"
33+
And as "user1" creating a share with
34+
| path | testshare |
35+
| shareType | 3 |
36+
| permissions | 1 |
37+
And As an "user0"
38+
Given parameter "outgoing_server2server_share_enabled" of app "files_sharing" is set to "no"
39+
Given using new public dav path
40+
When Downloading public file "/image.png" without ajax header
41+
Then the downloaded file has the content of "/testshare/image.png" from "user1" data

build/integration/features/bootstrap/CommandLineContext.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
*/
2727
require __DIR__ . '/../../vendor/autoload.php';
2828

29+
use Behat\Behat\Context\Exception\ContextNotFoundException;
2930
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
3031
use PHPUnit\Framework\Assert;
3132

@@ -61,8 +62,12 @@ public function maintenanceModeIsDisabled() {
6162
/** @BeforeScenario */
6263
public function gatherContexts(BeforeScenarioScope $scope) {
6364
$environment = $scope->getEnvironment();
64-
// this should really be "WebDavContext" ...
65-
$this->featureContext = $environment->getContext('FeatureContext');
65+
// this should really be "WebDavContext"
66+
try {
67+
$this->featureContext = $environment->getContext('FeatureContext');
68+
} catch (ContextNotFoundException) {
69+
$this->featureContext = $environment->getContext('DavFeatureContext');
70+
}
6671
}
6772

6873
private function findLastTransferFolderForUser($sourceUser, $targetUser) {

build/integration/features/bootstrap/CommentsContext.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ public function __construct($baseUrl) {
4949
}
5050
}
5151

52-
53-
5452
/**
5553
* get a named entry from response instead of picking a random entry from values
5654
*
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
/**
3+
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
4+
* SPDX-License-Identifier: AGPL-3.0-or-later
5+
*/
6+
7+
use Behat\Behat\Context\Context;
8+
use Behat\Behat\Context\SnippetAcceptingContext;
9+
10+
require __DIR__ . '/../../vendor/autoload.php';
11+
12+
class DavFeatureContext implements Context, SnippetAcceptingContext {
13+
use AppConfiguration;
14+
use ContactsMenu;
15+
use ExternalStorage;
16+
use Search;
17+
use WebDav;
18+
use Trashbin;
19+
20+
protected function resetAppConfigs() {
21+
$this->deleteServerConfig('files_sharing', 'outgoing_server2server_share_enabled');
22+
}
23+
}

build/integration/features/bootstrap/Download.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,18 @@ public function theDownloadedZipFileContainsAFolderNamed($folderName) {
138138
"Local header for folder did not appear once in zip file"
139139
);
140140
}
141+
142+
/**
143+
* @Then the downloaded file has the content of :sourceFilename from :user data
144+
*/
145+
public function theDownloadedFileHasContentOfUserFile($sourceFilename, $user) {
146+
$this->getDownloadedFile();
147+
$expectedFileContents = file_get_contents($this->getDataDirectory() . "/$user/files" . $sourceFilename);
148+
149+
// prevent the whole file from being printed in case of error.
150+
Assert::assertEquals(
151+
0, strcmp($expectedFileContents, $this->downloadedFile),
152+
'Downloaded file content does not match local file content'
153+
);
154+
}
141155
}

build/integration/features/bootstrap/FeatureContext.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828

2929
require __DIR__ . '/../../vendor/autoload.php';
3030

31-
3231
/**
3332
* Features context.
3433
*/

build/integration/features/bootstrap/WebDav.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ public function usingNewDavPath() {
8080
$this->usingOldDavPath = false;
8181
}
8282

83+
/**
84+
* @Given /^using new public dav path$/
85+
*/
86+
public function usingNewPublicDavPath() {
87+
$this->davPath = 'public.php/dav';
88+
$this->usingOldDavPath = false;
89+
}
90+
8391
public function getDavFilesPath($user) {
8492
if ($this->usingOldDavPath === true) {
8593
return $this->davPath;
@@ -270,6 +278,42 @@ public function downloadingFile($fileName) {
270278
}
271279
}
272280

281+
/**
282+
* @When Downloading public file :filename
283+
*/
284+
public function downloadingPublicFile(string $filename) {
285+
$token = $this->lastShareData->data->token;
286+
$fullUrl = substr($this->baseUrl, 0, -4) . "public.php/dav/files/$token/$filename";
287+
288+
$client = new GClient();
289+
$options = [
290+
'headers' => [
291+
'X-Requested-With' => 'XMLHttpRequest',
292+
]
293+
];
294+
295+
try {
296+
$this->response = $client->request('GET', $fullUrl, $options);
297+
} catch (\GuzzleHttp\Exception\ClientException $e) {
298+
$this->response = $e->getResponse();
299+
}
300+
}
301+
302+
/**
303+
* @When Downloading public file :filename without ajax header
304+
*/
305+
public function downloadingPublicFileWithoutHeader(string $filename) {
306+
$token = $this->lastShareData->data->token;
307+
$fullUrl = substr($this->baseUrl, 0, -4) . "public.php/dav/files/$token/$filename";
308+
309+
$client = new GClient();
310+
try {
311+
$this->response = $client->request('GET', $fullUrl);
312+
} catch (\GuzzleHttp\Exception\ClientException $e) {
313+
$this->response = $e->getResponse();
314+
}
315+
}
316+
273317
/**
274318
* @Then Downloaded content should start with :start
275319
* @param int $start

0 commit comments

Comments
 (0)