1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the LightSAML-Core package. |
5
|
|
|
* |
6
|
|
|
* (c) Milos Tomic <[email protected]> |
7
|
|
|
* |
8
|
|
|
* This source file is subject to the MIT license that is bundled |
9
|
|
|
* with this source code in the file LICENSE. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace LightSaml\Model\Metadata; |
13
|
|
|
|
14
|
|
|
use LightSaml\Helper; |
15
|
|
|
use LightSaml\Model\Context\DeserializationContext; |
16
|
|
|
use LightSaml\Model\Context\SerializationContext; |
17
|
|
|
use LightSaml\Model\XmlDSig\Signature; |
18
|
|
|
use LightSaml\SamlConstants; |
19
|
|
|
|
20
|
|
|
class EntityDescriptor extends Metadata |
21
|
|
|
{ |
22
|
|
|
/** @var string */ |
23
|
|
|
protected $entityID; |
24
|
|
|
|
25
|
|
|
/** @var int|null */ |
26
|
|
|
protected $validUntil; |
27
|
|
|
|
28
|
|
|
/** @var string|null */ |
29
|
|
|
protected $cacheDuration; |
30
|
|
|
|
31
|
|
|
/** @var string|null */ |
32
|
|
|
protected $id; |
33
|
|
|
|
34
|
|
|
/** @var Signature|null */ |
35
|
|
|
protected $signature; |
36
|
|
|
|
37
|
|
|
/** @var IdpSsoDescriptor[]|SpSsoDescriptor[] */ |
38
|
|
|
protected $items; |
39
|
|
|
|
40
|
|
|
/** @var Organization[]|null */ |
41
|
|
|
protected $organizations; |
42
|
|
|
|
43
|
|
|
/** @var ContactPerson[]|null */ |
44
|
|
|
protected $contactPersons; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* @param string $filename |
48
|
|
|
* |
49
|
|
|
* @return EntityDescriptor |
50
|
|
|
*/ |
51
|
30 |
|
public static function load($filename) |
52
|
|
|
{ |
53
|
30 |
|
return self::loadXml(file_get_contents($filename)); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* @param string $xml |
58
|
|
|
* |
59
|
|
|
* @return EntityDescriptor |
60
|
|
|
*/ |
61
|
30 |
View Code Duplication |
public static function loadXml($xml) |
|
|
|
|
62
|
|
|
{ |
63
|
30 |
|
$context = new DeserializationContext(); |
64
|
30 |
|
$context->getDocument()->loadXML($xml); |
65
|
30 |
|
$ed = new self(); |
66
|
30 |
|
$ed->deserialize($context->getDocument(), $context); |
67
|
|
|
|
68
|
27 |
|
return $ed; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* @param string|null $entityId |
73
|
|
|
* @param array $items |
74
|
|
|
*/ |
75
|
91 |
|
public function __construct($entityId = null, array $items = array()) |
76
|
|
|
{ |
77
|
91 |
|
$this->entityID = $entityId; |
78
|
91 |
|
$this->items = $items; |
79
|
91 |
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* @param ContactPerson $contactPerson |
83
|
|
|
* |
84
|
|
|
* @return EntityDescriptor |
85
|
|
|
*/ |
86
|
32 |
View Code Duplication |
public function addContactPerson(ContactPerson $contactPerson) |
|
|
|
|
87
|
|
|
{ |
88
|
32 |
|
if (false == is_array($this->contactPersons)) { |
|
|
|
|
89
|
32 |
|
$this->contactPersons = array(); |
90
|
|
|
} |
91
|
32 |
|
$this->contactPersons[] = $contactPerson; |
92
|
|
|
|
93
|
32 |
|
return $this; |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* @return ContactPerson[]|null |
98
|
|
|
*/ |
99
|
2 |
|
public function getAllContactPersons() |
100
|
|
|
{ |
101
|
2 |
|
return $this->contactPersons; |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* @return ContactPerson|null |
106
|
|
|
*/ |
107
|
1 |
|
public function getFirstContactPerson() |
108
|
|
|
{ |
109
|
1 |
|
if (is_array($this->contactPersons) && isset($this->contactPersons[0])) { |
110
|
1 |
|
return $this->contactPersons[0]; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
return null; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* @param \LightSaml\Model\Metadata\Organization $organization |
118
|
|
|
* |
119
|
|
|
* @return EntityDescriptor |
120
|
|
|
*/ |
121
|
12 |
View Code Duplication |
public function addOrganization(Organization $organization) |
|
|
|
|
122
|
|
|
{ |
123
|
12 |
|
if (false == is_array($this->organizations)) { |
|
|
|
|
124
|
12 |
|
$this->organizations = array(); |
125
|
|
|
} |
126
|
12 |
|
$this->organizations[] = $organization; |
127
|
|
|
|
128
|
12 |
|
return $this; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* @return Organization[]|null |
133
|
|
|
*/ |
134
|
1 |
|
public function getAllOrganizations() |
135
|
|
|
{ |
136
|
1 |
|
return $this->organizations; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* @return \LightSaml\Model\Metadata\Organization|null |
141
|
|
|
*/ |
142
|
1 |
|
public function getFirstOrganization() |
143
|
|
|
{ |
144
|
1 |
|
if (is_array($this->organizations) && isset($this->organizations[0])) { |
145
|
1 |
|
return $this->organizations[0]; |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
return null; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* @param string|null $cacheDuration |
153
|
|
|
* |
154
|
|
|
* @throws \InvalidArgumentException |
155
|
|
|
* |
156
|
|
|
* @return EntityDescriptor |
157
|
|
|
*/ |
158
|
|
|
public function setCacheDuration($cacheDuration) |
159
|
|
|
{ |
160
|
|
|
Helper::validateDurationString($cacheDuration); |
161
|
|
|
|
162
|
|
|
$this->cacheDuration = $cacheDuration; |
163
|
|
|
|
164
|
|
|
return $this; |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* @return string|null |
169
|
|
|
*/ |
170
|
6 |
|
public function getCacheDuration() |
171
|
|
|
{ |
172
|
6 |
|
return $this->cacheDuration; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* @param string $entityID |
177
|
|
|
* |
178
|
|
|
* @return EntityDescriptor |
179
|
|
|
*/ |
180
|
49 |
|
public function setEntityID($entityID) |
181
|
|
|
{ |
182
|
49 |
|
$this->entityID = (string) $entityID; |
183
|
|
|
|
184
|
49 |
|
return $this; |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* @return string |
189
|
|
|
*/ |
190
|
54 |
|
public function getEntityID() |
191
|
|
|
{ |
192
|
54 |
|
return $this->entityID; |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* @param string|null $id |
197
|
|
|
* |
198
|
|
|
* @return EntityDescriptor |
199
|
|
|
*/ |
200
|
32 |
|
public function setID($id) |
201
|
|
|
{ |
202
|
32 |
|
$this->id = null !== $id ? (string) $id : null; |
203
|
|
|
|
204
|
32 |
|
return $this; |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
/** |
208
|
|
|
* @return string|null |
209
|
|
|
*/ |
210
|
10 |
|
public function getID() |
211
|
|
|
{ |
212
|
10 |
|
return $this->id; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* @param \LightSaml\Model\Metadata\IdpSsoDescriptor|\LightSaml\Model\Metadata\SpSsoDescriptor $item |
217
|
|
|
* |
218
|
|
|
* @throws \InvalidArgumentException |
219
|
|
|
* |
220
|
|
|
* @return EntityDescriptor |
221
|
|
|
*/ |
222
|
44 |
|
public function addItem($item) |
223
|
|
|
{ |
224
|
44 |
|
if (false == $item instanceof IdpSsoDescriptor && |
|
|
|
|
225
|
44 |
|
false == $item instanceof SpSsoDescriptor |
|
|
|
|
226
|
|
|
) { |
227
|
|
|
throw new \InvalidArgumentException('EntityDescriptor item must be IdpSsoDescriptor or SpSsoDescriptor'); |
228
|
|
|
} |
229
|
|
|
|
230
|
44 |
|
if (false == is_array($this->items)) { |
|
|
|
|
231
|
|
|
$this->items = array(); |
232
|
|
|
} |
233
|
|
|
|
234
|
44 |
|
$this->items[] = $item; |
235
|
|
|
|
236
|
44 |
|
return $this; |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* @return IdpSsoDescriptor[]|SpSsoDescriptor[]|SSODescriptor[] |
241
|
|
|
*/ |
242
|
35 |
|
public function getAllItems() |
243
|
|
|
{ |
244
|
35 |
|
return $this->items; |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
/** |
248
|
|
|
* @return IdpSsoDescriptor[] |
249
|
|
|
*/ |
250
|
28 |
|
public function getAllIdpSsoDescriptors() |
251
|
|
|
{ |
252
|
28 |
|
$result = array(); |
253
|
28 |
|
foreach ($this->getAllItems() as $item) { |
254
|
20 |
|
if ($item instanceof IdpSsoDescriptor) { |
255
|
20 |
|
$result[] = $item; |
256
|
|
|
} |
257
|
|
|
} |
258
|
|
|
|
259
|
28 |
|
return $result; |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
/** |
263
|
|
|
* @return SpSsoDescriptor[] |
264
|
|
|
*/ |
265
|
28 |
|
public function getAllSpSsoDescriptors() |
266
|
|
|
{ |
267
|
28 |
|
$result = array(); |
268
|
28 |
|
foreach ($this->getAllItems() as $item) { |
269
|
20 |
|
if ($item instanceof SpSsoDescriptor) { |
270
|
20 |
|
$result[] = $item; |
271
|
|
|
} |
272
|
|
|
} |
273
|
|
|
|
274
|
28 |
|
return $result; |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* @return IdpSsoDescriptor|null |
279
|
|
|
*/ |
280
|
4 |
|
public function getFirstIdpSsoDescriptor() |
281
|
|
|
{ |
282
|
4 |
|
foreach ($this->getAllItems() as $item) { |
283
|
4 |
|
if ($item instanceof IdpSsoDescriptor) { |
284
|
4 |
|
return $item; |
285
|
|
|
} |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
return null; |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
/** |
292
|
|
|
* @return SpSsoDescriptor|null |
293
|
|
|
*/ |
294
|
2 |
|
public function getFirstSpSsoDescriptor() |
295
|
|
|
{ |
296
|
2 |
|
foreach ($this->getAllItems() as $item) { |
297
|
2 |
|
if ($item instanceof SpSsoDescriptor) { |
298
|
2 |
|
return $item; |
299
|
|
|
} |
300
|
|
|
} |
301
|
|
|
|
302
|
|
|
return null; |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
/** |
306
|
|
|
* @param Signature|null $signature |
307
|
|
|
* |
308
|
|
|
* @return EntityDescriptor |
309
|
|
|
*/ |
310
|
29 |
|
public function setSignature(Signature $signature) |
311
|
|
|
{ |
312
|
29 |
|
$this->signature = $signature; |
313
|
|
|
|
314
|
29 |
|
return $this; |
315
|
|
|
} |
316
|
|
|
|
317
|
|
|
/** |
318
|
|
|
* @return Signature|null |
319
|
|
|
*/ |
320
|
7 |
|
public function getSignature() |
321
|
|
|
{ |
322
|
7 |
|
return $this->signature; |
323
|
|
|
} |
324
|
|
|
|
325
|
|
|
/** |
326
|
|
|
* @param int $validUntil |
327
|
|
|
* |
328
|
|
|
* @return EntityDescriptor |
329
|
|
|
*/ |
330
|
1 |
|
public function setValidUntil($validUntil) |
331
|
|
|
{ |
332
|
1 |
|
$this->validUntil = Helper::getTimestampFromValue($validUntil); |
333
|
|
|
|
334
|
1 |
|
return $this; |
335
|
|
|
} |
336
|
|
|
|
337
|
|
|
/** |
338
|
|
|
* @return int|null |
339
|
|
|
*/ |
340
|
|
|
public function getValidUntilTimestamp() |
341
|
|
|
{ |
342
|
|
|
return $this->validUntil; |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
/** |
346
|
|
|
* @return string|null |
347
|
|
|
*/ |
348
|
6 |
|
public function getValidUntilString() |
349
|
|
|
{ |
350
|
6 |
|
if ($this->validUntil) { |
|
|
|
|
351
|
|
|
return Helper::time2string($this->validUntil); |
352
|
|
|
} |
353
|
|
|
|
354
|
6 |
|
return null; |
355
|
|
|
} |
356
|
|
|
|
357
|
|
|
/** |
358
|
|
|
* @return \DateTime|null |
359
|
|
|
*/ |
360
|
|
|
public function getValidUntilDateTime() |
361
|
|
|
{ |
362
|
|
|
if ($this->validUntil) { |
|
|
|
|
363
|
|
|
return new \DateTime('@'.$this->validUntil); |
364
|
|
|
} |
365
|
|
|
|
366
|
|
|
return null; |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
/** |
370
|
|
|
* @return array|KeyDescriptor[] |
371
|
|
|
*/ |
372
|
|
|
public function getAllIdpKeyDescriptors() |
373
|
|
|
{ |
374
|
|
|
$result = array(); |
375
|
|
|
foreach ($this->getAllIdpSsoDescriptors() as $idp) { |
376
|
|
|
foreach ($idp->getAllKeyDescriptors() as $key) { |
|
|
|
|
377
|
|
|
$result[] = $key; |
378
|
|
|
} |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
return $result; |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
/** |
385
|
|
|
* @return array|KeyDescriptor[] |
386
|
|
|
*/ |
387
|
|
|
public function getAllSpKeyDescriptors() |
388
|
|
|
{ |
389
|
|
|
$result = array(); |
390
|
|
|
foreach ($this->getAllSpSsoDescriptors() as $sp) { |
391
|
|
|
foreach ($sp->getAllKeyDescriptors() as $key) { |
|
|
|
|
392
|
|
|
$result[] = $key; |
393
|
|
|
} |
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
return $result; |
397
|
|
|
} |
398
|
|
|
|
399
|
|
|
/** |
400
|
|
|
* @return EndpointReference[] |
401
|
|
|
*/ |
402
|
19 |
|
public function getAllEndpoints() |
403
|
|
|
{ |
404
|
19 |
|
$result = array(); |
405
|
19 |
|
foreach ($this->getAllIdpSsoDescriptors() as $idpSsoDescriptor) { |
406
|
10 |
|
foreach ($idpSsoDescriptor->getAllSingleSignOnServices() as $sso) { |
|
|
|
|
407
|
10 |
|
$result[] = new EndpointReference($this, $idpSsoDescriptor, $sso); |
408
|
|
|
} |
409
|
10 |
|
foreach ($idpSsoDescriptor->getAllSingleLogoutServices() as $slo) { |
410
|
10 |
|
$result[] = new EndpointReference($this, $idpSsoDescriptor, $slo); |
411
|
|
|
} |
412
|
|
|
} |
413
|
19 |
|
foreach ($this->getAllSpSsoDescriptors() as $spSsoDescriptor) { |
414
|
10 |
|
foreach ($spSsoDescriptor->getAllAssertionConsumerServices() as $acs) { |
|
|
|
|
415
|
10 |
|
$result[] = new EndpointReference($this, $spSsoDescriptor, $acs); |
416
|
|
|
} |
417
|
10 |
|
foreach ($spSsoDescriptor->getAllSingleLogoutServices() as $slo) { |
418
|
10 |
|
$result[] = new EndpointReference($this, $spSsoDescriptor, $slo); |
419
|
|
|
} |
420
|
|
|
} |
421
|
|
|
|
422
|
19 |
|
return $result; |
423
|
|
|
} |
424
|
|
|
|
425
|
|
|
/** |
426
|
|
|
* @param \DOMNode $parent |
427
|
|
|
* @param SerializationContext $context |
428
|
|
|
* |
429
|
|
|
* @return void |
430
|
|
|
*/ |
431
|
6 |
|
public function serialize(\DOMNode $parent, SerializationContext $context) |
432
|
|
|
{ |
433
|
6 |
|
$result = $this->createElement('EntityDescriptor', SamlConstants::NS_METADATA, $parent, $context); |
434
|
|
|
|
435
|
6 |
|
$this->attributesToXml(array('entityID', 'validUntil', 'cacheDuration', 'ID'), $result); |
436
|
|
|
|
437
|
6 |
|
$this->manyElementsToXml($this->getAllItems(), $result, $context, null); |
438
|
6 |
|
if ($this->organizations) { |
439
|
1 |
|
$this->manyElementsToXml($this->organizations, $result, $context, null); |
440
|
|
|
} |
441
|
6 |
|
if ($this->contactPersons) { |
442
|
1 |
|
$this->manyElementsToXml($this->contactPersons, $result, $context, null); |
443
|
|
|
} |
444
|
|
|
|
445
|
6 |
|
$this->singleElementsToXml(array('Signature'), $result, $context); |
446
|
6 |
|
} |
447
|
|
|
|
448
|
|
|
/** |
449
|
|
|
* @param \DOMNode $node |
450
|
|
|
* @param DeserializationContext $context |
451
|
|
|
*/ |
452
|
42 |
|
public function deserialize(\DOMNode $node, DeserializationContext $context) |
453
|
|
|
{ |
454
|
42 |
|
$this->checkXmlNodeName($node, 'EntityDescriptor', SamlConstants::NS_METADATA); |
455
|
|
|
|
456
|
41 |
|
$this->attributesFromXml($node, array('entityID', 'validUntil', 'cacheDuration', 'ID')); |
|
|
|
|
457
|
|
|
|
458
|
41 |
|
$this->items = array(); |
459
|
|
|
|
460
|
41 |
|
$this->manyElementsFromXml( |
461
|
41 |
|
$node, |
|
|
|
|
462
|
41 |
|
$context, |
463
|
41 |
|
'IDPSSODescriptor', |
464
|
41 |
|
'md', |
465
|
41 |
|
'LightSaml\Model\Metadata\IdpSsoDescriptor', |
466
|
41 |
|
'addItem' |
467
|
|
|
); |
468
|
|
|
|
469
|
41 |
|
$this->manyElementsFromXml( |
470
|
41 |
|
$node, |
|
|
|
|
471
|
41 |
|
$context, |
472
|
41 |
|
'SPSSODescriptor', |
473
|
41 |
|
'md', |
474
|
41 |
|
'LightSaml\Model\Metadata\SpSsoDescriptor', |
475
|
41 |
|
'addItem' |
476
|
|
|
); |
477
|
|
|
|
478
|
41 |
|
$this->manyElementsFromXml( |
479
|
41 |
|
$node, |
|
|
|
|
480
|
41 |
|
$context, |
481
|
41 |
|
'Organization', |
482
|
41 |
|
'md', |
483
|
41 |
|
'LightSaml\Model\Metadata\Organization', |
484
|
41 |
|
'addOrganization' |
485
|
|
|
); |
486
|
|
|
|
487
|
41 |
|
$this->manyElementsFromXml( |
488
|
41 |
|
$node, |
|
|
|
|
489
|
41 |
|
$context, |
490
|
41 |
|
'ContactPerson', |
491
|
41 |
|
'md', |
492
|
41 |
|
'LightSaml\Model\Metadata\ContactPerson', |
493
|
41 |
|
'addContactPerson' |
494
|
|
|
); |
495
|
|
|
|
496
|
41 |
|
$this->singleElementsFromXml($node, $context, array( |
|
|
|
|
497
|
41 |
|
'Signature' => array('ds', 'LightSaml\Model\XmlDSig\SignatureXmlReader'), |
498
|
|
|
)); |
499
|
41 |
|
} |
500
|
|
|
} |
501
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.