Skip to content

Commit 8d19e84

Browse files
committed
Webhook: add service to validate incoming payload
1 parent 8d45847 commit 8d19e84

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,15 @@ Returns the new Magento legacy key.
558558
$client->customers()->magentoLegacyKeys()->remove($customerId, $publicKey);
559559
```
560560

561+
### Validate incoming webhook payloads
562+
```php
563+
$request = /** any Psr7 request */;
564+
$secret = 'webhook-secret';
565+
$webhookSignature = new \PrivatePackagist\ApiClient\WebhookSignature($secret);
566+
$requestSignature = $request->hasHeader('Packagist-Signature') ? $request->getHeader('Packagist-Signature')[0] : null;
567+
$webhookSignature->validate($requestSignature, (string) $request->getBody());
568+
```
569+
561570
## License
562571

563572
`private-packagist/api-client` is licensed under the MIT License

src/WebhookSignature.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace PrivatePackagist\ApiClient;
4+
5+
class WebhookSignature
6+
{
7+
/** @var string */
8+
private $secret;
9+
10+
public function __construct($secret)
11+
{
12+
$this->secret = $secret;
13+
}
14+
15+
/**
16+
* @param string $signature
17+
* @param string $payload
18+
* @return bool
19+
*/
20+
public function validate($signature, $payload)
21+
{
22+
$payloadSignature = 'sha1='.hash_hmac('sha1', $payload, $this->secret);
23+
24+
return hash_equals($payloadSignature, (string) $signature);
25+
}
26+
}

tests/WebhookSignatureTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace PrivatePackagist\ApiClient;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
class WebhookSignatureTest extends TestCase
8+
{
9+
/** @var WebhookSignature */
10+
private $webhookSignature;
11+
12+
protected function setUp()
13+
{
14+
$this->webhookSignature = new WebhookSignature('test');
15+
}
16+
17+
public function testValidate()
18+
{
19+
$this->assertTrue($this->webhookSignature->validate('sha1=b92a2ae52a340f2246a0ec24d45bb4ecfdf7b8ac', 'payload'));
20+
}
21+
22+
public function testValidateInvalid()
23+
{
24+
$this->assertFalse($this->webhookSignature->validate('sha1=invalid', 'payload'));
25+
}
26+
27+
public function testValidateNull()
28+
{
29+
$this->assertFalse($this->webhookSignature->validate('sha1=invalid', null));
30+
}
31+
}

0 commit comments

Comments
 (0)