diff options
Diffstat (limited to 'apps/dav/lib')
-rw-r--r-- | apps/dav/lib/CalDAV/Schedule/Plugin.php | 67 | ||||
-rw-r--r-- | apps/dav/lib/Command/CreateCalendar.php | 3 | ||||
-rw-r--r-- | apps/dav/lib/Connector/Sabre/AnonymousOptionsPlugin.php | 63 | ||||
-rw-r--r-- | apps/dav/lib/Connector/Sabre/Principal.php | 19 | ||||
-rw-r--r-- | apps/dav/lib/Connector/Sabre/ServerFactory.php | 1 | ||||
-rw-r--r-- | apps/dav/lib/RootCollection.php | 3 | ||||
-rw-r--r-- | apps/dav/lib/Server.php | 2 |
7 files changed, 152 insertions, 6 deletions
diff --git a/apps/dav/lib/CalDAV/Schedule/Plugin.php b/apps/dav/lib/CalDAV/Schedule/Plugin.php index 34df666637c..faf495a4de6 100644 --- a/apps/dav/lib/CalDAV/Schedule/Plugin.php +++ b/apps/dav/lib/CalDAV/Schedule/Plugin.php @@ -31,6 +31,10 @@ use Sabre\DAV\PropFind; use Sabre\DAV\Server; use Sabre\DAV\Xml\Property\LocalHref; use Sabre\DAVACL\IPrincipal; +use Sabre\HTTP\RequestInterface; +use Sabre\HTTP\ResponseInterface; +use Sabre\VObject\Component\VCalendar; +use Sabre\VObject\Reader; class Plugin extends \Sabre\CalDAV\Schedule\Plugin { @@ -98,4 +102,67 @@ class Plugin extends \Sabre\CalDAV\Schedule\Plugin { }); } } + + /** + * This method is triggered whenever there was a calendar object gets + * created or updated. + * + * Basically just a copy of parent::calendarObjectChange, with the change + * from: + * $addresses = $this->getAddressesForPrincipal($calendarNode->getOwner()); + * to: + * $addresses = $this->getAddressesForPrincipal($calendarNode->getPrincipalURI()); + * + * @param RequestInterface $request HTTP request + * @param ResponseInterface $response HTTP Response + * @param VCalendar $vCal Parsed iCalendar object + * @param mixed $calendarPath Path to calendar collection + * @param mixed $modified The iCalendar object has been touched. + * @param mixed $isNew Whether this was a new item or we're updating one + * @return void + */ + function calendarObjectChange(RequestInterface $request, ResponseInterface $response, VCalendar $vCal, $calendarPath, &$modified, $isNew) { + + if (!$this->scheduleReply($this->server->httpRequest)) { + return; + } + + $calendarNode = $this->server->tree->getNodeForPath($calendarPath); + + $addresses = $this->getAddressesForPrincipal( + $calendarNode->getPrincipalURI() + ); + + if (!$isNew) { + $node = $this->server->tree->getNodeForPath($request->getPath()); + $oldObj = Reader::read($node->get()); + } else { + $oldObj = null; + } + + $this->processICalendarChange($oldObj, $vCal, $addresses, [], $modified); + + if ($oldObj) { + // Destroy circular references so PHP will GC the object. + $oldObj->destroy(); + } + + } + + /** + * This method checks the 'Schedule-Reply' header + * and returns false if it's 'F', otherwise true. + * + * Copied from Sabre/DAV's Schedule plugin, because it's + * private for whatever reason + * + * @param RequestInterface $request + * @return bool + */ + private function scheduleReply(RequestInterface $request) { + + $scheduleReply = $request->getHeader('Schedule-Reply'); + return $scheduleReply !== 'F'; + + } } diff --git a/apps/dav/lib/Command/CreateCalendar.php b/apps/dav/lib/Command/CreateCalendar.php index 1cbd7b60944..45dd9ba941a 100644 --- a/apps/dav/lib/Command/CreateCalendar.php +++ b/apps/dav/lib/Command/CreateCalendar.php @@ -77,7 +77,8 @@ class CreateCalendar extends Command { $this->userManager, $this->groupManager, \OC::$server->getShareManager(), - \OC::$server->getUserSession() + \OC::$server->getUserSession(), + \OC::$server->getConfig() ); $random = \OC::$server->getSecureRandom(); $logger = \OC::$server->getLogger(); diff --git a/apps/dav/lib/Connector/Sabre/AnonymousOptionsPlugin.php b/apps/dav/lib/Connector/Sabre/AnonymousOptionsPlugin.php new file mode 100644 index 00000000000..cefa0d5a19a --- /dev/null +++ b/apps/dav/lib/Connector/Sabre/AnonymousOptionsPlugin.php @@ -0,0 +1,63 @@ +<?php +/** + * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\DAV\Connector\Sabre; + +use Sabre\DAV\CorePlugin; +use Sabre\DAV\FS\Directory; +use Sabre\DAV\ServerPlugin; +use Sabre\DAV\Tree; +use Sabre\HTTP\RequestInterface; +use Sabre\HTTP\ResponseInterface; + +class AnonymousOptionsPlugin extends ServerPlugin { + + /** + * @var \Sabre\DAV\Server + */ + private $server; + + /** + * @param \Sabre\DAV\Server $server + * @return void + */ + public function initialize(\Sabre\DAV\Server $server) { + $this->server = $server; + // before auth + $this->server->on('beforeMethod', [$this, 'handleAnonymousOptions'], 9); + } + + /** + * @throws \Sabre\DAV\Exception\Forbidden + * @return bool + */ + public function handleAnonymousOptions(RequestInterface $request, ResponseInterface $response) { + if ($request->getMethod() === 'OPTIONS' && $request->getPath() === '') { + /** @var CorePlugin $corePlugin */ + $corePlugin = $this->server->getPlugin('core'); + // setup a fake tree for anonymous access + $this->server->tree = new Tree(new Directory('')); + $corePlugin->httpOptions($request, $response); + $this->server->sapi->sendResponse($response); + return false; + } + } +} diff --git a/apps/dav/lib/Connector/Sabre/Principal.php b/apps/dav/lib/Connector/Sabre/Principal.php index b94b093ab50..feba4d04624 100644 --- a/apps/dav/lib/Connector/Sabre/Principal.php +++ b/apps/dav/lib/Connector/Sabre/Principal.php @@ -30,6 +30,7 @@ namespace OCA\DAV\Connector\Sabre; +use OCP\IConfig; use OCP\IGroup; use OCP\IGroupManager; use OCP\IUser; @@ -54,6 +55,9 @@ class Principal implements BackendInterface { /** @var IUserSession */ private $userSession; + /** @var IConfig */ + private $config; + /** @var string */ private $principalPrefix; @@ -65,17 +69,20 @@ class Principal implements BackendInterface { * @param IGroupManager $groupManager * @param IShareManager $shareManager * @param IUserSession $userSession + * @param IConfig $config * @param string $principalPrefix */ public function __construct(IUserManager $userManager, IGroupManager $groupManager, IShareManager $shareManager, IUserSession $userSession, + IConfig $config, $principalPrefix = 'principals/users/') { $this->userManager = $userManager; $this->groupManager = $groupManager; $this->shareManager = $shareManager; $this->userSession = $userSession; + $this->config = $config; $this->principalPrefix = trim($principalPrefix, '/'); $this->hasGroups = ($principalPrefix === 'principals/users/'); } @@ -205,8 +212,10 @@ class Principal implements BackendInterface { protected function searchUserPrincipals(array $searchProperties, $test = 'allof') { $results = []; - // If sharing is disabled, return the empty array - if (!$this->shareManager->shareApiEnabled()) { + // If sharing is disabled (or FreeBusy was disabled on purpose), return the empty array + $shareAPIEnabled = $this->shareManager->shareApiEnabled(); + $disableFreeBusy = $this->config->getAppValue('dav', 'disableFreeBusy', $shareAPIEnabled ? 'no' : 'yes'); + if ($disableFreeBusy === 'yes') { return []; } @@ -289,8 +298,10 @@ class Principal implements BackendInterface { * @return string */ function findByUri($uri, $principalPrefix) { - // If sharing is disabled, return null as in user not found - if (!$this->shareManager->shareApiEnabled()) { + // If sharing is disabled (or FreeBusy was disabled on purpose), return the empty array + $shareAPIEnabled = $this->shareManager->shareApiEnabled(); + $disableFreeBusy = $this->config->getAppValue('dav', 'disableFreeBusy', $shareAPIEnabled ? 'no' : 'yes'); + if ($disableFreeBusy === 'yes') { return null; } diff --git a/apps/dav/lib/Connector/Sabre/ServerFactory.php b/apps/dav/lib/Connector/Sabre/ServerFactory.php index 302e1f52249..12b00be43f5 100644 --- a/apps/dav/lib/Connector/Sabre/ServerFactory.php +++ b/apps/dav/lib/Connector/Sabre/ServerFactory.php @@ -110,6 +110,7 @@ class ServerFactory { // Load plugins $server->addPlugin(new \OCA\DAV\Connector\Sabre\MaintenancePlugin($this->config)); $server->addPlugin(new \OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin($this->config)); + $server->addPlugin(new \OCA\DAV\Connector\Sabre\AnonymousOptionsPlugin()); $server->addPlugin($authPlugin); // 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()); diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php index a39b8716110..b9f381b4b92 100644 --- a/apps/dav/lib/RootCollection.php +++ b/apps/dav/lib/RootCollection.php @@ -51,7 +51,8 @@ class RootCollection extends SimpleCollection { $userManager, $groupManager, $shareManager, - \OC::$server->getUserSession() + \OC::$server->getUserSession(), + $config ); $groupPrincipalBackend = new GroupPrincipalBackend($groupManager); // as soon as debug mode is enabled we allow listing of principals diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php index 82978711156..b9f411ae7ec 100644 --- a/apps/dav/lib/Server.php +++ b/apps/dav/lib/Server.php @@ -52,6 +52,7 @@ use OCA\DAV\DAV\PublicAuth; use OCA\DAV\DAV\CustomPropertiesBackend; use OCA\DAV\Connector\Sabre\QuotaPlugin; use OCA\DAV\Files\BrowserErrorPagePlugin; +use OCA\DAV\Connector\Sabre\AnonymousOptionsPlugin; use OCA\DAV\SystemTag\SystemTagPlugin; use OCA\DAV\Upload\ChunkingPlugin; use OCP\IRequest; @@ -99,6 +100,7 @@ class Server { $this->server->setBaseUri($this->baseUri); $this->server->addPlugin(new BlockLegacyClientPlugin(\OC::$server->getConfig())); + $this->server->addPlugin(new AnonymousOptionsPlugin()); $authPlugin = new Plugin(); $authPlugin->addBackend(new PublicAuth()); $this->server->addPlugin($authPlugin); |