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\Assertion; |
13
|
|
|
|
14
|
|
|
use LightSaml\Helper; |
15
|
|
|
use LightSaml\Model\Context\DeserializationContext; |
16
|
|
|
use LightSaml\Model\Context\SerializationContext; |
17
|
|
|
use LightSaml\Model\AbstractSamlModel; |
18
|
|
|
use LightSaml\Model\XmlDSig\Signature; |
19
|
|
|
use LightSaml\SamlConstants; |
20
|
|
|
|
21
|
|
|
class Assertion extends AbstractSamlModel |
22
|
|
|
{ |
23
|
|
|
//region Attributes |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @var string |
27
|
|
|
*/ |
28
|
|
|
protected $id; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @var string |
32
|
|
|
*/ |
33
|
|
|
protected $version = SamlConstants::VERSION_20; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @var int |
37
|
|
|
*/ |
38
|
|
|
protected $issueInstant; |
39
|
|
|
|
40
|
|
|
//endregion |
41
|
|
|
|
42
|
|
|
//region Elements |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* @var Issuer |
46
|
|
|
*/ |
47
|
|
|
protected $issuer; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @var Signature|null |
51
|
|
|
*/ |
52
|
|
|
protected $signature; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* @var Subject|null |
56
|
|
|
*/ |
57
|
|
|
protected $subject; |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @var Conditions|null |
61
|
|
|
*/ |
62
|
|
|
protected $conditions; |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* @var array|AbstractStatement[]|AuthnStatement[]|AttributeStatement[] |
66
|
|
|
*/ |
67
|
|
|
protected $items = array(); |
68
|
|
|
|
69
|
|
|
//endregion |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Core 3.3.4 Processing rules. |
73
|
|
|
* |
74
|
|
|
* @param string $nameId |
75
|
|
|
* @param string|null $format |
76
|
|
|
* |
77
|
|
|
* @return bool |
78
|
|
|
*/ |
79
|
6 |
|
public function equals($nameId, $format) |
80
|
|
|
{ |
81
|
6 |
|
if (false == $this->getSubject()) { |
82
|
1 |
|
return false; |
83
|
|
|
} |
84
|
|
|
|
85
|
5 |
|
if (false == $this->getSubject()->getNameID()) { |
86
|
1 |
|
return false; |
87
|
|
|
} |
88
|
|
|
|
89
|
4 |
|
if ($this->getSubject()->getNameID()->getValue() != $nameId) { |
90
|
1 |
|
return false; |
91
|
|
|
} |
92
|
|
|
|
93
|
3 |
|
if ($this->getSubject()->getNameID()->getFormat() != $format) { |
94
|
2 |
|
return false; |
95
|
|
|
} |
96
|
|
|
|
97
|
1 |
|
return true; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* @param string $sessionIndex |
102
|
|
|
* |
103
|
|
|
* @return bool |
104
|
|
|
*/ |
105
|
4 |
View Code Duplication |
public function hasSessionIndex($sessionIndex) |
|
|
|
|
106
|
|
|
{ |
107
|
4 |
|
if (null == $this->getAllAuthnStatements()) { |
108
|
1 |
|
return false; |
109
|
|
|
} |
110
|
|
|
|
111
|
3 |
|
foreach ($this->getAllAuthnStatements() as $authnStatement) { |
112
|
3 |
|
if ($authnStatement->getSessionIndex() == $sessionIndex) { |
113
|
3 |
|
return true; |
114
|
|
|
} |
115
|
|
|
} |
116
|
|
|
|
117
|
2 |
|
return false; |
118
|
|
|
} |
119
|
|
|
|
120
|
4 |
View Code Duplication |
public function hasAnySessionIndex() |
|
|
|
|
121
|
|
|
{ |
122
|
4 |
|
if (false == $this->getAllAuthnStatements()) { |
123
|
1 |
|
return false; |
124
|
|
|
} |
125
|
|
|
|
126
|
3 |
|
foreach ($this->getAllAuthnStatements() as $authnStatement) { |
127
|
3 |
|
if ($authnStatement->getSessionIndex()) { |
|
|
|
|
128
|
3 |
|
return true; |
129
|
|
|
} |
130
|
|
|
} |
131
|
|
|
|
132
|
1 |
|
return false; |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
//region Getters & Setters |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* @param Conditions|null $conditions |
139
|
|
|
* |
140
|
|
|
* @return Assertion |
141
|
|
|
*/ |
142
|
16 |
|
public function setConditions(Conditions $conditions = null) |
143
|
|
|
{ |
144
|
16 |
|
$this->conditions = $conditions; |
145
|
|
|
|
146
|
16 |
|
return $this; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* @return \LightSaml\Model\Assertion\Conditions|null |
151
|
|
|
*/ |
152
|
22 |
|
public function getConditions() |
153
|
|
|
{ |
154
|
22 |
|
return $this->conditions; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* @param string $id |
159
|
|
|
* |
160
|
|
|
* @return Assertion |
161
|
|
|
*/ |
162
|
28 |
|
public function setId($id) |
163
|
|
|
{ |
164
|
28 |
|
$this->id = (string) $id; |
165
|
|
|
|
166
|
28 |
|
return $this; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* @return string |
171
|
|
|
*/ |
172
|
30 |
|
public function getId() |
173
|
|
|
{ |
174
|
30 |
|
return $this->id; |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* @param string|int|\DateTime $issueInstant |
179
|
|
|
* |
180
|
|
|
* @throws \InvalidArgumentException |
181
|
|
|
* |
182
|
|
|
* @return Assertion |
183
|
|
|
*/ |
184
|
21 |
|
public function setIssueInstant($issueInstant) |
185
|
|
|
{ |
186
|
21 |
|
$this->issueInstant = Helper::getTimestampFromValue($issueInstant); |
187
|
|
|
|
188
|
21 |
|
return $this; |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* @return int |
193
|
|
|
*/ |
194
|
20 |
|
public function getIssueInstantTimestamp() |
195
|
|
|
{ |
196
|
20 |
|
return $this->issueInstant; |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
/** |
200
|
|
|
* @return string |
201
|
|
|
*/ |
202
|
6 |
|
public function getIssueInstantString() |
203
|
|
|
{ |
204
|
6 |
|
if ($this->issueInstant) { |
205
|
6 |
|
return Helper::time2string($this->issueInstant); |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
return null; |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
/** |
212
|
|
|
* @return string |
213
|
|
|
*/ |
214
|
|
|
public function getIssueInstantDateTime() |
215
|
|
|
{ |
216
|
|
|
if ($this->issueInstant) { |
217
|
|
|
return new \DateTime('@'.$this->issueInstant); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
return null; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* @param Issuer $issuer |
225
|
|
|
* |
226
|
|
|
* @return Assertion |
227
|
|
|
*/ |
228
|
28 |
|
public function setIssuer(Issuer $issuer = null) |
229
|
|
|
{ |
230
|
28 |
|
$this->issuer = $issuer; |
231
|
|
|
|
232
|
28 |
|
return $this; |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
/** |
236
|
|
|
* @return \LightSaml\Model\Assertion\Issuer |
237
|
|
|
*/ |
238
|
32 |
|
public function getIssuer() |
239
|
|
|
{ |
240
|
32 |
|
return $this->issuer; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* @param Signature $signature |
245
|
|
|
* |
246
|
|
|
* @return Assertion |
247
|
|
|
*/ |
248
|
7 |
|
public function setSignature(Signature $signature = null) |
249
|
|
|
{ |
250
|
7 |
|
$this->signature = $signature; |
251
|
|
|
|
252
|
7 |
|
return $this; |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
/** |
256
|
|
|
* @return \LightSaml\Model\XmlDSig\Signature|null |
257
|
|
|
*/ |
258
|
7 |
|
public function getSignature() |
259
|
|
|
{ |
260
|
7 |
|
return $this->signature; |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
/** |
264
|
|
|
* @param Subject $subject |
265
|
|
|
* |
266
|
|
|
* @return Assertion |
267
|
|
|
*/ |
268
|
32 |
|
public function setSubject(Subject $subject) |
269
|
|
|
{ |
270
|
32 |
|
$this->subject = $subject; |
271
|
|
|
|
272
|
32 |
|
return $this; |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
/** |
276
|
|
|
* @return \LightSaml\Model\Assertion\Subject |
277
|
|
|
*/ |
278
|
44 |
|
public function getSubject() |
279
|
|
|
{ |
280
|
44 |
|
return $this->subject; |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
/** |
284
|
|
|
* @param string $version |
285
|
|
|
* |
286
|
|
|
* @return Assertion |
287
|
|
|
*/ |
288
|
6 |
|
public function setVersion($version) |
289
|
|
|
{ |
290
|
6 |
|
$this->version = (string) $version; |
291
|
|
|
|
292
|
6 |
|
return $this; |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
/** |
296
|
|
|
* @return string |
297
|
|
|
*/ |
298
|
25 |
|
public function getVersion() |
299
|
|
|
{ |
300
|
25 |
|
return $this->version; |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
/** |
304
|
|
|
* @param AbstractStatement $statement |
305
|
|
|
* |
306
|
|
|
* @return Assertion |
307
|
|
|
*/ |
308
|
27 |
|
public function addItem(AbstractStatement $statement) |
309
|
|
|
{ |
310
|
27 |
|
$this->items[] = $statement; |
311
|
|
|
|
312
|
27 |
|
return $this; |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
/** |
316
|
|
|
* @return AbstractStatement[]|AttributeStatement[]|AuthnStatement[]|array |
317
|
|
|
*/ |
318
|
7 |
|
public function getAllItems() |
319
|
|
|
{ |
320
|
7 |
|
return $this->items; |
321
|
|
|
} |
322
|
|
|
|
323
|
|
|
/** |
324
|
|
|
* @return \LightSaml\Model\Assertion\AuthnStatement[] |
325
|
|
|
*/ |
326
|
27 |
|
public function getAllAuthnStatements() |
327
|
|
|
{ |
328
|
27 |
|
$result = array(); |
329
|
27 |
|
foreach ($this->items as $item) { |
330
|
21 |
|
if ($item instanceof AuthnStatement) { |
331
|
21 |
|
$result[] = $item; |
332
|
|
|
} |
333
|
|
|
} |
334
|
|
|
|
335
|
27 |
|
return $result; |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
/** |
339
|
|
|
* @return \LightSaml\Model\Assertion\AttributeStatement[] |
340
|
|
|
*/ |
341
|
1 |
|
public function getAllAttributeStatements() |
342
|
|
|
{ |
343
|
1 |
|
$result = array(); |
344
|
1 |
|
foreach ($this->items as $item) { |
345
|
1 |
|
if ($item instanceof AttributeStatement) { |
346
|
1 |
|
$result[] = $item; |
347
|
|
|
} |
348
|
|
|
} |
349
|
|
|
|
350
|
1 |
|
return $result; |
351
|
|
|
} |
352
|
|
|
|
353
|
|
|
/** |
354
|
|
|
* @return \LightSaml\Model\Assertion\AttributeStatement|null |
355
|
|
|
*/ |
356
|
3 |
|
public function getFirstAttributeStatement() |
357
|
|
|
{ |
358
|
3 |
|
foreach ($this->items as $item) { |
359
|
3 |
|
if ($item instanceof AttributeStatement) { |
360
|
3 |
|
return $item; |
361
|
|
|
} |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
return null; |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
/** |
368
|
|
|
* @return \LightSaml\Model\Assertion\AuthnStatement|null |
369
|
|
|
*/ |
370
|
2 |
|
public function getFirstAuthnStatement() |
371
|
|
|
{ |
372
|
2 |
|
foreach ($this->items as $item) { |
373
|
2 |
|
if ($item instanceof AuthnStatement) { |
374
|
2 |
|
return $item; |
375
|
|
|
} |
376
|
|
|
} |
377
|
|
|
|
378
|
|
|
return null; |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
//endregion |
382
|
|
|
|
383
|
|
|
/** |
384
|
|
|
* @return bool |
385
|
|
|
*/ |
386
|
13 |
|
public function hasBearerSubject() |
387
|
|
|
{ |
388
|
13 |
|
if ($this->getAllAuthnStatements() && $this->getSubject()) { |
389
|
11 |
|
if ($this->getSubject()->getBearerConfirmations()) { |
390
|
11 |
|
return true; |
391
|
|
|
} |
392
|
|
|
} |
393
|
|
|
|
394
|
2 |
|
return false; |
395
|
|
|
} |
396
|
|
|
|
397
|
5 |
|
protected function prepareForXml() |
398
|
|
|
{ |
399
|
5 |
|
if (false == $this->getId()) { |
|
|
|
|
400
|
|
|
$this->setId(Helper::generateID()); |
401
|
|
|
} |
402
|
5 |
|
if (false == $this->getIssueInstantTimestamp()) { |
|
|
|
|
403
|
1 |
|
$this->setIssueInstant(time()); |
404
|
|
|
} |
405
|
5 |
|
} |
406
|
|
|
|
407
|
|
|
/** |
408
|
|
|
* @param \DOMNode $parent |
409
|
|
|
* @param SerializationContext $context |
410
|
|
|
* |
411
|
|
|
* @return void |
412
|
|
|
*/ |
413
|
5 |
|
public function serialize(\DOMNode $parent, SerializationContext $context) |
414
|
|
|
{ |
415
|
5 |
|
$this->prepareForXml(); |
416
|
|
|
|
417
|
5 |
|
$result = $this->createElement('Assertion', SamlConstants::NS_ASSERTION, $parent, $context); |
418
|
|
|
|
419
|
5 |
|
$this->attributesToXml(array('ID', 'Version', 'IssueInstant'), $result); |
420
|
|
|
|
421
|
5 |
|
$this->singleElementsToXml( |
422
|
5 |
|
array('Issuer', 'Subject', 'Conditions'), |
423
|
5 |
|
$result, |
424
|
5 |
|
$context |
425
|
|
|
); |
426
|
|
|
|
427
|
5 |
|
foreach ($this->items as $item) { |
428
|
4 |
|
$item->serialize($result, $context); |
429
|
|
|
} |
430
|
|
|
|
431
|
|
|
// must be added at the end |
432
|
5 |
|
$this->singleElementsToXml(array('Signature'), $result, $context); |
433
|
5 |
|
} |
434
|
|
|
|
435
|
|
|
/** |
436
|
|
|
* @param \DOMNode $node |
437
|
|
|
* @param DeserializationContext $context |
438
|
|
|
*/ |
439
|
4 |
|
public function deserialize(\DOMNode $node, DeserializationContext $context) |
440
|
|
|
{ |
441
|
4 |
|
$this->checkXmlNodeName($node, 'Assertion', SamlConstants::NS_ASSERTION); |
442
|
|
|
|
443
|
4 |
|
$this->attributesFromXml($node, array('ID', 'Version', 'IssueInstant')); |
|
|
|
|
444
|
|
|
|
445
|
4 |
|
$this->singleElementsFromXml($node, $context, array( |
|
|
|
|
446
|
4 |
|
'Issuer' => array('saml', 'LightSaml\Model\Assertion\Issuer'), |
447
|
|
|
'Subject' => array('saml', 'LightSaml\Model\Assertion\Subject'), |
448
|
|
|
'Conditions' => array('saml', 'LightSaml\Model\Assertion\Conditions'), |
449
|
|
|
)); |
450
|
|
|
|
451
|
4 |
|
$this->manyElementsFromXml( |
452
|
4 |
|
$node, |
|
|
|
|
453
|
4 |
|
$context, |
454
|
4 |
|
'AuthnStatement', |
455
|
4 |
|
'saml', |
456
|
4 |
|
'LightSaml\Model\Assertion\AuthnStatement', |
457
|
4 |
|
'addItem' |
458
|
|
|
); |
459
|
|
|
|
460
|
4 |
|
$this->manyElementsFromXml( |
461
|
4 |
|
$node, |
|
|
|
|
462
|
4 |
|
$context, |
463
|
4 |
|
'AttributeStatement', |
464
|
4 |
|
'saml', |
465
|
4 |
|
'LightSaml\Model\Assertion\AttributeStatement', |
466
|
4 |
|
'addItem' |
467
|
|
|
); |
468
|
|
|
|
469
|
4 |
|
$this->singleElementsFromXml($node, $context, array( |
|
|
|
|
470
|
4 |
|
'Signature' => array('ds', 'LightSaml\Model\XmlDSig\SignatureXmlReader'), |
471
|
|
|
)); |
472
|
4 |
|
} |
473
|
|
|
} |
474
|
|
|
|
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.