diff --git a/appinfo/info.xml b/appinfo/info.xml
index 8b63f009..606e69aa 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -38,7 +38,7 @@ to join us in shaping a more versatile, stable, and secure app landscape.
*Your insights, suggestions, and contributions are invaluable to us.*
]]>
- 32.0.0-dev.3
+ 32.0.0-dev.4
agpl
Andrey Borysenko
Alexander Piskun
@@ -80,7 +80,6 @@ to join us in shaping a more versatile, stable, and secure app landscape.
OCA\AppAPI\Command\ExApp\Enable
OCA\AppAPI\Command\ExApp\Disable
OCA\AppAPI\Command\ExApp\ListExApps
- OCA\AppAPI\Command\ExApp\Notify
OCA\AppAPI\Command\ExAppConfig\GetConfig
OCA\AppAPI\Command\ExAppConfig\SetConfig
OCA\AppAPI\Command\ExAppConfig\DeleteConfig
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index 10331d50..6be6d092 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -14,7 +14,6 @@
use OCA\AppAPI\Listener\DeclarativeSettings\GetValueListener;
use OCA\AppAPI\Listener\DeclarativeSettings\RegisterDeclarativeSettingsListener;
use OCA\AppAPI\Listener\DeclarativeSettings\SetValueListener;
-use OCA\AppAPI\Listener\FileEventsListener;
use OCA\AppAPI\Listener\GetTaskProcessingProvidersListener;
use OCA\AppAPI\Listener\LoadFilesPluginListener;
use OCA\AppAPI\Listener\LoadMenuEntriesListener;
@@ -32,12 +31,6 @@
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\EventDispatcher\IEventDispatcher;
-use OCP\Files\Events\Node\NodeCopiedEvent;
-use OCP\Files\Events\Node\NodeCreatedEvent;
-use OCP\Files\Events\Node\NodeDeletedEvent;
-use OCP\Files\Events\Node\NodeRenamedEvent;
-use OCP\Files\Events\Node\NodeTouchedEvent;
-use OCP\Files\Events\Node\NodeWrittenEvent;
use OCP\Navigation\Events\LoadAdditionalEntriesEvent;
use OCP\SabrePluginEvent;
use OCP\Settings\Events\DeclarativeSettingsGetValueEvent;
@@ -75,13 +68,6 @@ public function register(IRegistrationContext $context): void {
$context->registerEventListener(DeclarativeSettingsGetValueEvent::class, GetValueListener::class);
$context->registerEventListener(DeclarativeSettingsSetValueEvent::class, SetValueListener::class);
- $context->registerEventListener(NodeCreatedEvent::class, FileEventsListener::class);
- $context->registerEventListener(NodeTouchedEvent::class, FileEventsListener::class);
- $context->registerEventListener(NodeWrittenEvent::class, FileEventsListener::class);
- $context->registerEventListener(NodeDeletedEvent::class, FileEventsListener::class);
- $context->registerEventListener(NodeRenamedEvent::class, FileEventsListener::class);
- $context->registerEventListener(NodeCopiedEvent::class, FileEventsListener::class);
-
$context->registerSetupCheck(DaemonCheck::class);
}
diff --git a/lib/Command/ExApp/Notify.php b/lib/Command/ExApp/Notify.php
deleted file mode 100644
index 27ab32e1..00000000
--- a/lib/Command/ExApp/Notify.php
+++ /dev/null
@@ -1,77 +0,0 @@
-setName('app_api:app:notify');
- $this->setDescription('Notify ExApp about internal event');
- $this->setHidden(true);
- $this->addArgument('appid', InputArgument::REQUIRED);
- $this->addArgument('route', InputArgument::REQUIRED);
- $this->addOption('user-id', null, InputOption::VALUE_REQUIRED, 'User ID');
- $this->addOption('event-json', null, InputOption::VALUE_REQUIRED, 'Event JSON payload');
- }
-
- protected function execute(InputInterface $input, OutputInterface $output): int {
- $appId = $input->getArgument('appid');
-
- $exApp = $this->exAppService->getExApp($appId);
- if ($exApp === null) {
- $output->writeln(sprintf('ExApp %s not found. Failed to notify.', $appId));
- return 1;
- }
-
- $eventJson = $input->getOption('event-json');
- if ($eventJson === null) {
- $output->writeln('Event JSON payload is required');
- return 1;
- }
-
- $eventJsonData = json_decode($eventJson, true);
- if ($eventJsonData === null) {
- $output->writeln('Invalid JSON payload');
- return 1;
- }
-
- $route = $input->getArgument('route');
- $userId = $input->getOption('user-id');
- $response = $this->service->requestToExApp($exApp, $route, $userId, params: $eventJsonData,
- options: ['timeout' => 2]);
- if (is_array($response) && isset($response['error'])) {
- $output->writeln(sprintf('Failed to notify ExApp %s: %s', $appId, $response['error']));
- return 1;
- }
-
- if ($response->getStatusCode() !== 200) {
- $output->writeln(sprintf('Failed to notify ExApp %s: %s', $appId, $response->getBody()));
- return 1;
- }
-
- $output->writeln(sprintf('ExApp %s notified about event: %s', $appId, $eventJson));
-
- return 0;
- }
-}
diff --git a/lib/Controller/EventsListenerController.php b/lib/Controller/EventsListenerController.php
deleted file mode 100644
index 22f71ea9..00000000
--- a/lib/Controller/EventsListenerController.php
+++ /dev/null
@@ -1,67 +0,0 @@
-request = $request;
- }
-
- #[NoCSRFRequired]
- #[PublicPage]
- #[AppAPIAuth]
- public function registerListener(string $eventType, string $actionHandler, array $eventSubtypes = []): DataResponse {
- $listener = $this->service->registerEventsListener(
- $this->request->getHeader('EX-APP-ID'), $eventType, $actionHandler, $eventSubtypes);
- if ($listener === null) {
- return new DataResponse([], Http::STATUS_BAD_REQUEST);
- }
- return new DataResponse();
- }
-
- #[NoCSRFRequired]
- #[PublicPage]
- #[AppAPIAuth]
- public function unregisterListener(string $eventType): DataResponse {
- $unregistered = $this->service->unregisterEventsListener($this->request->getHeader('EX-APP-ID'), $eventType);
- if (!$unregistered) {
- return new DataResponse([], Http::STATUS_NOT_FOUND);
- }
- return new DataResponse();
- }
-
- #[AppAPIAuth]
- #[PublicPage]
- #[NoCSRFRequired]
- public function getListener(string $eventType): DataResponse {
- $result = $this->service->getEventsListener($this->request->getHeader('EX-APP-ID'), $eventType);
- if (!$result) {
- return new DataResponse([], Http::STATUS_NOT_FOUND);
- }
- return new DataResponse($result, Http::STATUS_OK);
- }
-}
diff --git a/lib/Db/ExAppEventsListener.php b/lib/Db/ExAppEventsListener.php
deleted file mode 100644
index 2d80dd01..00000000
--- a/lib/Db/ExAppEventsListener.php
+++ /dev/null
@@ -1,71 +0,0 @@
-addType('appid', 'string');
- $this->addType('eventType', 'string');
- $this->addType('eventSubtypes', 'json');
- $this->addType('actionHandler', 'string');
-
- if (isset($params['id'])) {
- $this->setId($params['id']);
- }
- if (isset($params['appid'])) {
- $this->setAppid($params['appid']);
- }
- if (isset($params['event_type'])) {
- $this->setEventType($params['event_type']);
- }
- if (isset($params['event_subtypes'])) {
- $this->setEventSubtypes($params['event_subtypes']);
- }
- if (isset($params['action_handler'])) {
- $this->setActionHandler($params['action_handler']);
- }
- }
-
- public function jsonSerialize(): array {
- return [
- 'id' => $this->getId(),
- 'appid' => $this->getAppid(),
- 'event_type' => $this->getEventType(),
- 'event_subtypes' => $this->getEventSubtypes(),
- 'action_handler' => $this->getActionHandler(),
- ];
- }
-}
diff --git a/lib/Db/ExAppEventsListenerMapper.php b/lib/Db/ExAppEventsListenerMapper.php
deleted file mode 100644
index 3ee09912..00000000
--- a/lib/Db/ExAppEventsListenerMapper.php
+++ /dev/null
@@ -1,90 +0,0 @@
-
- */
-class ExAppEventsListenerMapper extends QBMapper {
- public function __construct(IDBConnection $db) {
- parent::__construct($db, 'ex_event_handlers');
- }
-
- /**
- * @throws Exception
- */
- public function findAllEnabled(): array {
- $qb = $this->db->getQueryBuilder();
- $result = $qb->select('exs.*')
- ->from($this->tableName, 'exs')
- ->innerJoin('exs', 'ex_apps', 'exa', $qb->expr()->eq('exa.appid', 'exs.appid'))
- ->where(
- $qb->expr()->eq('exa.enabled', $qb->createNamedParameter(1, IQueryBuilder::PARAM_INT))
- )
- ->executeQuery();
- return $result->fetchAll();
- }
-
- public function removeByAppIdEventType(string $appId, string $eventType): bool {
- $qb = $this->db->getQueryBuilder();
- $qb->delete($this->tableName)
- ->where(
- $qb->expr()->eq('appid', $qb->createNamedParameter($appId, IQueryBuilder::PARAM_STR)),
- $qb->expr()->eq('event_type', $qb->createNamedParameter($eventType, IQueryBuilder::PARAM_STR))
- );
- try {
- $result = $qb->executeStatement();
- if ($result) {
- return true;
- }
- } catch (Exception) {
- }
- return false;
- }
-
- /**
- * @throws Exception
- */
- public function removeAllByAppId(string $appId): int {
- $qb = $this->db->getQueryBuilder();
- $qb->delete($this->tableName)
- ->where(
- $qb->expr()->eq('appid', $qb->createNamedParameter($appId, IQueryBuilder::PARAM_STR))
- );
- return $qb->executeStatement();
- }
-
- /**
- * @param string $appId
- * @param string $eventType
- *
- * @return ExAppEventsListener
- * @throws Exception
- * @throws MultipleObjectsReturnedException if more than one result
- * @throws DoesNotExistException if not found
- */
- public function findByAppIdEventType(string $appId, string $eventType): ExAppEventsListener {
- $qb = $this->db->getQueryBuilder();
- $qb->select('*')
- ->from($this->tableName)
- ->where(
- $qb->expr()->eq('appid', $qb->createNamedParameter($appId, IQueryBuilder::PARAM_STR)),
- $qb->expr()->eq('event_type', $qb->createNamedParameter($eventType, IQueryBuilder::PARAM_STR))
- );
- return $this->findEntity($qb);
- }
-}
diff --git a/lib/Listener/FileEventsListener.php b/lib/Listener/FileEventsListener.php
deleted file mode 100644
index cad15ba7..00000000
--- a/lib/Listener/FileEventsListener.php
+++ /dev/null
@@ -1,173 +0,0 @@
-
- */
-class FileEventsListener implements IEventListener {
-
- public function __construct(
- private readonly ExAppEventsListenerService $service,
- private readonly AppAPIService $appAPIService,
- private readonly ExAppService $exAppService,
- private readonly IConfig $config,
- private readonly LoggerInterface $logger,
- private readonly IUserSession $userSession,
- private readonly IRootFolder $rootFolder,
- ) {
- }
-
- public function handle(Event $event): void {
- $filteredNodeEventListeners = array_filter($this->service->getEventsListeners(), function ($eventsListener) {
- return $eventsListener->getEventType() === 'node_event';
- });
- if (empty($filteredNodeEventListeners)) {
- return;
- }
- $eventSubtype = '';
- if ($event instanceof NodeCreatedEvent) {
- $eventSubtype = 'NodeCreatedEvent';
- } elseif ($event instanceof NodeTouchedEvent) {
- $eventSubtype = 'NodeTouchedEvent';
- } elseif ($event instanceof NodeWrittenEvent) {
- $eventSubtype = 'NodeWrittenEvent';
- } elseif ($event instanceof NodeDeletedEvent) {
- $eventSubtype = 'NodeDeletedEvent';
- } elseif ($event instanceof NodeRenamedEvent) {
- $eventSubtype = 'NodeRenamedEvent';
- } elseif ($event instanceof NodeCopiedEvent) {
- $eventSubtype = 'NodeCopiedEvent';
- }
- if ($eventSubtype === '') {
- return;
- }
- $eventData = [
- 'event_type' => 'node_event',
- 'event_subtype' => $eventSubtype,
- ];
- try {
- if (($event instanceof NodeRenamedEvent) || ($event instanceof NodeCopiedEvent)) {
- $eventData['event_data'] = [
- 'target' => $this->serializeNodeInfo($event->getTarget()),
- ];
- $eventData['event_data']['source'] = $this->serializeNodeInfo($event->getSource(), $eventData['event_data']['target']);
- } elseif ($event instanceof AbstractNodeEvent) {
- $eventData['event_data'] = [
- 'target' => $this->serializeNodeInfo($event->getNode()),
- ];
- } else {
- return;
- }
- } catch (NotFoundException | NotPermittedException $e) {
- $this->logger->error(
- sprintf('Failed to serialize NodeInfo: %s', $e->getMessage()), ['exception' => $e]
- );
- return;
- }
- foreach ($filteredNodeEventListeners as $nodeEventListener) {
- if (
- empty($nodeEventListener->getEventSubtypes()) ||
- in_array($eventSubtype, $nodeEventListener->getEventSubtypes())
- ) {
- $exApp = $this->exAppService->getExApp($nodeEventListener->getAppid());
- if ($exApp !== null) {
- $args = [
- 'app_api:app:notify',
- escapeshellarg($exApp->getAppid()),
- escapeshellarg($nodeEventListener->getActionHandler()),
- '--event-json',
- escapeshellarg(json_encode($eventData))
- ];
- $userId = $this->userSession->getUser();
- if ($userId !== null) {
- $args[] = '--user-id';
- $args[] = escapeshellarg($userId->getUID());
- }
- $this->appAPIService->runOccCommandInternal($args);
- }
- }
- }
- }
-
- /**
- * @throws NotFoundException
- * @throws NotPermittedException
- */
- private function serializeNodeInfo(Node $node, array $fallbackInfo = []): array {
- $userPath = $this->getPathForNode($node);
- $result = $fallbackInfo;
- $result['favorite'] = '';
- $result['name'] = basename($userPath);
- $result['directory'] = dirname($userPath);
- $result['instanceId'] = $this->config->getSystemValue('instanceid');
- try {
- $result['fileId'] = $node->getId();
- $result['etag'] = $node->getEtag();
- $result['mime'] = $node->getMimeType();
- $result['permissions'] = $node->getPermissions();
- $result['fileType'] = $node->getType();
- $result['size'] = $node->getSize();
- $result['mtime'] = $node->getMTime();
- $result['userId'] = $node->getOwner()->getUID();
- } catch (NotFoundException | InvalidPathException) {
- }
- return $result;
- }
-
- /**
- * @throws NotPermittedException
- * @throws NotFoundException
- */
- private function getPathForNode(Node $node): ?string {
- $user = $this->userSession->getUser()?->getUID();
- if ($user) {
- $path = $this->rootFolder
- ->getUserFolder($user)
- ->getRelativePath($node->getPath());
-
- if ($path !== null) {
- return $path;
- }
- }
- $owner = $node->getOwner()?->getUid();
- if ($owner) {
- $path = $this->rootFolder
- ->getUserFolder($owner)
- ->getRelativePath($node->getPath());
-
- if ($path !== null) {
- return $path;
- }
- }
- return null;
- }
-}
diff --git a/lib/Migration/Version2204Date20240401104001.php b/lib/Migration/Version2204Date20240401104001.php
deleted file mode 100644
index 467eac84..00000000
--- a/lib/Migration/Version2204Date20240401104001.php
+++ /dev/null
@@ -1,59 +0,0 @@
-hasTable('ex_event_handlers')) {
- $table = $schema->createTable('ex_event_handlers');
-
- $table->addColumn('id', Types::BIGINT, [
- 'autoincrement' => true,
- 'notnull' => true,
- ]);
- $table->addColumn('appid', Types::STRING, [
- 'notnull' => true,
- 'length' => 32,
- ]);
- $table->addColumn('event_type', Types::STRING, [
- 'notnull' => true,
- 'length' => 32,
- ]);
- $table->addColumn('event_subtypes', Types::JSON, [
- 'notnull' => true,
- ]);
- $table->addColumn('action_handler', Types::STRING, [
- 'notnull' => true,
- 'length' => 410,
- ]);
-
- $table->setPrimaryKey(['id']);
- $table->addUniqueIndex(['appid', 'event_type'], 'ex_event_handlers__idx');
- }
-
- return $schema;
- }
-}
diff --git a/lib/Service/ExAppEventsListenerService.php b/lib/Service/ExAppEventsListenerService.php
deleted file mode 100644
index 32097354..00000000
--- a/lib/Service/ExAppEventsListenerService.php
+++ /dev/null
@@ -1,115 +0,0 @@
-isAvailable()) {
- $this->cache = $cacheFactory->createDistributed(Application::APP_ID . '/ex_events_listener');
- }
- }
-
- public function registerEventsListener(string $appId, string $eventType, string $actionHandler, array $eventSubtypes = []): ?ExAppEventsListener {
- $eventsListenerEntry = $this->getEventsListener($appId, $eventType);
- try {
- $newEventsListenerEntry = new ExAppEventsListener([
- 'appid' => $appId,
- 'event_type' => $eventType,
- 'event_subtypes' => $eventSubtypes,
- 'action_handler' => ltrim($actionHandler, '/'),
- ]);
- if ($eventsListenerEntry !== null) {
- $newEventsListenerEntry->setId($eventsListenerEntry->getId());
- }
- $eventsListenerEntry = $this->mapper->insertOrUpdate($newEventsListenerEntry);
- $this->resetCacheEnabled();
- } catch (Exception $e) {
- $this->logger->error(
- sprintf('Failed to register Events listener for %s. Error: %s', $appId, $e->getMessage()), ['exception' => $e]
- );
- return null;
- }
- return $eventsListenerEntry;
- }
-
- public function unregisterEventsListener(string $appId, string $eventType): bool {
- if (!$this->mapper->removeByAppIdEventType($appId, $eventType)) {
- return false;
- }
- $this->resetCacheEnabled();
- return true;
- }
-
- public function getEventsListener(string $appId, string $eventType): ?ExAppEventsListener {
- foreach ($this->getEventsListeners() as $eventsListener) {
- if (($eventsListener->getAppid() === $appId) && ($eventsListener->getEventType() === $eventType)) {
- return $eventsListener;
- }
- }
- try {
- return $this->mapper->findByAppIdEventType($appId, $eventType);
- } catch (DoesNotExistException|MultipleObjectsReturnedException|Exception) {
- return null;
- }
- }
-
- /**
- * Get list of registered Events Listeners (only for enabled ExApps)
- *
- * @return ExAppEventsListener[]
- */
- public function getEventsListeners(): array {
- try {
- $cacheKey = '/ex_events_listener';
- $records = $this->cache?->get($cacheKey);
- if ($records === null) {
- $records = $this->mapper->findAllEnabled();
- $this->cache?->set($cacheKey, $records);
- }
- return array_map(function ($record) {
- return new ExAppEventsListener($record);
- }, $records);
- } catch (Exception) {
- return [];
- }
- }
-
- public function unregisterExAppEventListeners(string $appId): int {
- try {
- $result = $this->mapper->removeAllByAppId($appId);
- } catch (Exception) {
- $result = -1;
- }
- $this->resetCacheEnabled();
- return $result;
- }
-
- public function resetCacheEnabled(): void {
- $this->cache?->remove('/ex_events_listener');
- }
-}
diff --git a/lib/Service/ExAppService.php b/lib/Service/ExAppService.php
index 34a0e771..ef9272f0 100644
--- a/lib/Service/ExAppService.php
+++ b/lib/Service/ExAppService.php
@@ -52,7 +52,6 @@ public function __construct(
private readonly TaskProcessingService $taskProcessingService,
private readonly TalkBotsService $talkBotsService,
private readonly SettingsService $settingsService,
- private readonly ExAppEventsListenerService $eventsListenerService,
private readonly ExAppOccService $occService,
private readonly ExAppDeployOptionsService $deployOptionsService,
private readonly IConfig $config,
@@ -118,7 +117,6 @@ public function unregisterExApp(string $appId): bool {
$this->taskProcessingService->unregisterExAppTaskProcessingProviders($appId);
$this->settingsService->unregisterExAppForms($appId);
$this->exAppArchiveFetcher->removeExAppFolder($appId);
- $this->eventsListenerService->unregisterExAppEventListeners($appId);
$this->occService->unregisterExAppOccCommands($appId);
$this->deployOptionsService->removeExAppDeployOptions($appId);
$this->unregisterExAppWebhooks($appId);
@@ -244,7 +242,6 @@ private function resetCaches(): void {
$this->topMenuService->resetCacheEnabled();
$this->filesActionsMenuService->resetCacheEnabled();
$this->settingsService->resetCacheEnabled();
- $this->eventsListenerService->resetCacheEnabled();
$this->occService->resetCacheEnabled();
$this->deployOptionsService->resetCache();
}
diff --git a/tests/psalm-baseline.xml b/tests/psalm-baseline.xml
index c6d2d1c9..8c566636 100644
--- a/tests/psalm-baseline.xml
+++ b/tests/psalm-baseline.xml
@@ -75,13 +75,6 @@
-
-
- rootFolder]]>
- rootFolder]]>
-
-
-