Skip to content

Commit d9aec9b

Browse files
committed
fix(caldav-delegation): send notification to delegator
Signed-off-by: Hamza <hamzamahjoubi221@gmail.com>
1 parent 8609cd4 commit d9aec9b

8 files changed

Lines changed: 390 additions & 0 deletions

File tree

apps/dav/composer/composer/autoload_classmap.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@
121121
'OCA\\DAV\\CalDAV\\ResourceBooking\\ResourcePrincipalBackend' => $baseDir . '/../lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php',
122122
'OCA\\DAV\\CalDAV\\ResourceBooking\\RoomPrincipalBackend' => $baseDir . '/../lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php',
123123
'OCA\\DAV\\CalDAV\\RetentionService' => $baseDir . '/../lib/CalDAV/RetentionService.php',
124+
'OCA\\DAV\\CalDAV\\Schedule\\DelegateActionCapturePlugin' => $baseDir . '/../lib/CalDAV/Schedule/DelegateActionCapturePlugin.php',
125+
'OCA\\DAV\\CalDAV\\Schedule\\DelegateActionContext' => $baseDir . '/../lib/CalDAV/Schedule/DelegateActionContext.php',
124126
'OCA\\DAV\\CalDAV\\Schedule\\IMipPlugin' => $baseDir . '/../lib/CalDAV/Schedule/IMipPlugin.php',
125127
'OCA\\DAV\\CalDAV\\Schedule\\IMipService' => $baseDir . '/../lib/CalDAV/Schedule/IMipService.php',
126128
'OCA\\DAV\\CalDAV\\Schedule\\Plugin' => $baseDir . '/../lib/CalDAV/Schedule/Plugin.php',
@@ -331,6 +333,7 @@
331333
'OCA\\DAV\\Listener\\AddressbookListener' => $baseDir . '/../lib/Listener/AddressbookListener.php',
332334
'OCA\\DAV\\Listener\\BirthdayListener' => $baseDir . '/../lib/Listener/BirthdayListener.php',
333335
'OCA\\DAV\\Listener\\CalendarContactInteractionListener' => $baseDir . '/../lib/Listener/CalendarContactInteractionListener.php',
336+
'OCA\\DAV\\Listener\\CalendarDelegateActionListener' => $baseDir . '/../lib/Listener/CalendarDelegateActionListener.php',
334337
'OCA\\DAV\\Listener\\CalendarDeletionDefaultUpdaterListener' => $baseDir . '/../lib/Listener/CalendarDeletionDefaultUpdaterListener.php',
335338
'OCA\\DAV\\Listener\\CalendarFederationNotificationListener' => $baseDir . '/../lib/Listener/CalendarFederationNotificationListener.php',
336339
'OCA\\DAV\\Listener\\CalendarObjectReminderUpdaterListener' => $baseDir . '/../lib/Listener/CalendarObjectReminderUpdaterListener.php',

