Page MenuHomeDevCentral

No OneTemporary

diff --git a/app/Http/Controllers/Gate/GitHubGateController.php b/app/Http/Controllers/Gate/GitHubGateController.php
index f59c388..b1b27de 100644
--- a/app/Http/Controllers/Gate/GitHubGateController.php
+++ b/app/Http/Controllers/Gate/GitHubGateController.php
@@ -1,166 +1,189 @@
<?php
namespace Nasqueron\Notifications\Http\Controllers\Gate;
use Event;
use Request;
use Nasqueron\Notifications\Events\GitHubPayloadEvent;
use Keruald\GitHub\XHubSignature;
class GitHubGateController extends GateController {
///
/// Private members
///
/**
* The request signature, allowing to determine if the payload is legit
*
* @var string
*/
private $signature;
/**
* The GitHub event triggering this request
*
* @var string
*/
private $event;
/**
* The request delivery GUID
*
* @var string
*/
private $delivery;
/**
* The request content, as a structured data
*
* @var stdClass
*/
private $payload;
/**
* The request content
*
* @var string
*/
private $rawRequestContent;
///
/// Constants
///
const SERVICE_NAME = 'GitHub';
///
/// Request processing
///
/**
* Handles POST requests
*
* @param Request $request the HTTP request
* @return Illuminate\Http\Response
*/
public function onPost ($door) {
// Parses the request and check if it's legit
$this->door = $door;
$this->extractHeaders();
$this->extractPayload();
if (!$this->isLegitRequest()) {
abort(403, 'Unauthorized action.');
}
+ if (!$this->isValidRequest()) {
+ abort(400, 'Bad request.');
+ }
+
// Process the request
$this->logGateRequest();
$this->onPayload();
// Output
return parent::renderReport();
}
/**
* Extracts headers from the request
*/
protected function extractHeaders () {
$this->signature = $this->getSignature();
$this->event = Request::header('X-Github-Event');
$this->delivery = Request::header('X-Github-Delivery');
}
/**
* Gets the signature from an X-Hub-Signature header
*
* @param string the signature part of the header
*/
private function getSignature () {
$headerSignature = Request::header('X-Hub-Signature');
return XHubSignature::parseSignature($headerSignature);
}
/**
* Extracts payload from the request
*/
protected function extractPayload () {
$request = Request::instance();
$this->rawRequestContent = $request->getContent();
$this->payload = json_decode($this->rawRequestContent);
}
+ /**
+ * Determines if the request is valid, ie contains the mandatory headers
+ * and a payload.
+ *
+ * @return bool true if the request looks valid; otherwise, false.
+ */
+ protected function isValidRequest () {
+ if (empty($this->event)) {
+ return false;
+ }
+ if (empty($this->delivery)) {
+ return false;
+ }
+ if (empty($this->payload) || !is_object($this->payload)) {
+ return false;
+ }
+ return true;
+ }
+
/**
* Determines if the request is legit.
*
* @return bool true if the request looks legit; otherwise, false.
*/
protected function isLegitRequest () {
$secret = $this->getSecret();
// If the secret is not defined, request legitimation is bypassed
if (empty($secret)) {
return true;
}
// If the secret is defined, but signature is missing from the
// request, we don't need to perform any other validation.
if (empty($this->signature)) {
return false;
}
return XHubSignature::validatePayload(
$secret,
$this->rawRequestContent,
$this->signature
);
}
/**
* Logs the request
*/
protected function logGateRequest () {
$this->logRequest([
'delivery' => $this->delivery,
'event' => $this->event,
]);
}
///
/// Payload processing
///
protected function onPayload () {
$this->initializeReport();
Event::fire(new GitHubPayloadEvent(
$this->door,
$this->event,
$this->payload
));
}
}
diff --git a/tests/Http/Controllers/GitHubGateControllerTest.php b/tests/Http/Controllers/GitHubGateControllerTest.php
index b41710c..86265de 100644
--- a/tests/Http/Controllers/GitHubGateControllerTest.php
+++ b/tests/Http/Controllers/GitHubGateControllerTest.php
@@ -1,46 +1,59 @@
<?php
namespace Nasqueron\Notifications\Tests\Http\Controllers;
use Nasqueron\Notifications\Tests\TestCase;
class GitHubGateControllerTest extends TestCase {
public function setUp () {
parent::setUp();
$this->disableEvents();
}
/**
* GitHub gate works.
*
* @return void
*/
public function testGet () {
$this->visit('/gate/GitHub')
->see('POST');
}
/**
* Tests a GitHub gate payload.
*/
public function testPost () {
$payload = file_get_contents(__DIR__ . '/../../data/payloads/GitHubPingPayload.json');
$this->sendPayload(
'/gate/GitHub/Quux', // A gate not existing in data/credentials.json
$payload,
'POST',
[
'X-Github-Event' => 'ping',
'X-Github-Delivery' => 'e5dd9fc7-17ac-11e5-9427-73dad6b9b17c'
]
)
->seeJson([
'gate' => 'GitHub',
'door' => 'Quux',
'actions' => []
]);
$this->assertResponseOk();
}
+
+ /**
+ * Tests a malformed GitHub gate payload.
+ */
+ public function testMalformedPost () {
+ $this->sendPayload(
+ '/gate/GitHub/Quux', // A gate not existing in data/credentials.json
+ "",
+ 'POST',
+ []
+ );
+ $this->assertResponseStatus(400);
+ }
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Sep 18, 03:40 (1 d, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2986802
Default Alt Text
(6 KB)

Event Timeline