Skip to content

Commit b1e8460

Browse files
committed
feat: add tokens in the webhook call data
Signed-off-by: Jana Peper <[email protected]>
1 parent 4aca4c5 commit b1e8460

File tree

5 files changed

+76
-10
lines changed

5 files changed

+76
-10
lines changed

apps/webhook_listeners/lib/BackgroundJobs/WebhookCall.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ protected function run($argument): void {
4242
[$data, $webhookId] = $argument;
4343
$webhookListener = $this->mapper->getById($webhookId);
4444
$client = $this->clientService->newClient();
45+
46+
// adding temporary auth tokens to the call
47+
$data['tokens'] = $this->getTokens($webhookListener, $data['user']['uid']);
4548
$options = [
4649
'verify' => $this->certificateManager->getAbsoluteBundlePath(),
4750
'headers' => $webhookListener->getHeaders() ?? [],
@@ -92,4 +95,31 @@ protected function run($argument): void {
9295
$this->logger->error('Webhook(' . $webhookId . ') call failed: ' . $e->getMessage(), ['exception' => $e]);
9396
}
9497
}
98+
99+
private function getTokens($webhookListener, $triggerUserId): array {
100+
$tokens = [];
101+
$tokenNeeded = $webhookListener->getTokenNeeded();
102+
if (isset($tokenNeeded['users'])) {
103+
foreach ($tokenNeeded['users'] as $userId) {
104+
$tokens['users'][$userId] = $webhookListener->createTemporaryToken($userId);
105+
}
106+
}
107+
if (isset($tokenNeeded['users'])) {
108+
foreach ($tokenNeeded['functions'] as $function) {
109+
switch ($function) {
110+
case 'owner':
111+
// token for the person who created the flow
112+
$functionId = $webhookListener->getUserId();
113+
$tokens['functions']['owner'][$functionId] = $webhookListener->createTemporaryToken($functionId);
114+
break;
115+
case 'trigger':
116+
// token for the person who triggered the webhook
117+
$tokens['functions']['trigger'][$triggerUserId] = $webhookListener->createTemporaryToken($triggerUserId);
118+
break;
119+
}
120+
}
121+
}
122+
123+
return $tokens;
124+
}
95125
}

