diff options
Diffstat (limited to 'apps/dav/lib/Server.php')
-rw-r--r-- | apps/dav/lib/Server.php | 271 |
1 files changed, 157 insertions, 114 deletions
diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php index deee381d24c..a92e162f1b0 100644 --- a/apps/dav/lib/Server.php +++ b/apps/dav/lib/Server.php @@ -1,51 +1,34 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @copyright Copyright (c) 2022 Informatyka Boguslawski sp. z o.o. sp.k., http://www.ib.pl/ - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Bjoern Schiessle <bjoern@schiessle.org> - * @author Brandon Kirsch <brandonkirsch@github.com> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Georg Ehrke <oc.list@georgehrke.com> - * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ <skjnldsv@protonmail.com> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Maxence Lange <maxence@artificial-owl.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Citharel <nextcloud@tcit.fr> - * @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: 2022 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\DAV; +use OC\Files\Filesystem; use OCA\DAV\AppInfo\PluginManager; use OCA\DAV\BulkUpload\BulkUploadPlugin; +use OCA\DAV\CalDAV\BirthdayCalendar\EnablePlugin; use OCA\DAV\CalDAV\BirthdayService; +use OCA\DAV\CalDAV\DefaultCalendarValidator; +use OCA\DAV\CalDAV\EventComparisonService; +use OCA\DAV\CalDAV\ICSExportPlugin\ICSExportPlugin; +use OCA\DAV\CalDAV\Publishing\PublishPlugin; +use OCA\DAV\CalDAV\Schedule\IMipPlugin; +use OCA\DAV\CalDAV\Schedule\IMipService; use OCA\DAV\CalDAV\Security\RateLimitingPlugin; +use OCA\DAV\CalDAV\Validation\CalDavValidatePlugin; use OCA\DAV\CardDAV\HasPhotoPlugin; use OCA\DAV\CardDAV\ImageExportPlugin; use OCA\DAV\CardDAV\MultiGetExportPlugin; use OCA\DAV\CardDAV\PhotoCache; +use OCA\DAV\CardDAV\Security\CardDavRateLimitingPlugin; +use OCA\DAV\CardDAV\Validation\CardDavValidatePlugin; use OCA\DAV\Comments\CommentsPlugin; use OCA\DAV\Connector\Sabre\AnonymousOptionsPlugin; +use OCA\DAV\Connector\Sabre\AppleQuirksPlugin; use OCA\DAV\Connector\Sabre\Auth; use OCA\DAV\Connector\Sabre\BearerAuth; use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin; @@ -55,34 +38,63 @@ use OCA\DAV\Connector\Sabre\CommentPropertiesPlugin; use OCA\DAV\Connector\Sabre\CopyEtagHeaderPlugin; use OCA\DAV\Connector\Sabre\DavAclPlugin; use OCA\DAV\Connector\Sabre\DummyGetResponsePlugin; +use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin; use OCA\DAV\Connector\Sabre\FakeLockerPlugin; use OCA\DAV\Connector\Sabre\FilesPlugin; use OCA\DAV\Connector\Sabre\FilesReportPlugin; +use OCA\DAV\Connector\Sabre\LockPlugin; +use OCA\DAV\Connector\Sabre\MaintenancePlugin; use OCA\DAV\Connector\Sabre\PropfindCompressionPlugin; +use OCA\DAV\Connector\Sabre\PropFindMonitorPlugin; use OCA\DAV\Connector\Sabre\QuotaPlugin; use OCA\DAV\Connector\Sabre\RequestIdHeaderPlugin; use OCA\DAV\Connector\Sabre\SharesPlugin; use OCA\DAV\Connector\Sabre\TagsPlugin; +use OCA\DAV\Connector\Sabre\ZipFolderPlugin; use OCA\DAV\DAV\CustomPropertiesBackend; use OCA\DAV\DAV\PublicAuth; use OCA\DAV\DAV\ViewOnlyPlugin; use OCA\DAV\Events\SabrePluginAddEvent; use OCA\DAV\Events\SabrePluginAuthInitEvent; use OCA\DAV\Files\BrowserErrorPagePlugin; +use OCA\DAV\Files\FileSearchBackend; use OCA\DAV\Files\LazySearchBackend; +use OCA\DAV\Paginate\PaginatePlugin; use OCA\DAV\Profiler\ProfilerPlugin; use OCA\DAV\Provisioning\Apple\AppleProvisioningPlugin; use OCA\DAV\SystemTag\SystemTagPlugin; use OCA\DAV\Upload\ChunkingPlugin; use OCA\DAV\Upload\ChunkingV2Plugin; +use OCA\DAV\Upload\UploadAutoMkcolPlugin; +use OCA\Theming\ThemingDefaults; +use OCP\Accounts\IAccountManager; +use OCP\App\IAppManager; use OCP\AppFramework\Http\Response; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\Comments\ICommentsManager; +use OCP\Defaults; use OCP\Diagnostics\IEventLogger; use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\IFilenameValidator; +use OCP\Files\IRootFolder; use OCP\FilesMetadata\IFilesMetadataManager; +use OCP\IAppConfig; use OCP\ICacheFactory; +use OCP\IConfig; +use OCP\IDBConnection; +use OCP\IGroupManager; +use OCP\IPreview; use OCP\IRequest; +use OCP\ISession; +use OCP\ITagManager; +use OCP\IURLGenerator; +use OCP\IUserSession; +use OCP\Mail\IMailer; use OCP\Profiler\IProfiler; use OCP\SabrePluginEvent; +use OCP\Security\Bruteforce\IThrottler; +use OCP\SystemTag\ISystemTagManager; +use OCP\SystemTag\ISystemTagObjectMapper; use Psr\Log\LoggerInterface; use Sabre\CardDAV\VCFExportPlugin; use Sabre\DAV\Auth\Plugin; @@ -90,40 +102,40 @@ use Sabre\DAV\UUIDUtil; use SearchDAV\DAV\SearchPlugin; class Server { - private IRequest $request; - private string $baseUri; public Connector\Sabre\Server $server; private IProfiler $profiler; - public function __construct(IRequest $request, string $baseUri) { - $this->profiler = \OC::$server->get(IProfiler::class); + public function __construct( + private IRequest $request, + private string $baseUri, + ) { + $debugEnabled = \OCP\Server::get(IConfig::class)->getSystemValue('debug', false); + $this->profiler = \OCP\Server::get(IProfiler::class); if ($this->profiler->isEnabled()) { /** @var IEventLogger $eventLogger */ - $eventLogger = \OC::$server->get(IEventLogger::class); + $eventLogger = \OCP\Server::get(IEventLogger::class); $eventLogger->start('runtime', 'DAV Runtime'); } - $this->request = $request; - $this->baseUri = $baseUri; - $logger = \OC::$server->get(LoggerInterface::class); - /** @var IEventDispatcher $dispatcher */ - $dispatcher = \OC::$server->get(IEventDispatcher::class); + $logger = \OCP\Server::get(LoggerInterface::class); + $eventDispatcher = \OCP\Server::get(IEventDispatcher::class); $root = new RootCollection(); $this->server = new \OCA\DAV\Connector\Sabre\Server(new CachingTree($root)); + $this->server->setLogger($logger); // Add maintenance plugin - $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\MaintenancePlugin(\OC::$server->getConfig(), \OC::$server->getL10N('dav'))); + $this->server->addPlugin(new MaintenancePlugin(\OCP\Server::get(IConfig::class), \OC::$server->getL10N('dav'))); - $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\AppleQuirksPlugin()); + $this->server->addPlugin(new AppleQuirksPlugin()); // Backends $authBackend = new Auth( - \OC::$server->getSession(), - \OC::$server->getUserSession(), - \OC::$server->getRequest(), - \OC::$server->getTwoFactorAuthManager(), - \OC::$server->getBruteForceThrottler() + \OCP\Server::get(ISession::class), + \OCP\Server::get(IUserSession::class), + \OCP\Server::get(IRequest::class), + \OCP\Server::get(\OC\Authentication\TwoFactorAuth\Manager::class), + \OCP\Server::get(IThrottler::class) ); // Set URL explicitly due to reverse-proxy situations @@ -131,7 +143,10 @@ class Server { $this->server->setBaseUri($this->baseUri); $this->server->addPlugin(new ProfilerPlugin($this->request)); - $this->server->addPlugin(new BlockLegacyClientPlugin(\OC::$server->getConfig())); + $this->server->addPlugin(new BlockLegacyClientPlugin( + \OCP\Server::get(IConfig::class), + \OCP\Server::get(ThemingDefaults::class), + )); $this->server->addPlugin(new AnonymousOptionsPlugin()); $authPlugin = new Plugin(); $authPlugin->addBackend(new PublicAuth()); @@ -139,29 +154,32 @@ class Server { // allow setup of additional auth backends $event = new SabrePluginEvent($this->server); - $dispatcher->dispatch('OCA\DAV\Connector\Sabre::authInit', $event); + $eventDispatcher->dispatch('OCA\DAV\Connector\Sabre::authInit', $event); $newAuthEvent = new SabrePluginAuthInitEvent($this->server); - $dispatcher->dispatchTyped($newAuthEvent); + $eventDispatcher->dispatchTyped($newAuthEvent); $bearerAuthBackend = new BearerAuth( - \OC::$server->getUserSession(), - \OC::$server->getSession(), - \OC::$server->getRequest() + \OCP\Server::get(IUserSession::class), + \OCP\Server::get(ISession::class), + \OCP\Server::get(IRequest::class), + \OCP\Server::get(IConfig::class), ); $authPlugin->addBackend($bearerAuthBackend); // because we are throwing exceptions this plugin has to be the last one $authPlugin->addBackend($authBackend); // debugging - if (\OC::$server->getConfig()->getSystemValue('debug', false)) { + if ($debugEnabled) { + $this->server->debugEnabled = true; + $this->server->addPlugin(new PropFindMonitorPlugin()); $this->server->addPlugin(new \Sabre\DAV\Browser\Plugin()); } else { $this->server->addPlugin(new DummyGetResponsePlugin()); } - $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin('webdav', $logger)); - $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\LockPlugin()); + $this->server->addPlugin(new ExceptionLoggerPlugin('webdav', $logger)); + $this->server->addPlugin(new LockPlugin()); $this->server->addPlugin(new \Sabre\DAV\Sync\Plugin()); // acl @@ -176,64 +194,69 @@ class Server { // calendar plugins if ($this->requestIsForSubtree(['calendars', 'public-calendars', 'system-calendars', 'principals'])) { + $this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OCP\Server::get(IRequest::class), \OCP\Server::get(IConfig::class))); $this->server->addPlugin(new \OCA\DAV\CalDAV\Plugin()); - $this->server->addPlugin(new \OCA\DAV\CalDAV\ICSExportPlugin\ICSExportPlugin(\OC::$server->getConfig(), $logger)); - $this->server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin(\OC::$server->getConfig(), \OC::$server->get(LoggerInterface::class))); - if (\OC::$server->getConfig()->getAppValue('dav', 'sendInvitations', 'yes') === 'yes') { - $this->server->addPlugin(\OC::$server->query(\OCA\DAV\CalDAV\Schedule\IMipPlugin::class)); - } + $this->server->addPlugin(new ICSExportPlugin(\OCP\Server::get(IConfig::class), $logger)); + $this->server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin(\OCP\Server::get(IConfig::class), \OCP\Server::get(LoggerInterface::class), \OCP\Server::get(DefaultCalendarValidator::class))); - $this->server->addPlugin(\OC::$server->get(\OCA\DAV\CalDAV\Trashbin\Plugin::class)); - $this->server->addPlugin(new \OCA\DAV\CalDAV\WebcalCaching\Plugin($request)); - if (\OC::$server->getConfig()->getAppValue('dav', 'allow_calendar_link_subscriptions', 'yes') === 'yes') { + $this->server->addPlugin(\OCP\Server::get(\OCA\DAV\CalDAV\Trashbin\Plugin::class)); + $this->server->addPlugin(new \OCA\DAV\CalDAV\WebcalCaching\Plugin($this->request)); + if (\OCP\Server::get(IConfig::class)->getAppValue('dav', 'allow_calendar_link_subscriptions', 'yes') === 'yes') { $this->server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin()); } $this->server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin()); - $this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest(), \OC::$server->getConfig())); - $this->server->addPlugin(new \OCA\DAV\CalDAV\Publishing\PublishPlugin( - \OC::$server->getConfig(), - \OC::$server->getURLGenerator() + $this->server->addPlugin(new PublishPlugin( + \OCP\Server::get(IConfig::class), + \OCP\Server::get(IURLGenerator::class) )); $this->server->addPlugin(\OCP\Server::get(RateLimitingPlugin::class)); + $this->server->addPlugin(\OCP\Server::get(CalDavValidatePlugin::class)); } // addressbook plugins if ($this->requestIsForSubtree(['addressbooks', 'principals'])) { - $this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest(), \OC::$server->getConfig())); + $this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OCP\Server::get(IRequest::class), \OCP\Server::get(IConfig::class))); $this->server->addPlugin(new \OCA\DAV\CardDAV\Plugin()); $this->server->addPlugin(new VCFExportPlugin()); $this->server->addPlugin(new MultiGetExportPlugin()); $this->server->addPlugin(new HasPhotoPlugin()); - $this->server->addPlugin(new ImageExportPlugin(new PhotoCache( - \OC::$server->getAppDataDir('dav-photocache'), - $logger) - )); + $this->server->addPlugin(new ImageExportPlugin(\OCP\Server::get(PhotoCache::class))); + + $this->server->addPlugin(\OCP\Server::get(CardDavRateLimitingPlugin::class)); + $this->server->addPlugin(\OCP\Server::get(CardDavValidatePlugin::class)); } // system tags plugins - $this->server->addPlugin(\OC::$server->get(SystemTagPlugin::class)); + $this->server->addPlugin(\OCP\Server::get(SystemTagPlugin::class)); // comments plugin $this->server->addPlugin(new CommentsPlugin( - \OC::$server->getCommentsManager(), - \OC::$server->getUserSession() + \OCP\Server::get(ICommentsManager::class), + \OCP\Server::get(IUserSession::class) )); $this->server->addPlugin(new CopyEtagHeaderPlugin()); - $this->server->addPlugin(new RequestIdHeaderPlugin(\OC::$server->get(IRequest::class))); + $this->server->addPlugin(new RequestIdHeaderPlugin(\OCP\Server::get(IRequest::class))); + $this->server->addPlugin(new UploadAutoMkcolPlugin()); $this->server->addPlugin(new ChunkingV2Plugin(\OCP\Server::get(ICacheFactory::class))); $this->server->addPlugin(new ChunkingPlugin()); + $this->server->addPlugin(new ZipFolderPlugin( + $this->server->tree, + $logger, + $eventDispatcher, + )); + $this->server->addPlugin(\OCP\Server::get(PaginatePlugin::class)); // allow setup of additional plugins - $dispatcher->dispatch('OCA\DAV\Connector\Sabre::addPlugin', $event); + $eventDispatcher->dispatch('OCA\DAV\Connector\Sabre::addPlugin', $event); $typedEvent = new SabrePluginAddEvent($this->server); - $dispatcher->dispatchTyped($typedEvent); + $eventDispatcher->dispatchTyped($typedEvent); // Some WebDAV clients do require Class 2 WebDAV support (locking), since // we do not provide locking we emulate it using a fake locking plugin. - if ($request->isUserAgent([ + if ($this->request->isUserAgent([ '/WebDAVFS/', '/OneNote/', '/^Microsoft-WebDAV/',// Microsoft-WebDAV-MiniRedir/6.1.7601 @@ -249,26 +272,29 @@ class Server { $this->server->addPlugin(new SearchPlugin($lazySearchBackend)); // wait with registering these until auth is handled and the filesystem is setup - $this->server->on('beforeMethod:*', function () use ($root, $lazySearchBackend, $logger) { + $this->server->on('beforeMethod:*', function () use ($root, $lazySearchBackend, $logger): void { // Allow view-only plugin for webdav requests $this->server->addPlugin(new ViewOnlyPlugin( \OC::$server->getUserFolder(), )); // custom properties plugin must be the last one - $userSession = \OC::$server->getUserSession(); + $userSession = \OCP\Server::get(IUserSession::class); $user = $userSession->getUser(); if ($user !== null) { - $view = \OC\Files\Filesystem::getView(); + $view = Filesystem::getView(); + $config = \OCP\Server::get(IConfig::class); $this->server->addPlugin( new FilesPlugin( $this->server->tree, - \OC::$server->getConfig(), + $config, $this->request, - \OC::$server->getPreviewManager(), - \OC::$server->getUserSession(), + \OCP\Server::get(IPreview::class), + \OCP\Server::get(IUserSession::class), + \OCP\Server::get(IFilenameValidator::class), + \OCP\Server::get(IAccountManager::class), false, - !\OC::$server->getConfig()->getSystemValue('debug', false) + $config->getSystemValueBool('debug', false) === false, ) ); $this->server->addPlugin(new ChecksumUpdatePlugin()); @@ -278,8 +304,9 @@ class Server { new CustomPropertiesBackend( $this->server, $this->server->tree, - \OC::$server->getDatabaseConnection(), - \OC::$server->getUserSession()->getUser() + \OCP\Server::get(IDBConnection::class), + \OCP\Server::get(IUserSession::class)->getUser(), + \OCP\Server::get(DefaultCalendarValidator::class), ) ) ); @@ -289,39 +316,55 @@ class Server { } $this->server->addPlugin( new TagsPlugin( - $this->server->tree, \OC::$server->getTagManager() + $this->server->tree, \OCP\Server::get(ITagManager::class), \OCP\Server::get(IEventDispatcher::class), \OCP\Server::get(IUserSession::class) ) ); + // TODO: switch to LazyUserFolder $userFolder = \OC::$server->getUserFolder(); + $shareManager = \OCP\Server::get(\OCP\Share\IManager::class); $this->server->addPlugin(new SharesPlugin( $this->server->tree, $userSession, $userFolder, - \OC::$server->getShareManager() + $shareManager, )); $this->server->addPlugin(new CommentPropertiesPlugin( - \OC::$server->getCommentsManager(), + \OCP\Server::get(ICommentsManager::class), $userSession )); + if (\OCP\Server::get(IConfig::class)->getAppValue('dav', 'sendInvitations', 'yes') === 'yes') { + $this->server->addPlugin(new IMipPlugin( + \OCP\Server::get(IAppConfig::class), + \OCP\Server::get(IMailer::class), + \OCP\Server::get(LoggerInterface::class), + \OCP\Server::get(ITimeFactory::class), + \OCP\Server::get(Defaults::class), + $userSession, + \OCP\Server::get(IMipService::class), + \OCP\Server::get(EventComparisonService::class), + \OCP\Server::get(\OCP\Mail\Provider\IManager::class) + )); + } $this->server->addPlugin(new \OCA\DAV\CalDAV\Search\SearchPlugin()); if ($view !== null) { $this->server->addPlugin(new FilesReportPlugin( $this->server->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), $userSession, - \OC::$server->getGroupManager(), + \OCP\Server::get(IGroupManager::class), $userFolder, - \OC::$server->getAppManager() + \OCP\Server::get(IAppManager::class) )); - $lazySearchBackend->setBackend(new \OCA\DAV\Files\FileSearchBackend( + $lazySearchBackend->setBackend(new FileSearchBackend( + $this->server, $this->server->tree, $user, - \OC::$server->getRootFolder(), - \OC::$server->getShareManager(), + \OCP\Server::get(IRootFolder::class), + $shareManager, $view, \OCP\Server::get(IFilesMetadataManager::class) )); @@ -332,16 +375,16 @@ class Server { ) ); } - $this->server->addPlugin(new \OCA\DAV\CalDAV\BirthdayCalendar\EnablePlugin( - \OC::$server->getConfig(), - \OC::$server->query(BirthdayService::class), + $this->server->addPlugin(new EnablePlugin( + \OCP\Server::get(IConfig::class), + \OCP\Server::get(BirthdayService::class), $user )); $this->server->addPlugin(new AppleProvisioningPlugin( - \OC::$server->getUserSession(), - \OC::$server->getURLGenerator(), - \OC::$server->getThemingDefaults(), - \OC::$server->getRequest(), + \OCP\Server::get(IUserSession::class), + \OCP\Server::get(IURLGenerator::class), + \OCP\Server::get(ThemingDefaults::class), + \OCP\Server::get(IRequest::class), \OC::$server->getL10N('dav'), function () { return UUIDUtil::getUUID(); @@ -352,7 +395,7 @@ class Server { // register plugins from apps $pluginManager = new PluginManager( \OC::$server, - \OC::$server->getAppManager() + \OCP\Server::get(IAppManager::class) ); foreach ($pluginManager->getAppPlugins() as $appPlugin) { $this->server->addPlugin($appPlugin); @@ -369,13 +412,13 @@ class Server { public function exec() { /** @var IEventLogger $eventLogger */ - $eventLogger = \OC::$server->get(IEventLogger::class); + $eventLogger = \OCP\Server::get(IEventLogger::class); $eventLogger->start('dav_server_exec', ''); - $this->server->exec(); + $this->server->start(); $eventLogger->end('dav_server_exec'); if ($this->profiler->isEnabled()) { $eventLogger->end('runtime'); - $profile = $this->profiler->collect(\OC::$server->get(IRequest::class), new Response()); + $profile = $this->profiler->collect(\OCP\Server::get(IRequest::class), new Response()); $this->profiler->saveProfile($profile); } } |