mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
fix(caldav): event links in shared calendar notifications
Signed-off-by: Richard Steinmetz <richard@steinmetz.cloud>
This commit is contained in:
parent
39c6329825
commit
012bb75dba
3 changed files with 61 additions and 18 deletions
|
|
@ -81,7 +81,7 @@ class Event extends Base {
|
|||
* @param array $eventData
|
||||
* @return array
|
||||
*/
|
||||
protected function generateObjectParameter(array $eventData) {
|
||||
protected function generateObjectParameter(array $eventData, string $affectedUser): array {
|
||||
if (!isset($eventData['id']) || !isset($eventData['name'])) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
|
|
@ -97,7 +97,15 @@ class Event extends Base {
|
|||
// The calendar app needs to be manually loaded for the routes to be loaded
|
||||
OC_App::loadApp('calendar');
|
||||
$linkData = $eventData['link'];
|
||||
$objectId = base64_encode($this->url->getWebroot() . '/remote.php/dav/calendars/' . $linkData['owner'] . '/' . $linkData['calendar_uri'] . '/' . $linkData['object_uri']);
|
||||
if ($affectedUser === $linkData['owner']) {
|
||||
$objectId = base64_encode($this->url->getWebroot() . '/remote.php/dav/calendars/' . $linkData['owner'] . '/' . $linkData['calendar_uri'] . '/' . $linkData['object_uri']);
|
||||
} else {
|
||||
// Can't use the "real" owner and calendar names here because we create a custom
|
||||
// calendar for incoming shares with the name "<calendar>_shared_by_<sharer>".
|
||||
// Hack: Fix the link by generating it for the incoming shared calendar instead,
|
||||
// as seen from the affected user.
|
||||
$objectId = base64_encode($this->url->getWebroot() . '/remote.php/dav/calendars/' . $affectedUser . '/' . $linkData['calendar_uri'] . '_shared_by_' . $linkData['owner'] . '/' . $linkData['object_uri']);
|
||||
}
|
||||
$link = [
|
||||
'view' => 'dayGridMonth',
|
||||
'timeRange' => 'now',
|
||||
|
|
@ -189,7 +197,7 @@ class Event extends Base {
|
|||
return [
|
||||
'actor' => $this->generateUserParameter($parameters['actor']),
|
||||
'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
|
||||
'event' => $this->generateClassifiedObjectParameter($parameters['object']),
|
||||
'event' => $this->generateClassifiedObjectParameter($parameters['object'], $event->getAffectedUser()),
|
||||
];
|
||||
case self::SUBJECT_OBJECT_ADD . '_event_self':
|
||||
case self::SUBJECT_OBJECT_DELETE . '_event_self':
|
||||
|
|
@ -198,7 +206,7 @@ class Event extends Base {
|
|||
case self::SUBJECT_OBJECT_RESTORE . '_event_self':
|
||||
return [
|
||||
'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
|
||||
'event' => $this->generateClassifiedObjectParameter($parameters['object']),
|
||||
'event' => $this->generateClassifiedObjectParameter($parameters['object'], $event->getAffectedUser()),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -210,13 +218,13 @@ class Event extends Base {
|
|||
'actor' => $this->generateUserParameter($parameters['actor']),
|
||||
'sourceCalendar' => $this->generateCalendarParameter($parameters['sourceCalendar'], $this->l),
|
||||
'targetCalendar' => $this->generateCalendarParameter($parameters['targetCalendar'], $this->l),
|
||||
'event' => $this->generateClassifiedObjectParameter($parameters['object']),
|
||||
'event' => $this->generateClassifiedObjectParameter($parameters['object'], $event->getAffectedUser()),
|
||||
];
|
||||
case self::SUBJECT_OBJECT_MOVE . '_event_self':
|
||||
return [
|
||||
'sourceCalendar' => $this->generateCalendarParameter($parameters['sourceCalendar'], $this->l),
|
||||
'targetCalendar' => $this->generateCalendarParameter($parameters['targetCalendar'], $this->l),
|
||||
'event' => $this->generateClassifiedObjectParameter($parameters['object']),
|
||||
'event' => $this->generateClassifiedObjectParameter($parameters['object'], $event->getAffectedUser()),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -233,22 +241,22 @@ class Event extends Base {
|
|||
return [
|
||||
'actor' => $this->generateUserParameter($parameters[0]),
|
||||
'calendar' => $this->generateLegacyCalendarParameter($event->getObjectId(), $parameters[1]),
|
||||
'event' => $this->generateObjectParameter($parameters[2]),
|
||||
'event' => $this->generateObjectParameter($parameters[2], $event->getAffectedUser()),
|
||||
];
|
||||
case self::SUBJECT_OBJECT_ADD . '_event_self':
|
||||
case self::SUBJECT_OBJECT_DELETE . '_event_self':
|
||||
case self::SUBJECT_OBJECT_UPDATE . '_event_self':
|
||||
return [
|
||||
'calendar' => $this->generateLegacyCalendarParameter($event->getObjectId(), $parameters[1]),
|
||||
'event' => $this->generateObjectParameter($parameters[2]),
|
||||
'event' => $this->generateObjectParameter($parameters[2], $event->getAffectedUser()),
|
||||
];
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
|
||||
private function generateClassifiedObjectParameter(array $eventData) {
|
||||
$parameter = $this->generateObjectParameter($eventData);
|
||||
private function generateClassifiedObjectParameter(array $eventData, string $affectedUser): array {
|
||||
$parameter = $this->generateObjectParameter($eventData, $affectedUser);
|
||||
if (!empty($eventData['classified'])) {
|
||||
$parameter['name'] = $this->l->t('Busy');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ class Todo extends Event {
|
|||
return [
|
||||
'actor' => $this->generateUserParameter($parameters['actor']),
|
||||
'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
|
||||
'todo' => $this->generateObjectParameter($parameters['object']),
|
||||
'todo' => $this->generateObjectParameter($parameters['object'], $event->getAffectedUser()),
|
||||
];
|
||||
case self::SUBJECT_OBJECT_ADD . '_todo_self':
|
||||
case self::SUBJECT_OBJECT_DELETE . '_todo_self':
|
||||
|
|
@ -113,7 +113,7 @@ class Todo extends Event {
|
|||
case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action_self':
|
||||
return [
|
||||
'calendar' => $this->generateCalendarParameter($parameters['calendar'], $this->l),
|
||||
'todo' => $this->generateObjectParameter($parameters['object']),
|
||||
'todo' => $this->generateObjectParameter($parameters['object'], $event->getAffectedUser()),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -125,13 +125,13 @@ class Todo extends Event {
|
|||
'actor' => $this->generateUserParameter($parameters['actor']),
|
||||
'sourceCalendar' => $this->generateCalendarParameter($parameters['sourceCalendar'], $this->l),
|
||||
'targetCalendar' => $this->generateCalendarParameter($parameters['targetCalendar'], $this->l),
|
||||
'todo' => $this->generateObjectParameter($parameters['object']),
|
||||
'todo' => $this->generateObjectParameter($parameters['object'], $event->getAffectedUser()),
|
||||
];
|
||||
case self::SUBJECT_OBJECT_MOVE . '_todo_self':
|
||||
return [
|
||||
'sourceCalendar' => $this->generateCalendarParameter($parameters['sourceCalendar'], $this->l),
|
||||
'targetCalendar' => $this->generateCalendarParameter($parameters['targetCalendar'], $this->l),
|
||||
'todo' => $this->generateObjectParameter($parameters['object']),
|
||||
'todo' => $this->generateObjectParameter($parameters['object'], $event->getAffectedUser()),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -150,7 +150,7 @@ class Todo extends Event {
|
|||
return [
|
||||
'actor' => $this->generateUserParameter($parameters[0]),
|
||||
'calendar' => $this->generateLegacyCalendarParameter($event->getObjectId(), $parameters[1]),
|
||||
'todo' => $this->generateObjectParameter($parameters[2]),
|
||||
'todo' => $this->generateObjectParameter($parameters[2], $event->getAffectedUser()),
|
||||
];
|
||||
case self::SUBJECT_OBJECT_ADD . '_todo_self':
|
||||
case self::SUBJECT_OBJECT_DELETE . '_todo_self':
|
||||
|
|
@ -159,7 +159,7 @@ class Todo extends Event {
|
|||
case self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action_self':
|
||||
return [
|
||||
'calendar' => $this->generateLegacyCalendarParameter($event->getObjectId(), $parameters[1]),
|
||||
'todo' => $this->generateObjectParameter($parameters[2]),
|
||||
'todo' => $this->generateObjectParameter($parameters[2], $event->getAffectedUser()),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,9 @@ class EventTest extends TestCase {
|
|||
* @param bool $calendarAppEnabled
|
||||
*/
|
||||
public function testGenerateObjectParameter(int $id, string $name, ?array $link, bool $calendarAppEnabled = true): void {
|
||||
$affectedUser = 'otheruser';
|
||||
if ($link) {
|
||||
$affectedUser = $link['owner'];
|
||||
$generatedLink = [
|
||||
'view' => 'dayGridMonth',
|
||||
'timeRange' => 'now',
|
||||
|
|
@ -141,7 +143,40 @@ class EventTest extends TestCase {
|
|||
if ($link && $calendarAppEnabled) {
|
||||
$result['link'] = 'fullLink';
|
||||
}
|
||||
$this->assertEquals($result, $this->invokePrivate($this->provider, 'generateObjectParameter', [$objectParameter]));
|
||||
$this->assertEquals($result, $this->invokePrivate($this->provider, 'generateObjectParameter', [$objectParameter, $affectedUser]));
|
||||
}
|
||||
|
||||
public function testGenerateObjectParameterWithSharedCalendar(): void {
|
||||
$link = [
|
||||
'object_uri' => 'someuuid.ics',
|
||||
'calendar_uri' => 'personal',
|
||||
'owner' => 'sharer'
|
||||
];
|
||||
$generatedLink = [
|
||||
'view' => 'dayGridMonth',
|
||||
'timeRange' => 'now',
|
||||
'mode' => 'sidebar',
|
||||
'objectId' => base64_encode('/remote.php/dav/calendars/sharee/' . $link['calendar_uri'] . '_shared_by_sharer/' . $link['object_uri']),
|
||||
'recurrenceId' => 'next'
|
||||
];
|
||||
$this->appManager->expects($this->once())
|
||||
->method('isEnabledForUser')
|
||||
->with('calendar')
|
||||
->willReturn(true);
|
||||
$this->url->expects($this->once())
|
||||
->method('getWebroot');
|
||||
$this->url->expects($this->once())
|
||||
->method('linkToRouteAbsolute')
|
||||
->with('calendar.view.indexview.timerange.edit', $generatedLink)
|
||||
->willReturn('fullLink');
|
||||
$objectParameter = ['id' => 42, 'name' => 'calendar', 'link' => $link];
|
||||
$result = [
|
||||
'type' => 'calendar-event',
|
||||
'id' => 42,
|
||||
'name' => 'calendar',
|
||||
'link' => 'fullLink',
|
||||
];
|
||||
$this->assertEquals($result, $this->invokePrivate($this->provider, 'generateObjectParameter', [$objectParameter, 'sharee']));
|
||||
}
|
||||
|
||||
public function dataGenerateObjectParameterThrows() {
|
||||
|
|
@ -160,6 +195,6 @@ class EventTest extends TestCase {
|
|||
public function testGenerateObjectParameterThrows($eventData, string $exception = InvalidArgumentException::class): void {
|
||||
$this->expectException($exception);
|
||||
|
||||
$this->invokePrivate($this->provider, 'generateObjectParameter', [$eventData]);
|
||||
$this->invokePrivate($this->provider, 'generateObjectParameter', [$eventData, 'no_user']);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue