diff --git a/lib/private/Calendar/Manager.php b/lib/private/Calendar/Manager.php index f0b8e9fd50de7..550ba36dd6bc3 100644 --- a/lib/private/Calendar/Manager.php +++ b/lib/private/Calendar/Manager.php @@ -330,12 +330,27 @@ public function handleIMipCancel(string $principalUri, string $sender, ?string $ // to the email address in the ORGANIZER. // We don't want to accept a CANCEL request from just anyone $organizer = substr($vEvent->{'ORGANIZER'}->getValue(), 7); - if (strcasecmp($sender, $organizer) !== 0 && strcasecmp($replyTo, $organizer) !== 0) { + $isNotOrganizer = ($replyTo !== null) ? (strcasecmp($sender, $organizer) !== 0 && strcasecmp($replyTo, $organizer) !== 0) : (strcasecmp($sender, $organizer) !== 0); + if ($isNotOrganizer) { $this->logger->warning('Sender must be the ORGANIZER of this event'); return false; } + //check if the event is in the future + /** @var DateTime $eventTime */ + $eventTime = $vEvent->{'DTSTART'}; + if ($eventTime->getDateTime()->getTimeStamp() < $this->timeFactory->getTime()) { // this might cause issues with recurrences + $this->logger->warning('Only events in the future are processed'); + return false; + } + + // Check if we have a calendar to work with $calendars = $this->getCalendarsForPrincipal($principalUri); + if (empty($calendars)) { + $this->logger->warning('Could not find any calendars for principal ' . $principalUri); + return false; + } + $found = null; // if the attendee has been found in at least one calendar event with the UID of the iMIP event // we process it. diff --git a/tests/lib/Calendar/ManagerTest.php b/tests/lib/Calendar/ManagerTest.php index 8b99c21ae41b1..ba30be1b54875 100644 --- a/tests/lib/Calendar/ManagerTest.php +++ b/tests/lib/Calendar/ManagerTest.php @@ -251,7 +251,7 @@ public function testHandleImipReplyWrongMethod(): void { $this->logger->expects(self::once()) ->method('warning'); $this->time->expects(self::never()) - ->method('getTimestamp'); + ->method('getTime'); $result = $this->manager->handleIMipReply($principalUri, $sender, $recipient, $calendarData->serialize()); $this->assertFalse($result); @@ -266,7 +266,7 @@ public function testHandleImipReplyOrganizerNotRecipient(): void { $this->logger->expects(self::once()) ->method('warning'); $this->time->expects(self::never()) - ->method('getTimestamp'); + ->method('getTime'); $result = $this->manager->handleIMipReply($principalUri, $sender, $recipient, $calendarData->serialize()); $this->assertFalse($result); @@ -280,7 +280,7 @@ public function testHandleImipReplyDateInThePast(): void { $calendarData->VEVENT->DTSTART = new \DateTime('2013-04-07'); // set to in the past $this->time->expects(self::once()) - ->method('getTimestamp') + ->method('getTime') ->willReturn(time()); $this->logger->expects(self::once()) @@ -301,15 +301,16 @@ public function testHandleImipReplyNoCalendars(): void { ]) ->setMethods([ 'getCalendarsForPrincipal' - ]); + ]) + ->getMock(); $principalUri = 'principals/user/linus'; $sender = 'pierre@general-store.com'; $recipient = 'linus@stardew-tent-living.com'; $calendarData = $this->getVCalendarReply(); $this->time->expects(self::once()) - ->method('getTimestamp') - ->willReturn(202208219); + ->method('getTime') + ->willReturn(1628374233); $manager->expects(self::once()) ->method('getCalendarsForPrincipal') ->willReturn([]); @@ -331,7 +332,8 @@ public function testHandleImipReplyEventNotFound(): void { ]) ->setMethods([ 'getCalendarsForPrincipal' - ]); + ]) + ->getMock(); $calendar = $this->createMock(ICreateFromString::class); $principalUri = 'principals/user/linus'; $sender = 'pierre@general-store.com'; @@ -339,8 +341,8 @@ public function testHandleImipReplyEventNotFound(): void { $calendarData = $this->getVCalendarReply(); $this->time->expects(self::once()) - ->method('getTimestamp') - ->willReturn(202208219); + ->method('getTime') + ->willReturn(1628374233); $manager->expects(self::once()) ->method('getCalendarsForPrincipal') ->willReturn([$calendar]); @@ -367,7 +369,8 @@ public function testHandleImipReply(): void { ]) ->setMethods([ 'getCalendarsForPrincipal' - ]); + ]) + ->getMock(); $calendar = $this->createMock(ICreateFromString::class); $principalUri = 'principals/user/linus'; $sender = 'pierre@general-store.com'; @@ -375,8 +378,8 @@ public function testHandleImipReply(): void { $calendarData = $this->getVCalendarReply(); $this->time->expects(self::once()) - ->method('getTimestamp') - ->willReturn(202208219); + ->method('getTime') + ->willReturn(1628374233); $manager->expects(self::once()) ->method('getCalendarsForPrincipal') ->willReturn([$calendar]); @@ -397,12 +400,12 @@ public function testHandleImipCancelWrongMethod(): void { $recipient = 'pierre@general-store.com'; $replyTo = null; $calendarData = $this->getVCalendarCancel(); - $calendarData->VEVENT->METHOD = 'REQUEST'; + $calendarData->METHOD = 'REQUEST'; $this->logger->expects(self::once()) ->method('warning'); $this->time->expects(self::never()) - ->method('getTimestamp'); + ->method('getTime'); $result = $this->manager->handleIMipCancel($principalUri, $sender, $replyTo, $recipient, $calendarData->serialize()); $this->assertFalse($result); @@ -414,12 +417,11 @@ public function testHandleImipCancelAttendeeNotRecipient(): void { $recipient = 'leah@general-store.com'; $replyTo = null; $calendarData = $this->getVCalendarCancel(); - $calendarData->VEVENT->METHOD = 'CANCEL'; $this->logger->expects(self::once()) ->method('warning'); $this->time->expects(self::never()) - ->method('getTimestamp'); + ->method('getTime'); $result = $this->manager->handleIMipCancel($principalUri, $sender, $replyTo, $recipient, $calendarData->serialize()); $this->assertFalse($result); @@ -434,7 +436,7 @@ public function testHandleImipCancelDateInThePast(): void { $calendarData->VEVENT->DTSTART = new \DateTime('2013-04-07'); // set to in the past $this->time->expects(self::once()) - ->method('getTimestamp') + ->method('getTime') ->willReturn(time()); $this->logger->expects(self::once()) ->method('warning'); @@ -454,7 +456,8 @@ public function testHandleImipCancelNoCalendars(): void { ]) ->setMethods([ 'getCalendarsForPrincipal' - ]); + ]) + ->getMock(); $principalUri = 'principals/user/pierre'; $sender = 'linus@stardew-tent-living.com'; $recipient = 'pierre@general-store.com'; @@ -462,8 +465,8 @@ public function testHandleImipCancelNoCalendars(): void { $calendarData = $this->getVCalendarCancel(); $this->time->expects(self::once()) - ->method('getTimestamp') - ->willReturn(202208219); + ->method('getTime') + ->willReturn(1628374233); $manager->expects(self::once()) ->method('getCalendarsForPrincipal') ->with($principalUri) @@ -471,8 +474,8 @@ public function testHandleImipCancelNoCalendars(): void { $this->logger->expects(self::once()) ->method('warning'); - $result = $this->manager->handleIMipCancel($principalUri, $sender, $replyTo, $recipient, $calendarData->serialize()); - $this->assertTrue($result); + $result = $manager->handleIMipCancel($principalUri, $sender, $replyTo, $recipient, $calendarData->serialize()); + $this->assertFalse($result); } public function testHandleImipCancelOrganiserInReplyTo(): void { @@ -486,18 +489,18 @@ public function testHandleImipCancelOrganiserInReplyTo(): void { ]) ->setMethods([ 'getCalendarsForPrincipal' - ]); + ]) + ->getMock(); $principalUri = 'principals/user/pierre'; $sender = 'clint@stardew-blacksmiths.com'; $recipient = 'pierre@general-store.com'; $replyTo = 'linus@stardew-tent-living.com'; $calendar = $this->createMock(ICreateFromString::class); $calendarData = $this->getVCalendarCancel(); - $calendarData->VEVENT->METHOD = 'CANCEL'; $this->time->expects(self::once()) - ->method('getTimestamp') - ->willReturn(202208219); + ->method('getTime') + ->willReturn(1628374233); $manager->expects(self::once()) ->method('getCalendarsForPrincipal') ->with($principalUri) @@ -508,8 +511,8 @@ public function testHandleImipCancelOrganiserInReplyTo(): void { $calendar->expects(self::once()) ->method('handleIMipMessage') ->with('testname.ics', $calendarData->serialize()); - $result = $this->manager->handleIMipCancel($principalUri, $sender, $replyTo, $recipient, $calendarData->serialize()); - $this->assertFalse($result); + $result = $manager->handleIMipCancel($principalUri, $sender, $replyTo, $recipient, $calendarData->serialize()); + $this->assertTrue($result); } public function testHandleImipCancel(): void { @@ -523,18 +526,18 @@ public function testHandleImipCancel(): void { ]) ->setMethods([ 'getCalendarsForPrincipal' - ]); + ]) + ->getMock(); $principalUri = 'principals/user/pierre'; $sender = 'linus@stardew-tent-living.com'; $recipient = 'pierre@general-store.com'; $replyTo = null; $calendar = $this->createMock(ICreateFromString::class); $calendarData = $this->getVCalendarCancel(); - $calendarData->VEVENT->METHOD = 'CANCEL'; $this->time->expects(self::once()) - ->method('getTimestamp') - ->willReturn(202208219); + ->method('getTime') + ->willReturn(1628374233); $manager->expects(self::once()) ->method('getCalendarsForPrincipal') ->with($principalUri) @@ -545,8 +548,8 @@ public function testHandleImipCancel(): void { $calendar->expects(self::once()) ->method('handleIMipMessage') ->with('testname.ics', $calendarData->serialize()); - $result = $this->manager->handleIMipCancel($principalUri, $sender, $replyTo, $recipient, $calendarData->serialize()); - $this->assertFalse($result); + $result = $manager->handleIMipCancel($principalUri, $sender, $replyTo, $recipient, $calendarData->serialize()); + $this->assertTrue($result); } private function getVCalendarReply(): Document {