Skip to content

Commit 64bdf08

Browse files
committed
fix(caldav): event links in shared calendar notifications
Signed-off-by: Richard Steinmetz <[email protected]>
1 parent cef6d50 commit 64bdf08

File tree

2 files changed

+55
-12
lines changed

2 files changed

+55
-12
lines changed

apps/dav/lib/CalDAV/Activity/Provider/Event.php

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public function __construct(IFactory $languageFactory, IURLGenerator $url, IMana
6060
* @param array $eventData
6161
* @return array
6262
*/
63-
protected function generateObjectParameter(array $eventData) {
63+
protected function generateObjectParameter(array $eventData, string $affectedUser) {
6464
if (!isset($eventData['id']) || !isset($eventData['name'])) {
6565
throw new \InvalidArgumentException();
6666
}
@@ -76,7 +76,15 @@ protected function generateObjectParameter(array $eventData) {
7676
// The calendar app needs to be manually loaded for the routes to be loaded
7777
OC_App::loadApp('calendar');
7878
$linkData = $eventData['link'];
79-
$objectId = base64_encode($this->url->getWebroot() . '/remote.php/dav/calendars/' . $linkData['owner'] . '/' . $linkData['calendar_uri'] . '/' . $linkData['object_uri']);
79+
if ($affectedUser === $linkData['owner']) {
80+
$objectId = base64_encode($this->url->getWebroot() . '/remote.php/dav/calendars/' . $linkData['owner'] . '/' . $linkData['calendar_uri'] . '/' . $linkData['object_uri']);
81+
} else {
82+
// Can't use the "real" owner and calendar names here because we create a custom
83+
// calendar for incoming shares with the name "<calendar>_shared_by_<sharer>".
84+
// Hack: Fix the link by generating it for the incoming shared calendar instead,
85+
// as seen from the affected user.
86+
$objectId = base64_encode($this->url->getWebroot() . '/remote.php/dav/calendars/' . $affectedUser . '/' . $linkData['calendar_uri'] . '_shared_by_' . $linkData['owner'] . '/' . $linkData['object_uri']);
87+
}
8088
$link = [
8189
'view' => 'dayGridMonth',
8290
'timeRange' => 'now',
@@ -168,7 +176,7 @@ protected function getParameters(IEvent $event) {
168176
return [
169177
'actor' => $this->generateUserParameter($parameters['actor']),
170178
'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
171-
'event' => $this->generateClassifiedObjectParameter($parameters['object']),
179+
'event' => $this->generateClassifiedObjectParameter($parameters['object'], $event->getAffectedUser()),
172180
];
173181
case self::SUBJECT_OBJECT_ADD . '_event_self':
174182
case self::SUBJECT_OBJECT_DELETE . '_event_self':
@@ -177,7 +185,7 @@ protected function getParameters(IEvent $event) {
177185
case self::SUBJECT_OBJECT_RESTORE . '_event_self':
178186
return [
179187
'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
180-
'event' => $this->generateClassifiedObjectParameter($parameters['object']),
188+
'event' => $this->generateClassifiedObjectParameter($parameters['object'], $event->getAffectedUser()),
181189
];
182190
}
183191
}
@@ -189,13 +197,13 @@ protected function getParameters(IEvent $event) {
189197
'actor' => $this->generateUserParameter($parameters['actor']),
190198
'sourceCalendar' => $this->generateCalendarParameter($parameters['sourceCalendar'], $this->l),
191199
'targetCalendar' => $this->generateCalendarParameter($parameters['targetCalendar'], $this->l),
192-
'event' => $this->generateClassifiedObjectParameter($parameters['object']),
200+
'event' => $this->generateClassifiedObjectParameter($parameters['object'], $event->getAffectedUser()),
193201
];
194202
case self::SUBJECT_OBJECT_MOVE . '_event_self':
195203
return [
196204
'sourceCalendar' => $this->generateCalendarParameter($parameters['sourceCalendar'], $this->l),
197205
'targetCalendar' => $this->generateCalendarParameter($parameters['targetCalendar'], $this->l),
198-
'event' => $this->generateClassifiedObjectParameter($parameters['object']),
206+
'event' => $this->generateClassifiedObjectParameter($parameters['object'], $event->getAffectedUser()),
199207
];
200208
}
201209
}
@@ -212,22 +220,22 @@ protected function getParameters(IEvent $event) {
212220
return [
213221
'actor' => $this->generateUserParameter($parameters[0]),
214222
'calendar' => $this->generateLegacyCalendarParameter($event->getObjectId(), $parameters[1]),
215-
'event' => $this->generateObjectParameter($parameters[2]),
223+
'event' => $this->generateObjectParameter($parameters[2], $event->getAffectedUser()),
216224
];
217225
case self::SUBJECT_OBJECT_ADD . '_event_self':
218226
case self::SUBJECT_OBJECT_DELETE . '_event_self':
219227
case self::SUBJECT_OBJECT_UPDATE . '_event_self':
220228
return [
221229
'calendar' => $this->generateLegacyCalendarParameter($event->getObjectId(), $parameters[1]),
222-
'event' => $this->generateObjectParameter($parameters[2]),
230+
'event' => $this->generateObjectParameter($parameters[2], $event->getAffectedUser()),
223231
];
224232
}
225233

226234
throw new \InvalidArgumentException();
227235
}
228236

229-
private function generateClassifiedObjectParameter(array $eventData) {
230-
$parameter = $this->generateObjectParameter($eventData);
237+
private function generateClassifiedObjectParameter(array $eventData, string $affectedUser) {
238+
$parameter = $this->generateObjectParameter($eventData, $affectedUser);
231239
if (!empty($eventData['classified'])) {
232240
$parameter['name'] = $this->l->t('Busy');
233241
}

apps/dav/tests/unit/CalDAV/Activity/Provider/EventTest.php

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ public function dataGenerateObjectParameter() {
9191
* @param bool $calendarAppEnabled
9292
*/
9393
public function testGenerateObjectParameter(int $id, string $name, ?array $link, bool $calendarAppEnabled = true): void {
94+
$affectedUser = 'otheruser';
9495
if ($link) {
96+
$affectedUser = $link['owner'];
9597
$generatedLink = [
9698
'view' => 'dayGridMonth',
9799
'timeRange' => 'now',
@@ -124,7 +126,40 @@ public function testGenerateObjectParameter(int $id, string $name, ?array $link,
124126
if ($link && $calendarAppEnabled) {
125127
$result['link'] = 'fullLink';
126128
}
127-
$this->assertEquals($result, $this->invokePrivate($this->provider, 'generateObjectParameter', [$objectParameter]));
129+
$this->assertEquals($result, $this->invokePrivate($this->provider, 'generateObjectParameter', [$objectParameter, $affectedUser]));
130+
}
131+
132+
public function testGenerateObjectParameterWithSharedCalendar(): void {
133+
$link = [
134+
'object_uri' => 'someuuid.ics',
135+
'calendar_uri' => 'personal',
136+
'owner' => 'sharer'
137+
];
138+
$generatedLink = [
139+
'view' => 'dayGridMonth',
140+
'timeRange' => 'now',
141+
'mode' => 'sidebar',
142+
'objectId' => base64_encode('/remote.php/dav/calendars/sharee/' . $link['calendar_uri'] . '_shared_by_sharer/' . $link['object_uri']),
143+
'recurrenceId' => 'next'
144+
];
145+
$this->appManager->expects($this->once())
146+
->method('isEnabledForUser')
147+
->with('calendar')
148+
->willReturn(true);
149+
$this->url->expects($this->once())
150+
->method('getWebroot');
151+
$this->url->expects($this->once())
152+
->method('linkToRouteAbsolute')
153+
->with('calendar.view.indexview.timerange.edit', $generatedLink)
154+
->willReturn('fullLink');
155+
$objectParameter = ['id' => 42, 'name' => 'calendar', 'link' => $link];
156+
$result = [
157+
'type' => 'calendar-event',
158+
'id' => 42,
159+
'name' => 'calendar',
160+
'link' => 'fullLink',
161+
];
162+
$this->assertEquals($result, $this->invokePrivate($this->provider, 'generateObjectParameter', [$objectParameter, 'sharee']));
128163
}
129164

130165
public function dataGenerateObjectParameterThrows() {
@@ -143,6 +178,6 @@ public function dataGenerateObjectParameterThrows() {
143178
public function testGenerateObjectParameterThrows($eventData, string $exception = InvalidArgumentException::class): void {
144179
$this->expectException($exception);
145180

146-
$this->invokePrivate($this->provider, 'generateObjectParameter', [$eventData]);
181+
$this->invokePrivate($this->provider, 'generateObjectParameter', [$eventData, 'no_user']);
147182
}
148183
}

0 commit comments

Comments
 (0)