apps/dav/composer/composer/autoload_static.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ class ComposerStaticInitDAV
136136
'OCA\\DAV\\CalDAV\\ResourceBooking\\ResourcePrincipalBackend' => __DIR__ . '/..' . '/../lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php',
137137
'OCA\\DAV\\CalDAV\\ResourceBooking\\RoomPrincipalBackend' => __DIR__ . '/..' . '/../lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php',
138138
'OCA\\DAV\\CalDAV\\RetentionService' => __DIR__ . '/..' . '/../lib/CalDAV/RetentionService.php',
139+
'OCA\\DAV\\CalDAV\\Schedule\\DelegateActionCapturePlugin' => __DIR__ . '/..' . '/../lib/CalDAV/Schedule/DelegateActionCapturePlugin.php',
140+
'OCA\\DAV\\CalDAV\\Schedule\\DelegateActionContext' => __DIR__ . '/..' . '/../lib/CalDAV/Schedule/DelegateActionContext.php',
139141
'OCA\\DAV\\CalDAV\\Schedule\\IMipPlugin' => __DIR__ . '/..' . '/../lib/CalDAV/Schedule/IMipPlugin.php',
140142
'OCA\\DAV\\CalDAV\\Schedule\\IMipService' => __DIR__ . '/..' . '/../lib/CalDAV/Schedule/IMipService.php',
141143
'OCA\\DAV\\CalDAV\\Schedule\\Plugin' => __DIR__ . '/..' . '/../lib/CalDAV/Schedule/Plugin.php',
@@ -346,6 +348,7 @@ class ComposerStaticInitDAV
346348
'OCA\\DAV\\Listener\\AddressbookListener' => __DIR__ . '/..' . '/../lib/Listener/AddressbookListener.php',
347349
'OCA\\DAV\\Listener\\BirthdayListener' => __DIR__ . '/..' . '/../lib/Listener/BirthdayListener.php',
348350
'OCA\\DAV\\Listener\\CalendarContactInteractionListener' => __DIR__ . '/..' . '/../lib/Listener/CalendarContactInteractionListener.php',
351+
'OCA\\DAV\\Listener\\CalendarDelegateActionListener' => __DIR__ . '/..' . '/../lib/Listener/CalendarDelegateActionListener.php',
349352
'OCA\\DAV\\Listener\\CalendarDeletionDefaultUpdaterListener' => __DIR__ . '/..' . '/../lib/Listener/CalendarDeletionDefaultUpdaterListener.php',
350353
'OCA\\DAV\\Listener\\CalendarFederationNotificationListener' => __DIR__ . '/..' . '/../lib/Listener/CalendarFederationNotificationListener.php',
351354
'OCA\\DAV\\Listener\\CalendarObjectReminderUpdaterListener' => __DIR__ . '/..' . '/../lib/Listener/CalendarObjectReminderUpdaterListener.php',

