From 9f4569950a0c7375b4fef7a366748110097579ad Mon Sep 17 00:00:00 2001 From: Hamza Mahjoubi Date: Fri, 28 Feb 2025 12:12:39 +0100 Subject: [PATCH] fix(imip): dont propagate attendee changes in reply message Signed-off-by: Hamza Mahjoubi --- apps/dav/lib/CalDAV/CalDavBackend.php | 17 +++++++++ apps/dav/lib/CalDAV/Schedule/IMipPlugin.php | 3 +- apps/dav/lib/CalDAV/Schedule/IMipService.php | 38 +++++++++++++++++++- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 0c8b52a7491c7..346eb598bbc4a 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -3591,4 +3591,21 @@ protected function purgeObjectInvitations(string $eventId): void { ->where($cmd->expr()->eq('uid', $cmd->createNamedParameter($eventId, IQueryBuilder::PARAM_STR), IQueryBuilder::PARAM_STR)); $cmd->executeStatement(); } + + public function findEventDataByUri(string $uid, string $organizerUri): ?array { + $principalUri = $this->principalBackend->findByUri($organizerUri, 'principals/users'); + $query = $this->db->getQueryBuilder(); + $query->select('co.*') + ->from('calendarobjects', 'co') + ->join('co', 'calendars', 'c', $query->expr()->eq('co.calendarid', 'c.id')) + ->where($query->expr()->eq('co.uid', $query->createNamedParameter($uid))) + ->andWhere($query->expr()->eq('c.principaluri', $query->createNamedParameter($principalUri))); + $stmt = $query->executeQuery(); + $row = $stmt->fetch(); + $stmt->closeCursor(); + if (!$row) { + return null; + } + return $this->rowToCalendarObject($row); + } } diff --git a/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php b/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php index 0aecb18ce8092..aff10a6317981 100644 --- a/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php +++ b/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php @@ -185,7 +185,8 @@ public function schedule(Message $iTipMessage) { switch (strtolower($iTipMessage->method)) { case self::METHOD_REPLY: $method = self::METHOD_REPLY; - $data = $this->imipService->buildBodyData($vEvent, $oldVevent); + $organizerEvent = $this->imipService->getOrganizerVEvent($vEvent->uid, $iTipMessage->recipient); + $data = $this->imipService->buildReplyBodyData($organizerEvent); $replyingAttendee = $this->imipService->getReplyingAttendee($iTipMessage); break; case self::METHOD_CANCEL: diff --git a/apps/dav/lib/CalDAV/Schedule/IMipService.php b/apps/dav/lib/CalDAV/Schedule/IMipService.php index e2844960a231c..97894edeedf59 100644 --- a/apps/dav/lib/CalDAV/Schedule/IMipService.php +++ b/apps/dav/lib/CalDAV/Schedule/IMipService.php @@ -9,6 +9,7 @@ namespace OCA\DAV\CalDAV\Schedule; use OC\URLGenerator; +use OCA\DAV\CalDAV\CaldavBackend; use OCA\DAV\CalDAV\EventReader; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IConfig; @@ -23,6 +24,7 @@ use Sabre\VObject\ITip\Message; use Sabre\VObject\Parameter; use Sabre\VObject\Property; +use Sabre\VObject\Reader; use Sabre\VObject\Recur\EventIterator; class IMipService { @@ -44,6 +46,7 @@ public function __construct( private ISecureRandom $random, private L10NFactory $l10nFactory, private ITimeFactory $timeFactory, + private CaldavBackend $caldavBackend, ) { $language = $this->l10nFactory->findGenericLanguage(); $locale = $this->l10nFactory->findLocale($language); @@ -159,7 +162,35 @@ public function buildBodyData(VEvent $vEvent, ?VEvent $oldVEvent): array { if ($eventReaderCurrent->recurs()) { $data['meeting_occurring'] = $this->generateOccurringString($eventReaderCurrent); } - + return $data; + } + + /** + * @param VEvent $vEvent + * @return array + */ + public function buildReplyBodyData(VEvent $vEvent): array { + // construct event reader + $eventReader = new EventReader($vEvent); + $defaultVal = ''; + $data = []; + $data['meeting_when'] = $this->generateWhenString($eventReader); + + foreach (self::STRING_DIFF as $key => $property) { + $data[$key] = self::readPropertyWithDefault($vEvent, $property, $defaultVal); + } + + if (($locationHtml = $this->linkify($data['meeting_location'])) !== null) { + $data['meeting_location_html'] = $locationHtml; + } + + $data['meeting_url_html'] = $data['meeting_url'] ? sprintf('%1$s', $data['meeting_url']) : ''; + + // generate occurring next string + if ($eventReader->recurs()) { + $data['meeting_occurring'] = $this->generateOccurringString($eventReader); + } + return $data; } @@ -1142,6 +1173,11 @@ public function getReplyingAttendee(Message $iTipMessage): ?Property { return null; } + public function getOrganizerVEvent(string $uid, string $organizerUri): VEvent { + $organizerEvent = $this->caldavBackend->findEventDataByUri($uid, $organizerUri); + return Reader::read($organizerEvent['calendardata'])->VEVENT ; + } + public function isRoomOrResource(Property $attendee): bool { $cuType = $attendee->offsetGet('CUTYPE'); if (!$cuType instanceof Parameter) {