Assertion::prepareForXml()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.0416

Importance

Changes 0
Metric Value
dl 0
loc 9
c 0
b 0
f 0
ccs 5
cts 6
cp 0.8333
rs 9.9666
cc 3
nc 4
nop 0
crap 3.0416
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $authnStatement->getSessionIndex() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
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()) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $this->getId() of type string to the boolean false. If you are specifically checking for an empty string, consider using the more explicit === '' instead.
Loading history...
400
            $this->setId(Helper::generateID());
401
        }
402 5
        if (false == $this->getIssueInstantTimestamp()) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $this->getIssueInstantTimestamp() of type integer to the boolean false. If you are specifically checking for 0, consider using something more explicit like === 0 instead.
Loading history...
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'));
0 ignored issues
show
Compatibility introduced by
$node of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
444
445 4
        $this->singleElementsFromXml($node, $context, array(
0 ignored issues
show
Compatibility introduced by
$node of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
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,
0 ignored issues
show
Compatibility introduced by
$node of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
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,
0 ignored issues
show
Compatibility introduced by
$node of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
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(
0 ignored issues
show
Compatibility introduced by
$node of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
470 4
            'Signature' => array('ds', 'LightSaml\Model\XmlDSig\SignatureXmlReader'),
471
        ));
472 4
    }
473
}
474