aboutsummaryrefslogtreecommitdiffstats
path: root/apps/dav
diff options
context:
space:
mode:
authorblizzz <blizzz@arthur-schiwon.de>2023-03-02 11:54:51 +0100
committerGitHub <noreply@github.com>2023-03-02 11:54:51 +0100
commite08fa782249c201baf042c8cdf2362fc2300f85f (patch)
treee73deed0d20eed7e05beae4fe8f6b65c1a0d118e /apps/dav
parent2f64d16afdaeccee608c861a3729c817d7a8e7bb (diff)
parent4fd58aa45cdd4a15be0f3eafcd353715c37d4d63 (diff)
downloadnextcloud-server-e08fa782249c201baf042c8cdf2362fc2300f85f.tar.gz
nextcloud-server-e08fa782249c201baf042c8cdf2362fc2300f85f.zip
Merge pull request #36594 from nextcloud/fix-handling-of-invitations
fix(caldav): Correctly handle calendar recreation for invitations when the current calendar is in the trashbin
Diffstat (limited to 'apps/dav')
-rw-r--r--apps/dav/lib/CalDAV/Schedule/Plugin.php37
-rw-r--r--apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php29
2 files changed, 48 insertions, 18 deletions
diff --git a/apps/dav/lib/CalDAV/Schedule/Plugin.php b/apps/dav/lib/CalDAV/Schedule/Plugin.php
index ac8521acfee..0751638b697 100644
--- a/apps/dav/lib/CalDAV/Schedule/Plugin.php
+++ b/apps/dav/lib/CalDAV/Schedule/Plugin.php
@@ -48,7 +48,6 @@ use Sabre\VObject\Component;
use Sabre\VObject\Component\VCalendar;
use Sabre\VObject\Component\VEvent;
use Sabre\VObject\DateTimeParser;
-use Sabre\VObject\Document;
use Sabre\VObject\FreeBusyGenerator;
use Sabre\VObject\ITip;
use Sabre\VObject\Parameter;
@@ -329,12 +328,12 @@ EOF;
/** @var CalendarHome $calendarHome */
$calendarHome = $this->server->tree->getNodeForPath($calendarHomePath);
- if (!$calendarHome->childExists($uri)) {
+ $currentCalendarDeleted = false;
+ if (!$calendarHome->childExists($uri) || $currentCalendarDeleted = $this->isCalendarDeleted($calendarHome, $uri)) {
// If the default calendar doesn't exist
if ($isResourceOrRoom) {
- $calendarHome->getCalDAVBackend()->createCalendar($principalUrl, $uri, [
- '{DAV:}displayname' => $displayName,
- ]);
+ // Resources or rooms can't be in the trashbin, so we're fine
+ $this->createCalendar($calendarHome, $principalUrl, $uri, $displayName);
} else {
// And we're not handling scheduling on resource/room booking
$userCalendars = [];
@@ -359,9 +358,16 @@ EOF;
$uri = $userCalendars[0]->getName();
} else {
// Otherwise if we have really nothing, create a new calendar
- $calendarHome->getCalDAVBackend()->createCalendar($principalUrl, $uri, [
- '{DAV:}displayname' => $displayName,
- ]);
+ if ($currentCalendarDeleted) {
+ // If the calendar exists but is deleted, we need to purge it first
+ // This may cause some issues in a non synchronous database setup
+ $calendar = $this->getCalendar($calendarHome, $uri);
+ if ($calendar instanceof Calendar) {
+ $calendar->disableTrashbin();
+ $calendar->delete();
+ }
+ }
+ $this->createCalendar($calendarHome, $principalUrl, $uri, $displayName);
}
}
}
@@ -609,4 +615,19 @@ EOF;
return $email;
}
+
+ private function getCalendar(CalendarHome $calendarHome, string $uri): INode {
+ return $calendarHome->getChild($uri);
+ }
+
+ private function isCalendarDeleted(CalendarHome $calendarHome, string $uri): bool {
+ $calendar = $this->getCalendar($calendarHome, $uri);
+ return $calendar instanceof Calendar && $calendar->isDeleted();
+ }
+
+ private function createCalendar(CalendarHome $calendarHome, string $principalUri, string $uri, string $displayName): void {
+ $calendarHome->getCalDAVBackend()->createCalendar($principalUri, $uri, [
+ '{DAV:}displayname' => $displayName,
+ ]);
+ }
}
diff --git a/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php b/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php
index 4845188bc88..8f315eac0ee 100644
--- a/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php
+++ b/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php
@@ -197,6 +197,16 @@ class PluginTest extends TestCase {
false,
CalDavBackend::PERSONAL_CALENDAR_URI,
CalDavBackend::PERSONAL_CALENDAR_NAME,
+ true,
+ true
+ ],
+ [
+ 'principals/users/myuser',
+ 'calendars/myuser',
+ false,
+ CalDavBackend::PERSONAL_CALENDAR_URI,
+ CalDavBackend::PERSONAL_CALENDAR_NAME,
+ false,
false,
true
],
@@ -225,6 +235,7 @@ class PluginTest extends TestCase {
true,
false,
false,
+ false,
],
[
'principals/users/myuser',
@@ -263,16 +274,8 @@ class PluginTest extends TestCase {
/**
* @dataProvider propFindDefaultCalendarUrlProvider
- * @param string $principalUri
- * @param string|null $calendarHome
- * @param bool $isResource
- * @param string $calendarUri
- * @param string $displayName
- * @param bool $exists
- * @param bool $propertiesForPath
*/
- public function testPropFindDefaultCalendarUrl(string $principalUri, ?string $calendarHome, bool $isResource, string $calendarUri, string $displayName, bool $exists, bool $hasExistingCalendars = false, bool $propertiesForPath = true): void {
- /** @var PropFind $propFind */
+ public function testPropFindDefaultCalendarUrl(string $principalUri, ?string $calendarHome, bool $isResource, string $calendarUri, string $displayName, bool $exists, bool $deleted = false, bool $hasExistingCalendars = false, bool $propertiesForPath = true): void {
$propFind = new PropFind(
$principalUri,
[
@@ -328,6 +331,12 @@ class PluginTest extends TestCase {
->with($calendarUri)
->willReturn($exists);
+ if ($exists) {
+ $calendar = $this->createMock(Calendar::class);
+ $calendar->expects($this->once())->method('isDeleted')->willReturn($deleted);
+ $calendarHomeObject->expects($deleted && !$hasExistingCalendars ? $this->exactly(2) : $this->once())->method('getChild')->with($calendarUri)->willReturn($calendar);
+ }
+
$calendarBackend = $this->createMock(CalDavBackend::class);
$calendarUri = $hasExistingCalendars ? 'custom' : $calendarUri;
$displayName = $hasExistingCalendars ? 'Custom Calendar' : $displayName;
@@ -349,7 +358,7 @@ class PluginTest extends TestCase {
)
] : [];
- if (!$exists) {
+ if (!$exists || $deleted) {
if (!$hasExistingCalendars) {
$calendarBackend->expects($this->once())
->method('createCalendar')