aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2019-07-03 23:30:32 +0200
committerGitHub <noreply@github.com>2019-07-03 23:30:32 +0200
commit18b673e1d836ce1e31c658df94c35de8ca699bbf (patch)
tree200095d3ca0fd7ad6e7ff87f6bb834c955d3c7e8 /apps
parentc5c14d09b190d3e8e1fe5e8e6aff7e95b0ac6f20 (diff)
parent3b6df74a6dddc40c2cc664e74430eda6e8dc87eb (diff)
downloadnextcloud-server-18b673e1d836ce1e31c658df94c35de8ca699bbf.tar.gz
nextcloud-server-18b673e1d836ce1e31c658df94c35de8ca699bbf.zip
Merge pull request #15769 from nextcloud/part-file-non-creatable
dont use part files for dav writes when the target folder doesn't have create permissions
Diffstat (limited to 'apps')
-rw-r--r--apps/dav/lib/Connector/Sabre/File.php9
-rw-r--r--apps/dav/tests/unit/Connector/Sabre/FileTest.php54
2 files changed, 53 insertions, 10 deletions
diff --git a/apps/dav/lib/Connector/Sabre/File.php b/apps/dav/lib/Connector/Sabre/File.php
index 2f7bd804e3a..f183013f91f 100644
--- a/apps/dav/lib/Connector/Sabre/File.php
+++ b/apps/dav/lib/Connector/Sabre/File.php
@@ -147,7 +147,12 @@ class File extends Node implements IFile {
if ($needsPartFile) {
// mark file as partial while uploading (ignored by the scanner)
$partFilePath = $this->getPartFileBasePath($this->path) . '.ocTransferId' . rand() . '.part';
- } else {
+
+ if (!$view->isCreatable($partFilePath) && $view->isUpdatable($this->path)) {
+ $needsPartFile = false;
+ }
+ }
+ if (!$needsPartFile) {
// upload file directly as the final path
$partFilePath = $this->path;
@@ -178,7 +183,7 @@ class File extends Node implements IFile {
}
$isEOF = false;
- $wrappedData = CallbackWrapper::wrap($data, null, null, null, null, function($stream) use (&$isEOF) {
+ $wrappedData = CallbackWrapper::wrap($data, null, null, null, null, function ($stream) use (&$isEOF) {
$isEOF = feof($stream);
});
diff --git a/apps/dav/tests/unit/Connector/Sabre/FileTest.php b/apps/dav/tests/unit/Connector/Sabre/FileTest.php
index edb61edc6ed..3e3e80f7525 100644
--- a/apps/dav/tests/unit/Connector/Sabre/FileTest.php
+++ b/apps/dav/tests/unit/Connector/Sabre/FileTest.php
@@ -28,13 +28,20 @@
namespace OCA\DAV\Tests\unit\Connector\Sabre;
use OC\Files\Storage\Local;
+use OC\Files\Storage\Temporary;
+use OC\Files\Storage\Wrapper\PermissionsMask;
use OC\Files\View;
+use OCA\DAV\Connector\Sabre\File;
+use OCP\Constants;
use OCP\Files\ForbiddenException;
use OCP\Files\Storage;
use OCP\IConfig;
use Test\HookHelper;
use OC\Files\Filesystem;
use OCP\Lock\ILockingProvider;
+use Test\TestCase;
+use Test\Traits\MountProviderTrait;
+use Test\Traits\UserTrait;
/**
* Class File
@@ -43,7 +50,9 @@ use OCP\Lock\ILockingProvider;
*
* @package OCA\DAV\Tests\unit\Connector\Sabre
*/
-class FileTest extends \Test\TestCase {
+class FileTest extends TestCase {
+ use MountProviderTrait;
+ use UserTrait;
/**
* @var string
@@ -61,9 +70,8 @@ class FileTest extends \Test\TestCase {
\OC_Hook::clear();
- $this->user = $this->getUniqueID('user_');
- $userManager = \OC::$server->getUserManager();
- $userManager->createUser($this->user, 'pass');
+ $this->user = 'test_user';
+ $this->createUser($this->user, 'pass');
$this->loginAsUser($this->user);
@@ -79,15 +87,14 @@ class FileTest extends \Test\TestCase {
}
/**
- * @return \PHPUnit_Framework_MockObject_MockObject | Storage
+ * @return \PHPUnit_Framework_MockObject_MockObject|Storage
*/
private function getMockStorage() {
$storage = $this->getMockBuilder(Storage::class)
->disableOriginalConstructor()
->getMock();
- $storage->expects($this->any())
- ->method('getId')
- ->will($this->returnValue('home::someuser'));
+ $storage->method('getId')
+ ->willReturn('home::someuser');
return $storage;
}
@@ -1163,4 +1170,35 @@ class FileTest extends \Test\TestCase {
$file->get();
}
+
+ public function testSimplePutNoCreatePermissions() {
+ $this->logout();
+
+ $storage = new Temporary([]);
+ $storage->file_put_contents('file.txt', 'old content');
+ $noCreateStorage = new PermissionsMask([
+ 'storage'=> $storage,
+ 'mask' => Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE
+ ]);
+
+ $this->registerMount($this->user, $noCreateStorage, '/' . $this->user . '/files/root');
+
+ $this->loginAsUser($this->user);
+
+ $view = new View('/' . $this->user . '/files');
+
+ $info = $view->getFileInfo('root/file.txt');
+
+ $file = new File($view, $info);
+
+ // beforeMethod locks
+ $view->lockFile('root/file.txt', ILockingProvider::LOCK_SHARED);
+
+ $file->put($this->getStream('new content'));
+
+ // afterMethod unlocks
+ $view->unlockFile('root/file.txt', ILockingProvider::LOCK_SHARED);
+
+ $this->assertEquals('new content', $view->file_get_contents('root/file.txt'));
+ }
}