From 0401d6dc0ff33d31982f7aa7e752378d98d82f9d Mon Sep 17 00:00:00 2001 From: Anna Larch Date: Tue, 12 Oct 2021 16:30:00 +0200 Subject: [PATCH] Add create method to extended calendar implementation Signed-off-by: Anna Larch Signed-off-by: Christoph Wurst --- .../composer/composer/autoload_classmap.php | 2 + .../dav/composer/composer/autoload_static.php | 2 + .../lib/CalDAV/Auth/CustomPrincipalPlugin.php | 38 +++++++++++++++++ .../lib/CalDAV/Auth/PublicPrincipalPlugin.php | 37 ++++++++++++++++ apps/dav/lib/CalDAV/CalendarImpl.php | 42 +++++++++++++++++-- .../InvitationResponseServer.php | 17 ++++---- lib/composer/composer/autoload_classmap.php | 2 + lib/composer/composer/autoload_static.php | 2 + .../Calendar/Exceptions/CalendarException.php | 33 +++++++++++++++ lib/public/Calendar/ICreateFromString.php | 41 ++++++++++++++++++ 10 files changed, 206 insertions(+), 10 deletions(-) create mode 100644 apps/dav/lib/CalDAV/Auth/CustomPrincipalPlugin.php create mode 100644 apps/dav/lib/CalDAV/Auth/PublicPrincipalPlugin.php create mode 100644 lib/public/Calendar/Exceptions/CalendarException.php create mode 100644 lib/public/Calendar/ICreateFromString.php diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php index daf2cff31613e..62c41a0828d6f 100644 --- a/apps/dav/composer/composer/autoload_classmap.php +++ b/apps/dav/composer/composer/autoload_classmap.php @@ -33,6 +33,8 @@ 'OCA\\DAV\\CalDAV\\Activity\\Setting\\Calendar' => $baseDir . '/../lib/CalDAV/Activity/Setting/Calendar.php', 'OCA\\DAV\\CalDAV\\Activity\\Setting\\Event' => $baseDir . '/../lib/CalDAV/Activity/Setting/Event.php', 'OCA\\DAV\\CalDAV\\Activity\\Setting\\Todo' => $baseDir . '/../lib/CalDAV/Activity/Setting/Todo.php', + 'OCA\\DAV\\CalDAV\\Auth\\CustomPrincipalPlugin' => $baseDir . '/../lib/CalDAV/Auth/CustomPrincipalPlugin.php', + 'OCA\\DAV\\CalDAV\\Auth\\PublicPrincipalPlugin' => $baseDir . '/../lib/CalDAV/Auth/PublicPrincipalPlugin.php', 'OCA\\DAV\\CalDAV\\BirthdayCalendar\\EnablePlugin' => $baseDir . '/../lib/CalDAV/BirthdayCalendar/EnablePlugin.php', 'OCA\\DAV\\CalDAV\\BirthdayService' => $baseDir . '/../lib/CalDAV/BirthdayService.php', 'OCA\\DAV\\CalDAV\\CachedSubscription' => $baseDir . '/../lib/CalDAV/CachedSubscription.php', diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php index d00299ed047ba..5d5f57eb51b3c 100644 --- a/apps/dav/composer/composer/autoload_static.php +++ b/apps/dav/composer/composer/autoload_static.php @@ -48,6 +48,8 @@ class ComposerStaticInitDAV 'OCA\\DAV\\CalDAV\\Activity\\Setting\\Calendar' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Setting/Calendar.php', 'OCA\\DAV\\CalDAV\\Activity\\Setting\\Event' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Setting/Event.php', 'OCA\\DAV\\CalDAV\\Activity\\Setting\\Todo' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Setting/Todo.php', + 'OCA\\DAV\\CalDAV\\Auth\\CustomPrincipalPlugin' => __DIR__ . '/..' . '/../lib/CalDAV/Auth/CustomPrincipalPlugin.php', + 'OCA\\DAV\\CalDAV\\Auth\\PublicPrincipalPlugin' => __DIR__ . '/..' . '/../lib/CalDAV/Auth/PublicPrincipalPlugin.php', 'OCA\\DAV\\CalDAV\\BirthdayCalendar\\EnablePlugin' => __DIR__ . '/..' . '/../lib/CalDAV/BirthdayCalendar/EnablePlugin.php', 'OCA\\DAV\\CalDAV\\BirthdayService' => __DIR__ . '/..' . '/../lib/CalDAV/BirthdayService.php', 'OCA\\DAV\\CalDAV\\CachedSubscription' => __DIR__ . '/..' . '/../lib/CalDAV/CachedSubscription.php', diff --git a/apps/dav/lib/CalDAV/Auth/CustomPrincipalPlugin.php b/apps/dav/lib/CalDAV/Auth/CustomPrincipalPlugin.php new file mode 100644 index 0000000000000..89e50c7da6bc9 --- /dev/null +++ b/apps/dav/lib/CalDAV/Auth/CustomPrincipalPlugin.php @@ -0,0 +1,38 @@ + + * + * @author Anna Larch + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 library. If not, see . + * + */ + +namespace OCA\DAV\CalDAV\Auth; + +use Sabre\DAV\Auth\Plugin; + +/** + * Set a custom principal uri to allow public requests to its calendar + */ +class CustomPrincipalPlugin extends Plugin { + public function setCurrentPrincipal(?string $currentPrincipal): void { + $this->currentPrincipal = $currentPrincipal; + } +} diff --git a/apps/dav/lib/CalDAV/Auth/PublicPrincipalPlugin.php b/apps/dav/lib/CalDAV/Auth/PublicPrincipalPlugin.php new file mode 100644 index 0000000000000..9666955881808 --- /dev/null +++ b/apps/dav/lib/CalDAV/Auth/PublicPrincipalPlugin.php @@ -0,0 +1,37 @@ + + * + * @author Anna Larch + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 library. If not, see . + * + */ +namespace OCA\DAV\CalDAV\Auth; + +use Sabre\DAV\Auth\Plugin; + +/** + * Defines the public facing principal option + */ +class PublicPrincipalPlugin extends Plugin { + public function getCurrentPrincipal(): ?string { + return 'principals/system/public'; + } +} diff --git a/apps/dav/lib/CalDAV/CalendarImpl.php b/apps/dav/lib/CalDAV/CalendarImpl.php index 356f28000317b..ed37c0a745ddb 100644 --- a/apps/dav/lib/CalDAV/CalendarImpl.php +++ b/apps/dav/lib/CalDAV/CalendarImpl.php @@ -27,10 +27,14 @@ */ namespace OCA\DAV\CalDAV; -use OCP\Calendar\ICalendar; +use OCA\DAV\CalDAV\Auth\CustomPrincipalPlugin; +use OCA\DAV\CalDAV\InvitationResponse\InvitationResponseServer; +use OCP\Calendar\Exceptions\CalendarException; +use OCP\Calendar\ICreateFromString; use OCP\Constants; +use Sabre\DAV\Exception\Conflict; -class CalendarImpl implements ICalendar { +class CalendarImpl implements ICreateFromString { /** @var CalDavBackend */ private $backend; @@ -48,7 +52,8 @@ class CalendarImpl implements ICalendar { * @param array $calendarInfo * @param CalDavBackend $backend */ - public function __construct(Calendar $calendar, array $calendarInfo, + public function __construct(Calendar $calendar, + array $calendarInfo, CalDavBackend $backend) { $this->calendar = $calendar; $this->calendarInfo = $calendarInfo; @@ -120,4 +125,35 @@ public function getPermissions() { return $result; } + + /** + * Create a new calendar event for this calendar + * by way of an ICS string + * + * @param string $name the file name - needs to contan the .ics ending + * @param string $calendarData a string containing a valid VEVENT ics + * + * @throws CalendarException + */ + public function createFromString(string $name, string $calendarData): void { + $server = new InvitationResponseServer(false); + + /** @var CustomPrincipalPlugin $plugin */ + $plugin = $server->server->getPlugin('auth'); + // we're working around the previous implementation + // that only allowed the public system principal to be used + // so set the custom principal here + $plugin->setCurrentPrincipal($this->calendar->getPrincipalURI()); + + $stream = fopen('php://memory', 'rb+'); + fwrite($stream, $calendarData); + rewind($stream); + try { + $server->server->createFile($name, $stream); + } catch (Conflict $e) { + throw new CalendarException('Could not create new calendar event: ' . $e->getMessage(), 0, $e); + } finally { + fclose($stream); + } + } } diff --git a/apps/dav/lib/CalDAV/InvitationResponse/InvitationResponseServer.php b/apps/dav/lib/CalDAV/InvitationResponse/InvitationResponseServer.php index d1ea6902af39a..90e2e478e1ce3 100644 --- a/apps/dav/lib/CalDAV/InvitationResponse/InvitationResponseServer.php +++ b/apps/dav/lib/CalDAV/InvitationResponse/InvitationResponseServer.php @@ -26,6 +26,8 @@ namespace OCA\DAV\CalDAV\InvitationResponse; use OCA\DAV\AppInfo\PluginManager; +use OCA\DAV\CalDAV\Auth\CustomPrincipalPlugin; +use OCA\DAV\CalDAV\Auth\PublicPrincipalPlugin; use OCA\DAV\Connector\Sabre\AnonymousOptionsPlugin; use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin; use OCA\DAV\Connector\Sabre\CachingTree; @@ -33,7 +35,6 @@ use OCA\DAV\Events\SabrePluginAuthInitEvent; use OCA\DAV\RootCollection; use OCP\EventDispatcher\IEventDispatcher; -use Sabre\DAV\Auth\Plugin; use Sabre\VObject\ITip\Message; class InvitationResponseServer { @@ -44,7 +45,7 @@ class InvitationResponseServer { /** * InvitationResponseServer constructor. */ - public function __construct() { + public function __construct(bool $public = true) { $baseUri = \OC::$WEBROOT . '/remote.php/dav/'; $logger = \OC::$server->getLogger(); /** @var IEventDispatcher $dispatcher */ @@ -62,11 +63,13 @@ public function __construct() { $this->server->addPlugin(new BlockLegacyClientPlugin(\OC::$server->getConfig())); $this->server->addPlugin(new AnonymousOptionsPlugin()); - $this->server->addPlugin(new class() extends Plugin { - public function getCurrentPrincipal() { - return 'principals/system/public'; - } - }); + + // allow custom principal uri option + if ($public) { + $this->server->addPlugin(new PublicPrincipalPlugin()); + } else { + $this->server->addPlugin(new CustomPrincipalPlugin()); + } // allow setup of additional auth backends $event = new SabrePluginAuthInitEvent($this->server); diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 353fc22d48698..b67b25b77f8bb 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -116,9 +116,11 @@ 'OCP\\BackgroundJob\\TimedJob' => $baseDir . '/lib/public/BackgroundJob/TimedJob.php', 'OCP\\Broadcast\\Events\\IBroadcastEvent' => $baseDir . '/lib/public/Broadcast/Events/IBroadcastEvent.php', 'OCP\\Calendar\\BackendTemporarilyUnavailableException' => $baseDir . '/lib/public/Calendar/BackendTemporarilyUnavailableException.php', + 'OCP\\Calendar\\Exceptions\\CalendarException' => $baseDir . '/lib/public/Calendar/Exceptions/CalendarException.php', 'OCP\\Calendar\\ICalendar' => $baseDir . '/lib/public/Calendar/ICalendar.php', 'OCP\\Calendar\\ICalendarProvider' => $baseDir . '/lib/public/Calendar/ICalendarProvider.php', 'OCP\\Calendar\\ICalendarQuery' => $baseDir . '/lib/public/Calendar/ICalendarQuery.php', + 'OCP\\Calendar\\ICreateFromString' => $baseDir . '/lib/public/Calendar/ICreateFromString.php', 'OCP\\Calendar\\IManager' => $baseDir . '/lib/public/Calendar/IManager.php', 'OCP\\Calendar\\IMetadataProvider' => $baseDir . '/lib/public/Calendar/IMetadataProvider.php', 'OCP\\Calendar\\Resource\\IBackend' => $baseDir . '/lib/public/Calendar/Resource/IBackend.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index f7c541d8c319d..cf2f6505817ee 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -145,9 +145,11 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OCP\\BackgroundJob\\TimedJob' => __DIR__ . '/../../..' . '/lib/public/BackgroundJob/TimedJob.php', 'OCP\\Broadcast\\Events\\IBroadcastEvent' => __DIR__ . '/../../..' . '/lib/public/Broadcast/Events/IBroadcastEvent.php', 'OCP\\Calendar\\BackendTemporarilyUnavailableException' => __DIR__ . '/../../..' . '/lib/public/Calendar/BackendTemporarilyUnavailableException.php', + 'OCP\\Calendar\\Exceptions\\CalendarException' => __DIR__ . '/../../..' . '/lib/public/Calendar/Exceptions/CalendarException.php', 'OCP\\Calendar\\ICalendar' => __DIR__ . '/../../..' . '/lib/public/Calendar/ICalendar.php', 'OCP\\Calendar\\ICalendarProvider' => __DIR__ . '/../../..' . '/lib/public/Calendar/ICalendarProvider.php', 'OCP\\Calendar\\ICalendarQuery' => __DIR__ . '/../../..' . '/lib/public/Calendar/ICalendarQuery.php', + 'OCP\\Calendar\\ICreateFromString' => __DIR__ . '/../../..' . '/lib/public/Calendar/ICreateFromString.php', 'OCP\\Calendar\\IManager' => __DIR__ . '/../../..' . '/lib/public/Calendar/IManager.php', 'OCP\\Calendar\\IMetadataProvider' => __DIR__ . '/../../..' . '/lib/public/Calendar/IMetadataProvider.php', 'OCP\\Calendar\\Resource\\IBackend' => __DIR__ . '/../../..' . '/lib/public/Calendar/Resource/IBackend.php', diff --git a/lib/public/Calendar/Exceptions/CalendarException.php b/lib/public/Calendar/Exceptions/CalendarException.php new file mode 100644 index 0000000000000..834dd1a234a88 --- /dev/null +++ b/lib/public/Calendar/Exceptions/CalendarException.php @@ -0,0 +1,33 @@ + + * + * @author Anna Larch + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 library. If not, see . + * + */ + +namespace OCP\Calendar\Exceptions; + +use Exception; + +/** + * @since 23.0.0 + */ +class CalendarException extends Exception { +} diff --git a/lib/public/Calendar/ICreateFromString.php b/lib/public/Calendar/ICreateFromString.php new file mode 100644 index 0000000000000..343405e8ab65e --- /dev/null +++ b/lib/public/Calendar/ICreateFromString.php @@ -0,0 +1,41 @@ + + * + * @author Anna Larch + * + * @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 OCP\Calendar; + +use OCP\Calendar\Exceptions\CalendarException; + +/** + * Extends the current ICalendar interface + * to add a public write method + * + * @since 23.0.0 + */ +interface ICreateFromString extends ICalendar { + + /** + * @since 23.0.0 + * + * @throws CalendarException + */ + public function createFromString(string $name, string $calendarData): void; +}