diff --git a/apps/dav/lib/CalDAV/Calendar.php b/apps/dav/lib/CalDAV/Calendar.php index f7de4cbdaef82..61bb499529d7e 100644 --- a/apps/dav/lib/CalDAV/Calendar.php +++ b/apps/dav/lib/CalDAV/Calendar.php @@ -340,6 +340,11 @@ public function childExists($name) { #[\Override] public function calendarQuery(array $filters) { + // Objects of a calendar in the trash bin must not be matched, e.g. in free-busy reports + if ($this->isDeleted()) { + return []; + } + $uris = $this->caldavBackend->calendarQuery($this->calendarInfo['id'], $filters, $this->getCalendarType()); if ($this->isShared()) { return array_filter($uris, function ($uri) { diff --git a/apps/dav/lib/CalDAV/CalendarImpl.php b/apps/dav/lib/CalDAV/CalendarImpl.php index 63abfc4cdad17..6335e91db005a 100644 --- a/apps/dav/lib/CalDAV/CalendarImpl.php +++ b/apps/dav/lib/CalDAV/CalendarImpl.php @@ -112,6 +112,11 @@ public function getSchedulingTimezone(): ?VTimeZone { #[\Override] public function search(string $pattern, array $searchProperties = [], array $options = [], $limit = null, $offset = null): array { + // Objects of a calendar in the trash bin must not be matched, e.g. when calculating the user status + if ($this->isDeleted()) { + return []; + } + return $this->backend->search($this->calendarInfo, $pattern, $searchProperties, $options, $limit, $offset); } diff --git a/apps/dav/tests/unit/CalDAV/CalendarImplTest.php b/apps/dav/tests/unit/CalDAV/CalendarImplTest.php index 03978ad6cfc86..39d0237c39db4 100644 --- a/apps/dav/tests/unit/CalDAV/CalendarImplTest.php +++ b/apps/dav/tests/unit/CalDAV/CalendarImplTest.php @@ -95,6 +95,16 @@ public function testSearch(): void { $this->assertEquals($result, ['SEARCHRESULTS']); } + public function testSearchDeletedCalendar(): void { + $this->calendar->expects($this->once()) + ->method('isDeleted') + ->willReturn(true); + $this->backend->expects($this->never()) + ->method('search'); + + $this->assertEquals([], $this->calendarImpl->search('abc')); + } + public function testGetPermissionRead(): void { $this->calendar->expects($this->once()) ->method('getACL') diff --git a/apps/dav/tests/unit/CalDAV/CalendarTest.php b/apps/dav/tests/unit/CalDAV/CalendarTest.php index 2509996dd171e..1ba4d0d5a2f68 100644 --- a/apps/dav/tests/unit/CalDAV/CalendarTest.php +++ b/apps/dav/tests/unit/CalDAV/CalendarTest.php @@ -12,6 +12,7 @@ use OCA\DAV\CalDAV\BirthdayService; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\Calendar; +use OCA\DAV\CalDAV\Trashbin\Plugin as TrashbinPlugin; use OCP\IConfig; use OCP\IL10N; use PHPUnit\Framework\MockObject\MockObject; @@ -451,6 +452,69 @@ public static function providesConfidentialClassificationData(): array { ]; } + public function testCalendarQuery(): void { + /** @var CalDavBackend&MockObject $backend */ + $backend = $this->createMock(CalDavBackend::class); + $backend->expects($this->once()) + ->method('calendarQuery') + ->with(666, [], CalDavBackend::CALENDAR_TYPE_CALENDAR) + ->willReturn(['event-0.ics']); + + // A calendar that is not in the trash bin has the property set to null + $calendarInfo = [ + 'principaluri' => 'user1', + 'id' => 666, + 'uri' => 'cal', + TrashbinPlugin::PROPERTY_DELETED_AT => null, + ]; + $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger); + + $this->assertEquals(['event-0.ics'], $c->calendarQuery([])); + } + + public function testCalendarQuerySharedCalendar(): void { + /** @var CalDavBackend&MockObject $backend */ + $backend = $this->createMock(CalDavBackend::class); + $backend->expects($this->once()) + ->method('calendarQuery') + ->with(666, [], CalDavBackend::CALENDAR_TYPE_CALENDAR) + ->willReturn(['event-public.ics', 'event-private.ics']); + $backend->expects($this->any()) + ->method('getCalendarObject') + ->willReturnMap([ + [666, 'event-public.ics', CalDavBackend::CALENDAR_TYPE_CALENDAR, ['uri' => 'event-public.ics', 'classification' => CalDavBackend::CLASSIFICATION_PUBLIC]], + [666, 'event-private.ics', CalDavBackend::CALENDAR_TYPE_CALENDAR, ['uri' => 'event-private.ics', 'classification' => CalDavBackend::CLASSIFICATION_PRIVATE]], + ]); + + $calendarInfo = [ + '{http://owncloud.org/ns}owner-principal' => 'user1', + 'principaluri' => 'user2', + 'id' => 666, + 'uri' => 'cal', + TrashbinPlugin::PROPERTY_DELETED_AT => null, + ]; + $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger); + + $this->assertEquals(['event-public.ics'], $c->calendarQuery([])); + } + + public function testCalendarQueryDeletedCalendar(): void { + /** @var CalDavBackend&MockObject $backend */ + $backend = $this->createMock(CalDavBackend::class); + $backend->expects($this->never()) + ->method('calendarQuery'); + + $calendarInfo = [ + 'principaluri' => 'user1', + 'id' => 666, + 'uri' => 'cal', + TrashbinPlugin::PROPERTY_DELETED_AT => 1234567890, + ]; + $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger); + + $this->assertEquals([], $c->calendarQuery([])); + } + public function testRemoveVAlarms(): void { $publicObjectData = <<