15
15
use InvalidArgumentException ;
16
16
use Lcobucci \JWT \Builder ;
17
17
use Lcobucci \JWT \Parser ;
18
+ use Lcobucci \JWT \Signer ;
18
19
use Lcobucci \JWT \Signer \Key ;
20
+ use Lcobucci \JWT \Signer \Rsa \Sha256 as RS256 ;
21
+ use Lcobucci \JWT \Token ;
22
+ use Lcobucci \JWT \Token \DataSet ;
23
+ use Lcobucci \JWT \Validation \Constraint ;
19
24
use Mockery ;
20
25
use Mockery \MockInterface ;
21
26
use PHPOpenSourceSaver \JWTAuth \Exceptions \JWTException ;
26
31
27
32
class LcobucciTest extends AbstractTestCase
28
33
{
34
+ /**
35
+ * Mocks {@see Configuration}.
36
+ *
37
+ * @var MockInterface
38
+ */
39
+ protected $ config ;
40
+
29
41
/**
30
42
* @var MockInterface
31
43
*/
@@ -37,9 +49,9 @@ class LcobucciTest extends AbstractTestCase
37
49
protected $ builder ;
38
50
39
51
/**
40
- * @var Namshi
52
+ * @var MockInterface
41
53
*/
42
- protected $ provider ;
54
+ protected $ validator ;
43
55
44
56
public function setUp (): void
45
57
{
@@ -54,19 +66,22 @@ public function it_should_return_the_token_when_passing_a_valid_payload_to_encod
54
66
{
55
67
$ payload = ['sub ' => 1 , 'exp ' => $ this ->testNowTimestamp + 3600 , 'iat ' => $ this ->testNowTimestamp , 'iss ' => '/foo ' ];
56
68
57
- $ this ->builder ->shouldReceive ('unsign ' )->once ()->andReturnSelf ();
58
- $ this ->builder ->shouldReceive ('set ' )->times (count ($ payload ));
59
- $ this ->builder ->shouldReceive ('sign ' )->once ()->with (Mockery::any (), 'secret ' );
60
- $ this ->builder ->shouldReceive ('getToken ' )->once ()->andReturn ('foo.bar.baz ' );
69
+ $ dataSet = new DataSet ($ payload , 'payload ' );
61
70
62
- $ token = $ this ->getProvider ('secret ' , 'HS256 ' )->encode ($ payload );
71
+ $ this ->builder ->shouldReceive ('relatedTo ' )->once ()->andReturnSelf (); // sub
72
+ $ this ->builder ->shouldReceive ('expiresAt ' )->once ()->andReturnSelf (); // exp
73
+ $ this ->builder ->shouldReceive ('issuedAt ' )->once ()->andReturnSelf (); // iat
74
+ $ this ->builder ->shouldReceive ('issuedBy ' )->once ()->andReturnSelf (); // iss
75
+ $ this ->builder
76
+ ->shouldReceive ('getToken ' )
77
+ ->once ()
78
+ ->with (\Mockery::type (Signer::class), \Mockery::type (Key::class))
79
+ ->andReturn (new Token \Plain (new DataSet ([], 'header ' ), $ dataSet , (new Token \Signature ('' , 'signature ' ))));
63
80
64
- $ this -> assertSame ( ' foo.bar.baz ' , $ token);
65
- }
81
+ /** @var Token $token */
82
+ $ token = $ this -> getProvider ( ' secret ' , ' HS256 ' )-> encode ( $ payload );
66
83
67
- public function getProvider ($ secret , $ algo , array $ keys = [])
68
- {
69
- return new Lcobucci ($ this ->builder , $ this ->parser , $ secret , $ algo , $ keys );
84
+ $ this ->assertSame ('header.payload.signature ' , $ token );
70
85
}
71
86
72
87
/** @test */
@@ -77,9 +92,15 @@ public function it_should_throw_an_invalid_exception_when_the_payload_could_not_
77
92
78
93
$ payload = ['sub ' => 1 , 'exp ' => $ this ->testNowTimestamp , 'iat ' => $ this ->testNowTimestamp , 'iss ' => '/foo ' ];
79
94
80
- $ this ->builder ->shouldReceive ('unsign ' )->once ()->andReturnSelf ();
81
- $ this ->builder ->shouldReceive ('set ' )->times (count ($ payload ));
82
- $ this ->builder ->shouldReceive ('sign ' )->once ()->with (Mockery::any (), 'secret ' )->andThrow (new Exception );
95
+ $ this ->builder ->shouldReceive ('relatedTo ' )->once ()->andReturnSelf (); // sub
96
+ $ this ->builder ->shouldReceive ('expiresAt ' )->once ()->andReturnSelf (); // exp
97
+ $ this ->builder ->shouldReceive ('issuedAt ' )->once ()->andReturnSelf (); // iat
98
+ $ this ->builder ->shouldReceive ('issuedBy ' )->once ()->andReturnSelf (); // iss
99
+ $ this ->builder
100
+ ->shouldReceive ('getToken ' )
101
+ ->once ()
102
+ ->with (\Mockery::type (Signer::class), \Mockery::type (Key::class))
103
+ ->andThrow (new Exception );
83
104
84
105
$ this ->getProvider ('secret ' , 'HS256 ' )->encode ($ payload );
85
106
}
@@ -89,24 +110,36 @@ public function it_should_return_the_payload_when_passing_a_valid_token_to_decod
89
110
{
90
111
$ payload = ['sub ' => 1 , 'exp ' => $ this ->testNowTimestamp + 3600 , 'iat ' => $ this ->testNowTimestamp , 'iss ' => '/foo ' ];
91
112
92
- $ this ->parser ->shouldReceive ('parse ' )->once ()->with ('foo.bar.baz ' )->andReturn (Mockery::self ());
93
- $ this ->parser ->shouldReceive ('verify ' )->once ()->with (Mockery::any (), 'secret ' )->andReturn (true );
94
- $ this ->parser ->shouldReceive ('getClaims ' )->once ()->andReturn ($ payload );
113
+ $ token = Mockery::mock (Token::class);
114
+ $ dataSet = Mockery::mock (new DataSet ($ payload , 'payload ' ));
115
+
116
+ $ provider = $ this ->getProvider ('secret ' , 'HS256 ' );
117
+
118
+ $ this ->parser ->shouldReceive ('parse ' )->once ()->with ('foo.bar.baz ' )->andReturn ($ token );
119
+ $ this ->validator ->shouldReceive ('validate ' )->once ()->with ($ token , Mockery::any ())->andReturnTrue ();
120
+ $ token ->shouldReceive ('claims ' )->once ()->andReturn ($ dataSet );
121
+ $ dataSet ->shouldReceive ('all ' )->once ()->andReturn ($ payload );
95
122
96
- $ this ->assertSame ($ payload , $ this -> getProvider ( ' secret ' , ' HS256 ' ) ->decode ('foo.bar.baz ' ));
123
+ $ this ->assertSame ($ payload , $ provider ->decode ('foo.bar.baz ' ));
97
124
}
98
125
99
126
/** @test */
100
127
public function it_should_throw_a_token_invalid_exception_when_the_token_could_not_be_decoded_due_to_a_bad_signature ()
101
128
{
129
+ $ token = Mockery::mock (Token::class);
130
+ $ dataSet = Mockery::mock (new DataSet (['pay ' , 'load ' ], 'payload ' ));
131
+
132
+ $ provider = $ this ->getProvider ('secret ' , 'HS256 ' );
133
+
102
134
$ this ->expectException (TokenInvalidException::class);
103
135
$ this ->expectExceptionMessage ('Token Signature could not be verified. ' );
104
136
105
- $ this ->parser ->shouldReceive ('parse ' )->once ()->with ('foo.bar.baz ' )->andReturn (Mockery::self ());
106
- $ this ->parser ->shouldReceive ('verify ' )->once ()->with (Mockery::any (), 'secret ' )->andReturn (false );
107
- $ this ->parser ->shouldReceive ('getClaims ' )->never ();
137
+ $ this ->parser ->shouldReceive ('parse ' )->once ()->with ('foo.bar.baz ' )->andReturn ($ token );
138
+ $ this ->validator ->shouldReceive ('validate ' )->once ()->with ($ token , Mockery::any ())->andReturnFalse ();
139
+ $ token ->shouldReceive ('claims ' )->never ();
140
+ $ dataSet ->shouldReceive ('all ' )->never ();
108
141
109
- $ this -> getProvider ( ' secret ' , ' HS256 ' ) ->decode ('foo.bar.baz ' );
142
+ $ provider ->decode ('foo.bar.baz ' );
110
143
}
111
144
112
145
/** @test */
@@ -125,32 +158,32 @@ public function it_should_throw_a_token_invalid_exception_when_the_token_could_n
125
158
/** @test */
126
159
public function it_should_generate_a_token_when_using_an_rsa_algorithm ()
127
160
{
161
+ $ dummyPrivateKey = $ this ->getDummyPrivateKey ();
162
+ $ dummyPublicKey = $ this ->getDummyPublicKey ();
163
+
128
164
$ provider = $ this ->getProvider (
129
165
'does_not_matter ' ,
130
166
'RS256 ' ,
131
- ['private ' => $ this -> getDummyPrivateKey () , 'public ' => $ this -> getDummyPublicKey () ]
167
+ ['private ' => $ dummyPrivateKey , 'public ' => $ dummyPublicKey ]
132
168
);
133
169
134
170
$ payload = ['sub ' => 1 , 'exp ' => $ this ->testNowTimestamp + 3600 , 'iat ' => $ this ->testNowTimestamp , 'iss ' => '/foo ' ];
135
171
136
- $ this ->builder ->shouldReceive ('unsign ' )->once ()->andReturnSelf ();
137
- $ this ->builder ->shouldReceive ('set ' )->times (count ($ payload ));
138
- $ this ->builder ->shouldReceive ('sign ' )->once ()->with (Mockery::any (), Mockery::type (Key::class));
139
- $ this ->builder ->shouldReceive ('getToken ' )->once ()->andReturn ('foo.bar.baz ' );
140
-
141
- $ token = $ provider ->encode ($ payload );
172
+ $ dataSet = new DataSet ($ payload , 'payload ' );
142
173
143
- $ this ->assertSame ('foo.bar.baz ' , $ token );
144
- }
174
+ $ this ->builder ->shouldReceive ('relatedTo ' )->once ()->andReturnSelf (); // sub
175
+ $ this ->builder ->shouldReceive ('expiresAt ' )->once ()->andReturnSelf (); // exp
176
+ $ this ->builder ->shouldReceive ('issuedAt ' )->once ()->andReturnSelf (); // iat
177
+ $ this ->builder ->shouldReceive ('issuedBy ' )->once ()->andReturnSelf (); // iss
178
+ $ this ->builder
179
+ ->shouldReceive ('getToken ' )
180
+ ->once ()
181
+ ->with (Mockery::type (RS256 ::class), Mockery::type (Key::class))
182
+ ->andReturn (new Token \Plain (new DataSet ([], 'header ' ), $ dataSet , (new Token \Signature ('' , 'signature ' ))));
145
183
146
- public function getDummyPrivateKey ()
147
- {
148
- return file_get_contents (__DIR__ . '/../Keys/id_rsa ' );
149
- }
184
+ $ token = $ provider ->encode ($ payload );
150
185
151
- public function getDummyPublicKey ()
152
- {
153
- return file_get_contents (__DIR__ . '/../Keys/id_rsa.pub ' );
186
+ $ this ->assertSame ('header.payload.signature ' , $ token );
154
187
}
155
188
156
189
/** @test */
@@ -188,4 +221,34 @@ public function it_should_return_the_keys()
188
221
189
222
$ this ->assertSame ($ keys , $ provider ->getKeys ());
190
223
}
224
+
225
+ public function getProvider ($ secret , $ algo , array $ keys = [])
226
+ {
227
+ $ provider = new Lcobucci ($ secret , $ algo , $ keys );
228
+
229
+ $ this ->validator = Mockery::mock (\Lcobucci \JWT \Validator::class);
230
+ $ this ->config = Mockery::mock ($ provider ->getConfig ());
231
+
232
+ $ provider = new Lcobucci ($ secret , $ algo , $ keys , $ this ->config );
233
+
234
+ $ this ->config ->shouldReceive ('builder ' )->andReturn ($ this ->builder );
235
+ $ this ->config ->shouldReceive ('parser ' )->andReturn ($ this ->parser );
236
+ $ this ->config ->shouldReceive ('validator ' )->andReturn ($ this ->validator );
237
+
238
+ $ constraint = Mockery::mock (Constraint::class);
239
+ $ constraint ->shouldReceive ('assert ' )->andReturn ();
240
+ $ this ->config ->shouldReceive ('validationConstraints ' )->andReturn ([$ constraint ]);
241
+
242
+ return $ provider ;
243
+ }
244
+
245
+ public function getDummyPrivateKey ()
246
+ {
247
+ return file_get_contents (__DIR__ . '/../Keys/id_rsa ' );
248
+ }
249
+
250
+ public function getDummyPublicKey ()
251
+ {
252
+ return file_get_contents (__DIR__ . '/../Keys/id_rsa.pub ' );
253
+ }
191
254
}
0 commit comments