Skip to content

Commit 424800c

Browse files
committed
Moved OpenID token verification to separate class and added tests
1 parent de94a1b commit 424800c

File tree

3 files changed

+71
-31
lines changed

3 files changed

+71
-31
lines changed

src/OpenIdVerificator.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,33 @@ class OpenIdVerificator
1717

1818
private $guzzle;
1919
private $rsa;
20+
private $jwt;
2021

21-
public function __construct(Client $guzzle, RSA $rsa)
22+
public function __construct(Client $guzzle, RSA $rsa, JWT $jwt)
2223
{
2324
$this->guzzle = $guzzle;
2425
$this->rsa = $rsa;
26+
$this->jwt = $jwt;
27+
}
28+
29+
public function guardAgainstInvalidOpenIdToken($token)
30+
{
31+
$kid = $this->getKidFromOpenIdToken($token);
32+
$publicKey = $this->getPublicKey($kid);
33+
34+
$decodedToken = $this->jwt->decode($token, $publicKey, ['RS256']);
35+
36+
/**
37+
* https://developers.google.com/identity/protocols/oauth2/openid-connect#validatinganidtoken
38+
*/
39+
40+
if (!in_array($decodedToken->iss, ['https://accounts.google.com', 'accounts.google.com'])) {
41+
throw new CloudSchedulerException('The given OpenID token is not valid');
42+
}
43+
44+
if ($decodedToken->exp < time()) {
45+
throw new CloudSchedulerException('The given OpenID token has expired');
46+
}
2547
}
2648

2749
public function getPublicKey($kid = null)

src/TaskHandler.php

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,21 @@
22

33
namespace Stackkit\LaravelGoogleCloudScheduler;
44

5-
use Firebase\JWT\JWT;
65
use Illuminate\Http\Request;
76
use Illuminate\Support\Facades\Artisan;
7+
use Throwable;
88

99
class TaskHandler
1010
{
1111
private $command;
1212
private $request;
1313
private $openId;
14-
private $jwt;
1514

16-
public function __construct(Command $command, Request $request, OpenIdVerificator $openId, JWT $jwt)
15+
public function __construct(Command $command, Request $request, OpenIdVerificator $openId)
1716
{
1817
$this->command = $command;
1918
$this->request = $request;
2019
$this->openId = $openId;
21-
$this->jwt = $jwt;
2220
}
2321

2422
/**
@@ -34,8 +32,6 @@ public function handle()
3432

3533
$output = Artisan::output();
3634

37-
logger($output);
38-
3935
return $this->cleanOutput($output);
4036
}
4137

@@ -45,32 +41,15 @@ public function handle()
4541
private function authorizeRequest()
4642
{
4743
if (!$this->request->hasHeader('Authorization')) {
48-
return;
44+
throw new CloudSchedulerException('Unauthorized');
4945
}
5046

5147
$openIdToken = $this->request->bearerToken();
52-
$kid = $this->openId->getKidFromOpenIdToken($openIdToken);
53-
$publicKey = $this->openId->getPublicKey($kid);
54-
55-
$decodedToken = $this->jwt->decode($openIdToken, $publicKey, ['RS256']);
56-
57-
$this->validateToken($decodedToken);
58-
}
59-
60-
/**
61-
* https://developers.google.com/identity/protocols/oauth2/openid-connect#validatinganidtoken
62-
*
63-
* @param $openIdToken
64-
* @throws CloudSchedulerException
65-
*/
66-
protected function validateToken($openIdToken)
67-
{
68-
if (!in_array($openIdToken->iss, ['https://accounts.google.com', 'accounts.google.com'])) {
69-
throw new CloudSchedulerException('The given OpenID token is not valid');
70-
}
7148

72-
if ($openIdToken->exp < time()) {
73-
throw new CloudSchedulerException('The given OpenID token has expired');
49+
try {
50+
$this->openId->guardAgainstInvalidOpenIdToken($openIdToken);
51+
} catch (Throwable $e) {
52+
throw new CloudSchedulerException('Unauthorized');
7453
}
7554
}
7655

tests/TaskHandlerTest.php

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
use Firebase\JWT\JWT;
66
use Illuminate\Console\Scheduling\Schedule;
7+
use Illuminate\Http\Request;
78
use Illuminate\Support\Facades\Log;
9+
use Stackkit\LaravelGoogleCloudScheduler\CloudSchedulerException;
810
use Stackkit\LaravelGoogleCloudScheduler\Command;
911
use Stackkit\LaravelGoogleCloudScheduler\OpenIdVerificator;
1012
use Stackkit\LaravelGoogleCloudScheduler\TaskHandler;
@@ -13,17 +15,25 @@ class TaskHandlerTest extends TestCase
1315
{
1416
private $taskHandler;
1517
private $fakeCommand;
18+
private $openId;
19+
private $request;
1620

1721
public function setUp(): void
1822
{
1923
parent::setUp();
2024

2125
$this->fakeCommand = \Mockery::mock(Command::class)->makePartial();
2226

27+
// ensure we don't call Google services to validate the token
28+
$this->openId = \Mockery::mock(app(OpenIdVerificator::class))->makePartial();
29+
30+
$this->request = new Request();
31+
$this->request->headers->add(['Authorization' => 'test']);
32+
2333
$this->taskHandler = new TaskHandler(
2434
$this->fakeCommand,
25-
request(),
26-
app(OpenIdVerificator::class),
35+
$this->request,
36+
$this->openId,
2737
app(JWT::class)
2838
);
2939
}
@@ -32,9 +42,38 @@ public function setUp(): void
3242
public function it_executes_the_incoming_command()
3343
{
3444
$this->fakeCommand->shouldReceive('capture')->andReturn('env');
45+
$this->openId->shouldReceive('guardAgainstInvalidOpenIdToken')->andReturnNull();
3546

3647
$output = $this->taskHandler->handle();
3748

3849
$this->assertEquals('Current application environment: testing', $output);
3950
}
51+
52+
/** @test */
53+
public function it_requires_a_jwt()
54+
{
55+
$this->fakeCommand->shouldReceive('capture')->andReturn('env');
56+
$this->openId->shouldReceive('guardAgainstInvalidOpenIdToken')->andReturnNull();
57+
58+
$this->request->headers->remove('Authorization');
59+
60+
$this->expectException(CloudSchedulerException::class);
61+
62+
$this->taskHandler->handle();
63+
}
64+
65+
/** @test */
66+
public function it_requires_a_jwt_signed_by_google()
67+
{
68+
$this->fakeCommand->shouldReceive('capture')->andReturn('env');
69+
70+
$dummyJwt = JWT::encode('test', 'test');
71+
72+
$this->request->headers->add(['Authorization' => 'Bearer ' . $dummyJwt]);
73+
74+
$this->expectException(CloudSchedulerException::class);
75+
$this->expectExceptionMessage('Unauthorized');
76+
77+
$this->taskHandler->handle();
78+
}
4079
}

0 commit comments

Comments
 (0)