Skip to content

Commit 78f33c5

Browse files
committed
fixup! feat: calendar federation
1 parent a4d2e27 commit 78f33c5

15 files changed

+122
-58
lines changed

apps/dav/appinfo/info.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<name>WebDAV</name>
1111
<summary>WebDAV endpoint</summary>
1212
<description>WebDAV endpoint</description>
13-
<version>1.34.1</version>
13+
<version>1.34.2</version>
1414
<licence>agpl</licence>
1515
<author>owncloud.org</author>
1616
<namespace>DAV</namespace>
@@ -30,6 +30,7 @@
3030
<job>OCA\DAV\BackgroundJob\EventReminderJob</job>
3131
<job>OCA\DAV\BackgroundJob\CalendarRetentionJob</job>
3232
<job>OCA\DAV\BackgroundJob\PruneOutdatedSyncTokensJob</job>
33+
<job>OCA\DAV\BackgroundJob\FederatedCalendarSyncJob</job>
3334
</background-jobs>
3435

3536
<repair-steps>

apps/dav/composer/composer/autoload_classmap.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
'OCA\\DAV\\BackgroundJob\\CleanupOrphanedChildrenJob' => $baseDir . '/../lib/BackgroundJob/CleanupOrphanedChildrenJob.php',
2020
'OCA\\DAV\\BackgroundJob\\DeleteOutdatedSchedulingObjects' => $baseDir . '/../lib/BackgroundJob/DeleteOutdatedSchedulingObjects.php',
2121
'OCA\\DAV\\BackgroundJob\\EventReminderJob' => $baseDir . '/../lib/BackgroundJob/EventReminderJob.php',
22+
'OCA\\DAV\\BackgroundJob\\FederatedCalendarsSyncJob' => $baseDir . '/../lib/BackgroundJob/FederatedCalendarsSyncJob.php',
2223
'OCA\\DAV\\BackgroundJob\\GenerateBirthdayCalendarBackgroundJob' => $baseDir . '/../lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php',
2324
'OCA\\DAV\\BackgroundJob\\OutOfOfficeEventDispatcherJob' => $baseDir . '/../lib/BackgroundJob/OutOfOfficeEventDispatcherJob.php',
2425
'OCA\\DAV\\BackgroundJob\\PruneOutdatedSyncTokensJob' => $baseDir . '/../lib/BackgroundJob/PruneOutdatedSyncTokensJob.php',
@@ -65,6 +66,7 @@
6566
'OCA\\DAV\\CalDAV\\EventReaderRDate' => $baseDir . '/../lib/CalDAV/EventReaderRDate.php',
6667
'OCA\\DAV\\CalDAV\\EventReaderRRule' => $baseDir . '/../lib/CalDAV/EventReaderRRule.php',
6768
'OCA\\DAV\\CalDAV\\Export\\ExportService' => $baseDir . '/../lib/CalDAV/Export/ExportService.php',
69+
'OCA\\DAV\\CalDAV\\Federation\\CalendarFederationConfig' => $baseDir . '/../lib/CalDAV/Federation/CalendarFederationConfig.php',
6870
'OCA\\DAV\\CalDAV\\Federation\\CalendarFederationProvider' => $baseDir . '/../lib/CalDAV/Federation/CalendarFederationProvider.php',
6971
'OCA\\DAV\\CalDAV\\Federation\\FederatedCalendar' => $baseDir . '/../lib/CalDAV/Federation/FederatedCalendar.php',
7072
'OCA\\DAV\\CalDAV\\Federation\\FederatedCalendarAuth' => $baseDir . '/../lib/CalDAV/Federation/FederatedCalendarAuth.php',

apps/dav/composer/composer/autoload_static.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class ComposerStaticInitDAV
3434
'OCA\\DAV\\BackgroundJob\\CleanupOrphanedChildrenJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupOrphanedChildrenJob.php',
3535
'OCA\\DAV\\BackgroundJob\\DeleteOutdatedSchedulingObjects' => __DIR__ . '/..' . '/../lib/BackgroundJob/DeleteOutdatedSchedulingObjects.php',
3636
'OCA\\DAV\\BackgroundJob\\EventReminderJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/EventReminderJob.php',
37+
'OCA\\DAV\\BackgroundJob\\FederatedCalendarsSyncJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/FederatedCalendarsSyncJob.php',
3738
'OCA\\DAV\\BackgroundJob\\GenerateBirthdayCalendarBackgroundJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/GenerateBirthdayCalendarBackgroundJob.php',
3839
'OCA\\DAV\\BackgroundJob\\OutOfOfficeEventDispatcherJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/OutOfOfficeEventDispatcherJob.php',
3940
'OCA\\DAV\\BackgroundJob\\PruneOutdatedSyncTokensJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/PruneOutdatedSyncTokensJob.php',
@@ -80,6 +81,7 @@ class ComposerStaticInitDAV
8081
'OCA\\DAV\\CalDAV\\EventReaderRDate' => __DIR__ . '/..' . '/../lib/CalDAV/EventReaderRDate.php',
8182
'OCA\\DAV\\CalDAV\\EventReaderRRule' => __DIR__ . '/..' . '/../lib/CalDAV/EventReaderRRule.php',
8283
'OCA\\DAV\\CalDAV\\Export\\ExportService' => __DIR__ . '/..' . '/../lib/CalDAV/Export/ExportService.php',
84+
'OCA\\DAV\\CalDAV\\Federation\\CalendarFederationConfig' => __DIR__ . '/..' . '/../lib/CalDAV/Federation/CalendarFederationConfig.php',
8385
'OCA\\DAV\\CalDAV\\Federation\\CalendarFederationProvider' => __DIR__ . '/..' . '/../lib/CalDAV/Federation/CalendarFederationProvider.php',
8486
'OCA\\DAV\\CalDAV\\Federation\\FederatedCalendar' => __DIR__ . '/..' . '/../lib/CalDAV/Federation/FederatedCalendar.php',
8587
'OCA\\DAV\\CalDAV\\Federation\\FederatedCalendarAuth' => __DIR__ . '/..' . '/../lib/CalDAV/Federation/FederatedCalendarAuth.php',

