From f8a87f8cdccdd9d6ebb2b04b73f392267503dc41 Mon Sep 17 00:00:00 2001
From: Christoph Wurst <christoph@winzerhof-wurst.at>
Date: Tue, 2 Feb 2021 10:38:22 +0100
Subject: [PATCH] Emit an interaction event for calendar event user attendees

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
---
 apps/dav/lib/AppInfo/Application.php          |  4 ++
 .../CalendarContactInteractionListener.php    | 49 +++++++++++++------
 2 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/apps/dav/lib/AppInfo/Application.php b/apps/dav/lib/AppInfo/Application.php
index 09081403140..f1bf77c3285 100644
--- a/apps/dav/lib/AppInfo/Application.php
+++ b/apps/dav/lib/AppInfo/Application.php
@@ -53,6 +53,8 @@ use OCA\DAV\CardDAV\CardDavBackend;
 use OCA\DAV\CardDAV\ContactsManager;
 use OCA\DAV\CardDAV\PhotoCache;
 use OCA\DAV\CardDAV\SyncService;
+use OCA\DAV\Events\CalendarObjectCreatedEvent;
+use OCA\DAV\Events\CalendarObjectUpdatedEvent;
 use OCA\DAV\Events\CalendarShareUpdatedEvent;
 use OCA\DAV\HookManager;
 use OCA\DAV\Listener\CalendarContactInteractionListener;
@@ -112,6 +114,8 @@ class Application extends App implements IBootstrap {
 		/**
 		 * Register event listeners
 		 */
+		$context->registerEventListener(CalendarObjectCreatedEvent::class, CalendarContactInteractionListener::class);
+		$context->registerEventListener(CalendarObjectUpdatedEvent::class, CalendarContactInteractionListener::class);
 		$context->registerEventListener(CalendarShareUpdatedEvent::class, CalendarContactInteractionListener::class);
 	}
 
diff --git a/apps/dav/lib/Listener/CalendarContactInteractionListener.php b/apps/dav/lib/Listener/CalendarContactInteractionListener.php
index a0b94c34f1f..62bddd500e4 100644
--- a/apps/dav/lib/Listener/CalendarContactInteractionListener.php
+++ b/apps/dav/lib/Listener/CalendarContactInteractionListener.php
@@ -26,11 +26,14 @@ declare(strict_types=1);
 namespace OCA\DAV\Listener;
 
 use OCA\DAV\Connector\Sabre\Principal;
+use OCA\DAV\Events\CalendarObjectCreatedEvent;
+use OCA\DAV\Events\CalendarObjectUpdatedEvent;
 use OCA\DAV\Events\CalendarShareUpdatedEvent;
 use OCP\Contacts\Events\ContactInteractedWithEvent;
 use OCP\EventDispatcher\Event;
 use OCP\EventDispatcher\IEventDispatcher;
 use OCP\EventDispatcher\IEventListener;
+use OCP\IUser;
 use OCP\IUserSession;
 use Psr\Log\LoggerInterface;
 use function strlen;
@@ -68,6 +71,17 @@ class CalendarContactInteractionListener implements IEventListener {
 			return;
 		}
 
+		if ($event instanceof CalendarObjectCreatedEvent || $event instanceof CalendarObjectUpdatedEvent) {
+			// users: href => principal:principals/users/admin
+			// TODO: parse (email) attendees from the VCARD
+			foreach ($event->getShares() as $share) {
+				if (!isset($share['href'])) {
+					continue;
+				}
+				$this->emitFromUri($share['href'], $user);
+			}
+		}
+
 		if ($event instanceof CalendarShareUpdatedEvent && !empty($event->getAdded())) {
 			// group: href => principal:principals/groups/admin
 			// users: href => principal:principals/users/admin
@@ -76,21 +90,28 @@ class CalendarContactInteractionListener implements IEventListener {
 					// Nothing to work with
 					continue;
 				}
-				$principal = $this->principalConnector->findByUri(
-					$added['href'],
-					$this->principalConnector->getPrincipalPrefix()
-				);
-				if ($principal === null) {
-					// Invalid principal
-					continue;
-				}
-				if (strpos($principal, self::URI_USERS) === 0) {
-					$uid = substr($principal, strlen(self::URI_USERS));
-					$this->dispatcher->dispatchTyped(
-						(new ContactInteractedWithEvent($user))->setUid($uid)
-					);
-				}
+				$this->emitFromUri($added['href'], $user);
 			}
 		}
 	}
+
+	private function emitFromUri(string $uri, IUser $user): void {
+		$principal = $this->principalConnector->findByUri(
+			$uri,
+			$this->principalConnector->getPrincipalPrefix()
+		);
+		if ($principal === null) {
+			// Invalid principal
+			return;
+		}
+		if (strpos($principal, self::URI_USERS) !== 0) {
+			// Not a user principal
+			return;
+		}
+
+		$uid = substr($principal, strlen(self::URI_USERS));
+		$this->dispatcher->dispatchTyped(
+			(new ContactInteractedWithEvent($user))->setUid($uid)
+		);
+	}
 }
-- 
GitLab