apps/webhook_listeners/lib/Controller/WebhooksController.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ public function show(int $id): DataResponse {
112112
* @param ?array<string,string> $headers Array of headers to send
113113
* @param "none"|"header"|null $authMethod Authentication method to use
114114
* @param ?array<string,mixed> $authData Array of data for authentication
115-
* @param ?array<string,mixed> $tokenNeeded List of user ids for which to include auth tokens in the event
115+
* @param ?array<string,mixed> $tokenNeeded List of user ids for which to include auth tokens in the event.
116+
* Has to fields: "users" lists uids of users for which tokens are needed, "functions" lists functions for which tokens can be included.
117+
* Possible functions: "owner" for the user creating the webhook, "trigger" for the user triggering the webhook call
116118
*
117119
* @return DataResponse<Http::STATUS_OK, WebhookListenersWebhookInfo, array{}>
118120
*
@@ -183,7 +185,9 @@ public function create(
183185
* @param ?array<string,string> $headers Array of headers to send
184186
* @param "none"|"header"|null $authMethod Authentication method to use
185187
* @param ?array<string,mixed> $authData Array of data for authentication
186-
* @param ?array<string,mixed> $tokenNeeded List of user ids for which to include auth tokens in the event
188+
* @param ?array<string,mixed> $tokenNeeded List of user ids for which to include auth tokens in the event.
189+
* Has to fields: "users" lists uids of users for which tokens are needed, "functions" lists functions for which tokens can be included.
190+
* Possible functions: "owner" for the user creating the webhook, "trigger" for the user triggering the webhook call
187191
*
188192
* @return DataResponse<Http::STATUS_OK, WebhookListenersWebhookInfo, array{}>
189193
*

apps/webhook_listeners/lib/Db/WebhookListener.php

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99

1010
namespace OCA\WebhookListeners\Db;
1111

12+
use OC\Authentication\Token\IProvider;
1213
use OCP\AppFramework\Db\Entity;
14+
use OCP\Authentication\Token\IToken;
1315
use OCP\Security\ICrypto;
16+
use OCP\Security\ISecureRandom;
1417
use OCP\Server;
1518

1619
/**
@@ -23,6 +26,7 @@
2326
* @method ?string getAuthData()
2427
* @method void setAuthData(?string $data)
2528
* @method string getAuthMethod()
29+
* @method ?array getTokenNeeded()
2630
* @psalm-suppress PropertyNotSetInConstructor
2731
*/
2832
class WebhookListener extends Entity implements \JsonSerializable {
@@ -84,21 +88,32 @@ class WebhookListener extends Entity implements \JsonSerializable {
8488
*/
8589
protected $authData = null;
8690

87-
/**
91+
/**
8892
* @var array
8993
* @psalm-suppress PropertyNotSetInConstructor
9094
*/
9195
protected $tokenNeeded;
9296

9397
private ICrypto $crypto;
9498

99+
private IProvider $tokenProvider;
95100
public function __construct(
96101
?ICrypto $crypto = null,
102+
?IProvider $tokenProvider = null,
103+
private ?ISecureRandom $random = null,
97104
) {
98105
if ($crypto === null) {
99106
$crypto = Server::get(ICrypto::class);
100107
}
101108
$this->crypto = $crypto;
109+
if ($tokenProvider === null) {
110+
$tokenProvider = Server::get(IProvider::class);
111+
}
112+
$this->tokenProvider = $tokenProvider;
113+
if ($random === null) {
114+
$random = Server::get(ISecureRandom::class);
115+
}
116+
$this->random = $random;
102117
$this->addType('appId', 'string');
103118
$this->addType('userId', 'string');
104119
$this->addType('httpMethod', 'string');
@@ -152,4 +167,21 @@ public function jsonSerialize(): array {
152167
public function getAppId(): ?string {
153168
return $this->appId;
154169
}
170+
171+
172+
public function createTemporaryToken($userId) {
173+
$token = $this->generateRandomDeviceToken();
174+
$name = 'Authentication for Webhook';
175+
$password = null;
176+
$deviceToken = $this->tokenProvider->generateToken($token, $userId, $userId, $password, $name, IToken::PERMANENT_TOKEN);
177+
return $token;
178+
}
179+
180+
private function generateRandomDeviceToken() {
181+
$groups = [];
182+
for ($i = 0; $i < 5; $i++) {
183+
$groups[] = $this->random->generate(5, ISecureRandom::CHAR_HUMAN_READABLE);
184+
}
185+
return implode('-', $groups);
186+
}
155187
}

apps/webhook_listeners/lib/Db/WebhookListenerMapper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public function addWebhookListener(
8282
AuthMethod $authMethod,
8383
#[\SensitiveParameter]
8484
?array $authData,
85-
?array $tokenNeeded
85+
?array $tokenNeeded,
8686
): WebhookListener {
8787
/* Remove any superfluous antislash */
8888
$event = ltrim($event, '\\');

apps/webhook_listeners/lib/Migration/Version1500Date20251007130000.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
use Closure;
1313
use OCA\WebhookListeners\Db\WebhookListenerMapper;
1414
use OCP\DB\ISchemaWrapper;
15+
use OCP\DB\Types;
1516
use OCP\Migration\IOutput;
1617
use OCP\Migration\SimpleMigrationStep;
17-
use OCP\DB\Types;
1818

1919
class Version1500Date20251007130000 extends SimpleMigrationStep {
2020

@@ -29,14 +29,14 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
2929

3030
if ($schema->hasTable(WebhookListenerMapper::TABLE_NAME)) {
3131
$table = $schema->getTable(WebhookListenerMapper::TABLE_NAME);
32-
if(!$table->hasColumn('token_needed')){
32+
if (!$table->hasColumn('token_needed')) {
3333
$table->addColumn('token_needed', Types::TEXT, [
34-
'notnull' => false,
35-
]);
34+
'notnull' => false,
35+
]);
3636
}
37-
37+
3838
return $schema;
3939
}
4040
return null;
4141
}
42-
}
42+
}

0 commit comments

Comments
 (0)