apps/dav/lib/AppInfo/Application.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,12 +297,6 @@ public function registerCloudFederationProvider(
297297
CalendarFederationProvider::PROVIDER_ID,
298298
'Calendar Federation',
299299
static fn() => Server::get(CalendarFederationProvider::class),
300-
/*
301-
static fn (): ICloudFederationProvider => new CalendarFederationProvider(
302-
Server::get(CalDavBackend::class),
303-
Server::get(LoggerInterface::class),
304-
),
305-
*/
306300
);
307301
}
308302
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OCA\DAV\BackgroundJob;
11+
12+
use OCA\DAV\CalDAV\Federation\CalendarFederationConfig;
13+
use OCA\DAV\CalDAV\Federation\FederatedCalendarMapper;
14+
use OCA\DAV\CalDAV\Federation\FederatedCalendarSyncService;
15+
use OCP\AppFramework\Utility\ITimeFactory;
16+
use OCP\BackgroundJob\TimedJob;
17+
18+
class FederatedCalendarsSyncJob extends TimedJob {
19+
public function __construct(
20+
ITimeFactory $time,
21+
private readonly FederatedCalendarSyncService $syncService,
22+
private readonly FederatedCalendarMapper $federatedCalendarMapper,
23+
private readonly CalendarFederationConfig $calendarFederationConfig,
24+
) {
25+
parent::__construct($time);
26+
27+
$this->setTimeSensitivity(self::TIME_SENSITIVE);
28+
$this->setAllowParallelRuns(false);
29+
$this->setInterval(3600);
30+
}
31+
32+
protected function run($argument): void {
33+
if (!$this->calendarFederationConfig->isFederationEnabled()) {
34+
return;
35+
}
36+
37+
$oneHourAgo = $this->time->getTime() - 3600;
38+
$calendars = $this->federatedCalendarMapper->findUnsyncedSinceBefore($oneHourAgo);
39+
foreach ($calendars as $calendar) {
40+
$this->syncService->syncOne($calendar);
41+
}
42+
}
43+
}

