From 9cf8ff30971306eb4ba3720858b8348e3ad2b6b3 Mon Sep 17 00:00:00 2001
From: Christoph Wurst <christoph@winzerhof-wurst.at>
Date: Wed, 2 Jun 2021 10:35:46 +0200
Subject: [PATCH] Add missing ACLs for deleted calendar objects to fix deletion

Due to a bug in Sabre it's necessary for calendar objects to implement
ACLs. Otherwise the scheduling plugin will throw an error when it tries
to fetch the owner of a calendar object that is being deleted.

Ref https://github.com/sabre-io/dav/issues/1345

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
---
 .../CalDAV/Trashbin/DeletedCalendarObject.php | 22 +++++++++++++++++--
 .../DeletedCalendarObjectsCollection.php      |  5 +++--
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/apps/dav/lib/CalDAV/Trashbin/DeletedCalendarObject.php b/apps/dav/lib/CalDAV/Trashbin/DeletedCalendarObject.php
index c704f454e7ff8..e669ebfc9b884 100644
--- a/apps/dav/lib/CalDAV/Trashbin/DeletedCalendarObject.php
+++ b/apps/dav/lib/CalDAV/Trashbin/DeletedCalendarObject.php
@@ -29,8 +29,12 @@
 use OCA\DAV\CalDAV\IRestorable;
 use Sabre\CalDAV\ICalendarObject;
 use Sabre\DAV\Exception\Forbidden;
+use Sabre\DAVACL\ACLTrait;
+use Sabre\DAVACL\IACL;
 
-class DeletedCalendarObject implements ICalendarObject, IRestorable {
+class DeletedCalendarObject implements IACL, ICalendarObject, IRestorable {
+
+	use ACLTrait;
 
 	/** @var string */
 	private $name;
@@ -38,19 +42,29 @@ class DeletedCalendarObject implements ICalendarObject, IRestorable {
 	/** @var mixed[] */
 	private $objectData;
 
+	/** @var string */
+	private $principalUri;
+
 	/** @var CalDavBackend */
 	private $calDavBackend;
 
 	public function __construct(string $name,
 								array $objectData,
+								string $principalUri,
 								CalDavBackend $calDavBackend) {
 		$this->name = $name;
 		$this->objectData = $objectData;
 		$this->calDavBackend = $calDavBackend;
+		$this->principalUri = $principalUri;
 	}
 
 	public function delete() {
-		throw new Forbidden();
+		$this->calDavBackend->deleteCalendarObject(
+			$this->objectData['calendarid'],
+			$this->objectData['uri'],
+			CalDavBackend::CALENDAR_TYPE_CALENDAR, // because birthday calendars never go into the bin
+			true
+		);
 	}
 
 	public function getName() {
@@ -101,4 +115,8 @@ public function getDeletedAt(): ?int {
 	public function getCalendarUri(): string {
 		return $this->objectData['calendaruri'];
 	}
+
+	public function getOwner() {
+		return $this->principalUri;
+	}
 }
diff --git a/apps/dav/lib/CalDAV/Trashbin/DeletedCalendarObjectsCollection.php b/apps/dav/lib/CalDAV/Trashbin/DeletedCalendarObjectsCollection.php
index 2d79db03bce16..6b084d7c85767 100644
--- a/apps/dav/lib/CalDAV/Trashbin/DeletedCalendarObjectsCollection.php
+++ b/apps/dav/lib/CalDAV/Trashbin/DeletedCalendarObjectsCollection.php
@@ -78,6 +78,7 @@ public function getChild($name) {
 		return new DeletedCalendarObject(
 			$this->getRelativeObjectPath($data),
 			$data,
+			$this->principalInfo['uri'],
 			$this->caldavBackend
 		);
 	}
@@ -117,8 +118,8 @@ public function getLastModified(): int {
 	}
 
 	public function calendarQuery(array $filters) {
-		return array_map(function (array $calendarInfo) {
-			return $this->getRelativeObjectPath($calendarInfo);
+		return array_map(function (array $calendarObjectInfo) {
+			return $this->getRelativeObjectPath($calendarObjectInfo);
 		}, $this->caldavBackend->getDeletedCalendarObjectsByPrincipal($this->principalInfo['uri']));
 	}