Skip to content

Commit

Permalink
Merge pull request #114 from Tarpsvo/feature/optional-audience-hash
Browse files Browse the repository at this point in the history
Add optional signed_audience flag
  • Loading branch information
marickvantuil authored Jul 2, 2023
2 parents 9e11378 + aad2d5d commit 48d5402
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 5 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Please check the [Laravel support policy](https://laravel.com/docs/master/releas
'handler' => env('STACKKIT_CLOUD_TASKS_HANDLER', ''),
'queue' => env('STACKKIT_CLOUD_TASKS_QUEUE', 'default'),
'service_account_email' => env('STACKKIT_CLOUD_TASKS_SERVICE_EMAIL', ''),
'signed_audience' => env('STACKKIT_CLOUD_TASKS_SIGNED_AUDIENCE', true),
// Optional: The deadline in seconds for requests sent to the worker. If the worker
// does not respond by this deadline then the request is cancelled and the attempt
// is marked as a DEADLINE_EXCEEDED failure.
Expand All @@ -70,6 +71,7 @@ Please check the table below on what the values mean and what their value should
| `STACKKIT_CLOUD_TASKS_QUEUE` | The default queue a job will be added to |`emails`
| `STACKKIT_CLOUD_TASKS_SERVICE_EMAIL` | The email address of the service account. Important, it should have the correct roles. See the section below which roles. |`[email protected]`
| `STACKKIT_CLOUD_TASKS_HANDLER` (optional) | The URL that Cloud Tasks will call to process a job. This should be the URL to your Laravel app. By default we will use the URL that dispatched the job. |`https://<your website>.com`
| `STACKKIT_CLOUD_TASKS_SIGNED_AUDIENCE` (optional) | True or false depending if you want extra security by signing the audience of your tasks. May misbehave in certain Cloud Run setups. Defaults to true. | `true`
</details>
<details>
<summary>
Expand Down
24 changes: 21 additions & 3 deletions src/CloudTasksQueue.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,16 @@ protected function pushToCloudTasks($queue, $payload, $delay = 0)

$token = new OidcToken;
$token->setServiceAccountEmail($this->config['service_account_email']);
$token->setAudience(hash_hmac('sha256', $this->getHandler(), config('app.key')));
if ($audience = $this->getAudience()) {
$token->setAudience($audience);
}
$httpRequest->setOidcToken($token);

if ($availableAt > time()) {
$task->setScheduleTime(new Timestamp(['seconds' => $availableAt]));
}

$createdTask = CloudTasksApi::createTask($queueName, $task);
CloudTasksApi::createTask($queueName, $task);

event((new TaskCreated)->queue($queue)->task($task));

Expand All @@ -192,7 +194,7 @@ private function withUuid(array $payload): array

private function taskName(string $queueName, array $payload): string
{
$displayName = str_replace("\\", '-', $payload['displayName']);
$displayName = $this->sanitizeTaskName($payload['displayName']);

return CloudTasksClient::taskName(
$this->config['project'],
Expand All @@ -202,6 +204,17 @@ private function taskName(string $queueName, array $payload): string
);
}

private function sanitizeTaskName(string $taskName)
{
// Remove all characters that are not -, letters, numbers, or whitespace
$sanitizedName = preg_replace('![^-\pL\pN\s]+!u', '-', $taskName);

// Replace all separator characters and whitespace by a -
$sanitizedName = preg_replace('![-\s]+!u', '-', $sanitizedName);

return trim($sanitizedName, '-');
}

private function withAttempts(array $payload): array
{
if (!isset($payload['internal']['attempts'])) {
Expand Down Expand Up @@ -268,4 +281,9 @@ public function getHandler(): string
{
return Config::getHandler($this->config['handler']);
}

public function getAudience(): ?string
{
return Config::getAudience($this->config);
}
}
11 changes: 11 additions & 0 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,15 @@ public static function getHandler($handler): string
);
}
}

/**
* @param array $config
* @return string|null The audience as an hash or null if not needed
*/
public static function getAudience(array $config): ?string
{
return $config['signed_audience'] ?? true
? hash_hmac('sha256', self::getHandler($config['handler']), config('app.key'))
: null;
}
}
2 changes: 1 addition & 1 deletion src/OpenIdVerificatorConcrete.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public function verify(?string $token, array $config): void
(new AccessToken())->verify(
$token,
[
'audience' => hash_hmac('sha256', app('queue')->getHandler(), config('app.key')),
'audience' => Config::getAudience($config),
'throwException' => true,
]
);
Expand Down
2 changes: 1 addition & 1 deletion src/OpenIdVerificatorFake.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public function verify(?string $token, array $config): void
(new AccessToken())->verify(
$token,
[
'audience' => hash_hmac('sha256', app('queue')->getHandler(), config('app.key')),
'audience' => Config::getAudience($config),
'throwException' => true,
'certsLocation' => __DIR__ . '/../tests/Support/self-signed-public-key-as-jwk.json',
]
Expand Down
1 change: 1 addition & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ protected function getEnvironmentSetUp($app)
'location' => 'europe-west6',
'handler' => env('CLOUD_TASKS_HANDLER', 'https://docker.for.mac.localhost:8080'),
'service_account_email' => '[email protected]',
'signed_audience' => true,
]);
$app['config']->set('queue.failed.driver', 'database-uuids');
$app['config']->set('queue.failed.database', 'testbench');
Expand Down

0 comments on commit 48d5402

Please sign in to comment.