Implemented a way to verify webhook signature (#325)

* Implemented a way to verify webhook signature

* CS
This commit is contained in:
Tobias Nyholm 2017-04-08 01:29:20 +02:00 committed by Sean Johnson
parent d8e716fbd3
commit 7665700b00
3 changed files with 54 additions and 6 deletions

View File

@ -9,18 +9,66 @@
namespace Mailgun\Api; namespace Mailgun\Api;
use Http\Client\HttpClient;
use Mailgun\Assert; use Mailgun\Assert;
use Mailgun\Hydrator\Hydrator;
use Mailgun\Model\Webhook\CreateResponse; use Mailgun\Model\Webhook\CreateResponse;
use Mailgun\Model\Webhook\DeleteResponse; use Mailgun\Model\Webhook\DeleteResponse;
use Mailgun\Model\Webhook\IndexResponse; use Mailgun\Model\Webhook\IndexResponse;
use Mailgun\Model\Webhook\ShowResponse; use Mailgun\Model\Webhook\ShowResponse;
use Mailgun\Model\Webhook\UpdateResponse; use Mailgun\Model\Webhook\UpdateResponse;
use Mailgun\RequestBuilder;
/** /**
* @author Tobias Nyholm <tobias.nyholm@gmail.com> * @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/ */
class Webhook extends HttpApi class Webhook extends HttpApi
{ {
/**
* @var string
*/
private $apiKey;
/**
* @param HttpClient $httpClient
* @param RequestBuilder $requestBuilder
* @param Hydrator $hydrator
* @param string $apiKey
*/
public function __construct(HttpClient $httpClient, RequestBuilder $requestBuilder, Hydrator $hydrator, $apiKey)
{
parent::__construct($httpClient, $requestBuilder, $hydrator);
$this->apiKey = $apiKey;
}
/**
* This function verifies the webhook signature with your API key to to see if it is authentic.
*
* If this function returns FALSE, you must not process the request.
* You should reject the request with status code 403 Forbidden.
*
* @param int $timestamp
* @param string $token
* @param string $signature
*
* @return bool
*/
public function verifyWebhookSignature($timestamp, $token, $signature)
{
if (empty($timestamp) || empty($token) || empty($signature)) {
return false;
}
$hmac = hash_hmac('sha256', $timestamp.$token, $this->apiKey);
if (function_exists('hash_equals')) {
// hash_equals is constant time, but will not be introduced until PHP 5.6
return hash_equals($hmac, $signature);
} else {
return $hmac === $signature;
}
}
/** /**
* @param string $domain * @param string $domain
* *

View File

@ -110,7 +110,7 @@ final class HttpClientConfigurator
/** /**
* @return string * @return string
*/ */
private function getApiKey() public function getApiKey()
{ {
return $this->apiKey; return $this->apiKey;
} }

View File

@ -84,20 +84,20 @@ class Mailgun
} }
/** /**
* @param HttpClientConfigurator $httpClientConfigurator * @param HttpClientConfigurator $configurator
* @param Hydrator|null $hydrator * @param Hydrator|null $hydrator
* @param RequestBuilder|null $requestBuilder * @param RequestBuilder|null $requestBuilder
* *
* @return Mailgun * @return Mailgun
*/ */
public static function configure( public static function configure(
HttpClientConfigurator $httpClientConfigurator, HttpClientConfigurator $configurator,
Hydrator $hydrator = null, Hydrator $hydrator = null,
RequestBuilder $requestBuilder = null RequestBuilder $requestBuilder = null
) { ) {
$httpClient = $httpClientConfigurator->createConfiguredClient(); $httpClient = $configurator->createConfiguredClient();
return new self(null, $httpClient, 'api.mailgun.net', $hydrator, $requestBuilder); return new self($configurator->getApiKey(), $httpClient, 'api.mailgun.net', $hydrator, $requestBuilder);
} }
/** /**
@ -358,7 +358,7 @@ class Mailgun
*/ */
public function webhooks() public function webhooks()
{ {
return new Api\Webhook($this->httpClient, $this->requestBuilder, $this->hydrator); return new Api\Webhook($this->httpClient, $this->requestBuilder, $this->hydrator, $this->apiKey);
} }
/** /**