Skip to content

Commit 48d5402

Browse files
Merge pull request #114 from Tarpsvo/feature/optional-audience-hash
Add optional signed_audience flag
2 parents 9e11378 + aad2d5d commit 48d5402

6 files changed

+37
-5
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Please check the [Laravel support policy](https://laravel.com/docs/master/releas
4545
'handler' => env('STACKKIT_CLOUD_TASKS_HANDLER', ''),
4646
'queue' => env('STACKKIT_CLOUD_TASKS_QUEUE', 'default'),
4747
'service_account_email' => env('STACKKIT_CLOUD_TASKS_SERVICE_EMAIL', ''),
48+
'signed_audience' => env('STACKKIT_CLOUD_TASKS_SIGNED_AUDIENCE', true),
4849
// Optional: The deadline in seconds for requests sent to the worker. If the worker
4950
// does not respond by this deadline then the request is cancelled and the attempt
5051
// is marked as a DEADLINE_EXCEEDED failure.
@@ -70,6 +71,7 @@ Please check the table below on what the values mean and what their value should
7071
| `STACKKIT_CLOUD_TASKS_QUEUE` | The default queue a job will be added to |`emails`
7172
| `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]`
7273
| `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`
74+
| `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`
7375
</details>
7476
<details>
7577
<summary>

src/CloudTasksQueue.php

+21-3
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,16 @@ protected function pushToCloudTasks($queue, $payload, $delay = 0)
167167

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

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

177-
$createdTask = CloudTasksApi::createTask($queueName, $task);
179+
CloudTasksApi::createTask($queueName, $task);
178180

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

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

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

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

207+
private function sanitizeTaskName(string $taskName)
208+
{
209+
// Remove all characters that are not -, letters, numbers, or whitespace
210+
$sanitizedName = preg_replace('![^-\pL\pN\s]+!u', '-', $taskName);
211+
212+
// Replace all separator characters and whitespace by a -
213+
$sanitizedName = preg_replace('![-\s]+!u', '-', $sanitizedName);
214+
215+
return trim($sanitizedName, '-');
216+
}
217+
205218
private function withAttempts(array $payload): array
206219
{
207220
if (!isset($payload['internal']['attempts'])) {
@@ -268,4 +281,9 @@ public function getHandler(): string
268281
{
269282
return Config::getHandler($this->config['handler']);
270283
}
284+
285+
public function getAudience(): ?string
286+
{
287+
return Config::getAudience($this->config);
288+
}
271289
}

src/Config.php

+11
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,15 @@ public static function getHandler($handler): string
8282
);
8383
}
8484
}
85+
86+
/**
87+
* @param array $config
88+
* @return string|null The audience as an hash or null if not needed
89+
*/
90+
public static function getAudience(array $config): ?string
91+
{
92+
return $config['signed_audience'] ?? true
93+
? hash_hmac('sha256', self::getHandler($config['handler']), config('app.key'))
94+
: null;
95+
}
8596
}

src/OpenIdVerificatorConcrete.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public function verify(?string $token, array $config): void
1818
(new AccessToken())->verify(
1919
$token,
2020
[
21-
'audience' => hash_hmac('sha256', app('queue')->getHandler(), config('app.key')),
21+
'audience' => Config::getAudience($config),
2222
'throwException' => true,
2323
]
2424
);

src/OpenIdVerificatorFake.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public function verify(?string $token, array $config): void
1717
(new AccessToken())->verify(
1818
$token,
1919
[
20-
'audience' => hash_hmac('sha256', app('queue')->getHandler(), config('app.key')),
20+
'audience' => Config::getAudience($config),
2121
'throwException' => true,
2222
'certsLocation' => __DIR__ . '/../tests/Support/self-signed-public-key-as-jwk.json',
2323
]

tests/TestCase.php

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ protected function getEnvironmentSetUp($app)
103103
'location' => 'europe-west6',
104104
'handler' => env('CLOUD_TASKS_HANDLER', 'https://docker.for.mac.localhost:8080'),
105105
'service_account_email' => '[email protected]',
106+
'signed_audience' => true,
106107
]);
107108
$app['config']->set('queue.failed.driver', 'database-uuids');
108109
$app['config']->set('queue.failed.database', 'testbench');

0 commit comments

Comments
 (0)