Properly handle missing READ permission
This commit is contained in:
parent
53deb26778
commit
614bd5c294
|
@ -44,6 +44,7 @@ use Sabre\DAV\INode;
|
||||||
use Sabre\DAV\Exception\BadRequest;
|
use Sabre\DAV\Exception\BadRequest;
|
||||||
use OC\Files\Mount\MoveableMount;
|
use OC\Files\Mount\MoveableMount;
|
||||||
use Sabre\DAV\IFile;
|
use Sabre\DAV\IFile;
|
||||||
|
use Sabre\DAV\Exception\NotFound;
|
||||||
|
|
||||||
class Directory extends \OCA\DAV\Connector\Sabre\Node
|
class Directory extends \OCA\DAV\Connector\Sabre\Node
|
||||||
implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuota, \Sabre\DAV\IMoveTarget {
|
implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuota, \Sabre\DAV\IMoveTarget {
|
||||||
|
@ -199,6 +200,11 @@ class Directory extends \OCA\DAV\Connector\Sabre\Node
|
||||||
* @throws \Sabre\DAV\Exception\ServiceUnavailable
|
* @throws \Sabre\DAV\Exception\ServiceUnavailable
|
||||||
*/
|
*/
|
||||||
public function getChild($name, $info = null) {
|
public function getChild($name, $info = null) {
|
||||||
|
if (!$this->info->isReadable()) {
|
||||||
|
// avoid detecting files through this way
|
||||||
|
throw new NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
$path = $this->path . '/' . $name;
|
$path = $this->path . '/' . $name;
|
||||||
if (is_null($info)) {
|
if (is_null($info)) {
|
||||||
try {
|
try {
|
||||||
|
@ -232,12 +238,17 @@ class Directory extends \OCA\DAV\Connector\Sabre\Node
|
||||||
* Returns an array with all the child nodes
|
* Returns an array with all the child nodes
|
||||||
*
|
*
|
||||||
* @return \Sabre\DAV\INode[]
|
* @return \Sabre\DAV\INode[]
|
||||||
|
* @throws \Sabre\DAV\Exception\Locked
|
||||||
|
* @throws \OCA\DAV\Connector\Sabre\Exception\Forbidden
|
||||||
*/
|
*/
|
||||||
public function getChildren() {
|
public function getChildren() {
|
||||||
if (!is_null($this->dirContent)) {
|
if (!is_null($this->dirContent)) {
|
||||||
return $this->dirContent;
|
return $this->dirContent;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
if (!$this->info->isReadable()) {
|
||||||
|
throw new Forbidden('No read permissions');
|
||||||
|
}
|
||||||
$folderContent = $this->fileView->getDirectoryContent($this->path);
|
$folderContent = $this->fileView->getDirectoryContent($this->path);
|
||||||
} catch (LockedException $e) {
|
} catch (LockedException $e) {
|
||||||
throw new Locked();
|
throw new Locked();
|
||||||
|
|
|
@ -54,6 +54,7 @@ use Sabre\DAV\Exception\Forbidden;
|
||||||
use Sabre\DAV\Exception\NotImplemented;
|
use Sabre\DAV\Exception\NotImplemented;
|
||||||
use Sabre\DAV\Exception\ServiceUnavailable;
|
use Sabre\DAV\Exception\ServiceUnavailable;
|
||||||
use Sabre\DAV\IFile;
|
use Sabre\DAV\IFile;
|
||||||
|
use Sabre\DAV\Exception\NotFound;
|
||||||
|
|
||||||
class File extends Node implements IFile {
|
class File extends Node implements IFile {
|
||||||
|
|
||||||
|
@ -307,6 +308,10 @@ class File extends Node implements IFile {
|
||||||
public function get() {
|
public function get() {
|
||||||
//throw exception if encryption is disabled but files are still encrypted
|
//throw exception if encryption is disabled but files are still encrypted
|
||||||
try {
|
try {
|
||||||
|
if (!$this->info->isReadable()) {
|
||||||
|
// do a if the file did not exist
|
||||||
|
throw new NotFound();
|
||||||
|
}
|
||||||
$res = $this->fileView->fopen(ltrim($this->path, '/'), 'rb');
|
$res = $this->fileView->fopen(ltrim($this->path, '/'), 'rb');
|
||||||
if ($res === false) {
|
if ($res === false) {
|
||||||
throw new ServiceUnavailable("Could not open file");
|
throw new ServiceUnavailable("Could not open file");
|
||||||
|
|
|
@ -286,6 +286,10 @@ class FilesPlugin extends ServerPlugin {
|
||||||
$httpRequest = $this->server->httpRequest;
|
$httpRequest = $this->server->httpRequest;
|
||||||
|
|
||||||
if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
|
if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
|
||||||
|
if (!$node->getFileInfo()->isReadable()) {
|
||||||
|
// avoid detecting files through this means
|
||||||
|
throw new NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
$propFind->handle(self::FILEID_PROPERTYNAME, function() use ($node) {
|
$propFind->handle(self::FILEID_PROPERTYNAME, function() use ($node) {
|
||||||
return $node->getFileId();
|
return $node->getFileId();
|
||||||
|
|
|
@ -77,12 +77,11 @@ class DirectoryTest extends \Test\TestCase {
|
||||||
protected function setUp() {
|
protected function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->view = $this->getMockBuilder('OC\Files\View')
|
$this->view = $this->createMock('OC\Files\View');
|
||||||
->disableOriginalConstructor()
|
$this->info = $this->createMock('OC\Files\FileInfo');
|
||||||
->getMock();
|
$this->info->expects($this->any())
|
||||||
$this->info = $this->getMockBuilder('OC\Files\FileInfo')
|
->method('isReadable')
|
||||||
->disableOriginalConstructor()
|
->will($this->returnValue(true));
|
||||||
->getMock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getDir($path = '/') {
|
private function getDir($path = '/') {
|
||||||
|
|
|
@ -1003,4 +1003,23 @@ class FileTest extends \Test\TestCase {
|
||||||
|
|
||||||
$file->get();
|
$file->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Sabre\DAV\Exception\NotFound
|
||||||
|
*/
|
||||||
|
public function testGetThrowsIfNoPermission() {
|
||||||
|
$view = $this->getMockBuilder(View::class)
|
||||||
|
->setMethods(['fopen'])
|
||||||
|
->getMock();
|
||||||
|
$view->expects($this->never())
|
||||||
|
->method('fopen');
|
||||||
|
|
||||||
|
$info = new FileInfo('/test.txt', $this->getMockStorage(), null, [
|
||||||
|
'permissions' => Constants::PERMISSION_CREATE // no read perm
|
||||||
|
], null);
|
||||||
|
|
||||||
|
$file = new File($view, $info);
|
||||||
|
|
||||||
|
$file->get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ use Sabre\HTTP\ResponseInterface;
|
||||||
use Test\TestCase;
|
use Test\TestCase;
|
||||||
use OCA\DAV\Upload\FutureFile;
|
use OCA\DAV\Upload\FutureFile;
|
||||||
use OCA\DAV\Connector\Sabre\Directory;
|
use OCA\DAV\Connector\Sabre\Directory;
|
||||||
|
use OCP\Files\FileInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com>
|
* Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com>
|
||||||
|
@ -148,13 +149,15 @@ class FilesPluginTest extends TestCase {
|
||||||
$node->expects($this->any())
|
$node->expects($this->any())
|
||||||
->method('getDavPermissions')
|
->method('getDavPermissions')
|
||||||
->will($this->returnValue('DWCKMSR'));
|
->will($this->returnValue('DWCKMSR'));
|
||||||
|
|
||||||
|
$fileInfo = $this->createMock(FileInfo::class);
|
||||||
|
$fileInfo->expects($this->any())
|
||||||
|
->method('isReadable')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
$node->expects($this->any())
|
$node->expects($this->any())
|
||||||
->method('getFileInfo')
|
->method('getFileInfo')
|
||||||
->will($this->returnValue(
|
->willReturn($fileInfo);
|
||||||
$this->getMockBuilder('\OCP\Files\FileInfo')
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock()
|
|
||||||
));
|
|
||||||
|
|
||||||
return $node;
|
return $node;
|
||||||
}
|
}
|
||||||
|
@ -313,6 +316,15 @@ class FilesPluginTest extends TestCase {
|
||||||
->getMock();
|
->getMock();
|
||||||
$node->expects($this->any())->method('getPath')->willReturn('/');
|
$node->expects($this->any())->method('getPath')->willReturn('/');
|
||||||
|
|
||||||
|
$fileInfo = $this->createMock(FileInfo::class);
|
||||||
|
$fileInfo->expects($this->any())
|
||||||
|
->method('isReadable')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$node->expects($this->any())
|
||||||
|
->method('getFileInfo')
|
||||||
|
->willReturn($fileInfo);
|
||||||
|
|
||||||
$propFind = new PropFind(
|
$propFind = new PropFind(
|
||||||
'/',
|
'/',
|
||||||
[
|
[
|
||||||
|
@ -329,6 +341,39 @@ class FilesPluginTest extends TestCase {
|
||||||
$this->assertEquals('my_fingerprint', $propFind->get(self::DATA_FINGERPRINT_PROPERTYNAME));
|
$this->assertEquals('my_fingerprint', $propFind->get(self::DATA_FINGERPRINT_PROPERTYNAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Sabre\DAV\Exception\NotFound
|
||||||
|
*/
|
||||||
|
public function testGetPropertiesWhenNoPermission() {
|
||||||
|
/** @var \OCA\DAV\Connector\Sabre\Directory | \PHPUnit_Framework_MockObject_MockObject $node */
|
||||||
|
$node = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\Directory')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$node->expects($this->any())->method('getPath')->willReturn('/');
|
||||||
|
|
||||||
|
$fileInfo = $this->createMock(FileInfo::class);
|
||||||
|
$fileInfo->expects($this->any())
|
||||||
|
->method('isReadable')
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
$node->expects($this->any())
|
||||||
|
->method('getFileInfo')
|
||||||
|
->willReturn($fileInfo);
|
||||||
|
|
||||||
|
$propFind = new PropFind(
|
||||||
|
'/test',
|
||||||
|
[
|
||||||
|
self::DATA_FINGERPRINT_PROPERTYNAME,
|
||||||
|
],
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->plugin->handleGetProperties(
|
||||||
|
$propFind,
|
||||||
|
$node
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testUpdateProps() {
|
public function testUpdateProps() {
|
||||||
$node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File');
|
$node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File');
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ use OCP\Files\Folder;
|
||||||
use OCP\IGroupManager;
|
use OCP\IGroupManager;
|
||||||
use OCP\SystemTag\ISystemTagManager;
|
use OCP\SystemTag\ISystemTagManager;
|
||||||
use OCP\ITags;
|
use OCP\ITags;
|
||||||
|
use OCP\Files\FileInfo;
|
||||||
|
|
||||||
class FilesReportPluginTest extends \Test\TestCase {
|
class FilesReportPluginTest extends \Test\TestCase {
|
||||||
/** @var \Sabre\DAV\Server|\PHPUnit_Framework_MockObject_MockObject */
|
/** @var \Sabre\DAV\Server|\PHPUnit_Framework_MockObject_MockObject */
|
||||||
|
@ -349,6 +350,9 @@ class FilesReportPluginTest extends \Test\TestCase {
|
||||||
public function testPrepareResponses() {
|
public function testPrepareResponses() {
|
||||||
$requestedProps = ['{DAV:}getcontentlength', '{http://owncloud.org/ns}fileid', '{DAV:}resourcetype'];
|
$requestedProps = ['{DAV:}getcontentlength', '{http://owncloud.org/ns}fileid', '{DAV:}resourcetype'];
|
||||||
|
|
||||||
|
$fileInfo = $this->createMock(FileInfo::class);
|
||||||
|
$fileInfo->method('isReadable')->willReturn(true);
|
||||||
|
|
||||||
$node1 = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\Directory')
|
$node1 = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\Directory')
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
|
@ -362,6 +366,7 @@ class FilesReportPluginTest extends \Test\TestCase {
|
||||||
$node1->expects($this->any())
|
$node1->expects($this->any())
|
||||||
->method('getPath')
|
->method('getPath')
|
||||||
->will($this->returnValue('/node1'));
|
->will($this->returnValue('/node1'));
|
||||||
|
$node1->method('getFileInfo')->willReturn($fileInfo);
|
||||||
$node2->expects($this->once())
|
$node2->expects($this->once())
|
||||||
->method('getInternalFileId')
|
->method('getInternalFileId')
|
||||||
->will($this->returnValue('222'));
|
->will($this->returnValue('222'));
|
||||||
|
@ -371,6 +376,7 @@ class FilesReportPluginTest extends \Test\TestCase {
|
||||||
$node2->expects($this->any())
|
$node2->expects($this->any())
|
||||||
->method('getPath')
|
->method('getPath')
|
||||||
->will($this->returnValue('/sub/node2'));
|
->will($this->returnValue('/sub/node2'));
|
||||||
|
$node2->method('getFileInfo')->willReturn($fileInfo);
|
||||||
|
|
||||||
$config = $this->getMockBuilder('\OCP\IConfig')
|
$config = $this->getMockBuilder('\OCP\IConfig')
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
|
|
Loading…
Reference in New Issue