apps/dav/lib/AppInfo/Application.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
use OCA\DAV\Listener\AddressbookListener;
4949
use OCA\DAV\Listener\BirthdayListener;
5050
use OCA\DAV\Listener\CalendarContactInteractionListener;
51+
use OCA\DAV\Listener\CalendarDelegateActionListener;
5152
use OCA\DAV\Listener\CalendarDeletionDefaultUpdaterListener;
5253
use OCA\DAV\Listener\CalendarFederationNotificationListener;
5354
use OCA\DAV\Listener\CalendarObjectReminderUpdaterListener;
@@ -217,6 +218,12 @@ public function register(IRegistrationContext $context): void {
217218
$context->registerEventListener(CalendarObjectUpdatedEvent::class, CalendarFederationNotificationListener::class);
218219
$context->registerEventListener(CalendarObjectDeletedEvent::class, CalendarFederationNotificationListener::class);
219220

221+
$context->registerEventListener(CalendarObjectCreatedEvent::class, CalendarDelegateActionListener::class);
222+
$context->registerEventListener(CalendarObjectUpdatedEvent::class, CalendarDelegateActionListener::class);
223+
$context->registerEventListener(CalendarObjectDeletedEvent::class, CalendarDelegateActionListener::class);
224+
$context->registerEventListener(CalendarObjectMovedToTrashEvent::class, CalendarDelegateActionListener::class);
225+
$context->registerEventListener(CalendarObjectRestoredEvent::class, CalendarDelegateActionListener::class);
226+
220227
$context->registerNotifierService(NotifierCalDAV::class);
221228
$context->registerNotifierService(NotifierCardDAV::class);
222229

apps/dav/lib/CalDAV/EmbeddedCalDavServer.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use OCA\DAV\CalDAV\Auth\CustomPrincipalPlugin;
1414
use OCA\DAV\CalDAV\Auth\PublicPrincipalPlugin;
1515
use OCA\DAV\CalDAV\Publishing\PublishPlugin;
16+
use OCA\DAV\CalDAV\Schedule\DelegateActionCapturePlugin;
1617
use OCA\DAV\CalDAV\Schedule\IMipPlugin;
1718
use OCA\DAV\Connector\Sabre\AnonymousOptionsPlugin;
1819
use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin;
@@ -97,6 +98,7 @@ public function __construct(bool $public = true) {
9798
if ($appConfig->getValueString('dav', 'sendInvitations', 'yes') === 'yes') {
9899
$this->server->addPlugin(Server::get(IMipPlugin::class));
99100
}
101+
$this->server->addPlugin(Server::get(DelegateActionCapturePlugin::class));
100102

101103
// collection preload plugin
102104
$this->server->addPlugin(new PropFindPreloadNotifyPlugin());
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OCA\DAV\CalDAV\Schedule;
11+
12+
use OCA\DAV\CalDAV\CalendarObject;
13+
use Sabre\DAV\INode;
14+
use Sabre\DAV\Server;
15+
use Sabre\DAV\ServerPlugin;
16+
use Sabre\VObject\Component\VCalendar;
17+
use Sabre\VObject\Reader;
18+
use Throwable;
19+
20+
/**
21+
* Captures the iCalendar payload of a calendar object before it is overwritten
22+
* (PUT) or deleted (DELETE), and stashes it in DelegateActionContext so that
23+
* CalendarDelegateActionListener can diff old vs new when it fires later in
24+
* the same request.
25+
*/
26+
class DelegateActionCapturePlugin extends ServerPlugin {
27+
28+
private ?Server $server = null;
29+
30+
public function __construct(
31+
private readonly DelegateActionContext $context,
32+
) {
33+
}
34+
35+
#[\Override]
36+
public function initialize(Server $server): void {
37+
$this->server = $server;
38+
$server->on('beforeWriteContent', [$this, 'beforeWriteContent'], 10);
39+
$server->on('beforeUnbind', [$this, 'beforeUnbind'], 10);
40+
}
41+
42+
#[\Override]
43+
public function getPluginName(): string {
44+
return 'nc-delegate-action-capture';
45+
}
46+
47+
public function beforeWriteContent(string $uri, INode $node, $data, $modified): void {
48+
$this->capture($node);
49+
}
50+
51+
public function beforeUnbind(string $path): void {
52+
if ($this->server === null) {
53+
return;
54+
}
55+
try {
56+
$node = $this->server->tree->getNodeForPath($path);
57+
} catch (Throwable) {
58+
return;
59+
}
60+
$this->capture($node);
61+
}
62+
63+
private function capture(INode $node): void {
64+
if (!$node instanceof CalendarObject) {
65+
return;
66+
}
67+
try {
68+
$raw = $node->get();
69+
if ($raw === '') {
70+
return;
71+
}
72+
$vCalendar = Reader::read($raw);
73+
if ($vCalendar instanceof VCalendar) {
74+
$this->context->setPrevious($vCalendar);
75+
}
76+
} catch (Throwable) {
77+
// Capture is best-effort: swallow malformed iCalendar.
78+
}
79+
}
80+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OCA\DAV\CalDAV\Schedule;
11+
12+
use Sabre\VObject\Component\VCalendar;
13+
14+
/**
15+
* Request-scoped container that lets a Sabre plugin (capturing the
16+
* pre-write iCalendar in beforeWriteContent / beforeUnbind) hand the
17+
* previous VCalendar to the CalendarDelegateActionListener, which fires
18+
* later in the same request from the CalDavBackend event dispatcher.
19+
*/
20+
class DelegateActionContext {
21+
22+
private ?VCalendar $previous = null;
23+
24+
public function setPrevious(?VCalendar $vCalendar): void {
25+
$this->previous = $vCalendar;
26+
}
27+
28+
public function getPrevious(): ?VCalendar {
29+
return $this->previous;
30+
}
31+
}

0 commit comments

Comments
 (0)