// Allow view-only plugin for webdav requests
$server->addPlugin(new ViewOnlyPlugin(
- $this->logger
+ $userFolder,
));
if ($this->userSession->isLoggedIn()) {
use OCA\DAV\Connector\Sabre\Exception\Forbidden;
use OCA\DAV\Connector\Sabre\File as DavFile;
use OCA\Files_Versions\Sabre\VersionFile;
+use OCP\Files\Folder;
use OCP\Files\NotFoundException;
-use Psr\Log\LoggerInterface;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\Server;
use Sabre\DAV\ServerPlugin;
*/
class ViewOnlyPlugin extends ServerPlugin {
private ?Server $server = null;
- private LoggerInterface $logger;
+ private ?Folder $userFolder;
- public function __construct(LoggerInterface $logger) {
- $this->logger = $logger;
+ public function __construct(
+ ?Folder $userFolder,
+ ) {
+ $this->userFolder = $userFolder;
}
/**
$node = $davNode->getNode();
} elseif ($davNode instanceof VersionFile) {
$node = $davNode->getVersion()->getSourceFile();
+ $currentUserId = $this->userFolder?->getOwner()?->getUID();
+ // The version source file is relative to the owner storage.
+ // But we need the node from the current user perspective.
+ if ($node->getOwner()->getUID() !== $currentUserId) {
+ $nodes = $this->userFolder->getById($node->getId());
+ $node = array_pop($nodes);
+ if (!$node) {
+ throw new NotFoundException("Version file not accessible by current user");
+ }
+ }
} else {
return true;
}
// Allow view-only plugin for webdav requests
$this->server->addPlugin(new ViewOnlyPlugin(
- $logger
+ \OC::$server->getUserFolder(),
));
if (BrowserErrorPagePlugin::isBrowserRequest($request)) {
use OCA\Files_Versions\Sabre\VersionFile;
use OCA\Files_Versions\Versions\IVersion;
use OCP\Files\File;
+use OCP\Files\Folder;
use OCP\Files\Storage\IStorage;
+use OCP\IUser;
use OCP\Share\IAttributes;
use OCP\Share\IShare;
-use Psr\Log\LoggerInterface;
use Sabre\DAV\Server;
use Sabre\DAV\Tree;
use Sabre\HTTP\RequestInterface;
private $tree;
/** @var RequestInterface | \PHPUnit\Framework\MockObject\MockObject */
private $request;
+ /** @var Folder | \PHPUnit\Framework\MockObject\MockObject */
+ private $userFolder;
public function setUp(): void {
+ $this->userFolder = $this->createMock(Folder::class);
$this->plugin = new ViewOnlyPlugin(
- $this->createMock(LoggerInterface::class)
+ $this->userFolder,
);
$this->request = $this->createMock(RequestInterface::class);
$this->tree = $this->createMock(Tree::class);
$davNode->expects($this->once())
->method('getVersion')
->willReturn($version);
+
+ $currentUser = $this->createMock(IUser::class);
+ $currentUser->expects($this->once())
+ ->method('getUID')
+ ->willReturn('alice');
+ $nodeInfo->expects($this->once())
+ ->method('getOwner')
+ ->willReturn($currentUser);
+
+ $nodeInfo = $this->createMock(File::class);
+ $owner = $this->createMock(IUser::class);
+ $owner->expects($this->once())
+ ->method('getUID')
+ ->willReturn('bob');
+ $this->userFolder->expects($this->once())
+ ->method('getById')
+ ->willReturn([$nodeInfo]);
+ $this->userFolder->expects($this->once())
+ ->method('getOwner')
+ ->willReturn($owner);
} else {
$davPath = 'files/path/to/file.odt';
$davNode = $this->createMock(DavFile::class);
/** @var IRequest | \PHPUnit\Framework\MockObject\MockObject $r */
$r = $this->createMock(IRequest::class);
$r->expects($this->any())->method('getRequestUri')->willReturn($uri);
+ $this->loginAsUser('admin');
$s = new Server($r, '/');
$this->assertNotNull($s->server);
foreach ($plugins as $plugin) {