diff --git a/apps/dav/lib/CalDAV/ICalendarHomePlugin.php b/apps/dav/lib/CalDAV/ICalendarHomePlugin.php new file mode 100644 index 0000000000000..fb551c1487257 --- /dev/null +++ b/apps/dav/lib/CalDAV/ICalendarHomePlugin.php @@ -0,0 +1,44 @@ + + * + * @author Julius Härtl + * + * @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 . + * + */ + +namespace OCA\DAV\CalDAV; + +/** + * Interface that allows a SabreDAV plugin to register a calendar home to be + * returned as calendar-home-set + */ +interface ICalendarHomePlugin { + + /** + * Returns the path to a principal's calendar home. + * + * The return url must not end with a slash. + * This function should return null in case a principal did not have + * a calendar home. + * + * @param string $principalUrl + * @return string|null + */ + public function getCalendarHomeForPrincipal($principalUrl); + +} \ No newline at end of file diff --git a/apps/dav/lib/CalDAV/Plugin.php b/apps/dav/lib/CalDAV/Plugin.php index 647dbb5c58768..495b8c257186d 100644 --- a/apps/dav/lib/CalDAV/Plugin.php +++ b/apps/dav/lib/CalDAV/Plugin.php @@ -1,5 +1,6 @@ * @author Thomas Müller * * @copyright Copyright (c) 2016, ownCloud GmbH. @@ -21,21 +22,69 @@ namespace OCA\DAV\CalDAV; -use Sabre\HTTP\URLUtil; +use Sabre\DAV\Server; +use Sabre\DAV; +use Sabre\DAV\Xml\Property\LocalHref; +use Sabre\DAVACL\IPrincipal; -class Plugin extends \Sabre\CalDAV\Plugin { +class Plugin extends \Sabre\CalDAV\Plugin implements ICalendarHomePlugin { /** - * @inheritdoc + * Initializes the plugin + * + * @param Server $server + * @return void */ - function getCalendarHomeForPrincipal($principalUrl) { + public function initialize(Server $server) { + $this->server = $server; + $server->on('propFind', [$this, 'propFind'], 90); + } + /** + * PropFind + * + * This method handler is invoked before any after properties for a + * resource are fetched. This allows us to add in any CalDAV specific + * properties. + * + * @param DAV\PropFind $propFind + * @param DAV\INode $node + * @return void + */ + public function propFind(DAV\PropFind $propFind, DAV\INode $node) { + if ($node instanceof IPrincipal) { + $principalUrl = $node->getPrincipalUrl(); + $propFind->handle('{' . self::NS_CALDAV . '}calendar-home-set', function () use ($principalUrl) { + $calendarHomes = []; + // Make sure the dav apps caldav endpoint is at the first place + $calendarHomePath = $this->getCalendarHomeForPrincipal($principalUrl); + if ($calendarHomePath !== null) { + $calendarHomes[] = $calendarHomePath; + } + foreach ($this->server->getPlugins() as $plugin) { + if ($plugin instanceof ICalendarHomePlugin && $plugin !== $this) { + $calendarHomePath = $plugin->getCalendarHomeForPrincipal($principalUrl); + if ($calendarHomePath !== null) { + $calendarHomes[] = $calendarHomePath; + } + } + } + return new LocalHref($calendarHomes); + }); + } + } + + /** + * Add the Nextcloud default calendar home + * + * @inheritdoc + */ + public function getCalendarHomeForPrincipal($principalUrl) { if (strrpos($principalUrl, 'principals/users', -strlen($principalUrl)) !== false) { list(, $principalId) = \Sabre\Uri\split($principalUrl); return self::CALENDAR_ROOT .'/' . $principalId; } - - return; + return null; } } diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php index 719e497475505..2fe1b7a9caee6 100644 --- a/apps/dav/lib/Server.php +++ b/apps/dav/lib/Server.php @@ -135,6 +135,7 @@ public function __construct(IRequest $request, $baseUri) { $this->server->addPlugin($acl); // calendar plugins + $this->server->addPlugin(new \Sabre\CalDAV\Plugin()); $this->server->addPlugin(new \OCA\DAV\CalDAV\Plugin()); $this->server->addPlugin(new \Sabre\CalDAV\ICSExportPlugin()); $this->server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin());