diff --git a/apps/webhooks/composer/composer/autoload_classmap.php b/apps/webhooks/composer/composer/autoload_classmap.php index efd4a43d58a..3ac7eb7e702 100644 --- a/apps/webhooks/composer/composer/autoload_classmap.php +++ b/apps/webhooks/composer/composer/autoload_classmap.php @@ -11,6 +11,7 @@ return array( 'OCA\\Webhooks\\BackgroundJobs\\WebhookCall' => $baseDir . '/../lib/BackgroundJobs/WebhookCall.php', 'OCA\\Webhooks\\Command\\Index' => $baseDir . '/../lib/Command/Index.php', 'OCA\\Webhooks\\Controller\\WebhooksController' => $baseDir . '/../lib/Controller/WebhooksController.php', + 'OCA\\Webhooks\\Db\\AuthMethod' => $baseDir . '/../lib/Db/AuthMethod.php', 'OCA\\Webhooks\\Db\\WebhookListener' => $baseDir . '/../lib/Db/WebhookListener.php', 'OCA\\Webhooks\\Db\\WebhookListenerMapper' => $baseDir . '/../lib/Db/WebhookListenerMapper.php', 'OCA\\Webhooks\\Listener\\WebhooksEventListener' => $baseDir . '/../lib/Listener/WebhooksEventListener.php', diff --git a/apps/webhooks/composer/composer/autoload_static.php b/apps/webhooks/composer/composer/autoload_static.php index 75182423ae6..788787644d7 100644 --- a/apps/webhooks/composer/composer/autoload_static.php +++ b/apps/webhooks/composer/composer/autoload_static.php @@ -26,6 +26,7 @@ class ComposerStaticInitWebhooks 'OCA\\Webhooks\\BackgroundJobs\\WebhookCall' => __DIR__ . '/..' . '/../lib/BackgroundJobs/WebhookCall.php', 'OCA\\Webhooks\\Command\\Index' => __DIR__ . '/..' . '/../lib/Command/Index.php', 'OCA\\Webhooks\\Controller\\WebhooksController' => __DIR__ . '/..' . '/../lib/Controller/WebhooksController.php', + 'OCA\\Webhooks\\Db\\AuthMethod' => __DIR__ . '/..' . '/../lib/Db/AuthMethod.php', 'OCA\\Webhooks\\Db\\WebhookListener' => __DIR__ . '/..' . '/../lib/Db/WebhookListener.php', 'OCA\\Webhooks\\Db\\WebhookListenerMapper' => __DIR__ . '/..' . '/../lib/Db/WebhookListenerMapper.php', 'OCA\\Webhooks\\Listener\\WebhooksEventListener' => __DIR__ . '/..' . '/../lib/Listener/WebhooksEventListener.php', diff --git a/apps/webhooks/lib/BackgroundJobs/WebhookCall.php b/apps/webhooks/lib/BackgroundJobs/WebhookCall.php index 469b554a886..4c0def3f69d 100644 --- a/apps/webhooks/lib/BackgroundJobs/WebhookCall.php +++ b/apps/webhooks/lib/BackgroundJobs/WebhookCall.php @@ -9,6 +9,7 @@ declare(strict_types=1); namespace OCA\Webhooks\BackgroundJobs; +use OCA\Webhooks\Db\AuthMethod; use OCA\Webhooks\Db\WebhookListenerMapper; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\QueuedJob; @@ -31,7 +32,16 @@ class WebhookCall extends QueuedJob { $client = $this->clientService->newClient(); $options = []; $options['body'] = json_encode($data); + $options['headers'] = $webhookListener->getHeaders(); try { + switch ($webhookListener->getAuthMethodEnum()) { + case AuthMethod::None: + break; + case AuthMethod::Header: + $authHeaders = $webhookListener->getAuthDataClear(); + $options['headers'] = array_merge($options['headers'], $authHeaders); + break; + } $response = $client->request($webhookListener->getHttpMethod(), $webhookListener->getUri(), $options); $statusCode = $response->getStatusCode(); if ($statusCode >= 200 && $statusCode < 300) { diff --git a/apps/webhooks/lib/Command/Index.php b/apps/webhooks/lib/Command/Index.php index 78feda3ec68..4457e95c196 100644 --- a/apps/webhooks/lib/Command/Index.php +++ b/apps/webhooks/lib/Command/Index.php @@ -31,11 +31,10 @@ class Index extends Base { protected function execute(InputInterface $input, OutputInterface $output): int { $webhookListeners = array_map( - function (WebhookListener $listener): array { - $data = $listener->jsonSerialize(); - $data['eventFilter'] = json_encode($data['eventFilter']); - return $data; - }, + fn (WebhookListener $listener): array => array_map( + fn (string|array|null $value): ?string => (is_array($value) ? json_encode($value) : $value), + $listener->jsonSerialize() + ), $this->mapper->getAll() ); $this->writeTableInOutputFormat($input, $output, $webhookListeners); diff --git a/apps/webhooks/lib/Controller/WebhooksController.php b/apps/webhooks/lib/Controller/WebhooksController.php index 0893743cdb9..040e076be65 100644 --- a/apps/webhooks/lib/Controller/WebhooksController.php +++ b/apps/webhooks/lib/Controller/WebhooksController.php @@ -10,6 +10,7 @@ declare(strict_types=1); namespace OCA\Webhooks\Controller; use Doctrine\DBAL\Exception; +use OCA\Webhooks\Db\AuthMethod; use OCA\Webhooks\Db\WebhookListenerMapper; use OCP\AppFramework\Http\Attribute\ApiRoute; use OCP\AppFramework\Http\Attribute\AuthorizedAdminSetting; @@ -112,7 +113,7 @@ class WebhooksController extends OCSController { $event, $eventFilter, $headers, - $authMethod, + AuthMethod::from($authMethod ?? AuthMethod::None->value), $authData, ); return new DataResponse($webhookListener); @@ -172,7 +173,7 @@ class WebhooksController extends OCSController { $event, $eventFilter, $headers, - $authMethod, + AuthMethod::from($authMethod ?? AuthMethod::None->value), $authData, ); return new DataResponse($webhookListener); diff --git a/apps/webhooks/lib/Db/AuthMethod.php b/apps/webhooks/lib/Db/AuthMethod.php new file mode 100644 index 00000000000..4fe06ef34fb --- /dev/null +++ b/apps/webhooks/lib/Db/AuthMethod.php @@ -0,0 +1,15 @@ +crypto = $crypto; $this->addType('appId', 'string'); $this->addType('userId', 'string'); $this->addType('httpMethod', 'string'); @@ -52,7 +61,26 @@ class WebhookListener extends Entity implements \JsonSerializable { $this->addType('eventFilter', 'json'); $this->addType('headers', 'json'); $this->addType('authMethod', 'string'); - $this->addType('authData', 'json'); + $this->addType('authData', 'string'); + } + + public function getAuthMethodEnum(): AuthMethod { + return AuthMethod::from(parent::getAuthMethod()); + } + + public function getAuthDataClear(): array { + if ($this->authData === null) { + return []; + } + return json_decode($this->crypto->decrypt($this->getAuthData()), associative:true, flags:JSON_THROW_ON_ERROR); + } + + public function setAuthDataClear(?array $data): void { + if ($data === null) { + $this->setAuthData(null); + return; + } + $this->setAuthData($this->crypto->encrypt(json_encode($data))); } public function jsonSerialize(): array { diff --git a/apps/webhooks/lib/Db/WebhookListenerMapper.php b/apps/webhooks/lib/Db/WebhookListenerMapper.php index 3b472231e37..8f07a413c7f 100644 --- a/apps/webhooks/lib/Db/WebhookListenerMapper.php +++ b/apps/webhooks/lib/Db/WebhookListenerMapper.php @@ -64,7 +64,7 @@ class WebhookListenerMapper extends QBMapper { string $event, ?array $eventFilter, ?array $headers, - ?string $authMethod, + AuthMethod $authMethod, ?array $authData, ) { $webhookListener = WebhookListener::fromParams( @@ -76,10 +76,10 @@ class WebhookListenerMapper extends QBMapper { 'event' => $event, 'eventFilter' => $eventFilter ?? [], 'headers' => $headers, - 'authMethod' => $authMethod ?? 'none', - 'authData' => $authData, + 'authMethod' => $authMethod->value, ] ); + $webhookListener->setAuthDataClear($authData); return $this->insert($webhookListener); } @@ -92,7 +92,7 @@ class WebhookListenerMapper extends QBMapper { string $event, ?array $eventFilter, ?array $headers, - ?string $authMethod, + AuthMethod $authMethod, ?array $authData, ) { $webhookListener = WebhookListener::fromParams( @@ -105,10 +105,10 @@ class WebhookListenerMapper extends QBMapper { 'event' => $event, 'eventFilter' => $eventFilter ?? [], 'headers' => $headers, - 'authMethod' => $authMethod, - 'authData' => $authData, + 'authMethod' => $authMethod->value, ] ); + $webhookListener->setAuthDataClear($authData); return $this->update($webhookListener); } diff --git a/apps/webhooks/tests/Db/WebhookListenerMapperTest.php b/apps/webhooks/tests/Db/WebhookListenerMapperTest.php index c9f6e39b31f..a30c07280ba 100644 --- a/apps/webhooks/tests/Db/WebhookListenerMapperTest.php +++ b/apps/webhooks/tests/Db/WebhookListenerMapperTest.php @@ -9,6 +9,7 @@ declare(strict_types=1); namespace OCA\Webhooks\Tests\Db; +use OCA\Webhooks\Db\AuthMethod; use OCA\Webhooks\Db\WebhookListenerMapper; use OCP\IDBConnection; use OCP\User\Events\UserCreatedEvent; @@ -51,7 +52,7 @@ class WebhookListenerMapperTest extends TestCase { UserCreatedEvent::class, null, null, - null, + AuthMethod::None, null, ); @@ -60,4 +61,23 @@ class WebhookListenerMapperTest extends TestCase { $listener1->resetUpdatedFields(); $this->assertEquals($listener1, $listener2); } + + public function testInsertListenerAndGetItWithAuthData() { + $listener1 = $this->mapper->addWebhookListener( + null, + 'bob', + 'POST', + 'https://webhook.example.com/endpoint', + UserCreatedEvent::class, + null, + null, + AuthMethod::Header, + ['secretHeader' => 'header'], + ); + + $listener2 = $this->mapper->getById($listener1->getId()); + + $listener1->resetUpdatedFields(); + $this->assertEquals($listener1, $listener2); + } } diff --git a/apps/webhooks/tests/Service/PHPMongoQueryTest.php b/apps/webhooks/tests/Service/PHPMongoQueryTest.php index 06658b718f0..51684bb8e34 100644 --- a/apps/webhooks/tests/Service/PHPMongoQueryTest.php +++ b/apps/webhooks/tests/Service/PHPMongoQueryTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\Webhooks\Tests\Db; +namespace OCA\Webhooks\Tests\Service; use OCA\Webhooks\Service\PHPMongoQuery; use OCP\Files\Events\Node\NodeWrittenEvent;