Skip to content

Commit

Permalink
Merge pull request #21 from renoki-co/feature/message-validator
Browse files Browse the repository at this point in the history
[feature] Message Validator
  • Loading branch information
rennokki authored Aug 5, 2020
2 parents a4bf925 + deaa38c commit 05dd18b
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 56 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
}
],
"require": {
"illuminate/support": "^6.0|^7.0"
"illuminate/support": "^6.0|^7.0",
"aws/aws-php-sns-message-validator": "^1.6"
},
"autoload": {
"psr-4": {
Expand Down
42 changes: 34 additions & 8 deletions src/Concerns/HandlesSns.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,55 @@

namespace Rennokki\LaravelSnsEvents\Concerns;

use Aws\Sns\Message;
use Aws\Sns\MessageValidator;
use Exception;
use Illuminate\Http\Request;

trait HandlesSns
{
/**
* Get the payload content from the request.
* Get the SNS message as array.
*
* @param \Illuminate\Http\Request $request
* @return null|string
* @return \Aws\Sns\Message
*/
public function getRequestContent(Request $request)
public function getSnsMessage(Request $request)
{
return $request->getContent() ?: file_get_contents('php://input');
try {
return Message::fromJsonString(
$request->getContent() ?: file_get_contents('php://input')
);
} catch (Exception $e) {
return new Message([]);
}
}

/**
* Get the JSON-decoded content.
* Check if the SNS message is valid.
*
* @param \Illuminate\Http\Request $request
* @return array
* @return bool
*/
public function getSnsMessage(Request $request): array
public function snsMessageIsValid(Request $request): bool
{
return json_decode($this->getRequestContent($request), true);
try {
return $this->getMessageValidator($request)->isValid(
$this->getSnsMessage($request)
);
} catch (Exception $e) {
return false;
}
}

/**
* Get the message validator instance.
*
* @param \Illuminate\Http\Request $request
* @return \Aws\Sns\MessageValidator
*/
protected function getMessageValidator(Request $request)
{
return new MessageValidator;
}
}
18 changes: 16 additions & 2 deletions src/Http/Controllers/SnsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ class SnsController extends Controller
*/
public function handle(Request $request)
{
$snsMessage = $this->getSnsMessage($request);
if (! $this->snsMessageIsValid($request)) {
return $this->okStatus();
}

$snsMessage = $this->getSnsMessage($request)->toArray();

if (isset($snsMessage['Type'])) {
if ($snsMessage['Type'] === 'SubscriptionConfirmation') {
Expand All @@ -46,7 +50,7 @@ public function handle(Request $request)
}
}

return response('OK', 200);
return $this->okStatus();
}

/**
Expand Down Expand Up @@ -121,4 +125,14 @@ protected function onSubscriptionConfirmation(array $snsMessage, Request $reques
{
//
}

/**
* Get a 200 OK status.
*
* @return \Illuminate\Http\Response
*/
protected function okStatus()
{
return response('OK', 200);
}
}
14 changes: 14 additions & 0 deletions tests/Controllers/CustomSnsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Rennokki\LaravelSnsEvents\Tests\Controllers;

use Aws\Sns\MessageValidator;
use Illuminate\Http\Request;
use Rennokki\LaravelSnsEvents\Http\Controllers\SnsController;
use Rennokki\LaravelSnsEvents\Tests\Events\CustomSnsEvent;
Expand Down Expand Up @@ -86,4 +87,17 @@ protected function onSubscriptionConfirmation(array $snsMessage, Request $reques
{
mt_rand(0, 10000);
}

/**
* Get the message validator instance.
*
* @param \Illuminate\Http\Request $request
* @return \Aws\Sns\MessageValidator
*/
protected function getMessageValidator(Request $request)
{
return new MessageValidator(function ($url) use ($request) {
return $request->certificate ?: $url;
});
}
}
23 changes: 23 additions & 0 deletions tests/Controllers/SnsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Rennokki\LaravelSnsEvents\Tests\Controllers;

use Aws\Sns\MessageValidator;
use Illuminate\Http\Request;
use Rennokki\LaravelSnsEvents\Http\Controllers\SnsController as BaseSnsController;

class SnsController extends BaseSnsController
{
/**
* Get the message validator instance.
*
* @param \Illuminate\Http\Request $request
* @return \Aws\Sns\MessageValidator
*/
protected function getMessageValidator(Request $request)
{
return new MessageValidator(function ($url) use ($request) {
return $request->certificate ?: $url;
});
}
}
70 changes: 42 additions & 28 deletions tests/EventTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,22 @@ public function test_no_event_triggering_on_bad_request()
{
Event::fake();

$this
->json('GET', route('sns'))
$this->json('GET', route('sns'))
->assertSee('OK');

Event::assertNotDispatched(SnsNotification::class);
Event::assertNotDispatched(SnsSubscriptionConfirmation::class);

$this->json('GET', route('sns', ['certificate' => static::$certificate]))
->assertSee('OK');

Event::assertNotDispatched(SnsNotification::class);
Event::assertNotDispatched(SnsSubscriptionConfirmation::class);

$payload = $this->getSubscriptionConfirmationPayload();

$this->withHeaders($this->getHeadersForMessage($payload))
->json('GET', route('sns', ['certificate' => static::$certificate]))
->assertSee('OK');

Event::assertNotDispatched(SnsNotification::class);
Expand All @@ -26,12 +40,13 @@ public function test_subscription_confirmation()
{
Event::fake();

$this
->withHeaders([
'x-test-header' => 1,
])
->json('POST', route('sns'), $this->getSubscriptionConfirmationPayload())
->assertSee('OK');
$payload = $this->getSubscriptionConfirmationPayload();

$this->withHeaders(array_merge($this->getHeadersForMessage($payload), [
'x-test-header' => 1,
]))
->json('POST', route('sns', ['certificate' => static::$certificate]), $payload)
->assertSee('OK');

Event::assertNotDispatched(SnsNotification::class);

Expand All @@ -48,17 +63,16 @@ public function test_notification_confirmation()
{
Event::fake();

$payload = json_encode([
$payload = $this->getNotificationPayload([
'test' => 1,
'sns' => true,
]);

$this
->withHeaders([
'x-test-header' => 1,
])
->json('POST', route('sns'), $this->getNotificationPayload($payload))
->assertSee('OK');
$this->withHeaders(array_merge($this->getHeadersForMessage($payload), [
'x-test-header' => 1,
]))
->json('POST', route('sns', ['certificate' => static::$certificate]), $payload)
->assertSee('OK');

Event::assertNotDispatched(SnsSubscriptionConfirmation::class);

Expand All @@ -82,12 +96,13 @@ public function test_custom_controller_confirmation()
{
Event::fake();

$this
->withHeaders([
'x-test-header' => 1,
])
->json('POST', route('custom-sns', ['test' => 'some-string']), $this->getSubscriptionConfirmationPayload())
->assertSee('OK');
$payload = $this->getSubscriptionConfirmationPayload();

$this->withHeaders(array_merge($this->getHeadersForMessage($payload), [
'x-test-header' => 1,
]))
->json('POST', route('custom-sns', ['test' => 'some-string', 'certificate' => static::$certificate]), $payload)
->assertSee('OK');

Event::assertNotDispatched(CustomSnsEvent::class);

Expand All @@ -108,17 +123,16 @@ public function test_custom_controller_notification()
{
Event::fake();

$payload = json_encode([
$payload = $this->getNotificationPayload([
'test' => 1,
'sns' => true,
]);

$this
->withHeaders([
'x-test-header' => 1,
])
->json('POST', route('custom-sns', ['test' => 'some-string']), $this->getNotificationPayload($payload))
->assertSee('OK');
$this->withHeaders(array_merge($this->getHeadersForMessage($payload), [
'x-test-header' => 1,
]))
->json('POST', route('custom-sns', ['test' => 'some-string', 'certificate' => static::$certificate]), $payload)
->assertSee('OK');

Event::assertNotDispatched(CustomSubscriptionConfirmation::class);

Expand Down
Loading

0 comments on commit 05dd18b

Please sign in to comment.