aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorRichard Steinmetz <richard@steinmetz.cloud>2024-06-20 15:44:34 +0200
committerGitHub <noreply@github.com>2024-06-20 15:44:34 +0200
commitefe3244acfe57b4286c340b169962e60628faf63 (patch)
treeb2f13a7314ae932a59d14d958b9423f794c6f50b /apps
parent8ac9e08f2086aa95a9b9423fbef3dc21814c012b (diff)
parentdf28c04a8f49dca0454169ad3c11b84b092dc8ff (diff)
downloadnextcloud-server-efe3244acfe57b4286c340b169962e60628faf63.tar.gz
nextcloud-server-efe3244acfe57b4286c340b169962e60628faf63.zip
Merge pull request #45999 from nextcloud/fix/caldav/shared-calendars-activity-umlauts
fix(caldav): encode calendar URIs with umlauts for activities
Diffstat (limited to 'apps')
-rw-r--r--apps/dav/lib/CalDAV/Activity/Provider/Event.php17
-rw-r--r--apps/dav/tests/unit/CalDAV/Activity/Provider/EventTest.php53
2 files changed, 62 insertions, 8 deletions
diff --git a/apps/dav/lib/CalDAV/Activity/Provider/Event.php b/apps/dav/lib/CalDAV/Activity/Provider/Event.php
index 45d4f731e20..959c0a815dd 100644
--- a/apps/dav/lib/CalDAV/Activity/Provider/Event.php
+++ b/apps/dav/lib/CalDAV/Activity/Provider/Event.php
@@ -76,14 +76,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'];
+ $calendarUri = $this->urlencodeLowerHex($linkData['calendar_uri']);
if ($affectedUser === $linkData['owner']) {
- $objectId = base64_encode($this->url->getWebroot() . '/remote.php/dav/calendars/' . $linkData['owner'] . '/' . $linkData['calendar_uri'] . '/' . $linkData['object_uri']);
+ $objectId = base64_encode($this->url->getWebroot() . '/remote.php/dav/calendars/' . $linkData['owner'] . '/' . $calendarUri . '/' . $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']);
+ $objectId = base64_encode($this->url->getWebroot() . '/remote.php/dav/calendars/' . $affectedUser . '/' . $calendarUri . '_shared_by_' . $linkData['owner'] . '/' . $linkData['object_uri']);
}
$link = [
'view' => 'dayGridMonth',
@@ -241,4 +242,16 @@ class Event extends Base {
}
return $parameter;
}
+
+ /**
+ * Return urlencoded string but with lower cased hex sequences.
+ * The remaining casing will be untouched.
+ */
+ private function urlencodeLowerHex(string $raw): string {
+ return preg_replace_callback(
+ '/%[0-9A-F]{2}/',
+ static fn (array $matches) => strtolower($matches[0]),
+ urlencode($raw),
+ );
+ }
}
diff --git a/apps/dav/tests/unit/CalDAV/Activity/Provider/EventTest.php b/apps/dav/tests/unit/CalDAV/Activity/Provider/EventTest.php
index b0b2cc936a5..ec237825731 100644
--- a/apps/dav/tests/unit/CalDAV/Activity/Provider/EventTest.php
+++ b/apps/dav/tests/unit/CalDAV/Activity/Provider/EventTest.php
@@ -129,17 +129,58 @@ class EventTest extends TestCase {
$this->assertEquals($result, $this->invokePrivate($this->provider, 'generateObjectParameter', [$objectParameter, $affectedUser]));
}
- public function testGenerateObjectParameterWithSharedCalendar(): void {
- $link = [
- 'object_uri' => 'someuuid.ics',
- 'calendar_uri' => 'personal',
- 'owner' => 'sharer'
+ public static function generateObjectParameterLinkEncodingDataProvider(): array {
+ return [
+ [ // Shared calendar
+ [
+ 'object_uri' => 'someuuid.ics',
+ 'calendar_uri' => 'personal',
+ 'owner' => 'sharer'
+ ],
+ base64_encode('/remote.php/dav/calendars/sharee/personal_shared_by_sharer/someuuid.ics'),
+ ],
+ [ // Shared calendar with umlauts
+ [
+ 'object_uri' => 'someuuid.ics',
+ 'calendar_uri' => 'umlaut_äüöß',
+ 'owner' => 'sharer'
+ ],
+ base64_encode('/remote.php/dav/calendars/sharee/umlaut_%c3%a4%c3%bc%c3%b6%c3%9f_shared_by_sharer/someuuid.ics'),
+ ],
+ [ // Shared calendar with umlauts and mixed casing
+ [
+ 'object_uri' => 'someuuid.ics',
+ 'calendar_uri' => 'Umlaut_äüöß',
+ 'owner' => 'sharer'
+ ],
+ base64_encode('/remote.php/dav/calendars/sharee/Umlaut_%c3%a4%c3%bc%c3%b6%c3%9f_shared_by_sharer/someuuid.ics'),
+ ],
+ [ // Owned calendar with umlauts
+ [
+ 'object_uri' => 'someuuid.ics',
+ 'calendar_uri' => 'umlaut_äüöß',
+ 'owner' => 'sharee'
+ ],
+ base64_encode('/remote.php/dav/calendars/sharee/umlaut_%c3%a4%c3%bc%c3%b6%c3%9f/someuuid.ics'),
+ ],
+ [ // Owned calendar with umlauts and mixed casing
+ [
+ 'object_uri' => 'someuuid.ics',
+ 'calendar_uri' => 'Umlaut_äüöß',
+ 'owner' => 'sharee'
+ ],
+ base64_encode('/remote.php/dav/calendars/sharee/Umlaut_%c3%a4%c3%bc%c3%b6%c3%9f/someuuid.ics'),
+ ],
];
+ }
+
+ /** @dataProvider generateObjectParameterLinkEncodingDataProvider */
+ public function testGenerateObjectParameterLinkEncoding(array $link, string $objectId): void {
$generatedLink = [
'view' => 'dayGridMonth',
'timeRange' => 'now',
'mode' => 'sidebar',
- 'objectId' => base64_encode('/remote.php/dav/calendars/sharee/' . $link['calendar_uri'] . '_shared_by_sharer/' . $link['object_uri']),
+ 'objectId' => $objectId,
'recurrenceId' => 'next'
];
$this->appManager->expects($this->once())