diff options
author | Marcel Klehr <mklehr@gmx.net> | 2023-12-19 16:14:13 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-19 16:14:13 +0100 |
commit | 53be798a70436b77a512a7ea5045b675280f43bc (patch) | |
tree | d5664cc59e2c2e6cbaf5acc6b5b8e4ec08aa8061 /apps | |
parent | e5622171b45639302c173e427c424963a0ff7b9f (diff) | |
parent | 9327e36ef4ad0b306d060c1bbaed1dc3ac4c73ed (diff) | |
download | nextcloud-server-53be798a70436b77a512a7ea5045b675280f43bc.tar.gz nextcloud-server-53be798a70436b77a512a7ea5045b675280f43bc.zip |
Merge branch 'master' into enh/text-processing-provider-with-id
Diffstat (limited to 'apps')
-rw-r--r-- | apps/dav/lib/CalDAV/Schedule/Plugin.php | 68 | ||||
-rw-r--r-- | apps/dav/lib/Connector/Sabre/FilesPlugin.php | 6 | ||||
-rw-r--r-- | apps/settings/lib/Settings/Admin/ArtificialIntelligence.php | 3 |
3 files changed, 72 insertions, 5 deletions
diff --git a/apps/dav/lib/CalDAV/Schedule/Plugin.php b/apps/dav/lib/CalDAV/Schedule/Plugin.php index 2845ccdf6c2..232ee607c94 100644 --- a/apps/dav/lib/CalDAV/Schedule/Plugin.php +++ b/apps/dav/lib/CalDAV/Schedule/Plugin.php @@ -36,11 +36,14 @@ use OCA\DAV\CalDAV\CalendarHome; use OCP\IConfig; use Psr\Log\LoggerInterface; use Sabre\CalDAV\ICalendar; +use Sabre\CalDAV\ICalendarObject; +use Sabre\CalDAV\Schedule\ISchedulingObject; use Sabre\DAV\INode; use Sabre\DAV\IProperties; use Sabre\DAV\PropFind; use Sabre\DAV\Server; use Sabre\DAV\Xml\Property\LocalHref; +use Sabre\DAVACL\IACL; use Sabre\DAVACL\IPrincipal; use Sabre\HTTP\RequestInterface; use Sabre\HTTP\ResponseInterface; @@ -50,6 +53,7 @@ use Sabre\VObject\Component\VEvent; use Sabre\VObject\DateTimeParser; use Sabre\VObject\FreeBusyGenerator; use Sabre\VObject\ITip; +use Sabre\VObject\ITip\SameOrganizerForAllComponentsException; use Sabre\VObject\Parameter; use Sabre\VObject\Property; use Sabre\VObject\Reader; @@ -161,7 +165,29 @@ class Plugin extends \Sabre\CalDAV\Schedule\Plugin { $this->pathOfCalendarObjectChange = $request->getPath(); } - parent::calendarObjectChange($request, $response, $vCal, $calendarPath, $modified, $isNew); + try { + parent::calendarObjectChange($request, $response, $vCal, $calendarPath, $modified, $isNew); + } catch (SameOrganizerForAllComponentsException $e) { + $this->handleSameOrganizerException($e, $vCal, $calendarPath); + } + } + + /** + * @inheritDoc + */ + public function beforeUnbind($path): void { + try { + parent::beforeUnbind($path); + } catch (SameOrganizerForAllComponentsException $e) { + $node = $this->server->tree->getNodeForPath($path); + if (!$node instanceof ICalendarObject || $node instanceof ISchedulingObject) { + throw $e; + } + + /** @var VCalendar $vCal */ + $vCal = Reader::read($node->get()); + $this->handleSameOrganizerException($e, $vCal, $path); + } } /** @@ -630,4 +656,44 @@ EOF; '{DAV:}displayname' => $displayName, ]); } + + /** + * Try to handle the given exception gracefully or throw it if necessary. + * + * @throws SameOrganizerForAllComponentsException If the exception should not be ignored + */ + private function handleSameOrganizerException( + SameOrganizerForAllComponentsException $e, + VCalendar $vCal, + string $calendarPath, + ): void { + // This is very hacky! However, we want to allow saving events with multiple + // organizers. Those events are not RFC compliant, but sometimes imported from major + // external calendar services (e.g. Google). If the current user is not an organizer of + // the event we ignore the exception as no scheduling messages will be sent anyway. + + // It would be cleaner to patch Sabre to validate organizers *after* checking if + // scheduling messages are necessary. Currently, organizers are validated first and + // afterwards the broker checks if messages should be scheduled. So the code will throw + // even if the organizers are not relevant. This is to ensure compliance with RFCs but + // a bit too strict for real world usage. + + if (!isset($vCal->VEVENT)) { + throw $e; + } + + $calendarNode = $this->server->tree->getNodeForPath($calendarPath); + if (!($calendarNode instanceof IACL)) { + // Should always be an instance of IACL but just to be sure + throw $e; + } + + $addresses = $this->getAddressesForPrincipal($calendarNode->getOwner()); + foreach ($vCal->VEVENT as $vevent) { + if (in_array($vevent->ORGANIZER->getNormalizedValue(), $addresses, true)) { + // User is an organizer => throw the exception + throw $e; + } + } + } } diff --git a/apps/dav/lib/Connector/Sabre/FilesPlugin.php b/apps/dav/lib/Connector/Sabre/FilesPlugin.php index 81cdfa464b5..f7904e87883 100644 --- a/apps/dav/lib/Connector/Sabre/FilesPlugin.php +++ b/apps/dav/lib/Connector/Sabre/FilesPlugin.php @@ -388,9 +388,9 @@ class FilesPlugin extends ServerPlugin { } $propFind->handle(self::HIDDEN_PROPERTYNAME, function () use ($node) { - $filesMetadataManager = \OCP\Server::get(IFilesMetadataManager::class); - $metadata = $filesMetadataManager->getMetadata((int)$node->getFileId(), true); - return $metadata->hasKey('files-live-photo') && $node->getFileInfo()->getMimetype() === 'video/quicktime' ? 'true' : 'false'; + $isLivePhoto = isset($node->getFileInfo()->getMetadata()['files-live-photo']); + $isMovFile = $node->getFileInfo()->getMimetype() === 'video/quicktime'; + return ($isLivePhoto && $isMovFile) ? 'true' : 'false'; }); /** diff --git a/apps/settings/lib/Settings/Admin/ArtificialIntelligence.php b/apps/settings/lib/Settings/Admin/ArtificialIntelligence.php index 25c815cb140..e2862139e49 100644 --- a/apps/settings/lib/Settings/Admin/ArtificialIntelligence.php +++ b/apps/settings/lib/Settings/Admin/ArtificialIntelligence.php @@ -31,6 +31,7 @@ use OCP\IConfig; use OCP\IL10N; use OCP\Settings\IDelegatedSettings; use OCP\SpeechToText\ISpeechToTextManager; +use OCP\SpeechToText\ISpeechToTextProviderWithId; use OCP\TextProcessing\IManager; use OCP\TextProcessing\IProvider; use OCP\TextProcessing\IProviderWithId; @@ -70,7 +71,7 @@ class ArtificialIntelligence implements IDelegatedSettings { $sttProviders = []; foreach ($this->sttManager->getProviders() as $provider) { $sttProviders[] = [ - 'class' => $provider::class, + 'class' => $provider instanceof ISpeechToTextProviderWithId ? $provider->getId() : $provider::class, 'name' => $provider->getName(), ]; } |