Skip to content

Commit 001f09c

Browse files
authored
Merge pull request #63917 from nextcloud/backport/63898/stable35
[stable35] Update node checks
2 parents e14859c + 141f99f commit 001f09c

4 files changed

Lines changed: 48 additions & 11 deletions

File tree

.github/workflows/integration-sqlite.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ jobs:
5151
- 'capabilities_features'
5252
- 'collaboration_features'
5353
- 'comments_features'
54-
- 'dav_features'
54+
- '--tags ~@requires-s3 dav_features'
5555
- 'features'
5656
- 'federation_features'
5757
- '--tags ~@large files_features'

apps/dav/lib/Upload/ChunkingV2Plugin.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use OCP\IConfig;
3030
use OCP\Lock\ILockingProvider;
3131
use Sabre\DAV\Exception\BadRequest;
32+
use Sabre\DAV\Exception\Forbidden;
3233
use Sabre\DAV\Exception\InsufficientStorage;
3334
use Sabre\DAV\Exception\MethodNotAllowed;
3435
use Sabre\DAV\Exception\NotFound;
@@ -108,18 +109,26 @@ public function forbiddenMethod(RequestInterface $request) {
108109
* @param string $path
109110
* @param bool $createIfNotExists
110111
* @return FutureFile|UploadFile|ICollection|INode
112+
* @throws Forbidden if the file already exists, but is not updateable
111113
*/
112114
private function getUploadFile(string $path, bool $createIfNotExists = false) {
113115
try {
114116
$actualFile = $this->server->tree->getNodeForPath($path);
115-
// Only directly upload to the target file if it is on the same storage
116-
// There may be further potential to optimize here by also uploading
117-
// to other storages directly. This would require to also carefully pick
118-
// the storage/path used in getStorage()
119-
if ($actualFile instanceof File && $this->uploadFolder->getStorage()->getId() === $actualFile->getNode()->getStorage()->getId()) {
120-
return $actualFile;
117+
if ($actualFile instanceof File) {
118+
$node = $actualFile->getNode();
119+
// check that the node has update permissions
120+
if (!$node->isUpdateable()) {
121+
throw new Forbidden();
122+
}
123+
// Only directly upload to the target file if it is on the same storage
124+
// There may be further potential to optimize here by also uploading
125+
// to other storages directly. This would require to also carefully pick
126+
// the storage/path used in getStorage()
127+
if ($this->uploadFolder->getStorage()->getId() === $node->getStorage()->getId()) {
128+
return $actualFile;
129+
}
121130
}
122-
} catch (NotFound $e) {
131+
} catch (NotFound) {
123132
// If there is no target file we upload to the upload folder first
124133
}
125134

build/integration/dav_features/webdav-related.feature

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,3 +737,23 @@ Feature: webdav-related
737737
When As an "user0"
738738
And Downloading file "/üäöé/äöü.txt"
739739
Then Downloaded content should be the created file
740+
741+
@requires-s3
742+
Scenario: Cannot overwrite a file the user may not update with new chunking v2
743+
Given using new dav path
744+
And user "user0" exists
745+
And user "user1" exists
746+
And As an "user1"
747+
And user "user1" created a folder "/testshare"
748+
And User "user1" copies file "/welcome.txt" to "/testshare/test.txt"
749+
And as "user1" creating a share with
750+
| path | testshare |
751+
| shareType | 0 |
752+
| permissions | 5 |
753+
| shareWith | user0 |
754+
And user "user0" accepts last share
755+
And As an "user0"
756+
And user "user0" creates a file locally with "3" x 5 MB chunks
757+
When user "user0" creates a new chunking v2 upload with id "chunking-update" and destination "/testshare/test.txt"
758+
Then the HTTP status code should be "403"
759+
And Downloaded content when downloading file "/testshare/test.txt" with range "bytes=0-6" should be "Welcome"

build/integration/features/bootstrap/WebDav.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -985,9 +985,17 @@ public function userCreatesANewChunkingv2UploadWithIdAndDestination($user, $id,
985985
$this->s3MultipartDestination = $this->getTargetDestination($user, $targetDestination);
986986
$this->newUploadId();
987987
$destination = '/uploads/' . $user . '/' . $this->getUploadId($id);
988-
$this->response = $this->makeDavRequest($user, 'MKCOL', $destination, [
989-
'Destination' => $this->s3MultipartDestination,
990-
], null, 'uploads');
988+
try {
989+
$this->response = $this->makeDavRequest($user, 'MKCOL', $destination, [
990+
'Destination' => $this->s3MultipartDestination,
991+
], null, 'uploads');
992+
} catch (\GuzzleHttp\Exception\ServerException $e) {
993+
// 5xx responses cause a server exception
994+
$this->response = $e->getResponse();
995+
} catch (\GuzzleHttp\Exception\ClientException $e) {
996+
// 4xx responses cause a client exception
997+
$this->response = $e->getResponse();
998+
}
991999
}
9921000

9931001
/**

0 commit comments

Comments
 (0)