Skip to content

Commit 88e5c74

Browse files
fix: aliases and capitalization of emails
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
1 parent 0a73113 commit 88e5c74

9 files changed

Lines changed: 403 additions & 790 deletions

File tree

apps/dav/lib/CalDAV/CalendarImpl.php

Lines changed: 60 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use OCP\Calendar\CalendarExportOptions;
1515
use OCP\Calendar\Exceptions\CalendarException;
1616
use OCP\Calendar\ICalendarExport;
17+
use OCP\Calendar\ICalendarHandleImip;
1718
use OCP\Calendar\ICalendarIsEnabled;
1819
use OCP\Calendar\ICalendarIsShared;
1920
use OCP\Calendar\ICalendarIsWritable;
@@ -30,7 +31,7 @@
3031
use Sabre\VObject\Reader;
3132
use function Sabre\Uri\split as uriSplit;
3233

33-
class CalendarImpl implements ICreateFromString, IHandleImipMessage, ICalendarIsWritable, ICalendarIsShared, ICalendarExport, ICalendarIsEnabled {
34+
class CalendarImpl implements ICreateFromString, IHandleImipMessage, ICalendarIsEnabled, ICalendarIsWritable, ICalendarIsShared, ICalendarHandleImip, ICalendarExport {
3435
public function __construct(
3536
private Calendar $calendar,
3637
/** @var array<string, mixed> */
@@ -211,60 +212,79 @@ public function createFromString(string $name, string $calendarData): void {
211212

212213
/**
213214
* @throws CalendarException
215+
*
216+
* @deprecated 32.0.0 Use handleIMip() instead
214217
*/
215218
public function handleIMipMessage(string $name, string $calendarData): void {
219+
/** @var VCalendar $vObject */
220+
$vObject = Reader::read($calendarData);
221+
$this->handleIMip($vObject);
222+
}
223+
224+
/**
225+
* Processes an iMip message
226+
*
227+
* @since 32.0.0
228+
*
229+
* @throws CalendarException
230+
*/
231+
public function handleIMip(VCalendar $vObject): void {
216232
$server = $this->getInvitationResponseServer();
217233

218-
/** @var CustomPrincipalPlugin $plugin */
219-
$plugin = $server->getServer()->getPlugin('auth');
234+
/** @var CustomPrincipalPlugin $authPlugin */
235+
$authPlugin = $server->getServer()->getPlugin('auth');
220236
// we're working around the previous implementation
221237
// that only allowed the public system principal to be used
222238
// so set the custom principal here
223-
$plugin->setCurrentPrincipal($this->calendar->getPrincipalURI());
239+
$authPlugin->setCurrentPrincipal($this->calendar->getPrincipalURI());
224240

225241
if (empty($this->calendarInfo['uri'])) {
226242
throw new CalendarException('Could not write to calendar as URI parameter is missing');
227243
}
228244
// Force calendar change URI
229-
/** @var Schedule\Plugin $schedulingPlugin */
245+
/** @var \OCA\DAV\CalDAV\Schedule\Plugin $schedulingPlugin */
230246
$schedulingPlugin = $server->getServer()->getPlugin('caldav-schedule');
231-
// Let sabre handle the rest
232-
$iTipMessage = new Message();
233-
/** @var VCalendar $vObject */
234-
$vObject = Reader::read($calendarData);
235-
/** @var VEvent $vEvent */
236-
$vEvent = $vObject->{'VEVENT'};
237-
238-
if ($vObject->{'METHOD'} === null) {
239-
throw new CalendarException('No Method provided for scheduling data. Could not process message');
240-
}
241-
242-
if (!isset($vEvent->{'ORGANIZER'}) || !isset($vEvent->{'ATTENDEE'})) {
243-
throw new CalendarException('Could not process scheduling data, neccessary data missing from ICAL');
244-
}
245-
$organizer = $vEvent->{'ORGANIZER'}->getValue();
246-
$attendee = $vEvent->{'ATTENDEE'}->getValue();
247-
248-
$iTipMessage->method = $vObject->{'METHOD'}->getValue();
249-
if ($iTipMessage->method === 'REQUEST') {
250-
$iTipMessage->sender = $organizer;
251-
$iTipMessage->recipient = $attendee;
252-
} elseif ($iTipMessage->method === 'REPLY') {
253-
if ($server->isExternalAttendee($vEvent->{'ATTENDEE'}->getValue())) {
254-
$iTipMessage->recipient = $organizer;
255-
} else {
256-
$iTipMessage->recipient = $attendee;
247+
// retrieve all uses addresses
248+
$userAddresses = $schedulingPlugin->getAddressesForPrincipal($this->calendar->getPrincipalURI());
249+
$userAddresses = array_map('strtolower', $userAddresses);
250+
// validate the method, recipient and sender
251+
$imipMethod = strtoupper($vObject->METHOD->getValue());
252+
if (in_array($imipMethod, ['REPLY', 'REFRESH'], true)) {
253+
// extract sender (REPLY and REFRESH method should only have one attendee)
254+
$sender = strtolower($vObject->VEVENT->ATTENDEE->getValue());
255+
// extract and verify the recipient
256+
$recipient = strtolower($vObject->VEVENT->ORGANIZER->getValue());
257+
if (!in_array($recipient, $userAddresses, true)) {
258+
throw new CalendarException('iMip message dose not contain an organizer that matches the user');
259+
}
260+
} elseif (in_array($imipMethod, ['PUBLISH', 'REQUEST', 'ADD', 'CANCEL'], true)) {
261+
// extract sender
262+
$sender = strtolower($vObject->VEVENT->ORGANIZER->getValue());
263+
// extract and verify the recipient
264+
foreach ($vObject->VEVENT->ATTENDEE as $attendee) {
265+
$recipient = strtolower($attendee->getValue());
266+
if (in_array($recipient, $userAddresses, true)) {
267+
break;
268+
}
269+
$recipient = null;
270+
}
271+
if ($recipient === null) {
272+
throw new CalendarException('iMip message dose not contain an attendee that matches the user');
257273
}
258-
$iTipMessage->sender = $attendee;
259-
} elseif ($iTipMessage->method === 'CANCEL') {
260-
$iTipMessage->recipient = $attendee;
261-
$iTipMessage->sender = $organizer;
274+
} else {
275+
throw new CalendarException('iMip message contains a method that is not supported: ' . $imipMethod);
262276
}
263-
$iTipMessage->uid = isset($vEvent->{'UID'}) ? $vEvent->{'UID'}->getValue() : '';
264-
$iTipMessage->component = 'VEVENT';
265-
$iTipMessage->sequence = isset($vEvent->{'SEQUENCE'}) ? (int)$vEvent->{'SEQUENCE'}->getValue() : 0;
266-
$iTipMessage->message = $vObject;
267-
$server->server->emit('schedule', [$iTipMessage]);
277+
// generate the iTip message
278+
$iTip = new Message();
279+
$iTip->method = $imipMethod;
280+
$iTip->sender = $sender;
281+
$iTip->recipient = $recipient;
282+
$iTip->component = 'VEVENT';
283+
$iTip->uid = $vObject->VEVENT->UID->getValue();
284+
$iTip->sequence = (int)$vObject->VEVENT->SEQUENCE->getValue() ?? 0;
285+
$iTip->message = $vObject;
286+
287+
$server->server->emit('schedule', [$iTip]);
268288
}
269289

270290
public function getInvitationResponseServer(): InvitationResponseServer {

apps/dav/lib/CalDAV/Schedule/Plugin.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public function propFind(PropFind $propFind, INode $node) {
132132
* @param string $principal
133133
* @return array
134134
*/
135-
protected function getAddressesForPrincipal($principal) {
135+
public function getAddressesForPrincipal($principal) {
136136
$result = parent::getAddressesForPrincipal($principal);
137137

138138
if ($result === null) {

0 commit comments

Comments
 (0)