Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 33 additions & 5 deletions apps/dav/lib/Connector/Sabre/FilesReportPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ public function getSupportedReportSet($uri) {
public function onReport($reportName, $report, $uri) {
$reportTargetNode = $this->server->tree->getNodeForPath($uri);
if (!$reportTargetNode instanceof Directory || $reportName !== self::REPORT_NAME) {
throw new ReportNotSupported();
return;
}

$ns = '{' . $this::NS_OWNCLOUD . '}';
Expand Down Expand Up @@ -205,7 +205,8 @@ public function onReport($reportName, $report, $uri) {
// find sabre nodes by file id, restricted to the root node path
$results = $this->findNodesByFileIds($reportTargetNode, $resultFileIds);

$responses = $this->prepareResponses($requestedProps, $results);
$filesUri = $this->getFilesBaseUri($uri, $reportTargetNode->getPath());
$responses = $this->prepareResponses($filesUri, $requestedProps, $results);

$xml = $this->server->xml->write(
'{DAV:}multistatus',
Expand All @@ -219,6 +220,31 @@ public function onReport($reportName, $report, $uri) {
return false;
}

/**
* Returns the base uri of the files root by removing
* the subpath from the URI
*
* @param string $uri URI from this request
* @param string $subPath subpath to remove from the URI
*
* @return string files base uri
*/
private function getFilesBaseUri($uri, $subPath) {
$uri = trim($uri, '/');
$subPath = trim($subPath, '/');
$filesUri = '';
if (empty($subPath)) {
$filesUri = $uri;
} else {
$filesUri = substr($uri, 0, strlen($uri) - strlen($subPath));
}
$filesUri = trim($filesUri, '/');
if (empty($filesUri)) {
return '';
}
return '/' . $filesUri;
}

/**
* Find file ids matching the given filter rules
*
Expand Down Expand Up @@ -306,14 +332,16 @@ private function getSystemTagFileIds($systemTagIds) {
/**
* Prepare propfind response for the given nodes
*
* @param string $filesUri $filesUri URI leading to root of the files URI,
* with a leading slash but no trailing slash
* @param string[] $requestedProps requested properties
* @param Node[] nodes nodes for which to fetch and prepare responses
* @return Response[]
*/
public function prepareResponses($requestedProps, $nodes) {
public function prepareResponses($filesUri, $requestedProps, $nodes) {
$responses = [];
foreach ($nodes as $node) {
$propFind = new PropFind($node->getPath(), $requestedProps);
$propFind = new PropFind($filesUri . $node->getPath(), $requestedProps);

$this->server->getPropertiesByNode($propFind, $node);
// copied from Sabre Server's getPropertiesForPath
Expand All @@ -326,7 +354,7 @@ public function prepareResponses($requestedProps, $nodes) {
}

$responses[] = new Response(
rtrim($this->server->getBaseUri(), '/') . $node->getPath(),
rtrim($this->server->getBaseUri(), '/') . $filesUri . $node->getPath(),
$result,
200
);
Expand Down
2 changes: 1 addition & 1 deletion apps/dav/lib/Connector/Sabre/SharesPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public function handleGetProperties(
&& $propFind->getDepth() !== 0
&& !is_null($propFind->getStatus(self::SHARETYPES_PROPERTYNAME))
) {
$folderNode = $this->userFolder->get($propFind->getPath());
$folderNode = $this->userFolder->get($sabreNode->getPath());
$children = $folderNode->getDirectoryListing();

$this->cachedShareTypes[$folderNode->getId()] = $this->getShareTypes($folderNode);
Expand Down
26 changes: 25 additions & 1 deletion apps/dav/lib/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ public function __construct(IRequest $request, $baseUri) {
// wait with registering these until auth is handled and the filesystem is setup
$this->server->on('beforeMethod', function () {
// custom properties plugin must be the last one
$user = \OC::$server->getUserSession()->getUser();
$userSession = \OC::$server->getUserSession();
$user = $userSession->getUser();
if (!is_null($user)) {
$view = \OC\Files\Filesystem::getView();
$this->server->addPlugin(
Expand Down Expand Up @@ -196,7 +197,30 @@ public function __construct(IRequest $request, $baseUri) {
$this->server->tree, \OC::$server->getTagManager()
)
);
// TODO: switch to LazyUserFolder
$userFolder = \OC::$server->getUserFolder();
$this->server->addPlugin(new \OCA\DAV\Connector\Sabre\SharesPlugin(
$this->server->tree,
$userSession,
$userFolder,
\OC::$server->getShareManager()
));
$this->server->addPlugin(new \OCA\DAV\Connector\Sabre\CommentPropertiesPlugin(
\OC::$server->getCommentsManager(),
$userSession
));
$this->server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesReportPlugin(
$this->server->tree,
$view,
\OC::$server->getSystemTagManager(),
\OC::$server->getSystemTagObjectMapper(),
\OC::$server->getTagManager(),
$userSession,
\OC::$server->getGroupManager(),
$userFolder
));
}
$this->server->addPlugin(new \OCA\DAV\Connector\Sabre\CopyEtagHeaderPlugin());
});
}

Expand Down
46 changes: 35 additions & 11 deletions apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,13 @@ public function setUp() {

$this->server = $this->getMockBuilder('\Sabre\DAV\Server')
->setConstructorArgs([$this->tree])
->setMethods(['getRequestUri'])
->setMethods(['getRequestUri', 'getBaseUri'])
->getMock();

$this->server->expects($this->any())
->method('getBaseUri')
->will($this->returnValue('http://example.com/owncloud/remote.php/dav'));

$this->groupManager = $this->getMockBuilder('\OCP\IGroupManager')
->disableOriginalConstructor()
->getMock();
Expand Down Expand Up @@ -129,9 +133,6 @@ public function setUp() {
);
}

/**
* @expectedException \Sabre\DAV\Exception\ReportNotSupported
*/
public function testOnReportInvalidNode() {
$path = 'totally/unrelated/13';

Expand All @@ -149,12 +150,9 @@ public function testOnReportInvalidNode() {
->will($this->returnValue($path));
$this->plugin->initialize($this->server);

$this->plugin->onReport(FilesReportPluginImplementation::REPORT_NAME, [], '/' . $path);
$this->assertNull($this->plugin->onReport(FilesReportPluginImplementation::REPORT_NAME, [], '/' . $path));
}

/**
* @expectedException \Sabre\DAV\Exception\ReportNotSupported
*/
public function testOnReportInvalidReportName() {
$path = 'test';

Expand All @@ -172,7 +170,7 @@ public function testOnReportInvalidReportName() {
->will($this->returnValue($path));
$this->plugin->initialize($this->server);

$this->plugin->onReport('{whoever}whatever', [], '/' . $path);
$this->assertNull($this->plugin->onReport('{whoever}whatever', [], '/' . $path));
}

public function testOnReport() {
Expand Down Expand Up @@ -254,7 +252,7 @@ public function testOnReport() {
$this->server->httpResponse = $response;
$this->plugin->initialize($this->server);

$this->plugin->onReport(FilesReportPluginImplementation::REPORT_NAME, $parameters, '/' . $path);
$this->assertFalse($this->plugin->onReport(FilesReportPluginImplementation::REPORT_NAME, $parameters, '/' . $path));
}

public function testFindNodesByFileIdsRoot() {
Expand Down Expand Up @@ -362,12 +360,18 @@ public function testPrepareResponses() {
$node1->expects($this->once())
->method('getInternalFileId')
->will($this->returnValue('111'));
$node1->expects($this->any())
->method('getPath')
->will($this->returnValue('/node1'));
$node2->expects($this->once())
->method('getInternalFileId')
->will($this->returnValue('222'));
$node2->expects($this->once())
->method('getSize')
->will($this->returnValue(1024));
$node2->expects($this->any())
->method('getPath')
->will($this->returnValue('/sub/node2'));

$config = $this->getMockBuilder('\OCP\IConfig')
->disableOriginalConstructor()
Expand All @@ -385,13 +389,16 @@ public function testPrepareResponses() {
)
);
$this->plugin->initialize($this->server);
$responses = $this->plugin->prepareResponses($requestedProps, [$node1, $node2]);
$responses = $this->plugin->prepareResponses('/files/username', $requestedProps, [$node1, $node2]);

$this->assertCount(2, $responses);

$this->assertEquals(200, $responses[0]->getHttpStatus());
$this->assertEquals(200, $responses[1]->getHttpStatus());

$this->assertEquals('http://example.com/owncloud/remote.php/dav/files/username/node1', $responses[0]->getHref());
$this->assertEquals('http://example.com/owncloud/remote.php/dav/files/username/sub/node2', $responses[1]->getHref());

$props1 = $responses[0]->getResponseProperties();
$this->assertEquals('111', $props1[200]['{http://owncloud.org/ns}fileid']);
$this->assertNull($props1[404]['{DAV:}getcontentlength']);
Expand Down Expand Up @@ -671,4 +678,21 @@ public function testProcessFavoriteFilter() {

$this->assertEquals(['456', '789'], array_values($this->invokePrivate($this->plugin, 'processFilterRules', [$rules])));
}

public function filesBaseUriProvider() {
return [
['', '', ''],
['files/username', '', '/files/username'],
['files/username/test', '/test', '/files/username'],
['files/username/test/sub', '/test/sub', '/files/username'],
['test', '/test', ''],
];
}

/**
* @dataProvider filesBaseUriProvider
*/
public function testFilesBaseUri($uri, $reportPath, $expectedUri) {
$this->assertEquals($expectedUri, $this->invokePrivate($this->plugin, 'getFilesBaseUri', [$uri, $reportPath]));
}
}