Merge pull request #19852 from nextcloud/dav/provide-dav-setting-for-default-calendar
Provide dav setting for user's default calendar
This commit is contained in:
commit
3ea9dd8487
|
@ -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));
|
||||
|
|
|
@ -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,22 @@ 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);
|
||||
$uri = $event->getArgument('calendarData')['uri'];
|
||||
if ($config->getUserValue($UID, 'dav', 'defaultCalendar') === $uri) {
|
||||
$config->deleteUserValue($UID, 'dav', 'defaultCalendar');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getSyncService() {
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
$this->plugin = new Plugin();
|
||||
$response = $this->getMockBuilder(ResponseInterface::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$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());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue