AbstractRequestAbstractType   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 11
eloc 26
c 2
b 0
f 0
dl 0
loc 104
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getRespondWith() 0 3 1
A __construct() 0 10 1
A toXML() 0 33 6
A toUnsignedXML() 0 10 2
A getID() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML11\XML\samlp;
6
7
use DOMElement;
8
use SimpleSAML\SAML11\Assert\Assert;
9
use SimpleSAML\SAML11\Type\SAMLDateTimeValue;
10
use SimpleSAML\SAML11\Utils\XPath;
11
use SimpleSAML\XMLSchema\Exception\SchemaViolationException;
12
use SimpleSAML\XMLSchema\Type\IDValue;
13
use SimpleSAML\XMLSchema\Type\NonNegativeIntegerValue;
14
15
use function array_pop;
16
use function strval;
17
18
/**
19
 * Base class for all SAML 1.1 requests.
20
 *
21
 * @package simplesamlphp/saml11
22
 */
23
abstract class AbstractRequestAbstractType extends AbstractMessage
24
{
25
    /**
26
     * Initialize a request.
27
     *
28
     * @param \SimpleSAML\XMLSchema\Type\IDValue $id
29
     * @param \SimpleSAML\XMLSchema\Type\NonNegativeIntegerValue $majorVersion
30
     * @param \SimpleSAML\XMLSchema\Type\NonNegativeIntegerValue $minorVersion
31
     * @param \SimpleSAML\SAML11\Type\SAMLDateTimeValue $issueInstant
32
     * @param array<\SimpleSAML\SAML11\XML\samlp\RespondWith>
33
     *
34
     * @throws \Exception
35
     */
36
    protected function __construct(
37
        protected IDValue $id,
38
        protected NonNegativeIntegerValue $majorVersion,
39
        protected NonNegativeIntegerValue $minorVersion,
40
        protected SAMLDateTimeValue $issueInstant,
41
        protected array $respondWith = [],
42
    ) {
43
        Assert::allIsInstanceOf($respondWith, RespondWith::class, SchemaViolationException::class);
44
45
        parent::__construct($majorVersion, $minorVersion, $issueInstant);
46
    }
47
48
49
    /**
50
     * Retrieve the ID of this request.
51
     *
52
     * @return \SimpleSAML\XMLSchema\Type\IDValue The ID of this request
53
     */
54
    public function getID(): IDValue
55
    {
56
        return $this->id;
57
    }
58
59
60
    /**
61
     * @return array<\SimpleSAML\SAML11\XML\samlp\RespondWith>
62
     */
63
    public function getRespondWith(): array
64
    {
65
        return $this->respondWith;
66
    }
67
68
69
    /**
70
     * Convert this message to an unsigned XML document.
71
     * This method does not sign the resulting XML document.
72
     *
73
     * @return \DOMElement The root element of the DOM tree
74
     */
75
    protected function toUnsignedXML(?DOMElement $parent = null): DOMElement
76
    {
77
        $e = parent::toUnsignedXML($parent);
78
        $e->setAttribute('RequestID', strval($this->getID()));
79
80
        foreach ($this->getRespondWith() as $respondWith) {
81
            $respondWith->toXML($e);
82
        }
83
84
        return $e;
85
    }
86
87
88
    /**
89
     * Create XML from this class
90
     *
91
     * @param \DOMElement|null $parent
92
     * @return \DOMElement
93
     */
94
    public function toXML(?DOMElement $parent = null): DOMElement
95
    {
96
        if ($this->isSigned() === true && $this->signer === null) {
97
            // We already have a signed document and no signer was set to re-sign it
98
            if ($parent === null) {
99
                return $this->xml;
100
            }
101
102
            $node = $parent->ownerDocument?->importNode($this->getXML(), true);
103
            $parent->appendChild($node);
104
105
            return $parent;
106
        }
107
108
        $e = $this->toUnsignedXML($parent);
109
110
        if ($this->signer !== null) {
111
            $signedXML = $this->doSign($e);
112
113
            // Test for an RespondWith
114
            $messageElements = XPath::xpQuery($signedXML, './saml_protocol:RespondWith', XPath::getXPath($signedXML));
115
            $respondWith = array_pop($messageElements);
116
117
            if ($respondWith === null) {
118
                $signedXML->appendChild($this->signature?->toXML($signedXML));
119
            } else {
120
                $signedXML->insertBefore($this->signature?->toXML($signedXML), $respondWith->nextSibling);
121
            }
122
123
            return $signedXML;
124
        }
125
126
        return $e;
127
    }
128
}
129