1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\WebhookListeners\Listener;
use OCA\WebhookListeners\BackgroundJobs\WebhookCall;
use OCA\WebhookListeners\Db\WebhookListenerMapper;
use OCA\WebhookListeners\Service\PHPMongoQuery;
use OCP\BackgroundJob\IJobList;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\EventDispatcher\IWebhookCompatibleEvent;
use OCP\EventDispatcher\JsonSerializer;
use OCP\IUserSession;
use Psr\Log\LoggerInterface;
/**
* The class to handle the share events
* @template-implements IEventListener<IWebhookCompatibleEvent&Event>
*/
class WebhooksEventListener implements IEventListener {
public function __construct(
private WebhookListenerMapper $mapper,
private IJobList $jobList,
private LoggerInterface $logger,
private IUserSession $userSession,
) {
}
public function handle(Event $event): void {
$user = $this->userSession->getUser();
$webhookListeners = $this->mapper->getByEvent($event::class, $user?->getUID());
foreach ($webhookListeners as $webhookListener) {
// TODO add group membership to be able to filter on it
$data = [
'event' => $this->serializeEvent($event),
/* Do not remove 'user' from here, see BackgroundJobs/WebhookCall.php */
'user' => (is_null($user) ? null : JsonSerializer::serializeUser($user)),
'time' => time(),
];
if ($this->filterMatch($webhookListener->getEventFilter(), $data)) {
$this->jobList->add(
WebhookCall::class,
[
$data,
$webhookListener->getId(),
/* Random string to avoid collision with another job with the same parameters */
bin2hex(random_bytes(5)),
]
);
}
}
}
private function serializeEvent(IWebhookCompatibleEvent $event): array {
$data = $event->getWebhookSerializable();
$data['class'] = $event::class;
return $data;
}
private function filterMatch(array $filter, array $data): bool {
if ($filter === []) {
return true;
}
return PHPMongoQuery::executeQuery($filter, $data);
}
}
|