diff options
Diffstat (limited to 'apps/dav/lib/Connector/Sabre/ServerFactory.php')
-rw-r--r-- | apps/dav/lib/Connector/Sabre/ServerFactory.php | 231 |
1 files changed, 134 insertions, 97 deletions
diff --git a/apps/dav/lib/Connector/Sabre/ServerFactory.php b/apps/dav/lib/Connector/Sabre/ServerFactory.php index 758951c42ff..38fd057bc91 100644 --- a/apps/dav/lib/Connector/Sabre/ServerFactory.php +++ b/apps/dav/lib/Connector/Sabre/ServerFactory.php @@ -1,114 +1,112 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Georg Ehrke <oc.list@georgehrke.com> - * @author Joas Schilling <coding@schilljs.com> - * @author Julius Härtl <jus@bitgrid.net> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\DAV\Connector\Sabre; +use OC\Files\View; +use OC\KnownUser\KnownUserService; use OCA\DAV\AppInfo\PluginManager; +use OCA\DAV\CalDAV\DefaultCalendarValidator; +use OCA\DAV\CalDAV\Proxy\ProxyMapper; +use OCA\DAV\DAV\CustomPropertiesBackend; use OCA\DAV\DAV\ViewOnlyPlugin; +use OCA\DAV\Db\PropertyMapper; use OCA\DAV\Files\BrowserErrorPagePlugin; +use OCA\DAV\Files\Sharing\RootCollection; +use OCA\DAV\Upload\CleanupService; +use OCA\Theming\ThemingDefaults; +use OCP\Accounts\IAccountManager; +use OCP\App\IAppManager; +use OCP\Comments\ICommentsManager; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Folder; +use OCP\Files\IFilenameValidator; +use OCP\Files\IRootFolder; use OCP\Files\Mount\IMountManager; use OCP\IConfig; use OCP\IDBConnection; +use OCP\IGroupManager; use OCP\IL10N; use OCP\IPreview; use OCP\IRequest; use OCP\ITagManager; +use OCP\IUserManager; use OCP\IUserSession; use OCP\SabrePluginEvent; +use OCP\SystemTag\ISystemTagManager; +use OCP\SystemTag\ISystemTagObjectMapper; use Psr\Log\LoggerInterface; use Sabre\DAV\Auth\Plugin; +use Sabre\DAV\SimpleCollection; class ServerFactory { - private IConfig $config; - private LoggerInterface $logger; - private IDBConnection $databaseConnection; - private IUserSession $userSession; - private IMountManager $mountManager; - private ITagManager $tagManager; - private IRequest $request; - private IPreview $previewManager; - private IEventDispatcher $eventDispatcher; - private IL10N $l10n; public function __construct( - IConfig $config, - LoggerInterface $logger, - IDBConnection $databaseConnection, - IUserSession $userSession, - IMountManager $mountManager, - ITagManager $tagManager, - IRequest $request, - IPreview $previewManager, - IEventDispatcher $eventDispatcher, - IL10N $l10n + private IConfig $config, + private LoggerInterface $logger, + private IDBConnection $databaseConnection, + private IUserSession $userSession, + private IMountManager $mountManager, + private ITagManager $tagManager, + private IRequest $request, + private IPreview $previewManager, + private IEventDispatcher $eventDispatcher, + private IL10N $l10n, ) { - $this->config = $config; - $this->logger = $logger; - $this->databaseConnection = $databaseConnection; - $this->userSession = $userSession; - $this->mountManager = $mountManager; - $this->tagManager = $tagManager; - $this->request = $request; - $this->previewManager = $previewManager; - $this->eventDispatcher = $eventDispatcher; - $this->l10n = $l10n; } /** * @param callable $viewCallBack callback that should return the view for the dav endpoint */ - public function createServer(string $baseUri, + public function createServer( + bool $isPublicShare, + string $baseUri, string $requestUri, Plugin $authPlugin, - callable $viewCallBack): Server { + callable $viewCallBack, + ): Server { + $debugEnabled = $this->config->getSystemValue('debug', false); // Fire up server - $objectTree = new \OCA\DAV\Connector\Sabre\ObjectTree(); - $server = new \OCA\DAV\Connector\Sabre\Server($objectTree); + if ($isPublicShare) { + $rootCollection = new SimpleCollection('root'); + $tree = new CachingTree($rootCollection); + } else { + $rootCollection = null; + $tree = new ObjectTree(); + } + $server = new Server($tree); // Set URL explicitly due to reverse-proxy situations $server->httpRequest->setUrl($requestUri); $server->setBaseUri($baseUri); // Load plugins - $server->addPlugin(new \OCA\DAV\Connector\Sabre\MaintenancePlugin($this->config, $this->l10n)); - $server->addPlugin(new \OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin($this->config)); - $server->addPlugin(new \OCA\DAV\Connector\Sabre\AnonymousOptionsPlugin()); + $server->addPlugin(new MaintenancePlugin($this->config, $this->l10n)); + $server->addPlugin(new BlockLegacyClientPlugin( + $this->config, + \OCP\Server::get(ThemingDefaults::class), + )); + $server->addPlugin(new AnonymousOptionsPlugin()); $server->addPlugin($authPlugin); + if ($debugEnabled) { + $server->debugEnabled = $debugEnabled; + $server->addPlugin(new PropFindMonitorPlugin()); + } // FIXME: The following line is a workaround for legacy components relying on being able to send a GET to / - $server->addPlugin(new \OCA\DAV\Connector\Sabre\DummyGetResponsePlugin()); - $server->addPlugin(new \OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin('webdav', $this->logger)); - $server->addPlugin(new \OCA\DAV\Connector\Sabre\LockPlugin()); + $server->addPlugin(new DummyGetResponsePlugin()); + $server->addPlugin(new ExceptionLoggerPlugin('webdav', $this->logger)); + $server->addPlugin(new LockPlugin()); - $server->addPlugin(new RequestIdHeaderPlugin(\OC::$server->get(IRequest::class))); + $server->addPlugin(new RequestIdHeaderPlugin($this->request)); + + $server->addPlugin(new ZipFolderPlugin( + $tree, + $this->logger, + $this->eventDispatcher, + )); // Some WebDAV clients do require Class 2 WebDAV support (locking), since // we do not provide locking we emulate it using a fake locking plugin. @@ -117,7 +115,7 @@ class ServerFactory { '/OneNote/', '/Microsoft-WebDAV-MiniRedir/', ])) { - $server->addPlugin(new \OCA\DAV\Connector\Sabre\FakeLockerPlugin()); + $server->addPlugin(new FakeLockerPlugin()); } if (BrowserErrorPagePlugin::isBrowserRequest($this->request)) { @@ -125,11 +123,12 @@ class ServerFactory { } // wait with registering these until auth is handled and the filesystem is setup - $server->on('beforeMethod:*', function () use ($server, $objectTree, $viewCallBack) { + $server->on('beforeMethod:*', function () use ($server, $tree, + $viewCallBack, $isPublicShare, $rootCollection, $debugEnabled): void { // ensure the skeleton is copied $userFolder = \OC::$server->getUserFolder(); - /** @var \OC\Files\View $view */ + /** @var View $view */ $view = $viewCallBack($server); if ($userFolder instanceof Folder && $userFolder->getPath() === $view->getRoot()) { $rootInfo = $userFolder; @@ -139,25 +138,61 @@ class ServerFactory { // Create Nextcloud Dir if ($rootInfo->getType() === 'dir') { - $root = new \OCA\DAV\Connector\Sabre\Directory($view, $rootInfo, $objectTree); + $root = new Directory($view, $rootInfo, $tree); + } else { + $root = new File($view, $rootInfo); + } + + if ($isPublicShare) { + $userPrincipalBackend = new Principal( + \OCP\Server::get(IUserManager::class), + \OCP\Server::get(IGroupManager::class), + \OCP\Server::get(IAccountManager::class), + \OCP\Server::get(\OCP\Share\IManager::class), + \OCP\Server::get(IUserSession::class), + \OCP\Server::get(IAppManager::class), + \OCP\Server::get(ProxyMapper::class), + \OCP\Server::get(KnownUserService::class), + \OCP\Server::get(IConfig::class), + \OC::$server->getL10NFactory(), + ); + + // Mount the share collection at /public.php/dav/shares/<share token> + $rootCollection->addChild(new RootCollection( + $root, + $userPrincipalBackend, + 'principals/shares', + )); + + // Mount the upload collection at /public.php/dav/uploads/<share token> + $rootCollection->addChild(new \OCA\DAV\Upload\RootCollection( + $userPrincipalBackend, + 'principals/shares', + \OCP\Server::get(CleanupService::class), + \OCP\Server::get(IRootFolder::class), + \OCP\Server::get(IUserSession::class), + \OCP\Server::get(\OCP\Share\IManager::class), + )); } else { - $root = new \OCA\DAV\Connector\Sabre\File($view, $rootInfo); + /** @var ObjectTree $tree */ + $tree->init($root, $view, $this->mountManager); } - $objectTree->init($root, $view, $this->mountManager); $server->addPlugin( - new \OCA\DAV\Connector\Sabre\FilesPlugin( - $objectTree, + new FilesPlugin( + $tree, $this->config, $this->request, $this->previewManager, $this->userSession, + \OCP\Server::get(IFilenameValidator::class), + \OCP\Server::get(IAccountManager::class), false, - !$this->config->getSystemValue('debug', false) + !$debugEnabled ) ); - $server->addPlugin(new \OCA\DAV\Connector\Sabre\QuotaPlugin($view, true)); - $server->addPlugin(new \OCA\DAV\Connector\Sabre\ChecksumUpdatePlugin()); + $server->addPlugin(new QuotaPlugin($view)); + $server->addPlugin(new ChecksumUpdatePlugin()); // Allow view-only plugin for webdav requests $server->addPlugin(new ViewOnlyPlugin( @@ -165,45 +200,47 @@ class ServerFactory { )); if ($this->userSession->isLoggedIn()) { - $server->addPlugin(new \OCA\DAV\Connector\Sabre\TagsPlugin($objectTree, $this->tagManager)); - $server->addPlugin(new \OCA\DAV\Connector\Sabre\SharesPlugin( - $objectTree, + $server->addPlugin(new TagsPlugin($tree, $this->tagManager, $this->eventDispatcher, $this->userSession)); + $server->addPlugin(new SharesPlugin( + $tree, $this->userSession, $userFolder, - \OC::$server->getShareManager() + \OCP\Server::get(\OCP\Share\IManager::class) )); - $server->addPlugin(new \OCA\DAV\Connector\Sabre\CommentPropertiesPlugin(\OC::$server->getCommentsManager(), $this->userSession)); - $server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesReportPlugin( - $objectTree, + $server->addPlugin(new CommentPropertiesPlugin(\OCP\Server::get(ICommentsManager::class), $this->userSession)); + $server->addPlugin(new FilesReportPlugin( + $tree, $view, - \OC::$server->getSystemTagManager(), - \OC::$server->getSystemTagObjectMapper(), - \OC::$server->getTagManager(), + \OCP\Server::get(ISystemTagManager::class), + \OCP\Server::get(ISystemTagObjectMapper::class), + \OCP\Server::get(ITagManager::class), $this->userSession, - \OC::$server->getGroupManager(), + \OCP\Server::get(IGroupManager::class), $userFolder, - \OC::$server->getAppManager() + \OCP\Server::get(IAppManager::class) )); // custom properties plugin must be the last one $server->addPlugin( new \Sabre\DAV\PropertyStorage\Plugin( - new \OCA\DAV\DAV\CustomPropertiesBackend( + new CustomPropertiesBackend( $server, - $objectTree, + $tree, $this->databaseConnection, - $this->userSession->getUser() + $this->userSession->getUser(), + \OCP\Server::get(PropertyMapper::class), + \OCP\Server::get(DefaultCalendarValidator::class), ) ) ); } - $server->addPlugin(new \OCA\DAV\Connector\Sabre\CopyEtagHeaderPlugin()); + $server->addPlugin(new CopyEtagHeaderPlugin()); // Load dav plugins from apps $event = new SabrePluginEvent($server); $this->eventDispatcher->dispatchTyped($event); $pluginManager = new PluginManager( \OC::$server, - \OC::$server->getAppManager() + \OCP\Server::get(IAppManager::class) ); foreach ($pluginManager->getAppPlugins() as $appPlugin) { $server->addPlugin($appPlugin); |