['jane', 'bob'], 'user_roles' => ['owner', 'trigger']] * as requested tokens in the registered webhook produces a result like * [ * ['user_ids' => [ * ['jane' => [ * 'userId' => 'jane', * 'token' => 'abcdtokenabcd1' * 'baseUrl' => 'https://nextcloud.example' * ], * ['bob'=> [ * 'userId' => 'bob', * 'token' => 'abcdtokenabcd2' * 'baseUrl' => 'https://nextcloud.example' * ], * ], * 'owner' => [ * 'userId' => 'admin', * 'token' => 'abcdtokenabcd3' * 'baseUrl' => 'https://nextcloud.example' * ], * 'trigger' => [ * 'userId' => 'user1', * 'token' => 'abcdtokenabcd4' * 'baseUrl' => 'https://nextcloud.example' * ], * ] * Created auth tokens are valid for 1 hour. * * @param WebhookListener $webhookListener * @param ?string $triggerUserId the user that triggered the webhook call * @return array{ * user_ids?: array, * trigger?: array{baseUrl: string, token: string, userId: string}, * owner?: array{baseUrl: string, token: string, userId: string}, * } */ public function getTokens(WebhookListener $webhookListener, ?string $triggerUserId): array { $tokens = []; $tokenNeeded = $webhookListener->getTokenNeeded(); if (isset($tokenNeeded['user_ids'])) { $tokens = [ 'user_ids' => [], ]; foreach ($tokenNeeded['user_ids'] as $userId) { try { $tokens['user_ids'][$userId] = [ 'userId' => $userId, 'token' => $this->createEphemeralToken($userId), 'baseUrl' => $this->urlGenerator->getBaseUrl() ]; } catch (\Exception $e) { $this->logger->error('Webhook token creation for user ' . $userId . ' failed: ' . $e->getMessage(), ['exception' => $e]); } } } if (isset($tokenNeeded['user_roles'])) { foreach ($tokenNeeded['user_roles'] as $user_role) { switch ($user_role) { case 'owner': // token for the person who created the flow $ownerId = $webhookListener->getUserId(); if (is_null($ownerId)) { // no owner uid available break; } $tokens['owner'] = [ 'userId' => $ownerId, 'token' => $this->createEphemeralToken($ownerId), 'baseUrl' => $this->urlGenerator->getBaseUrl() ]; break; case 'trigger': // token for the person who triggered the webhook if (is_null($triggerUserId)) { // no trigger uid available break; } $tokens['trigger'] = [ 'userId' => $triggerUserId, 'token' => $this->createEphemeralToken($triggerUserId), 'baseUrl' => $this->urlGenerator->getBaseUrl() ]; break; default: $this->logger->error('Webhook token creation for user role ' . $user_role . ' not defined. ', ['Not defined' => $user_role]); } } } return $tokens; } private function createEphemeralToken(string $userId): string { $token = $this->generateRandomDeviceToken(); // we need the user`s language to have the token name showing up in the session list in the correct language $user = $this->userManager->get($userId); $lang = $this->l10nFactory->getUserLanguage($user); $l = $this->l10nFactory->get('webhook_listeners', $lang); $name = $l->t('Ephemeral webhook authentication'); $password = null; $deviceToken = $this->tokenProvider->generateToken( $token, $userId, $userId, $password, $name, IToken::PERMANENT_TOKEN); $this->tokenMapper->addEphemeralToken( $deviceToken->getId(), $userId, $this->time->getTime()); return $token; } private function generateRandomDeviceToken(): string { $groups = []; for ($i = 0; $i < 5; $i++) { $groups[] = $this->random->generate(5, ISecureRandom::CHAR_HUMAN_READABLE); } return implode('-', $groups); } }