Skip to content

Commit 044b02d

Browse files
committed
first commit
0 parents  commit 044b02d

File tree

5 files changed

+216
-0
lines changed

5 files changed

+216
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/vendor
2+
/.idea
3+
.DS_Store
4+
coverage.xml
5+
composer.lock

composer.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "laravel-shield/stripe",
3+
"description": "A stripe service for shield",
4+
"type": "library",
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Ashley Clarke",
9+
"email": "[email protected]"
10+
}
11+
],
12+
"require": {
13+
"laravel-shield/shield": "^1.0",
14+
"stripe/stripe-php": "^5.3"
15+
},
16+
"require-dev": {
17+
"laravel-shield/testing": "^1.0"
18+
},
19+
"autoload": {
20+
"psr-4": {
21+
"Shield\\Stripe\\": "src/"
22+
}
23+
},
24+
"autoload-dev": {
25+
"psr-4": {
26+
"Shield\\Stripe\\Test\\": "tests/"
27+
}
28+
}
29+
}

phpunit.xml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit backupGlobals="false"
3+
backupStaticAttributes="false"
4+
bootstrap="vendor/autoload.php"
5+
colors="true"
6+
convertErrorsToExceptions="true"
7+
convertNoticesToExceptions="true"
8+
convertWarningsToExceptions="true"
9+
processIsolation="false"
10+
stopOnFailure="false">
11+
<testsuites>
12+
13+
<testsuite name="Unit Tests">
14+
<directory suffix="Test.php">./tests/Unit</directory>
15+
</testsuite>
16+
17+
</testsuites>
18+
<filter>
19+
<whitelist processUncoveredFilesFromWhitelist="true">
20+
<directory suffix=".php">./src</directory>
21+
</whitelist>
22+
</filter>
23+
<php>
24+
<env name="APP_ENV" value="testing"/>
25+
<env name="CACHE_DRIVER" value="array"/>
26+
<env name="SESSION_DRIVER" value="array"/>
27+
<env name="QUEUE_DRIVER" value="sync"/>
28+
</php>
29+
<logging>
30+
<log type="coverage-clover" target="coverage.xml" showUncoveredFiles="true"/>
31+
</logging>
32+
</phpunit>

src/Stripe.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace Shield\Stripe;
4+
5+
use Illuminate\Http\Request;
6+
use Illuminate\Support\Collection;
7+
use Shield\Shield\Contracts\Service;
8+
use Stripe\Error\SignatureVerification;
9+
use Stripe\Webhook;
10+
use UnexpectedValueException;
11+
12+
/**
13+
* Class Service
14+
*
15+
* @package \Shield\Stripe
16+
*/
17+
class Stripe implements Service
18+
{
19+
public function verify(Request $request, Collection $config): bool
20+
{
21+
try {
22+
Webhook::constructEvent(
23+
$request->getContent(),
24+
$request->header('Stripe-Signature'),
25+
$config->get('secret'),
26+
$config->get('tolerance', Webhook::DEFAULT_TOLERANCE)
27+
);
28+
} catch (UnexpectedValueException | SignatureVerification $exception) {
29+
return false;
30+
}
31+
32+
return true;
33+
}
34+
35+
public function headers(): array
36+
{
37+
return ['Stripe-Signature'];
38+
}
39+
}

tests/Unit/ServiceTest.php

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?php
2+
3+
namespace Shield\Stripe\Test\Unit;
4+
5+
use PHPUnit\Framework\Assert;
6+
use Shield\Shield\Contracts\Service;
7+
use Shield\Stripe\Stripe;
8+
use Shield\Testing\TestCase;
9+
10+
/**
11+
* Class ServiceTest
12+
*
13+
* @package \Shield\Stripe\Test
14+
*/
15+
class ServiceTest extends TestCase
16+
{
17+
/**
18+
* @var Stripe
19+
*/
20+
private $service;
21+
22+
public function setUp()
23+
{
24+
parent::setUp();
25+
26+
$this->service = new Stripe;
27+
}
28+
29+
/** @test */
30+
public function it_is_a_service()
31+
{
32+
Assert::assertInstanceOf(Service::class, new Stripe);
33+
}
34+
35+
/** @test */
36+
public function it_can_verify_a_valid_request()
37+
{
38+
$token = 'raNd0mk3y';
39+
40+
$this->app['config']['shield.services.stripe.options.secret'] = $token;
41+
42+
$content = json_encode(['data' => 'sample content']);
43+
44+
$request = $this->request($content);
45+
46+
$time = time();
47+
48+
$signature = $time . '.' . $content;
49+
50+
$headers = [
51+
'Stripe-Signature' => 't=' . $time . ',v1=' . hash_hmac('sha256', $signature, $token)
52+
];
53+
54+
$request->headers->add($headers);
55+
56+
Assert::assertTrue($this->service->verify($request, collect($this->app['config']['shield.services.stripe.options'])));
57+
}
58+
59+
/** @test */
60+
public function it_will_not_verify_a_bad_request()
61+
{
62+
$this->app['config']['shield.services.stripe.options.secret'] = 'good';
63+
64+
$content = json_encode(['data' => 'sample content']);
65+
66+
$request = $this->request($content);
67+
68+
$time = time();
69+
70+
$signature = $time . '.' . $content;
71+
72+
$headers = [
73+
'Stripe-Signature' => 't=' . $time . ',v1=' . hash_hmac('sha256', $signature, 'bad')
74+
];
75+
76+
$request->headers->add($headers);
77+
78+
Assert::assertFalse($this->service->verify($request, collect($this->app['config']['shield.services.stripe.options'])));
79+
}
80+
81+
/** @test */
82+
public function it_will_fail_if_timestamp_is_over_tolerance()
83+
{
84+
$token = 'raNd0mk3y';
85+
86+
$this->app['config']['shield.services.stripe.options.secret'] = $token;
87+
$this->app['config']['shield.services.stripe.options.tolerance'] = 60 * 5;
88+
89+
$content = 'sample content';
90+
91+
$request = $this->request($content);
92+
93+
$time = time() - 61 * 5; // 5 seconds over
94+
95+
$signature = $time . '.' . $content;
96+
97+
$headers = [
98+
'Stripe-Signature' => 't=' . $time . ',v1=' . hash_hmac('sha256', $signature, $token)
99+
];
100+
101+
$request->headers->add($headers);
102+
103+
Assert::assertFalse($this->service->verify($request, collect($this->app['config']['shield.services.stripe.options'])));
104+
}
105+
106+
/** @test */
107+
public function it_has_correct_headers_required()
108+
{
109+
Assert::assertArraySubset(['Stripe-Signature'], $this->service->headers());
110+
}
111+
}

0 commit comments

Comments
 (0)