Skip to content

Commit 03ca320

Browse files
committed
Break the dependency on guzzle
1 parent 9fa01b5 commit 03ca320

File tree

10 files changed

+98
-40
lines changed

10 files changed

+98
-40
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
phpunit.xml
22
Makefile
3-
.idea
3+
/.idea/
4+
/*.iml
45
atlassian-ide-plugin.xml
56
.DS_Store
67
.swp

.travis.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
language: php
2+
3+
php:
4+
- 5.4
5+
- 5.5
6+
- 5.6
7+
- 7.0
8+
- hhvm
9+
10+
sudo: false
11+
12+
install:
13+
- travis_retry composer update --no-interaction --prefer-dist
14+
15+
script: vendor/bin/phpunit

composer.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,20 @@
1313
],
1414
"support": {
1515
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
16-
"issues": "https://github.com/aws/aws-sdk-php/issues"
16+
"issues": "https://github.com/aws/aws-sns-message-validator/issues"
1717
},
1818
"require": {
1919
"php": ">=5.4",
2020
"ext-openssl": "*"
2121
},
2222
"require-dev": {
23-
"phpunit/phpunit": "^4.0"
23+
"phpunit/phpunit": "^4.0",
24+
"squizlabs/php_codesniffer": "^2.3"
2425
},
2526
"autoload": {
2627
"psr-4": { "Aws\\Sns\\": "src/" }
2728
},
2829
"autoload-dev": {
29-
"psr-4": { "Aws\\Sns\\Test\\": "tests/" }
30+
"psr-4": { "Aws\\Sns\\": "tests/" }
3031
}
3132
}

phpunit.xml.dist

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<phpunit bootstrap="./vendor/autoload.php">
4+
<testsuites>
5+
<testsuite name="AWS SNS Message Validator Test Suite">
6+
<directory>./tests</directory>
7+
</testsuite>
8+
</testsuites>
9+
</phpunit>

src/Message.php

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,39 @@
11
<?php
2+
23
namespace Aws\Sns;
34

45
class Message
56
{
67
private static $requiredKeys = [
7-
'__default' => ['Message', 'MessageId', 'Timestamp', 'TopicArn',
8-
'Type', 'Signature', 'SigningCertURL',],
9-
'SubscriptionConfirmation' => ['SubscribeURL', 'Token'],
10-
'UnsubscribeConfirmation' => ['SubscribeURL', 'Token']
8+
'__default' => [
9+
'Message',
10+
'MessageId',
11+
'Timestamp',
12+
'TopicArn',
13+
'Type',
14+
'Signature',
15+
'SigningCertURL',
16+
],
17+
'SubscriptionConfirmation' => [
18+
'SubscribeURL',
19+
'Token',
20+
],
21+
'UnsubscribeConfirmation' => [
22+
'SubscribeURL',
23+
'Token',
24+
],
1125
];
1226

13-
private static $signableKeys = ['Message', 'MessageId', 'Subject',
14-
'SubscribeURL', 'Timestamp', 'Token', 'TopicArn', 'Type'];
27+
private static $signableKeys = [
28+
'Message',
29+
'MessageId',
30+
'Subject',
31+
'SubscribeURL',
32+
'Timestamp',
33+
'Token',
34+
'TopicArn',
35+
'Type',
36+
];
1537

1638
/** @var array The message data */
1739
private $data;
@@ -58,8 +80,8 @@ public static function fromArray(array $data)
5880
// Determine required keys and create a collection from the message data
5981
$requiredKeys = array_merge(
6082
self::$requiredKeys['__default'],
61-
isset(self::$requiredKeys[$data['Type']])
62-
? self::$requiredKeys[$data['Type']]
83+
isset(self::$requiredKeys[$data['Type']]) ?
84+
self::$requiredKeys[$data['Type']]
6385
: []
6486
);
6587

src/MessageValidator.php

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
namespace Aws\Sns;
34

