Skip to content

Commit 40be0c5

Browse files
Merge pull request #63916 from nextcloud/backport/63898/stable34
[stable34] Update node checks
2 parents d7a525f + 647e441 commit 40be0c5

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
@@ -56,7 +56,7 @@ jobs:
5656
- 'capabilities_features'
5757
- 'collaboration_features'
5858
- 'comments_features'
59-
- 'dav_features'
59+
- '--tags ~@requires-s3 dav_features'
6060
- 'features'
6161
- 'federation_features'
6262
- '--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
@@ -987,9 +987,17 @@ public function userCreatesANewChunkingv2UploadWithIdAndDestination($user, $id,
987987
$this->s3MultipartDestination = $this->getTargetDestination($user, $targetDestination);
988988
$this->newUploadId();
989989
$destination = '/uploads/' . $user . '/' . $this->getUploadId($id);
990-
$this->response = $this->makeDavRequest($user, 'MKCOL', $destination, [
991-
'Destination' => $this->s3MultipartDestination,
992-
], null, 'uploads');
990+
try {
991+
$this->response = $this->makeDavRequest($user, 'MKCOL', $destination, [
992+
'Destination' => $this->s3MultipartDestination,
993+
], null, 'uploads');
994+
} catch (\GuzzleHttp\Exception\ServerException $e) {
995+
// 5xx responses cause a server exception
996+
$this->response = $e->getResponse();
997+
} catch (\GuzzleHttp\Exception\ClientException $e) {
998+
// 4xx responses cause a client exception
999+
$this->response = $e->getResponse();
1000+
}
9931001
}
9941002

9951003
/**

0 commit comments

Comments
 (0)