Skip to content

Commit 50c4920

Browse files
feat: meeting proposals
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com> Signed-off-by: Richard Steinmetz <richard@steinmetz.cloud> [skip ci]
1 parent c7f8afb commit 50c4920

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

lib/private/Calendar/Manager.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use DateTimeInterface;
1212
use OC\AppFramework\Bootstrap\Coordinator;
1313
use OCA\DAV\CalDAV\Auth\CustomPrincipalPlugin;
14+
use OCA\DAV\Db\PropertyMapper;
1415
use OCA\DAV\ServerFactory;
1516
use OCP\AppFramework\Utility\ITimeFactory;
1617
use OCP\Calendar\Exceptions\CalendarException;
@@ -58,6 +59,7 @@ public function __construct(
5859
private ISecureRandom $random,
5960
private IUserManager $userManager,
6061
private ServerFactory $serverFactory,
62+
private PropertyMapper $propertyMapper,
6163
) {
6264
}
6365

@@ -227,6 +229,7 @@ public function newQuery(string $principalUri): ICalendarQuery {
227229
protected function handleIMip(
228230
string $userId,
229231
string $message,
232+
array $options = [],
230233
): bool {
231234

232235
$userUri = 'principals/users/' . $userId;
@@ -287,6 +290,30 @@ protected function handleIMip(
287290
}
288291
}
289292

293+
if ($options['absent'] === 'create') {
294+
// retrieve the primary calendar for the user
295+
$calendar = $this->getPrimaryCalendar($userId);
296+
if ($calendar !== null && (
297+
!$calendar instanceof IHandleImipMessage || !$calendar instanceof ICalendarIsWritable || $calendar->isDeleted() || !$calendar->isWritable()
298+
)) {
299+
$calendar = null;
300+
}
301+
// if no primary calendar is set, use the first writable calendar
302+
if ($calendar === null) {
303+
foreach ($userCalendars as $userCalendar) {
304+
if ($userCalendar instanceof IHandleImipMessage && $userCalendar instanceof ICalendarIsWritable && !$userCalendar->isDeleted() && $userCalendar->isWritable()) {
305+
$calendar = $userCalendar;
306+
break;
307+
}
308+
}
309+
}
310+
if ($calendar === null) {
311+
$this->logger->warning('iMip message could not be processed because no writable calendar was found');
312+
return false;
313+
}
314+
$calendar->handleIMipMessage($userId, $vObject->serialize());
315+
}
316+
290317
$this->logger->warning('iMip message could not be processed because no corresponding event was found in any calendar');
291318

292319
return false;
@@ -437,4 +464,32 @@ public function checkAvailability(
437464

438465
return $result;
439466
}
467+
468+
public function getPrimaryCalendar(string $userId): ?ICalendar {
469+
// determine if the principal has a default calendar configured
470+
$properties = $this->propertyMapper->findPropertyByPathAndName(
471+
$userId,
472+
'principals/users/' . $userId,
473+
'{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL'
474+
);
475+
if ($properties === []) {
476+
return null;
477+
}
478+
// extract the calendar URI from the property value
479+
$propertyValue = $properties[0]->getPropertyvalue() ?? null;
480+
if (str_starts_with($propertyValue, 'calendars/' . $userId)) {
481+
$calendarUri = rtrim(str_replace('calendars/' . $userId . '/', '', $propertyValue), '/');
482+
}
483+
if (empty($calendarUri)) {
484+
return null;
485+
}
486+
// retrieve the calendar by URI
487+
$calendars = $this->getCalendarsForPrincipal('principals/users/' . $userId, [$calendarUri]);
488+
if ($calendars === []) {
489+
return null;
490+
}
491+
492+
return $calendars[0];
493+
}
494+
440495
}

tests/lib/Calendar/ManagerTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class ManagerTest extends TestCase {
5858

5959
private IUserManager&MockObject $userManager;
6060
private ServerFactory&MockObject $serverFactory;
61+
private PropertyMapper&MockObject $propertyMapper;
6162

6263
private VCalendar $vCalendar1a;
6364
private VCalendar $vCalendar2a;
@@ -73,6 +74,7 @@ protected function setUp(): void {
7374
$this->secureRandom = $this->createMock(ISecureRandom::class);
7475
$this->userManager = $this->createMock(IUserManager::class);
7576
$this->serverFactory = $this->createMock(ServerFactory::class);
77+
$this->propertyMapper = $this->createMock(PropertyMapper::class);
7678

7779
$this->manager = new Manager(
7880
$this->coordinator,
@@ -82,6 +84,7 @@ protected function setUp(): void {
8284
$this->secureRandom,
8385
$this->userManager,
8486
$this->serverFactory,
87+
$this->propertyMapper,
8588
);
8689

8790
// construct calendar with a 1 hour event and same start/end time zones
@@ -329,6 +332,7 @@ public function testHandleImipWithNoCalendars(): void {
329332
$this->secureRandom,
330333
$this->userManager,
331334
$this->serverFactory,
335+
$this->propertyMapper,
332336
])
333337
->onlyMethods(['getCalendarsForPrincipal'])
334338
->getMock();
@@ -362,6 +366,7 @@ public function testHandleImipWithNoEvent(): void {
362366
$this->secureRandom,
363367
$this->userManager,
364368
$this->serverFactory,
369+
$this->propertyMapper,
365370
])
366371
->onlyMethods(['getCalendarsForPrincipal'])
367372
->getMock();
@@ -396,6 +401,7 @@ public function testHandleImipWithNoUid(): void {
396401
$this->secureRandom,
397402
$this->userManager,
398403
$this->serverFactory,
404+
$this->propertyMapper,
399405
])
400406
->onlyMethods(['getCalendarsForPrincipal'])
401407
->getMock();
@@ -439,6 +445,7 @@ public function testHandleImipWithNoMatch(): void {
439445
$this->secureRandom,
440446
$this->userManager,
441447
$this->serverFactory,
448+
$this->propertyMapper,
442449
])
443450
->onlyMethods(['getCalendarsForPrincipal'])
444451
->getMock();
@@ -481,6 +488,7 @@ public function testHandleImip(): void {
481488
$this->secureRandom,
482489
$this->userManager,
483490
$this->serverFactory,
491+
$this->propertyMapper,
484492
])
485493
->onlyMethods(['getCalendarsForPrincipal'])
486494
->getMock();
@@ -528,6 +536,7 @@ public function testhandleIMipRequest() {
528536
$this->secureRandom,
529537
$this->userManager,
530538
$this->serverFactory,
539+
$this->propertyMapper,
531540
])
532541
->onlyMethods(['handleIMip'])
533542
->getMock();
@@ -570,6 +579,7 @@ public function testhandleIMipReply() {
570579
$this->secureRandom,
571580
$this->userManager,
572581
$this->serverFactory,
582+
$this->propertyMapper,
573583
])
574584
->onlyMethods(['handleIMip'])
575585
->getMock();
@@ -614,6 +624,7 @@ public function testhandleIMipCancel() {
614624
$this->secureRandom,
615625
$this->userManager,
616626
$this->serverFactory,
627+
$this->propertyMapper,
617628
])
618629
->onlyMethods(['handleIMip'])
619630
->getMock();

0 commit comments

Comments
 (0)