45
/**
@@ -7,14 +8,23 @@
78
*/
89
class MessageValidator
910
{
11+
/**
12+
* @var callable
13+
*/
14+
private $remoteFileReader;
15+
1016
/**
1117
* Constructs the Message Validator object and ensures that openssl is
1218
* installed.
1319
*
20+
* @param callable $remoteFileReader
21+
*
1422
* @throws \RuntimeException If openssl is not installed
1523
*/
16-
public function __construct()
24+
public function __construct(callable $remoteFileReader = null)
1725
{
26+
$this->remoteFileReader = $remoteFileReader ?: 'file_get_contents';
27+
1828
if (!extension_loaded('openssl')) {
1929
//@codeCoverageIgnoreStart
2030
throw new \RuntimeException('The openssl extension is required to '
@@ -40,20 +50,22 @@ public function validate(Message $message)
4050
$this->validateUrl($certUrl);
4151

4252
// Get the cert itself and extract the public key
43-
$certificate = file_get_contents($certUrl);
53+
$certificate = call_user_func($this->remoteFileReader, $certUrl);
4454
$key = openssl_get_publickey($certificate);
4555
if (!$key) {
46-
throw new MessageValidatorException('Cannot get the public key '
47-
. 'from the certificate.');
56+
throw new MessageValidatorException(
57+
'Cannot get the public key from the certificate.'
58+
);
4859
}
4960

5061
// Verify the signature of the message
5162
$content = $message->getStringToSign();
5263
$signature = base64_decode($message->get('Signature'));
5364

5465
if (!openssl_verify($content, $signature, $key, OPENSSL_ALGO_SHA1)) {
55-
throw new MessageValidatorException('The message signature is '
56-
. 'invalid.');
66+
throw new MessageValidatorException(
67+
'The message signature is invalid.'
68+
);
5769
}
5870
}
5971

@@ -88,7 +100,9 @@ private function validateUrl($url)
88100
// The cert URL must be https, a .pem, and match the following pattern.
89101
static $hostPattern = '/^sns\.[a-zA-Z0-9\-]{3,}\.amazonaws\.com(\.cn)?$/';
90102
$parsed = parse_url($url);
91-
if ($parsed['scheme'] !== 'https'
103+
if (empty($parsed['scheme'])
104+
|| empty($parsed['host'])
105+
|| $parsed['scheme'] !== 'https'
92106
|| substr($url, -4) !== '.pem'
93107
|| !preg_match($hostPattern, $parsed['host'])
94108
) {

src/MessageValidatorException.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
<?php
2+
23
namespace Aws\Sns;
34

45
/**
56
* Runtime exception thrown by the SNS Message Validator.
67
*/
7-
class MessageValidatorException extends \RuntimeException {}
8+
class MessageValidatorException extends \RuntimeException
9+
{
10+
}

tests/MessageTest.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<?php
2-
namespace Aws\Sns\Test;
32

4-
use Aws\Sns\Message;
3+
namespace Aws\Sns;
54

65
/**
76
* @covers Aws\Sns\Message
@@ -34,7 +33,7 @@ public function testGetters()
3433
public function testFactorySucceedsWithGoodData()
3534
{
3635
$this->assertInstanceOf(
37-
'Aws\Sns\MessageValidator\Message',
36+
'Aws\Sns\Message',
3837
Message::fromArray($this->messageData)
3938
);
4039
}
@@ -67,7 +66,7 @@ public function testCanCreateFromRawPost()
6766
stream_wrapper_register('php', __NAMESPACE__ . '\MockPhpStream');
6867

6968
$message = Message::fromRawPostData();
70-
$this->assertInstanceOf('Aws\Sns\MessageValidator\Message', $message);
69+
$this->assertInstanceOf('Aws\Sns\Message', $message);
7170

7271
stream_wrapper_restore("php");
7372
unset($_SERVER['HTTP_X_AMZ_SNS_MESSAGE_TYPE']);

tests/MessageValidatorTest.php

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
<?php
2-
namespace Aws\Sns\Test;
32

4-
use Aws\Sns\Message;
5-
use Aws\Sns\MessageValidator;
3+
namespace Aws\Sns;
64

75
/**
86
* @covers \Aws\Sns\MessageValidator
@@ -45,8 +43,7 @@ public function testValidateFailsWhenCertUrlInvalid()
4543
*/
4644
public function testValidateFailsWhenCannotDeterminePublicKey()
4745
{
48-
$client = $this->getMockClient();
49-
$validator = new MessageValidator($client);
46+
$validator = new MessageValidator($this->getMockClient(''));
5047
$message = new Message([
5148
'SigningCertURL' => self::VALID_CERT_URL
5249
]);
@@ -63,8 +60,7 @@ public function testValidateFailsWhenMessageIsInvalid()
6360
list($signature, $certificate) = $this->getSignature('foo');
6461
// Create the validator with a mock HTTP client that will respond with
6562
// the certificate
66-
$client = $this->getMockClient(new Psr7\Response(200, [], $certificate));
67-
$validator = new MessageValidator($client);
63+
$validator = new MessageValidator($this->getMockClient($certificate));
6864
$message = new Message([
6965
'SigningCertURL' => self::VALID_CERT_URL,
7066
'Signature' => $signature,
@@ -93,19 +89,16 @@ public function testValidateSucceedsWhenMessageIsValid()
9389

9490
// Create the validator with a mock HTTP client that will respond with
9591
// the certificate
96-
$client = $this->getMockClient(new Psr7\Response(200, [], $certificate));
97-
$validator = new MessageValidator($client);
92+
$validator = new MessageValidator($this->getMockClient($certificate));
9893

9994
// The message should validate
10095
$this->assertTrue($validator->isValid($message));
10196
}
10297

103-
protected function getMockClient(Psr7\Response $response = null)
98+
protected function getMockClient($responseBody)
10499
{
105-
$response = $response ?: new Psr7\Response(200);
106-
107-
return function () use ($response) {
108-
return \GuzzleHttp\Promise\promise_for($response);
100+
return static function () use ($responseBody) {
101+
return $responseBody;
109102
};
110103
}
111104

@@ -123,6 +116,6 @@ protected function getSignature($stringToSign)
123116
openssl_pkey_free($keypair);
124117
openssl_x509_free($x509);
125118

126-
return [base64_encode($signature), Psr7\stream_for($certificate)];
119+
return [base64_encode($signature), $certificate];
127120
}
128121
}

tests/MockPhpStream.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
2-
namespace Aws\Sns\Test;
2+
3+
namespace Aws\Sns;
34

45
class MockPhpStream
56
{

0 commit comments

Comments
 (0)