Skip to content

Commit e11fa57

Browse files
committed
Nearly competed, missing README and a test.
1 parent 076ea88 commit e11fa57

File tree

6 files changed

+157
-17
lines changed

6 files changed

+157
-17
lines changed

config/cloudfront-url-signer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
/*
1010
* The private key used to sign all URLs.
1111
*/
12-
'private_key' => storage_path(env('CLOUDFRONT_PRIVATE_KEY_PATH', 'trusted-signer.pem')),
12+
'private_key_path' => storage_path(env('CLOUDFRONT_PRIVATE_KEY_PATH', 'trusted-signer.pem')),
1313

1414
/*
1515
* Identifies the CloudFront key pair associated

src/CloudFrontUrlSigner.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use DateTime;
77
use Dreamonkey\CloudFrontUrlSigner\Exceptions\InvalidExpiration;
88
use Dreamonkey\CloudFrontUrlSigner\Exceptions\InvalidKeyPairId;
9-
use Dreamonkey\CloudFrontUrlSigner\Exceptions\InvalidPrivateKey;
9+
use Dreamonkey\CloudFrontUrlSigner\Exceptions\InvalidPrivateKeyPath;
1010
use League\Uri\Http;
1111

1212
class CloudFrontUrlSigner implements UrlSigner
@@ -19,11 +19,11 @@ class CloudFrontUrlSigner implements UrlSigner
1919
private $cloudFrontClient;
2020

2121
/**
22-
* Private key of the trusted signer.
22+
* Path where to find the private key of the trusted signer.
2323
*
2424
* @var string
2525
*/
26-
private $privateKey;
26+
private $privateKeyPath;
2727

2828
/**
2929
* Identifier of the CloudFront Key Pair associated to the trusted signer.
@@ -33,25 +33,25 @@ class CloudFrontUrlSigner implements UrlSigner
3333
private $keyPairId;
3434

3535
/**
36-
* @param array $cloudFrontParams
37-
* @param string $privateKey
36+
* @param \Aws\CloudFront\CloudFrontClient $cloudFrontClient
37+
* @param string $privateKeyPath
3838
* @param string $keyPairId
3939
*
40-
* @throws \Dreamonkey\CloudFrontUrlSigner\Exceptions\InvalidPrivateKey
40+
* @throws \Dreamonkey\CloudFrontUrlSigner\Exceptions\InvalidPrivateKeyPath
4141
* @throws \Dreamonkey\CloudFrontUrlSigner\Exceptions\InvalidKeyPairId
4242
*/
43-
public function __construct(array $cloudFrontParams, string $privateKey, string $keyPairId)
43+
public function __construct(CloudFrontClient $cloudFrontClient, string $privateKeyPath, string $keyPairId)
4444
{
45-
if ($privateKey == '') {
46-
throw new InvalidPrivateKey('Private key cannot be empty');
45+
if ($privateKeyPath == '') {
46+
throw new InvalidPrivateKeyPath('Private key path cannot be empty');
4747
}
4848

4949
if ($keyPairId == '') {
5050
throw new InvalidKeyPairId('Key pair id cannot be empty');
5151
}
5252

53-
$this->cloudFrontClient = new CloudFrontClient($cloudFrontParams);
54-
$this->privateKey = $privateKey;
53+
$this->cloudFrontClient = $cloudFrontClient;
54+
$this->privateKeyPath = $privateKeyPath;
5555
$this->keyPairId = $keyPairId;
5656
}
5757

@@ -73,7 +73,7 @@ public function sign($url, $expiration)
7373
return $this->cloudFrontClient->getSignedUrl([
7474
'url' => $resourceKey,
7575
'expires' => $expiration,
76-
'private_key' => $this->privateKey,
76+
'private_key' => $this->privateKeyPath,
7777
'key_pair_id' => $this->keyPairId,
7878
]);
7979
}

src/CloudFrontUrlSignerServiceProvider.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Dreamonkey\CloudFrontUrlSigner;
44

5+
use Aws\CloudFront\CloudFrontClient;
56
use Illuminate\Contracts\Foundation\Application;
67
use Illuminate\Support\ServiceProvider;
78

@@ -37,12 +38,12 @@ public function register()
3738
$config = config('cloudfront-url-signer');
3839

3940
$this->app->singleton(UrlSigner::class, function () use ($config) {
40-
$cloudFrontParams = [
41+
$cloudFrontClient = new CloudFrontClient([
4142
'region' => $config['region'],
4243
'version' => $config['version']
43-
];
44+
]);;
4445

45-
return new CloudFrontUrlSigner($cloudFrontParams, $config['key_pair_id'], $config['private_key']);
46+
return new CloudFrontUrlSigner($cloudFrontClient, $config['key_pair_id'], $config['private_key_path']);
4647
});
4748

4849
$this->app->alias(UrlSigner::class, 'cloudfront-url-signer');
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
namespace Dreamonkey\CloudFrontUrlSigner\Exceptions;
44

5-
class InvalidPrivateKey extends \Exception
5+
class InvalidPrivateKeyPath extends \Exception
66
{
77
}

tests/SignatureGenerationTest.php

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
3+
namespace Dreamonkey\CloudFrontUrlSigner\Tests;
4+
5+
use Aws\CloudFront\CloudFrontClient;
6+
use DateTime;
7+
use DateTimeZone;
8+
use Dreamonkey\CloudFrontUrlSigner\CloudFrontUrlSigner;
9+
10+
class SignatureGenerationTest extends TestCase
11+
{
12+
private $dummyUrl = 'http://myapp.com';
13+
private $dummyPrivateKeyPath = 'dummy/path/key.pem';
14+
private $dummyKeyPairId = 'dummyKeyPairId';
15+
16+
private $mockCloudFrontClient;
17+
18+
protected function setUp()
19+
{
20+
parent::setUp();
21+
$this->mockCloudFrontClient = $this->createMock(CloudFrontClient::class);
22+
$this->mockCloudFrontClient->method('getSignedUrl')->willReturn('dummysignedurl');
23+
}
24+
25+
/** @test */
26+
public function it_registered_cloudfront_url_signer_in_the_container()
27+
{
28+
config(['cloudfront-url-signer.private_key_path' => $this->dummyPrivateKeyPath]);
29+
$instance = $this->app['cloudfront-url-signer'];
30+
31+
$this->assertInstanceOf(\Dreamonkey\CloudFrontUrlSigner\CloudFrontUrlSigner::class, $instance);
32+
}
33+
34+
/**
35+
* @test
36+
*
37+
* @expectedException \Dreamonkey\CloudFrontUrlSigner\Exceptions\InvalidKeyPairId
38+
*/
39+
public function it_will_throw_an_exception_for_an_empty_key_pair_id()
40+
{
41+
/** @noinspection PhpUnhandledExceptionInspection */
42+
new CloudFrontUrlSigner($this->mockCloudFrontClient, $this->dummyPrivateKeyPath, '');
43+
}
44+
45+
/**
46+
* @test
47+
*
48+
* @expectedException \Dreamonkey\CloudFrontUrlSigner\Exceptions\InvalidPrivateKeyPath
49+
*/
50+
public function it_will_throw_an_exception_for_an_empty_private_key_path()
51+
{
52+
/** @noinspection PhpUnhandledExceptionInspection */
53+
new CloudFrontUrlSigner($this->mockCloudFrontClient, '', $this->dummyKeyPairId);
54+
}
55+
56+
/** @test */
57+
public function it_can_sign_a_signed_url_that_expires_at_a_certain_time()
58+
{
59+
$expiration = DateTime::createFromFormat('d/m/Y H:i:s', '10/08/2115 18:15:44',
60+
new DateTimeZone('Europe/Brussels'));
61+
62+
/** @noinspection PhpUnhandledExceptionInspection */
63+
$urlSigner = (new CloudFrontUrlSigner($this->mockCloudFrontClient,
64+
$this->dummyPrivateKeyPath, $this->dummyKeyPairId));
65+
66+
/** @noinspection PhpUnhandledExceptionInspection */
67+
$signedUrl = $urlSigner->sign($this->dummyUrl, $expiration);
68+
69+
$this->assertTrue(is_string($signedUrl));
70+
}
71+
72+
/** @test */
73+
public function it_can_sign_a_signed_url_that_expires_after_a_relative_amount_of_days()
74+
{
75+
$expiration = 30;
76+
77+
/** @noinspection PhpUnhandledExceptionInspection */
78+
$urlSigner = (new CloudFrontUrlSigner($this->mockCloudFrontClient,
79+
$this->dummyPrivateKeyPath, $this->dummyKeyPairId));
80+
81+
/** @noinspection PhpUnhandledExceptionInspection */
82+
$signedUrl = $urlSigner->sign($this->dummyUrl, $expiration);
83+
84+
$this->assertTrue(is_string($signedUrl));
85+
}
86+
87+
/**
88+
* @test
89+
*
90+
* @expectedException \Dreamonkey\CloudFrontUrlSigner\Exceptions\InvalidExpiration
91+
*/
92+
public function it_does_not_allow_expiration_in_the_past_when_integer_is_given()
93+
{
94+
$expiration = -5;
95+
96+
/** @noinspection PhpUnhandledExceptionInspection */
97+
$urlSigner = (new CloudFrontUrlSigner($this->mockCloudFrontClient,
98+
$this->dummyPrivateKeyPath, $this->dummyKeyPairId));
99+
100+
$urlSigner->sign($this->dummyUrl, $expiration);
101+
}
102+
103+
/**
104+
* @test
105+
*
106+
* @expectedException \Dreamonkey\CloudFrontUrlSigner\Exceptions\InvalidExpiration
107+
*/
108+
public function it_does_not_allow_expiration_in_the_past_when_datetime_is_given()
109+
{
110+
$expiration = DateTime::createFromFormat('d/m/Y H:i:s', '10/08/2005 18:15:44');
111+
112+
/** @noinspection PhpUnhandledExceptionInspection */
113+
$urlSigner = (new CloudFrontUrlSigner($this->mockCloudFrontClient,
114+
$this->dummyPrivateKeyPath, $this->dummyKeyPairId));
115+
116+
$urlSigner->sign($this->dummyUrl, $expiration);
117+
}
118+
}

tests/TestCase.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Dreamonkey\CloudFrontUrlSigner\Tests;
4+
5+
use Dreamonkey\CloudFrontUrlSigner\CloudFrontUrlSignerServiceProvider;
6+
use Orchestra\Testbench\TestCase as Orchestra;
7+
8+
abstract class TestCase extends Orchestra
9+
{
10+
/**
11+
* @param \Illuminate\Foundation\Application $app
12+
*
13+
* @return array
14+
*/
15+
protected function getPackageProviders($app)
16+
{
17+
return [
18+
CloudFrontUrlSignerServiceProvider::class,
19+
];
20+
}
21+
}

0 commit comments

Comments
 (0)