1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* This file is part of the Guarded Authentication package. |
4
|
|
|
* |
5
|
|
|
* (c) Jafar Jabr <[email protected]> |
6
|
|
|
* |
7
|
|
|
* For the full copyright and license information, please view the LICENSE |
8
|
|
|
* file that was distributed with this source code. |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace Jafar\Bundle\GuardedAuthenticationBundle\Tests\Api\JWSProvider; |
12
|
|
|
|
13
|
|
|
use Jafar\Bundle\GuardedAuthenticationBundle\Api\JWSCreator\JWSCreator; |
14
|
|
|
use Jafar\Bundle\GuardedAuthenticationBundle\Api\JWSProvider\JWSProvider; |
15
|
|
|
use Jafar\Bundle\GuardedAuthenticationBundle\Api\KeyLoader\KeyLoaderInterface; |
16
|
|
|
use Jafar\Bundle\GuardedAuthenticationBundle\Api\KeyLoader\LoadedJWS; |
17
|
|
|
use PHPUnit\Framework\TestCase; |
|
|
|
|
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Class JWSProviderTest. |
21
|
|
|
* |
22
|
|
|
* @author Jafar Jabr <[email protected]> |
23
|
|
|
*/ |
24
|
|
|
class JWSProviderTest extends TestCase |
25
|
|
|
{ |
26
|
|
|
const PRIVATE_KEY = ' |
27
|
|
|
-----BEGIN ENCRYPTED PRIVATE KEY----- |
28
|
|
|
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 |
79
|
|
|
D5LySC0J8wgebXtJlzqJxQ== |
80
|
|
|
-----END ENCRYPTED PRIVATE KEY----- |
81
|
|
|
'; |
82
|
|
|
|
83
|
|
|
const PUBLIC_KEY = ' |
84
|
|
|
-----BEGIN PUBLIC KEY----- |
85
|
|
|
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0WjReuizJ9YnRCMF+FSV |
86
|
|
|
aXBGMj8iEBvKcE7d863WfLk74EsLuRO2emeWeggsDzRmHKRz/aO+uXwzlIfJEvbA |
87
|
|
|
z18MnhnbK9zrXhgEaLsLcw/ibP2Kwzjf3Z2vsKn9MS8PPWEbZFTpoxIDnys2Z2gK |
88
|
|
|
WP4FCHz8tRo8RFwQ45jWH5JziOS/zNu5ONad91jCoz6D3R+4avoaVBFh9ibgZwb4 |
89
|
|
|
LGj9Md4kGvWkW+nPAWO7e0/YDQrPvinLQjprYAfvpkfzKHPpH01PcVYThr7QA5Xw |
90
|
|
|
Hr82iIx0gFJut6eYGq1E+gQTm5VefSAFd84fsiWF/juXo1G/4gHUbKuOetf988m7 |
91
|
|
|
eUPewzA/L9gQEyUgqy9tx+zThzHKJNvHkjS6+NDyaMAPoFOl8+oBltWVfLcfmPS+ |
92
|
|
|
y+dMUBxns/I7YZ2PV8vttFThDZqw84hqBIrs7P1Pu3/5y1ozGAkTWty7js+WT87Z |
93
|
|
|
aJCOf1GsrT/8of5ug1j1p4flIbQ/y3C2A9TBufURoY6BHXtObhR4JNufiGJqaU5c |
94
|
|
|
DxOt9qoZmUhkFHIm/hmzWV3+qnrRdj5uMuHPQ87OaQYTo8CCuykLptSYmw6yuWQS |
95
|
|
|
5zSC/uW+o+ItuvMaFvwxLpd2g3Gp+xNYfkJy60oZ092qSojZRM0hnJPmb1Po/uYg |
96
|
|
|
8BPdWv11mKmSwyrrStyjhAECAwEAAQ== |
97
|
|
|
-----END PUBLIC KEY----- |
98
|
|
|
'; |
99
|
|
|
|
100
|
|
|
protected static $keyLoaderClass; |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Tests to create a signed JWT Token. |
104
|
|
|
*/ |
105
|
|
|
public function testCreate() |
106
|
|
|
{ |
107
|
|
|
$keyLoaderMock = $this->getKeyLoaderMock(); |
108
|
|
|
$keyLoaderMock |
109
|
|
|
->expects($this->once()) |
110
|
|
|
->method('loadKey') |
111
|
|
|
->with('private') |
112
|
|
|
->willReturn(self::PRIVATE_KEY); |
113
|
|
|
$keyLoaderMock |
114
|
|
|
->expects($this->once()) |
115
|
|
|
->method('getPassphrase') |
116
|
|
|
->willReturn('anyPassphrase'); |
117
|
|
|
|
118
|
|
|
$payload = ['username' => 'jafaronly']; |
119
|
|
|
$jwsProvider = new JWSProvider($keyLoaderMock, 3600, 68700); |
120
|
|
|
|
121
|
|
|
$this->assertInstanceOf(JWSCreator::class, $created = $jwsProvider->create($payload)); |
122
|
|
|
|
123
|
|
|
return $created->getToken(); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Tests to verify the signature of a valid given JWT Token. |
128
|
|
|
* |
129
|
|
|
* @depends testCreate |
130
|
|
|
*/ |
131
|
|
|
public function testLoad($jwt) |
132
|
|
|
{ |
133
|
|
|
$keyLoaderMock = $this->getKeyLoaderMock(); |
134
|
|
|
$keyLoaderMock |
135
|
|
|
->expects($this->once()) |
136
|
|
|
->method('loadKey') |
137
|
|
|
->with('public') |
138
|
|
|
->willReturn(self::PUBLIC_KEY); |
139
|
|
|
|
140
|
|
|
$jwsProvider = new JWSProvider($keyLoaderMock, 3600, 68700); |
141
|
|
|
$loadedJWS = $jwsProvider->load($jwt); |
142
|
|
|
$this->assertInstanceOf(LoadedJWS::class, $loadedJWS); |
143
|
|
|
|
144
|
|
|
$payload = $loadedJWS->getPayload(); |
145
|
|
|
$this->assertTrue(isset($payload['exp'])); |
146
|
|
|
$this->assertTrue(isset($payload['iat'])); |
147
|
|
|
$this->assertTrue(isset($payload['username'])); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
// public function testAllowEmptyTtl() |
|
|
|
|
151
|
|
|
// { |
152
|
|
|
// $keyLoaderMock = $this->getKeyLoaderMock(); |
153
|
|
|
// $keyLoaderMock |
154
|
|
|
// ->expects($this->at(0)) |
155
|
|
|
// ->method('loadKey') |
156
|
|
|
// ->with('private') |
157
|
|
|
// ->willReturn(self::PRIVATE_KEY); |
158
|
|
|
// $keyLoaderMock |
159
|
|
|
// ->expects($this->at(1)) |
160
|
|
|
// ->method('getPassphrase') |
161
|
|
|
// ->willReturn('anyPassphrase'); |
162
|
|
|
// |
163
|
|
|
// $keyLoaderMock |
164
|
|
|
// ->expects($this->at(2)) |
165
|
|
|
// ->method('loadKey') |
166
|
|
|
// ->with('public') |
167
|
|
|
// ->willReturn(self::PUBLIC_KEY); |
168
|
|
|
// |
169
|
|
|
// $provider = new JWSProvider($keyLoaderMock); |
170
|
|
|
// $jws = $provider->create(['username' => 'jafaronly']); |
171
|
|
|
// |
172
|
|
|
// $this->assertInstanceOf(JWSCreator::class, $jws); |
173
|
|
|
// $this->assertTrue($jws->isSigned()); |
174
|
|
|
// |
175
|
|
|
// $jws = $provider->load($jws->getToken()); |
176
|
|
|
// |
177
|
|
|
// $this->assertInstanceOf(LoadedJWS::class, $jws); |
178
|
|
|
// $this->assertFalse($jws->isInvalid()); |
179
|
|
|
// $this->assertFalse($jws->isExpired()); |
180
|
|
|
// $this->assertTrue($jws->isVerified()); |
181
|
|
|
// $this->assertArrayNotHasKey('exp', $jws->getPayload()); |
182
|
|
|
// } |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* @expectedException \InvalidArgumentException |
186
|
|
|
* @expectedExceptionMessage The TTL should be a numeric value |
187
|
|
|
*/ |
188
|
|
|
public function testInvalidTtl() |
189
|
|
|
{ |
190
|
|
|
new JWSProvider($this->getKeyLoaderMock(), 'string_ttl', 98000); |
|
|
|
|
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* @return \PHPUnit\Framework\MockObject\MockObject |
|
|
|
|
195
|
|
|
*/ |
196
|
|
|
private function getKeyLoaderMock() |
197
|
|
|
{ |
198
|
|
|
return $this |
199
|
|
|
->getMockBuilder(KeyLoaderInterface::class) |
200
|
|
|
->disableOriginalConstructor() |
201
|
|
|
->getMock(); |
202
|
|
|
} |
203
|
|
|
} |
204
|
|
|
|
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths