Skip to content

Commit 62f9f4f

Browse files
Merge pull request #25462 from nextcloud/backport/25432/stable21
[stable21] Emit calendar interaction events
2 parents 207b7d5 + f8a87f8 commit 62f9f4f

4 files changed

Lines changed: 130 additions & 0 deletions

File tree

apps/dav/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@
204204
'OCA\\DAV\\Files\\Sharing\\FilesDropPlugin' => $baseDir . '/../lib/Files/Sharing/FilesDropPlugin.php',
205205
'OCA\\DAV\\Files\\Sharing\\PublicLinkCheckPlugin' => $baseDir . '/../lib/Files/Sharing/PublicLinkCheckPlugin.php',
206206
'OCA\\DAV\\HookManager' => $baseDir . '/../lib/HookManager.php',
207+
'OCA\\DAV\\Listener\\CalendarContactInteractionListener' => $baseDir . '/../lib/Listener/CalendarContactInteractionListener.php',
207208
'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndex.php',
208209
'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
209210
'OCA\\DAV\\Migration\\BuildSocialSearchIndex' => $baseDir . '/../lib/Migration/BuildSocialSearchIndex.php',

apps/dav/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ class ComposerStaticInitDAV
219219
'OCA\\DAV\\Files\\Sharing\\FilesDropPlugin' => __DIR__ . '/..' . '/../lib/Files/Sharing/FilesDropPlugin.php',
220220
'OCA\\DAV\\Files\\Sharing\\PublicLinkCheckPlugin' => __DIR__ . '/..' . '/../lib/Files/Sharing/PublicLinkCheckPlugin.php',
221221
'OCA\\DAV\\HookManager' => __DIR__ . '/..' . '/../lib/HookManager.php',
222+
'OCA\\DAV\\Listener\\CalendarContactInteractionListener' => __DIR__ . '/..' . '/../lib/Listener/CalendarContactInteractionListener.php',
222223
'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndex.php',
223224
'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
224225
'OCA\\DAV\\Migration\\BuildSocialSearchIndex' => __DIR__ . '/..' . '/../lib/Migration/BuildSocialSearchIndex.php',

apps/dav/lib/AppInfo/Application.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@
5353
use OCA\DAV\CardDAV\ContactsManager;
5454
use OCA\DAV\CardDAV\PhotoCache;
5555
use OCA\DAV\CardDAV\SyncService;
56+
use OCA\DAV\Events\CalendarObjectCreatedEvent;
57+
use OCA\DAV\Events\CalendarObjectUpdatedEvent;
58+
use OCA\DAV\Events\CalendarShareUpdatedEvent;
5659
use OCA\DAV\HookManager;
60+
use OCA\DAV\Listener\CalendarContactInteractionListener;
5761
use OCA\DAV\Search\ContactsSearchProvider;
5862
use OCA\DAV\Search\EventsSearchProvider;
5963
use OCA\DAV\Search\TasksSearchProvider;
@@ -106,6 +110,13 @@ public function register(IRegistrationContext $context): void {
106110
$context->registerSearchProvider(ContactsSearchProvider::class);
107111
$context->registerSearchProvider(EventsSearchProvider::class);
108112
$context->registerSearchProvider(TasksSearchProvider::class);
113+
114+
/**
115+
* Register event listeners
116+
*/
117+
$context->registerEventListener(CalendarObjectCreatedEvent::class, CalendarContactInteractionListener::class);
118+
$context->registerEventListener(CalendarObjectUpdatedEvent::class, CalendarContactInteractionListener::class);
119+
$context->registerEventListener(CalendarShareUpdatedEvent::class, CalendarContactInteractionListener::class);
109120
}
110121

111122
public function boot(IBootContext $context): void {
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
7+
*
8+
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
9+
*
10+
* @license GNU AGPL version 3 or any later version
11+
*
12+
* This program is free software: you can redistribute it and/or modify
13+
* it under the terms of the GNU Affero General Public License as
14+
* published by the Free Software Foundation, either version 3 of the
15+
* License, or (at your option) any later version.
16+
*
17+
* This program is distributed in the hope that it will be useful,
18+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
* GNU Affero General Public License for more details.
21+
*
22+
* You should have received a copy of the GNU Affero General Public License
23+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
24+
*/
25+
26+
namespace OCA\DAV\Listener;
27+
28+
use OCA\DAV\Connector\Sabre\Principal;
29+
use OCA\DAV\Events\CalendarObjectCreatedEvent;
30+
use OCA\DAV\Events\CalendarObjectUpdatedEvent;
31+
use OCA\DAV\Events\CalendarShareUpdatedEvent;
32+
use OCP\Contacts\Events\ContactInteractedWithEvent;
33+
use OCP\EventDispatcher\Event;
34+
use OCP\EventDispatcher\IEventDispatcher;
35+
use OCP\EventDispatcher\IEventListener;
36+
use OCP\IUser;
37+
use OCP\IUserSession;
38+
use Psr\Log\LoggerInterface;
39+
use function strlen;
40+
use function strpos;
41+
use function substr;
42+
43+
class CalendarContactInteractionListener implements IEventListener {
44+
private const URI_USERS = 'principals/users/';
45+
46+
/** @var IEventDispatcher */
47+
private $dispatcher;
48+
49+
/** @var IUserSession */
50+
private $userManager;
51+
52+
/** @var Principal */
53+
private $principalConnector;
54+
55+
/** @var LoggerInterface */
56+
private $logger;
57+
58+
public function __construct(IEventDispatcher $dispatcher,
59+
IUserSession $userManager,
60+
Principal $principalConnector,
61+
LoggerInterface $logger) {
62+
$this->dispatcher = $dispatcher;
63+
$this->userManager = $userManager;
64+
$this->principalConnector = $principalConnector;
65+
$this->logger = $logger;
66+
}
67+
68+
public function handle(Event $event): void {
69+
if (($user = $this->userManager->getUser()) === null) {
70+
// Without user context we can't do anything
71+
return;
72+
}
73+
74+
if ($event instanceof CalendarObjectCreatedEvent || $event instanceof CalendarObjectUpdatedEvent) {
75+
// users: href => principal:principals/users/admin
76+
// TODO: parse (email) attendees from the VCARD
77+
foreach ($event->getShares() as $share) {
78+
if (!isset($share['href'])) {
79+
continue;
80+
}
81+
$this->emitFromUri($share['href'], $user);
82+
}
83+
}
84+
85+
if ($event instanceof CalendarShareUpdatedEvent && !empty($event->getAdded())) {
86+
// group: href => principal:principals/groups/admin
87+
// users: href => principal:principals/users/admin
88+
foreach ($event->getAdded() as $added) {
89+
if (!isset($added['href'])) {
90+
// Nothing to work with
91+
continue;
92+
}
93+
$this->emitFromUri($added['href'], $user);
94+
}
95+
}
96+
}
97+
98+
private function emitFromUri(string $uri, IUser $user): void {
99+
$principal = $this->principalConnector->findByUri(
100+
$uri,
101+
$this->principalConnector->getPrincipalPrefix()
102+
);
103+
if ($principal === null) {
104+
// Invalid principal
105+
return;
106+
}
107+
if (strpos($principal, self::URI_USERS) !== 0) {
108+
// Not a user principal
109+
return;
110+
}
111+
112+
$uid = substr($principal, strlen(self::URI_USERS));
113+
$this->dispatcher->dispatchTyped(
114+
(new ContactInteractedWithEvent($user))->setUid($uid)
115+
);
116+
}
117+
}

0 commit comments

Comments
 (0)