Skip to content

Commit de94a1b

Browse files
committed
Added a very basic TaskHandler that runs Artisan commands
1 parent c7b43d2 commit de94a1b

File tree

8 files changed

+184
-6
lines changed

8 files changed

+184
-6
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
composer.lock
33
.idea/
44
.DS_Store
5+
.phpunit.result.cache

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
},
2121
"autoload": {
2222
"psr-4": {
23-
"Stackkit\\LaravelGoogleCloudTasksQueue\\": "src/"
23+
"Stackkit\\LaravelGoogleCloudScheduler\\": "src/"
2424
}
2525
},
2626
"autoload-dev": {
@@ -31,7 +31,7 @@
3131
"extra": {
3232
"laravel": {
3333
"providers": [
34-
"Stackkit\\LaravelGoogleCloudTasksQueue\\CloudTasksServiceProvider"
34+
"Stackkit\\LaravelGoogleCloudScheduler\\CloudSchedulerServiceProvider"
3535
]
3636
}
3737
}

src/CloudSchedulerException.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Stackkit\LaravelGoogleCloudScheduler;
4+
5+
use Exception;
6+
7+
class CloudSchedulerException extends Exception
8+
{
9+
//
10+
}

src/CloudSchedulerServiceProvider.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use Illuminate\Support\ServiceProvider as LaravelServiceProvider;
66
use Illuminate\Routing\Router;
7-
use Stackkit\LaravelGoogleCloudTasksQueue\TaskHandler;
87

98
class CloudSchedulerServiceProvider extends LaravelServiceProvider
109
{
@@ -15,6 +14,6 @@ public function boot(Router $router)
1514

1615
private function registerRoutes(Router $router)
1716
{
18-
$router->post('handle-task', [TaskHandler::class, 'handle']);
17+
$router->post('cloud-scheduler-job', [TaskHandler::class, 'handle']);
1918
}
2019
}

src/Command.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Stackkit\LaravelGoogleCloudScheduler;
4+
5+
class Command
6+
{
7+
public function capture()
8+
{
9+
return file_get_contents('php://input');
10+
}
11+
12+
public function captureWithoutArtisan()
13+
{
14+
return trim(str_replace('php artisan', '', $this->capture()));
15+
}
16+
}

src/TaskHandler.php

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,81 @@
11
<?php
22

3-
namespace Stackkit\LaravelGoogleCloudTasksQueue;
3+
namespace Stackkit\LaravelGoogleCloudScheduler;
4+
5+
use Firebase\JWT\JWT;
6+
use Illuminate\Http\Request;
7+
use Illuminate\Support\Facades\Artisan;
48

59
class TaskHandler
610
{
11+
private $command;
12+
private $request;
13+
private $openId;
14+
private $jwt;
15+
16+
public function __construct(Command $command, Request $request, OpenIdVerificator $openId, JWT $jwt)
17+
{
18+
$this->command = $command;
19+
$this->request = $request;
20+
$this->openId = $openId;
21+
$this->jwt = $jwt;
22+
}
23+
24+
/**
25+
* @throws CloudSchedulerException
26+
*/
727
public function handle()
828
{
9-
//
29+
$this->authorizeRequest();
30+
31+
set_time_limit(0);
32+
33+
Artisan::call($this->command->captureWithoutArtisan());
34+
35+
$output = Artisan::output();
36+
37+
logger($output);
38+
39+
return $this->cleanOutput($output);
40+
}
41+
42+
/**
43+
* @throws CloudSchedulerException
44+
*/
45+
private function authorizeRequest()
46+
{
47+
if (!$this->request->hasHeader('Authorization')) {
48+
return;
49+
}
50+
51+
$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+
}
71+
72+
if ($openIdToken->exp < time()) {
73+
throw new CloudSchedulerException('The given OpenID token has expired');
74+
}
75+
}
76+
77+
private function cleanOutput($output)
78+
{
79+
return trim($output);
1080
}
1181
}

tests/Support/TestCommand.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Tests\Support;
4+
5+
use Illuminate\Console\Command;
6+
7+
class TestCommand extends Command
8+
{
9+
/**
10+
* The name and signature of the console command.
11+
*
12+
* @var string
13+
*/
14+
protected $signature = 'test:command';
15+
16+
/**
17+
* The console command description.
18+
*
19+
* @var string
20+
*/
21+
protected $description = 'Do some testy stuff';
22+
23+
/**
24+
* Create a new command instance.
25+
*
26+
* @return void
27+
*/
28+
public function __construct()
29+
{
30+
parent::__construct();
31+
}
32+
33+
/**
34+
* Execute the console command.
35+
*
36+
* @return mixed
37+
*/
38+
public function handle()
39+
{
40+
logger('did something testy');
41+
}
42+
}

tests/TaskHandlerTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace Tests;
4+
5+
use Firebase\JWT\JWT;
6+
use Illuminate\Console\Scheduling\Schedule;
7+
use Illuminate\Support\Facades\Log;
8+
use Stackkit\LaravelGoogleCloudScheduler\Command;
9+
use Stackkit\LaravelGoogleCloudScheduler\OpenIdVerificator;
10+
use Stackkit\LaravelGoogleCloudScheduler\TaskHandler;
11+
12+
class TaskHandlerTest extends TestCase
13+
{
14+
private $taskHandler;
15+
private $fakeCommand;
16+
17+
public function setUp(): void
18+
{
19+
parent::setUp();
20+
21+
$this->fakeCommand = \Mockery::mock(Command::class)->makePartial();
22+
23+
$this->taskHandler = new TaskHandler(
24+
$this->fakeCommand,
25+
request(),
26+
app(OpenIdVerificator::class),
27+
app(JWT::class)
28+
);
29+
}
30+
31+
/** @test */
32+
public function it_executes_the_incoming_command()
33+
{
34+
$this->fakeCommand->shouldReceive('capture')->andReturn('env');
35+
36+
$output = $this->taskHandler->handle();
37+
38+
$this->assertEquals('Current application environment: testing', $output);
39+
}
40+
}

0 commit comments

Comments
 (0)