1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace AerialShip\SamlSPBundle\Tests\Config; |
4
|
|
|
|
5
|
|
|
use AerialShip\LightSaml\Bindings; |
6
|
|
|
use AerialShip\SamlSPBundle\Config\SpEntityDescriptorBuilder; |
7
|
|
|
use AerialShip\SamlSPBundle\Config\SPSigningProviderInterface; |
8
|
|
|
|
9
|
|
|
class SpEntityDescriptorBuilderTest extends \PHPUnit_Framework_TestCase |
10
|
|
|
{ |
11
|
|
|
/** |
12
|
|
|
* @test |
13
|
|
|
*/ |
14
|
|
|
public function shouldImplementEntityDescriptorProviderInterface() |
15
|
|
|
{ |
16
|
|
|
$rc = new \ReflectionClass('AerialShip\SamlSPBundle\Config\SpEntityDescriptorBuilder'); |
17
|
|
|
$this->assertTrue($rc->implementsInterface('AerialShip\SamlSPBundle\Config\EntityDescriptorProviderInterface')); |
18
|
|
|
} |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* @test |
22
|
|
|
*/ |
23
|
|
|
public function shouldBeConstructedWithRequiredArguments() |
24
|
|
|
{ |
25
|
|
|
new SpEntityDescriptorBuilder( |
26
|
|
|
'idp', |
27
|
|
|
$this->createSPSigningProviderMock(), |
|
|
|
|
28
|
|
|
array('entity_id'=>'entityID', 'base_url'=>'http://site.com'), |
29
|
|
|
'check_path', |
30
|
|
|
'logout_path', |
31
|
|
|
$this->createHttpUtilsMock() |
|
|
|
|
32
|
|
|
); |
33
|
|
|
} |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @test |
37
|
|
|
*/ |
38
|
|
|
public function shouldReturnIdpIDSetInConstructor() |
39
|
|
|
{ |
40
|
|
|
$builder = new SpEntityDescriptorBuilder( |
41
|
|
|
$expectedIDP = 'idp', |
42
|
|
|
$this->createSPSigningProviderMock(), |
|
|
|
|
43
|
|
|
array('entity_id'=>'entityID', 'base_url'=>'http://site.com'), |
44
|
|
|
'check_path', |
45
|
|
|
'logout_path', |
46
|
|
|
$this->createHttpUtilsMock() |
|
|
|
|
47
|
|
|
); |
48
|
|
|
|
49
|
|
|
$this->assertEquals($expectedIDP, $builder->getAuthenticationServiceID()); |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* @test |
54
|
|
|
* @expectedException \RuntimeException |
55
|
|
|
* @expectedExceptionMessage Missing required config entity_id |
56
|
|
|
*/ |
57
|
|
|
public function shouldThrowIfConstructedWithoutEntityID() |
58
|
|
|
{ |
59
|
|
|
new SpEntityDescriptorBuilder( |
60
|
|
|
'idp', |
61
|
|
|
$this->createSPSigningProviderMock(), |
|
|
|
|
62
|
|
|
array('base_url'=>'http://site.com'), |
63
|
|
|
'check_path', |
64
|
|
|
'logout_path', |
65
|
|
|
$this->createHttpUtilsMock() |
|
|
|
|
66
|
|
|
); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @test |
71
|
|
|
* @expectedException \RuntimeException |
72
|
|
|
* @expectedExceptionMessage If config base_url is not set, then httpUtils are required |
73
|
|
|
*/ |
74
|
|
|
public function shouldThrowIfConstructedWithoutBaseUrlAndHttpUtils() |
75
|
|
|
{ |
76
|
|
|
new SpEntityDescriptorBuilder( |
77
|
|
|
'idp', |
78
|
|
|
$this->createSPSigningProviderMock(), |
|
|
|
|
79
|
|
|
array('entity_id'=>'entityID'), |
80
|
|
|
'check_path', |
81
|
|
|
'logout_path', |
82
|
|
|
null |
83
|
|
|
); |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* @test |
89
|
|
|
*/ |
90
|
|
|
public function shouldBuildWithSigningDisabledAndBasePathSet() |
91
|
|
|
{ |
92
|
|
|
$signingProvider = $this->createSPSigningProviderStub(false, null, null); |
93
|
|
|
$expectedEntityID = 'entityID'; |
94
|
|
|
$expectedBaseUrl = 'http://site.com'; |
95
|
|
|
$checkPath = '/check_path'; |
96
|
|
|
$logoutPath = '/logout_path'; |
97
|
|
|
|
98
|
|
|
$builder = new SpEntityDescriptorBuilder( |
99
|
|
|
'idp', |
100
|
|
|
$signingProvider, |
|
|
|
|
101
|
|
|
array('entity_id'=>$expectedEntityID, 'base_url'=>$expectedBaseUrl), |
102
|
|
|
$checkPath, |
103
|
|
|
$logoutPath, |
104
|
|
|
null |
105
|
|
|
); |
106
|
|
|
|
107
|
|
|
$ed = $builder->getEntityDescriptor(); |
108
|
|
|
|
109
|
|
|
$this->assertInstanceOf('AerialShip\LightSaml\Model\Metadata\EntityDescriptor', $ed); |
110
|
|
|
|
111
|
|
|
$this->assertEquals($expectedEntityID, $ed->getEntityID()); |
112
|
|
|
|
113
|
|
|
$arr = $ed->getAllSpSsoDescriptors(); |
114
|
|
|
$this->assertInternalType('array', $arr); |
115
|
|
|
$this->assertCount(1, $arr); |
116
|
|
|
|
117
|
|
|
$sp = $ed->getFirstSpSsoDescriptor(); |
118
|
|
|
$this->assertInstanceOf('AerialShip\LightSaml\Model\Metadata\SpSsoDescriptor', $sp); |
119
|
|
|
|
120
|
|
|
$arr = $sp->getKeyDescriptors(); |
121
|
|
|
$this->assertInternalType('array', $arr); |
122
|
|
|
$this->assertCount(0, $arr); |
123
|
|
|
|
124
|
|
|
// SLO |
125
|
|
|
$arr = $sp->findSingleLogoutServices(); |
126
|
|
|
$this->assertInternalType('array', $arr); |
127
|
|
|
$this->assertCount(2, $arr); |
128
|
|
|
$this->assertInstanceOf('AerialShip\LightSaml\Model\Metadata\Service\SingleLogoutService', $arr[0]); |
129
|
|
|
$this->assertInstanceOf('AerialShip\LightSaml\Model\Metadata\Service\SingleLogoutService', $arr[1]); |
130
|
|
|
$this->assertEquals($expectedBaseUrl.$logoutPath, $arr[0]->getLocation()); |
131
|
|
|
$this->assertEquals($expectedBaseUrl.$logoutPath, $arr[1]->getLocation()); |
132
|
|
|
|
133
|
|
|
$arr = $sp->findSingleLogoutServices(Bindings::SAML2_HTTP_REDIRECT); |
134
|
|
|
$this->assertInternalType('array', $arr); |
135
|
|
|
$this->assertCount(1, $arr); |
136
|
|
|
|
137
|
|
|
$arr = $sp->findSingleLogoutServices(Bindings::SAML2_HTTP_POST); |
138
|
|
|
$this->assertInternalType('array', $arr); |
139
|
|
|
$this->assertCount(1, $arr); |
140
|
|
|
|
141
|
|
|
// ACS |
142
|
|
|
$arr = $sp->findAssertionConsumerServices(); |
143
|
|
|
$this->assertInternalType('array', $arr); |
144
|
|
|
$this->assertCount(2, $arr); |
145
|
|
|
$this->assertInstanceOf('AerialShip\LightSaml\Model\Metadata\Service\AssertionConsumerService', $arr[0]); |
146
|
|
|
$this->assertInstanceOf('AerialShip\LightSaml\Model\Metadata\Service\AssertionConsumerService', $arr[1]); |
147
|
|
|
$this->assertEquals($expectedBaseUrl.$checkPath, $arr[0]->getLocation()); |
148
|
|
|
$this->assertEquals($expectedBaseUrl.$checkPath, $arr[1]->getLocation()); |
149
|
|
|
|
150
|
|
|
$arr = $sp->findAssertionConsumerServices(Bindings::SAML2_HTTP_REDIRECT); |
151
|
|
|
$this->assertInternalType('array', $arr); |
152
|
|
|
$this->assertCount(1, $arr); |
153
|
|
|
|
154
|
|
|
$arr = $sp->findAssertionConsumerServices(Bindings::SAML2_HTTP_POST); |
155
|
|
|
$this->assertInternalType('array', $arr); |
156
|
|
|
$this->assertCount(1, $arr); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* @test |
162
|
|
|
*/ |
163
|
|
|
public function shouldBuildWithSigningEnabled() |
164
|
|
|
{ |
165
|
|
|
$expectedCertificate = $this->createX509CertificateMock(); |
166
|
|
|
$signingProvider = $this->createSPSigningProviderStub(true, $expectedCertificate, null); |
167
|
|
|
$expectedEntityID = 'entityID'; |
168
|
|
|
$expectedBaseUrl = 'http://site.com'; |
169
|
|
|
$checkPath = '/check_path'; |
170
|
|
|
$logoutPath = '/logout_path'; |
171
|
|
|
|
172
|
|
|
$builder = new SpEntityDescriptorBuilder( |
173
|
|
|
'idp', |
174
|
|
|
$signingProvider, |
|
|
|
|
175
|
|
|
array('entity_id'=>$expectedEntityID, 'base_url'=>$expectedBaseUrl), |
176
|
|
|
$checkPath, |
177
|
|
|
$logoutPath, |
178
|
|
|
null |
179
|
|
|
); |
180
|
|
|
|
181
|
|
|
$ed = $builder->getEntityDescriptor(); |
182
|
|
|
|
183
|
|
|
$sp = $ed->getFirstSpSsoDescriptor(); |
184
|
|
|
$this->assertInstanceOf('AerialShip\LightSaml\Model\Metadata\SpSsoDescriptor', $sp); |
185
|
|
|
|
186
|
|
|
$arr = $sp->getKeyDescriptors(); |
187
|
|
|
$this->assertInternalType('array', $arr); |
188
|
|
|
$this->assertCount(1, $arr); |
189
|
|
|
$this->assertEquals($expectedCertificate, $arr[0]->getCertificate()); |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* @test |
195
|
|
|
* @expectedException \RuntimeException |
196
|
|
|
* @expectedExceptionMessage Request not set |
197
|
|
|
*/ |
198
|
|
|
public function shouldThrowWhenBuildIsCalledWithoutSetBaseUrlAndRequest() |
199
|
|
|
{ |
200
|
|
|
$signingProvider = $this->createSPSigningProviderStub(false, null, null); |
201
|
|
|
$expectedEntityID = 'entityID'; |
202
|
|
|
$checkPath = '/check_path'; |
203
|
|
|
$logoutPath = '/logout_path'; |
204
|
|
|
|
205
|
|
|
$builder = new SpEntityDescriptorBuilder( |
206
|
|
|
'idp', |
207
|
|
|
$signingProvider, |
|
|
|
|
208
|
|
|
array('entity_id'=>$expectedEntityID), |
209
|
|
|
$checkPath, |
210
|
|
|
$logoutPath, |
211
|
|
|
$this->createHttpUtilsMock() |
|
|
|
|
212
|
|
|
); |
213
|
|
|
|
214
|
|
|
$builder->getEntityDescriptor(); |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
|
218
|
|
|
/** |
219
|
|
|
* @test |
220
|
|
|
*/ |
221
|
|
|
public function shouldBuildWithoutBaseUrlAndWithHttpUtils() |
222
|
|
|
{ |
223
|
|
|
$signingProvider = $this->createSPSigningProviderStub(false, null, null); |
224
|
|
|
$expectedEntityID = 'entityID'; |
225
|
|
|
$checkPath = '/check_path'; |
226
|
|
|
$logoutPath = '/logout_path'; |
227
|
|
|
$httpUtils = $this->createHttpUtilsStub($expectedLocation = 'generated_location'); |
228
|
|
|
|
229
|
|
|
$builder = new SpEntityDescriptorBuilder( |
230
|
|
|
'idp', |
231
|
|
|
$signingProvider, |
|
|
|
|
232
|
|
|
array('entity_id'=>$expectedEntityID), |
233
|
|
|
$checkPath, |
234
|
|
|
$logoutPath, |
235
|
|
|
$httpUtils |
|
|
|
|
236
|
|
|
); |
237
|
|
|
|
238
|
|
|
$builder->setRequest($this->createRequestMock()); |
|
|
|
|
239
|
|
|
$ed = $builder->getEntityDescriptor(); |
240
|
|
|
|
241
|
|
|
$this->assertInstanceOf('AerialShip\LightSaml\Model\Metadata\EntityDescriptor', $ed); |
242
|
|
|
|
243
|
|
|
$this->assertEquals($expectedEntityID, $ed->getEntityID()); |
244
|
|
|
|
245
|
|
|
$arr = $ed->getAllSpSsoDescriptors(); |
246
|
|
|
$this->assertInternalType('array', $arr); |
247
|
|
|
$this->assertCount(1, $arr); |
248
|
|
|
|
249
|
|
|
$sp = $ed->getFirstSpSsoDescriptor(); |
250
|
|
|
$this->assertInstanceOf('AerialShip\LightSaml\Model\Metadata\SpSsoDescriptor', $sp); |
251
|
|
|
|
252
|
|
|
$arr = $sp->getKeyDescriptors(); |
253
|
|
|
$this->assertInternalType('array', $arr); |
254
|
|
|
$this->assertCount(0, $arr); |
255
|
|
|
|
256
|
|
|
// SLO |
257
|
|
|
$arr = $sp->findSingleLogoutServices(); |
258
|
|
|
$this->assertInternalType('array', $arr); |
259
|
|
|
$this->assertCount(2, $arr); |
260
|
|
|
$this->assertInstanceOf('AerialShip\LightSaml\Model\Metadata\Service\SingleLogoutService', $arr[0]); |
261
|
|
|
$this->assertInstanceOf('AerialShip\LightSaml\Model\Metadata\Service\SingleLogoutService', $arr[1]); |
262
|
|
|
$this->assertEquals($expectedLocation, $arr[0]->getLocation()); |
263
|
|
|
$this->assertEquals($expectedLocation, $arr[1]->getLocation()); |
264
|
|
|
|
265
|
|
|
$arr = $sp->findSingleLogoutServices(Bindings::SAML2_HTTP_REDIRECT); |
266
|
|
|
$this->assertInternalType('array', $arr); |
267
|
|
|
$this->assertCount(1, $arr); |
268
|
|
|
|
269
|
|
|
$arr = $sp->findSingleLogoutServices(Bindings::SAML2_HTTP_POST); |
270
|
|
|
$this->assertInternalType('array', $arr); |
271
|
|
|
$this->assertCount(1, $arr); |
272
|
|
|
|
273
|
|
|
// ACS |
274
|
|
|
$arr = $sp->findAssertionConsumerServices(); |
275
|
|
|
$this->assertInternalType('array', $arr); |
276
|
|
|
$this->assertCount(2, $arr); |
277
|
|
|
$this->assertInstanceOf('AerialShip\LightSaml\Model\Metadata\Service\AssertionConsumerService', $arr[0]); |
278
|
|
|
$this->assertInstanceOf('AerialShip\LightSaml\Model\Metadata\Service\AssertionConsumerService', $arr[1]); |
279
|
|
|
$this->assertEquals($expectedLocation, $arr[0]->getLocation()); |
280
|
|
|
$this->assertEquals($expectedLocation, $arr[1]->getLocation()); |
281
|
|
|
|
282
|
|
|
$arr = $sp->findAssertionConsumerServices(Bindings::SAML2_HTTP_REDIRECT); |
283
|
|
|
$this->assertInternalType('array', $arr); |
284
|
|
|
$this->assertCount(1, $arr); |
285
|
|
|
|
286
|
|
|
$arr = $sp->findAssertionConsumerServices(Bindings::SAML2_HTTP_POST); |
287
|
|
|
$this->assertInternalType('array', $arr); |
288
|
|
|
$this->assertCount(1, $arr); |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
|
292
|
|
|
|
293
|
|
|
/** |
294
|
|
|
* @return \PHPUnit_Framework_MockObject_MockObject|SPSigningProviderInterface |
295
|
|
|
*/ |
296
|
|
|
protected function createSPSigningProviderMock() |
297
|
|
|
{ |
298
|
|
|
return $this->getMock('AerialShip\SamlSPBundle\Config\SPSigningProviderInterface'); |
299
|
|
|
} |
300
|
|
|
|
301
|
|
|
|
302
|
|
|
/** |
303
|
|
|
* @param $enabled |
304
|
|
|
* @param $certificate |
305
|
|
|
* @param $key |
306
|
|
|
* @return SPSigningProviderInterface|\PHPUnit_Framework_MockObject_MockObject |
307
|
|
|
*/ |
308
|
|
|
protected function createSPSigningProviderStub($enabled, $certificate, $key) |
309
|
|
|
{ |
310
|
|
|
$result = $this->createSPSigningProviderMock(); |
311
|
|
|
$result->expects($this->any())->method('isEnabled')->will($this->returnValue($enabled)); |
|
|
|
|
312
|
|
|
if ($enabled) { |
313
|
|
|
$result->expects($this->any())->method('getCertificate')->will($this->returnValue($certificate)); |
314
|
|
|
$result->expects($this->any())->method('getPrivateKey')->will($this->returnValue($key)); |
315
|
|
|
} else { |
316
|
|
|
$result->expects($this->never())->method('getCertificate'); |
317
|
|
|
$result->expects($this->never())->method('getPrivateKey'); |
318
|
|
|
} |
319
|
|
|
return $result; |
320
|
|
|
} |
321
|
|
|
|
322
|
|
|
/** |
323
|
|
|
* @return \PHPUnit_Framework_MockObject_MockObject|\Symfony\Component\Security\Http\HttpUtils |
324
|
|
|
*/ |
325
|
|
|
protected function createHttpUtilsMock() |
326
|
|
|
{ |
327
|
|
|
return $this->getMock('Symfony\Component\Security\Http\HttpUtils'); |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
/** |
331
|
|
|
* @param $generateUriReturn |
332
|
|
|
* @return \PHPUnit_Framework_MockObject_MockObject|\Symfony\Component\Security\Http\HttpUtils |
333
|
|
|
*/ |
334
|
|
|
protected function createHttpUtilsStub($generateUriReturn) |
335
|
|
|
{ |
336
|
|
|
$result = $this->createHttpUtilsMock(); |
337
|
|
|
$result->expects($this->any()) |
|
|
|
|
338
|
|
|
->method('generateUri') |
339
|
|
|
->will($this->returnValue($generateUriReturn)); |
340
|
|
|
return $result; |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
/** |
344
|
|
|
* @return \PHPUnit_Framework_MockObject_MockObject|\AerialShip\LightSaml\Security\X509Certificate |
345
|
|
|
*/ |
346
|
|
|
protected function createX509CertificateMock() |
347
|
|
|
{ |
348
|
|
|
return $this->getMock('AerialShip\LightSaml\Security\X509Certificate'); |
349
|
|
|
} |
350
|
|
|
|
351
|
|
|
|
352
|
|
|
/** |
353
|
|
|
* @return \PHPUnit_Framework_MockObject_MockObject|\Symfony\Component\HttpFoundation\Request |
354
|
|
|
*/ |
355
|
|
|
private function createRequestMock() |
356
|
|
|
{ |
357
|
|
|
return $this->getMock('Symfony\Component\HttpFoundation\Request', array(), array(), '', false, false); |
358
|
|
|
} |
359
|
|
|
} |
360
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.