Skip to content

Commit 8e95d0f

Browse files
committed
Check share attributes when downloading versions
Signed-off-by: Louis Chemineau <louis@chmn.me>
1 parent 7ff8183 commit 8e95d0f

File tree

5 files changed

+45
-8
lines changed

5 files changed

+45
-8
lines changed

apps/dav/lib/Connector/Sabre/ServerFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ public function createServer(string $baseUri,
161161

162162
// Allow view-only plugin for webdav requests
163163
$server->addPlugin(new ViewOnlyPlugin(
164-
$this->logger
164+
$userFolder,
165165
));
166166

167167
if ($this->userSession->isLoggedIn()) {

apps/dav/lib/DAV/ViewOnlyPlugin.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
use OCA\DAV\Connector\Sabre\Exception\Forbidden;
2525
use OCA\DAV\Connector\Sabre\File as DavFile;
2626
use OCA\Files_Versions\Sabre\VersionFile;
27+
use OCP\Files\Folder;
2728
use OCP\Files\NotFoundException;
28-
use Psr\Log\LoggerInterface;
2929
use Sabre\DAV\Exception\NotFound;
3030
use Sabre\DAV\Server;
3131
use Sabre\DAV\ServerPlugin;
@@ -36,10 +36,12 @@
3636
*/
3737
class ViewOnlyPlugin extends ServerPlugin {
3838
private ?Server $server = null;
39-
private LoggerInterface $logger;
39+
private ?Folder $userFolder;
4040

41-
public function __construct(LoggerInterface $logger) {
42-
$this->logger = $logger;
41+
public function __construct(
42+
?Folder $userFolder,
43+
) {
44+
$this->userFolder = $userFolder;
4345
}
4446

4547
/**
@@ -76,6 +78,16 @@ public function checkViewOnly(RequestInterface $request): bool {
7678
$node = $davNode->getNode();
7779
} elseif ($davNode instanceof VersionFile) {
7880
$node = $davNode->getVersion()->getSourceFile();
81+
$currentUserId = $this->userFolder?->getOwner()?->getUID();
82+
// The version source file is relative to the owner storage.
83+
// But we need the node from the current user perspective.
84+
if ($node->getOwner()->getUID() !== $currentUserId) {
85+
$nodes = $this->userFolder->getById($node->getId());
86+
$node = array_pop($nodes);
87+
if (!$node) {
88+
throw new NotFoundException("Version file not accessible by current user");
89+
}
90+
}
7991
} else {
8092
return true;
8193
}

apps/dav/lib/Server.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ public function __construct(IRequest $request, string $baseUri) {
240240

241241
// Allow view-only plugin for webdav requests
242242
$this->server->addPlugin(new ViewOnlyPlugin(
243-
$logger
243+
\OC::$server->getUserFolder(),
244244
));
245245

246246
if (BrowserErrorPagePlugin::isBrowserRequest($request)) {

apps/dav/tests/unit/DAV/ViewOnlyPluginTest.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@
2727
use OCA\Files_Versions\Sabre\VersionFile;
2828
use OCA\Files_Versions\Versions\IVersion;
2929
use OCP\Files\File;
30+
use OCP\Files\Folder;
3031
use OCP\Files\Storage\IStorage;
32+
use OCP\IUser;
3133
use OCP\Share\IAttributes;
3234
use OCP\Share\IShare;
33-
use Psr\Log\LoggerInterface;
3435
use Sabre\DAV\Server;
3536
use Sabre\DAV\Tree;
3637
use Sabre\HTTP\RequestInterface;
@@ -43,10 +44,13 @@ class ViewOnlyPluginTest extends TestCase {
4344
private $tree;
4445
/** @var RequestInterface | \PHPUnit\Framework\MockObject\MockObject */
4546
private $request;
47+
/** @var Folder | \PHPUnit\Framework\MockObject\MockObject */
48+
private $userFolder;
4649

4750
public function setUp(): void {
51+
$this->userFolder = $this->createMock(Folder::class);
4852
$this->plugin = new ViewOnlyPlugin(
49-
$this->createMock(LoggerInterface::class)
53+
$this->userFolder,
5054
);
5155
$this->request = $this->createMock(RequestInterface::class);
5256
$this->tree = $this->createMock(Tree::class);
@@ -111,6 +115,26 @@ public function testCanGet(bool $isVersion, ?bool $attrEnabled, bool $expectCanD
111115
$davNode->expects($this->once())
112116
->method('getVersion')
113117
->willReturn($version);
118+
119+
$currentUser = $this->createMock(IUser::class);
120+
$currentUser->expects($this->once())
121+
->method('getUID')
122+
->willReturn('alice');
123+
$nodeInfo->expects($this->once())
124+
->method('getOwner')
125+
->willReturn($currentUser);
126+
127+
$nodeInfo = $this->createMock(File::class);
128+
$owner = $this->createMock(IUser::class);
129+
$owner->expects($this->once())
130+
->method('getUID')
131+
->willReturn('bob');
132+
$this->userFolder->expects($this->once())
133+
->method('getById')
134+
->willReturn([$nodeInfo]);
135+
$this->userFolder->expects($this->once())
136+
->method('getOwner')
137+
->willReturn($owner);
114138
} else {
115139
$davPath = 'files/path/to/file.odt';
116140
$davNode = $this->createMock(DavFile::class);

apps/dav/tests/unit/ServerTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public function test($uri, array $plugins): void {
4545
/** @var IRequest | \PHPUnit\Framework\MockObject\MockObject $r */
4646
$r = $this->createMock(IRequest::class);
4747
$r->expects($this->any())->method('getRequestUri')->willReturn($uri);
48+
$this->loginAsUser('admin');
4849
$s = new Server($r, '/');
4950
$this->assertNotNull($s->server);
5051
foreach ($plugins as $plugin) {

0 commit comments

Comments
 (0)