apps/dav/lib/CalDAV/AppCalendar/AppCalendarPlugin.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use OCA\DAV\CalDAV\CachedSubscriptionImpl;
1313
use OCA\DAV\CalDAV\CalendarImpl;
14+
use OCA\DAV\CalDAV\Federation\FederatedCalendarImpl;
1415
use OCA\DAV\CalDAV\Integration\ExternalCalendar;
1516
use OCA\DAV\CalDAV\Integration\ICalendarProvider;
1617
use OCP\Calendar\IManager;
@@ -51,7 +52,11 @@ protected function getWrappedCalendars(string $principalUri, array $calendarUris
5152
return array_values(
5253
array_filter($this->manager->getCalendarsForPrincipal($principalUri, $calendarUris), function ($c) {
5354
// We must not provide a wrapper for DAV calendars
54-
return ! (($c instanceof CalendarImpl) || ($c instanceof CachedSubscriptionImpl));
55+
return !(
56+
($c instanceof CalendarImpl)
57+
|| ($c instanceof CachedSubscriptionImpl)
58+
|| ($c instanceof FederatedCalendarImpl)
59+
);
5560
})
5661
);
5762
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OCA\DAV\CalDAV\Federation;
11+
12+
use OCP\AppFramework\Services\IAppConfig;
13+
14+
final class CalendarFederationConfig {
15+
public function __construct(
16+
private readonly IAppConfig $appConfig,
17+
) {
18+
}
19+
20+
public function isFederationEnabled(): bool {
21+
return $this->appConfig->getAppValueBool('enableCalendarFederation', true);
22+
}
23+
}

apps/dav/lib/CalDAV/Federation/CalendarFederationProvider.php

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
use OCA\DAV\CalDAV\Federation\Protocol\ICalendarFederationProtocol;
1414
use OCA\DAV\DAV\Sharing\Backend as DavSharingBackend;
1515
use OCP\AppFramework\Http;
16-
use OCP\AppFramework\Services\IAppConfig;
1716
use OCP\Federation\Exceptions\ProviderCouldNotAddShareException;
1817
use OCP\Federation\ICloudFederationProvider;
1918
use OCP\Federation\ICloudFederationShare;
@@ -27,7 +26,7 @@ class CalendarFederationProvider implements ICloudFederationProvider {
2726
public function __construct(
2827
private readonly LoggerInterface $logger,
2928
private readonly FederatedCalendarMapper $federatedCalendarMapper,
30-
private readonly IAppConfig $appConfig,
29+
private readonly CalendarFederationConfig $calendarFederationConfig,
3130
) {
3231
}
3332

@@ -36,7 +35,7 @@ public function getShareType(): string {
3635
}
3736

3837
public function shareReceived(ICloudFederationShare $share): string {
39-
if (!$this->isFederationEnabled()) {
38+
if (!$this->calendarFederationConfig->isFederationEnabled()) {
4039
$this->logger->debug('Received a federation invite but federation is disabled');
4140
throw new ProviderCouldNotAddShareException(
4241
'Server does not support talk federation',
@@ -104,25 +103,6 @@ public function shareReceived(ICloudFederationShare $share): string {
104103
$calendarUri = hash('md5', $calendarUrl);
105104

106105
$sharedWithPrincipal = 'principals/users/' . $share->getShareWith();
107-
/*
108-
$hasExistingCalendar = $this->federatedCalendarMapper->hasCalendarWithUriAndPrincipalUri(
109-
$calendarUri,
110-
$sharedWithPrincipal,
111-
);
112-
if ($hasExistingCalendar) {
113-
throw new ProviderCouldNotAddShareException(
114-
'Calendar has already been shared with the user',
115-
'',
116-
Http::STATUS_CONFLICT,
117-
);
118-
}
119-
*/
120-
/*
121-
$existingCalendar = $this->federatedCalendarMapper->findByUri(
122-
$sharedWithPrincipal,
123-
$calendarUri,
124-
);
125-
*/
126106

127107
// Delete existing incoming federated share first
128108
$this->federatedCalendarMapper->deleteByUri($sharedWithPrincipal, $calendarUri);
@@ -143,6 +123,7 @@ public function shareReceived(ICloudFederationShare $share): string {
143123
}
144124

145125
public function notificationReceived($notificationType, $providerId, array $notification) {
126+
// TODO: implement a notification to queue a sync job immediately if a calendar is changed
146127
}
147128

148129
/**
@@ -151,8 +132,4 @@ public function notificationReceived($notificationType, $providerId, array $noti
151132
public function getSupportedShareTypes(): array {
152133
return [self::USER_SHARE_TYPE];
153134
}
154-
155-
private function isFederationEnabled(): bool {
156-
return $this->appConfig->getAppValueBool('enableCalendarFederation', true);
157-
}
158135
}

apps/dav/lib/CalDAV/Federation/FederatedCalendarAuth.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace OCA\DAV\CalDAV\Federation;
1111

12+
use OCA\DAV\DAV\RemoteUserPrincipalBackend;
1213
use OCP\DB\QueryBuilder\IQueryBuilder;
1314
use OCP\Defaults;
1415
use OCP\IDBConnection;
@@ -35,7 +36,7 @@ private function validateUserPass(
3536
string $username,
3637
string $password,
3738
): ?string {
38-
$remoteUserPrincipalUri = 'principals/remote-users/' . base64_encode($username);
39+
$remoteUserPrincipalUri = RemoteUserPrincipalBackend::PRINCIPAL_PREFIX . '/' . base64_encode($username);
3940
[, $remoteUserPrincipalId] = \Sabre\Uri\split($remoteUserPrincipalUri);
4041

4142
$qb = $this->db->getQueryBuilder();

apps/dav/lib/CalDAV/Federation/FederatedCalendarEntity.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace OCA\DAV\CalDAV\Federation;
1111

12+
use OCA\DAV\DAV\RemoteUserPrincipalBackend;
1213
use OCP\AppFramework\Db\Entity;
1314
use OCP\DB\Types;
1415
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet;
@@ -75,7 +76,7 @@ public function getSyncTokenForSabre(): string {
7576
}
7677

7778
public function getSharedByPrincipal(): string {
78-
return 'principals/remote-users/' . base64_encode($this->getSharedBy());
79+
return RemoteUserPrincipalBackend::PRINCIPAL_PREFIX . '/' . base64_encode($this->getSharedBy());
7980
}
8081

8182
public function getSupportedCalendarComponentSet(): SupportedCalendarComponentSet {

0 commit comments

Comments
 (0)