summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorThomas Citharel <tcit@tcit.fr>2020-03-08 17:33:27 +0100
committerThomas Citharel <tcit@tcit.fr>2020-04-13 15:07:42 +0200
commitebdf66b70619a30fd3f9172c1b725b8f56ea9358 (patch)
tree2e81468128e1ff9a6fe599255b153563507816a2 /apps
parent21d8a2bfc16bef4b813d316b18768947e5416ff8 (diff)
downloadnextcloud-server-ebdf66b70619a30fd3f9172c1b725b8f56ea9358.tar.gz
nextcloud-server-ebdf66b70619a30fd3f9172c1b725b8f56ea9358.zip
Provide dav setting for user's default calendar
And add tests to handle schedule-default-calendar-URL Signed-off-by: Thomas Citharel <tcit@tcit.fr>
Diffstat (limited to 'apps')
-rw-r--r--apps/dav/appinfo/v1/caldav.php2
-rw-r--r--apps/dav/lib/AppInfo/Application.php14
-rw-r--r--apps/dav/lib/CalDAV/InvitationResponse/InvitationResponseServer.php2
-rw-r--r--apps/dav/lib/CalDAV/Schedule/Plugin.php37
-rw-r--r--apps/dav/lib/Server.php2
-rw-r--r--apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php223
6 files changed, 265 insertions, 15 deletions
diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php
index 82fddd152e6..29733a3a623 100644
--- a/apps/dav/appinfo/v1/caldav.php
+++ b/apps/dav/appinfo/v1/caldav.php
@@ -92,7 +92,7 @@ if ($debugging) {
$server->addPlugin(new \Sabre\DAV\Sync\Plugin());
$server->addPlugin(new \Sabre\CalDAV\ICSExportPlugin());
-$server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin());
+$server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin(\OC::$server->getConfig()));
if ($sendInvitations) {
$server->addPlugin(\OC::$server->query(\OCA\DAV\CalDAV\Schedule\IMipPlugin::class));
diff --git a/apps/dav/lib/AppInfo/Application.php b/apps/dav/lib/AppInfo/Application.php
index 29c77cad07f..c22afa755cb 100644
--- a/apps/dav/lib/AppInfo/Application.php
+++ b/apps/dav/lib/AppInfo/Application.php
@@ -49,6 +49,7 @@ use OCA\DAV\HookManager;
use OCP\AppFramework\App;
use OCP\Calendar\IManager as ICalendarManager;
use OCP\Contacts\IManager as IContactsManager;
+use OCP\IConfig;
use OCP\IUser;
use Symfony\Component\EventDispatcher\GenericEvent;
@@ -244,6 +245,19 @@ class Application extends App {
$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject', $listener);
$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject', $listener);
$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject', $listener);
+
+ /**
+ * In case the user has set their default calendar to this one
+ */
+ $dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar', function (GenericEvent $event) {
+ /** @var IConfig $config */
+ $config = $this->getContainer()->getServer()->getConfig();
+ $principalUri = $event->getArgument('calendarData')['principaluri'];
+ if (strpos($principalUri, 'principals/users') === 0) {
+ list(, $UID) = \Sabre\Uri\split($principalUri);
+ $config->deleteUserValue($UID, 'dav', 'defaultCalendar');
+ }
+ });
}
public function getSyncService() {
diff --git a/apps/dav/lib/CalDAV/InvitationResponse/InvitationResponseServer.php b/apps/dav/lib/CalDAV/InvitationResponse/InvitationResponseServer.php
index e285bbc378c..ce8d0542eaf 100644
--- a/apps/dav/lib/CalDAV/InvitationResponse/InvitationResponseServer.php
+++ b/apps/dav/lib/CalDAV/InvitationResponse/InvitationResponseServer.php
@@ -84,7 +84,7 @@ class InvitationResponseServer {
// calendar plugins
$this->server->addPlugin(new \OCA\DAV\CalDAV\Plugin());
$this->server->addPlugin(new \Sabre\CalDAV\ICSExportPlugin());
- $this->server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin());
+ $this->server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin(\OC::$server->getConfig()));
$this->server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin());
$this->server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin());
//$this->server->addPlugin(new \OCA\DAV\DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest()));
diff --git a/apps/dav/lib/CalDAV/Schedule/Plugin.php b/apps/dav/lib/CalDAV/Schedule/Plugin.php
index 3b2f0374b46..9c5968a333c 100644
--- a/apps/dav/lib/CalDAV/Schedule/Plugin.php
+++ b/apps/dav/lib/CalDAV/Schedule/Plugin.php
@@ -29,6 +29,7 @@ namespace OCA\DAV\CalDAV\Schedule;
use DateTimeZone;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\CalendarHome;
+use OCP\IConfig;
use Sabre\CalDAV\ICalendar;
use Sabre\DAV\INode;
use Sabre\DAV\IProperties;
@@ -47,15 +48,31 @@ use Sabre\VObject\ITip;
use Sabre\VObject\Parameter;
use Sabre\VObject\Property;
use Sabre\VObject\Reader;
+use function \Sabre\Uri\split;
class Plugin extends \Sabre\CalDAV\Schedule\Plugin {
+ /**
+ * @var IConfig
+ */
+ private $config;
+
/** @var ITip\Message[] */
private $schedulingResponses = [];
/** @var string|null */
private $pathOfCalendarObjectChange = null;
+ public const CALENDAR_USER_TYPE = '{' . self::NS_CALDAV . '}calendar-user-type';
+ public const SCHEDULE_DEFAULT_CALENDAR_URL = '{' . Plugin::NS_CALDAV . '}schedule-default-calendar-URL';
+
+ /**
+ * @param IConfig $config
+ */
+ public function __construct(IConfig $config) {
+ $this->config = $config;
+ }
+
/**
* Initializes the plugin
*
@@ -81,13 +98,12 @@ class Plugin extends \Sabre\CalDAV\Schedule\Plugin {
public function propFind(PropFind $propFind, INode $node) {
if ($node instanceof IPrincipal) {
// overwrite Sabre/Dav's implementation
- $propFind->handle('{' . self::NS_CALDAV . '}calendar-user-type', function () use ($node) {
+ $propFind->handle(self::CALENDAR_USER_TYPE, function () use ($node) {
if ($node instanceof IProperties) {
- $calendarUserType = '{' . self::NS_CALDAV . '}calendar-user-type';
- $props = $node->getProperties([$calendarUserType]);
+ $props = $node->getProperties([self::CALENDAR_USER_TYPE]);
- if (isset($props[$calendarUserType])) {
- return $props[$calendarUserType];
+ if (isset($props[self::CALENDAR_USER_TYPE])) {
+ return $props[self::CALENDAR_USER_TYPE];
}
}
@@ -261,7 +277,7 @@ EOF;
*/
public function propFindDefaultCalendarUrl(PropFind $propFind, INode $node) {
if ($node instanceof IPrincipal) {
- $propFind->handle('{' . self::NS_CALDAV . '}schedule-default-calendar-URL', function () use ($node) {
+ $propFind->handle(self::SCHEDULE_DEFAULT_CALENDAR_URL, function () use ($node) {
/** @var \OCA\DAV\CalDAV\Plugin $caldavPlugin */
$caldavPlugin = $this->server->getPlugin('caldav');
$principalUrl = $node->getPrincipalUrl();
@@ -272,12 +288,13 @@ EOF;
}
if (strpos($principalUrl, 'principals/users') === 0) {
- $uri = CalDavBackend::PERSONAL_CALENDAR_URI;
- $displayname = CalDavBackend::PERSONAL_CALENDAR_NAME;
+ list(, $userId) = split($principalUrl);
+ $uri = $this->config->getUserValue($userId, 'dav', 'defaultCalendar', CalDavBackend::PERSONAL_CALENDAR_URI);
+ $displayName = CalDavBackend::PERSONAL_CALENDAR_NAME;
} elseif (strpos($principalUrl, 'principals/calendar-resources') === 0 ||
strpos($principalUrl, 'principals/calendar-rooms') === 0) {
$uri = CalDavBackend::RESOURCE_BOOKING_CALENDAR_URI;
- $displayname = CalDavBackend::RESOURCE_BOOKING_CALENDAR_NAME;
+ $displayName = CalDavBackend::RESOURCE_BOOKING_CALENDAR_NAME;
} else {
// How did we end up here?
// TODO - throw exception or just ignore?
@@ -288,7 +305,7 @@ EOF;
$calendarHome = $this->server->tree->getNodeForPath($calendarHomePath);
if (!$calendarHome->childExists($uri)) {
$calendarHome->getCalDAVBackend()->createCalendar($principalUrl, $uri, [
- '{DAV:}displayname' => $displayname,
+ '{DAV:}displayname' => $displayName,
]);
}
diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php
index b71c16e2319..9d120ddbdbf 100644
--- a/apps/dav/lib/Server.php
+++ b/apps/dav/lib/Server.php
@@ -151,7 +151,7 @@ class Server {
if ($this->requestIsForSubtree(['calendars', 'public-calendars', 'system-calendars', 'principals'])) {
$this->server->addPlugin(new \OCA\DAV\CalDAV\Plugin());
$this->server->addPlugin(new \OCA\DAV\CalDAV\ICSExportPlugin\ICSExportPlugin(\OC::$server->getConfig(), \OC::$server->getLogger()));
- $this->server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin());
+ $this->server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin(\OC::$server->getConfig()));
if (\OC::$server->getConfig()->getAppValue('dav', 'sendInvitations', 'yes') === 'yes') {
$this->server->addPlugin(\OC::$server->query(\OCA\DAV\CalDAV\Schedule\IMipPlugin::class));
}
diff --git a/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php b/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php
index 859dccbe489..aa245b71419 100644
--- a/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php
+++ b/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php
@@ -25,28 +25,68 @@
namespace OCA\DAV\Tests\unit\CalDAV\Schedule;
+use OCA\DAV\CalDAV\CalDavBackend;
+use OCA\DAV\CalDAV\CalendarHome;
+use OCA\DAV\CalDAV\Plugin as CalDAVPlugin;
use OCA\DAV\CalDAV\Schedule\Plugin;
+use OCP\IConfig;
+use PHPUnit\Framework\MockObject\MockObject;
+use Sabre\DAV\PropFind;
use Sabre\DAV\Server;
+use Sabre\DAV\Tree;
use Sabre\DAV\Xml\Property\Href;
+use Sabre\DAV\Xml\Property\LocalHref;
+use Sabre\DAVACL\IPrincipal;
+use Sabre\HTTP\ResponseInterface;
use Sabre\VObject\Parameter;
use Sabre\VObject\Property\ICalendar\CalAddress;
+use Sabre\Xml\Service;
use Test\TestCase;
class PluginTest extends TestCase {
/** @var Plugin */
private $plugin;
- /** @var Server|\PHPUnit_Framework_MockObject_MockObject */
+ /** @var Server|MockObject */
private $server;
+ /** @var IConfig|MockObject */
+ private $config;
+
protected function setUp(): void {
parent::setUp();
$this->server = $this->createMock(Server::class);
+ $this->config = $this->createMock(IConfig::class);
+
+ $response = $this->getMockBuilder(ResponseInterface::class)
+ ->disableOriginalConstructor()
+ ->getMock();
- $this->plugin = new Plugin();
+ $this->server->httpResponse = $response;
+ $this->server->xml = new Service();
+
+ $this->plugin = new Plugin($this->config);
$this->plugin->initialize($this->server);
}
+ public function testInitialize() {
+ $plugin = new Plugin($this->config);
+
+ $this->server->expects($this->at(7))
+ ->method('on')
+ ->with('propFind', [$plugin, 'propFindDefaultCalendarUrl'], 90);
+
+ $this->server->expects($this->at(8))
+ ->method('on')
+ ->with('afterWriteContent', [$plugin, 'dispatchSchedulingResponses']);
+
+ $this->server->expects($this->at(9))
+ ->method('on')
+ ->with('afterCreateFile', [$plugin, 'dispatchSchedulingResponses']);
+
+ $plugin->initialize($this->server);
+ }
+
public function testGetAddressesForPrincipal() {
$href = $this->createMock(Href::class);
$href
@@ -125,4 +165,183 @@ class PluginTest extends TestCase {
$this->assertFalse($this->invokePrivate($this->plugin, 'getAttendeeRSVP', [$property2]));
$this->assertFalse($this->invokePrivate($this->plugin, 'getAttendeeRSVP', [$property3]));
}
+
+ public function propFindDefaultCalendarUrlProvider(): array {
+ return [
+ [
+ 'principals/users/myuser',
+ 'calendars/myuser',
+ false,
+ CalDavBackend::PERSONAL_CALENDAR_URI,
+ CalDavBackend::PERSONAL_CALENDAR_NAME,
+ true
+ ],
+ [
+ 'principals/users/myuser',
+ 'calendars/myuser',
+ false,
+ CalDavBackend::PERSONAL_CALENDAR_URI,
+ CalDavBackend::PERSONAL_CALENDAR_NAME,
+ false
+ ],
+ [
+ 'principals/users/myuser',
+ null,
+ false,
+ CalDavBackend::PERSONAL_CALENDAR_URI,
+ CalDavBackend::PERSONAL_CALENDAR_NAME,
+ true
+ ],
+ [
+ 'principals/users/myuser',
+ 'calendars/myuser',
+ false,
+ CalDavBackend::PERSONAL_CALENDAR_URI,
+ CalDavBackend::PERSONAL_CALENDAR_NAME,
+ true,
+ false,
+ ],
+ [
+ 'principals/users/myuser',
+ 'calendars/myuser',
+ false,
+ 'my_other_calendar',
+ 'My Other Calendar',
+ true
+ ],
+ [
+ 'principals/calendar-resources',
+ 'system-calendars/calendar-resources/myuser',
+ true,
+ CalDavBackend::RESOURCE_BOOKING_CALENDAR_URI,
+ CalDavBackend::RESOURCE_BOOKING_CALENDAR_NAME,
+ true
+ ],
+ [
+ 'principals/calendar-resources',
+ 'system-calendars/calendar-resources/myuser',
+ true,
+ CalDavBackend::RESOURCE_BOOKING_CALENDAR_URI,
+ CalDavBackend::RESOURCE_BOOKING_CALENDAR_NAME,
+ false
+ ],
+ [
+ 'principals/something-else',
+ 'calendars/whatever',
+ false,
+ CalDavBackend::PERSONAL_CALENDAR_URI,
+ CalDavBackend::PERSONAL_CALENDAR_NAME,
+ true
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider propFindDefaultCalendarUrlProvider
+ * @param string $principalUri
+ * @param string $calendarHome
+ * @param bool $isResource
+ * @param string $calendarUri
+ * @param string $displayName
+ * @param bool $exists
+ * @param bool $propertiesForPath
+ */
+ public function testPropFindDefaultCalendarUrl(string $principalUri, ?string $calendarHome, bool $isResource, string $calendarUri, string $displayName, bool $exists, bool $propertiesForPath = true) {
+ /** @var PropFind $propFind */
+ $propFind = new PropFind(
+ $principalUri,
+ [
+ Plugin::SCHEDULE_DEFAULT_CALENDAR_URL
+ ],
+ 0
+ );
+ /** @var IPrincipal|MockObject $node */
+ $node = $this->getMockBuilder(IPrincipal::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $node->expects($this->once())
+ ->method('getPrincipalUrl')
+ ->with()
+ ->willReturn($principalUri);
+
+ $calDAVPlugin = $this->getMockBuilder(CalDAVPlugin::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $calDAVPlugin->expects($this->once())
+ ->method('getCalendarHomeForPrincipal')
+ ->willReturn($calendarHome);
+
+ $this->server->expects($this->once())
+ ->method('getPlugin')
+ ->with('caldav')
+ ->willReturn($calDAVPlugin);
+ if (!$calendarHome) {
+ $this->plugin->propFindDefaultCalendarUrl($propFind, $node);
+
+ $this->assertNull($propFind->get(Plugin::SCHEDULE_DEFAULT_CALENDAR_URL));
+ return;
+ }
+ if ($principalUri === 'principals/something-else') {
+ $this->plugin->propFindDefaultCalendarUrl($propFind, $node);
+
+ $this->assertNull($propFind->get(Plugin::SCHEDULE_DEFAULT_CALENDAR_URL));
+ return;
+ }
+ if (!$isResource) {
+ $this->config->expects($this->once())
+ ->method('getUserValue')
+ ->with('myuser', 'dav', 'defaultCalendar', CalDavBackend::PERSONAL_CALENDAR_URI)
+ ->willReturn($calendarUri);
+ }
+
+ $calendarHomeObject = $this->createMock(CalendarHome::class);
+ $calendarHomeObject->expects($this->once())
+ ->method('childExists')
+ ->with($calendarUri)
+ ->willReturn($exists);
+
+ if (!$exists) {
+ $calendarBackend = $this->createMock(CalDavBackend::class);
+ $calendarBackend->expects($this->once())
+ ->method('createCalendar')
+ ->with($principalUri, $calendarUri, [
+ '{DAV:}displayname' => $displayName,
+ ]);
+
+ $calendarHomeObject->expects($this->once())
+ ->method('getCalDAVBackend')
+ ->with()
+ ->willReturn($calendarBackend);
+ }
+
+ /** @var Tree|MockObject $tree */
+ $tree = $this->createMock(Tree::class);
+ $tree->expects($this->once())
+ ->method('getNodeForPath')
+ ->with($calendarHome)
+ ->willReturn($calendarHomeObject);
+ $this->server->tree = $tree;
+
+ $properties = $propertiesForPath ? [
+ ['href' => '/remote.php/dav/' . $calendarHome . '/' . $calendarUri]
+ ] : [];
+
+ $this->server->expects($this->once())
+ ->method('getPropertiesForPath')
+ ->with($calendarHome .'/' . $calendarUri, [], 1)
+ ->willReturn($properties);
+
+ $this->plugin->propFindDefaultCalendarUrl($propFind, $node);
+
+ if (!$propertiesForPath) {
+ $this->assertNull($propFind->get(Plugin::SCHEDULE_DEFAULT_CALENDAR_URL));
+ return;
+ }
+
+ /** @var LocalHref $result */
+ $result = $propFind->get(Plugin::SCHEDULE_DEFAULT_CALENDAR_URL);
+ $this->assertEquals('/remote.php/dav/'. $calendarHome . '/' . $calendarUri, $result->getHref());
+ }
}