|
|
|
@ -36,11 +36,14 @@ use OCA\DAV\CalDAV\CalendarHome;
|
|
|
|
|
use OCP\IConfig;
|
|
|
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
|
use Sabre\CalDAV\ICalendar;
|
|
|
|
|
use Sabre\CalDAV\ICalendarObject;
|
|
|
|
|
use Sabre\CalDAV\Schedule\ISchedulingObject;
|
|
|
|
|
use Sabre\DAV\INode;
|
|
|
|
|
use Sabre\DAV\IProperties;
|
|
|
|
|
use Sabre\DAV\PropFind;
|
|
|
|
|
use Sabre\DAV\Server;
|
|
|
|
|
use Sabre\DAV\Xml\Property\LocalHref;
|
|
|
|
|
use Sabre\DAVACL\IACL;
|
|
|
|
|
use Sabre\DAVACL\IPrincipal;
|
|
|
|
|
use Sabre\HTTP\RequestInterface;
|
|
|
|
|
use Sabre\HTTP\ResponseInterface;
|
|
|
|
@ -50,6 +53,7 @@ use Sabre\VObject\Component\VEvent;
|
|
|
|
|
use Sabre\VObject\DateTimeParser;
|
|
|
|
|
use Sabre\VObject\FreeBusyGenerator;
|
|
|
|
|
use Sabre\VObject\ITip;
|
|
|
|
|
use Sabre\VObject\ITip\SameOrganizerForAllComponentsException;
|
|
|
|
|
use Sabre\VObject\Parameter;
|
|
|
|
|
use Sabre\VObject\Property;
|
|
|
|
|
use Sabre\VObject\Reader;
|
|
|
|
@ -161,7 +165,29 @@ class Plugin extends \Sabre\CalDAV\Schedule\Plugin {
|
|
|
|
|
$this->pathOfCalendarObjectChange = $request->getPath();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
parent::calendarObjectChange($request, $response, $vCal, $calendarPath, $modified, $isNew);
|
|
|
|
|
try {
|
|
|
|
|
parent::calendarObjectChange($request, $response, $vCal, $calendarPath, $modified, $isNew);
|
|
|
|
|
} catch (SameOrganizerForAllComponentsException $e) {
|
|
|
|
|
$this->handleSameOrganizerException($e, $vCal, $calendarPath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @inheritDoc
|
|
|
|
|
*/
|
|
|
|
|
public function beforeUnbind($path): void {
|
|
|
|
|
try {
|
|
|
|
|
parent::beforeUnbind($path);
|
|
|
|
|
} catch (SameOrganizerForAllComponentsException $e) {
|
|
|
|
|
$node = $this->server->tree->getNodeForPath($path);
|
|
|
|
|
if (!$node instanceof ICalendarObject || $node instanceof ISchedulingObject) {
|
|
|
|
|
throw $e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @var VCalendar $vCal */
|
|
|
|
|
$vCal = Reader::read($node->get());
|
|
|
|
|
$this->handleSameOrganizerException($e, $vCal, $path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -630,4 +656,44 @@ EOF;
|
|
|
|
|
'{DAV:}displayname' => $displayName,
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Try to handle the given exception gracefully or throw it if necessary.
|
|
|
|
|
*
|
|
|
|
|
* @throws SameOrganizerForAllComponentsException If the exception should not be ignored
|
|
|
|
|
*/
|
|
|
|
|
private function handleSameOrganizerException(
|
|
|
|
|
SameOrganizerForAllComponentsException $e,
|
|
|
|
|
VCalendar $vCal,
|
|
|
|
|
string $calendarPath,
|
|
|
|
|
): void {
|
|
|
|
|
// This is very hacky! However, we want to allow saving events with multiple
|
|
|
|
|
// organizers. Those events are not RFC compliant, but sometimes imported from major
|
|
|
|
|
// external calendar services (e.g. Google). If the current user is not an organizer of
|
|
|
|
|
// the event we ignore the exception as no scheduling messages will be sent anyway.
|
|
|
|
|
|
|
|
|
|
// It would be cleaner to patch Sabre to validate organizers *after* checking if
|
|
|
|
|
// scheduling messages are necessary. Currently, organizers are validated first and
|
|
|
|
|
// afterwards the broker checks if messages should be scheduled. So the code will throw
|
|
|
|
|
// even if the organizers are not relevant. This is to ensure compliance with RFCs but
|
|
|
|
|
// a bit too strict for real world usage.
|
|
|
|
|
|
|
|
|
|
if (!isset($vCal->VEVENT)) {
|
|
|
|
|
throw $e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$calendarNode = $this->server->tree->getNodeForPath($calendarPath);
|
|
|
|
|
if (!($calendarNode instanceof IACL)) {
|
|
|
|
|
// Should always be an instance of IACL but just to be sure
|
|
|
|
|
throw $e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$addresses = $this->getAddressesForPrincipal($calendarNode->getOwner());
|
|
|
|
|
foreach ($vCal->VEVENT as $vevent) {
|
|
|
|
|
if (in_array($vevent->ORGANIZER->getNormalizedValue(), $addresses, true)) {
|
|
|
|
|
// User is an organizer => throw the exception
|
|
|
|
|
throw $e;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|