Passed
Push — master ( 9e6475...120d1c )
by Tim
02:24
created

SubjectConfirmationData::fromXML()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 35
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 23
nc 4
nop 1
dl 0
loc 35
rs 9.552
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML2\XML\saml;
6
7
use DateTimeImmutable;
8
use DOMElement;
9
use SimpleSAML\Assert\Assert;
10
use SimpleSAML\SAML2\Assert\Assert as SAMLAssert;
11
use SimpleSAML\SAML2\Constants as C;
12
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
13
use SimpleSAML\SAML2\Utils;
14
use SimpleSAML\XML\Exception\InvalidDOMElementException;
15
use SimpleSAML\XML\ExtendableAttributesTrait;
16
use SimpleSAML\XML\ExtendableElementTrait;
17
use SimpleSAML\XML\XsNamespace as NS;
18
19
use function filter_var;
20
use function is_null;
21
22
/**
23
 * Class representing SAML 2 SubjectConfirmationData element.
24
 *
25
 * @package simplesamlphp/saml2
26
 */
27
final class SubjectConfirmationData extends AbstractSamlElement
28
{
29
    use ExtendableAttributesTrait;
1 ignored issue
show
introduced by
The trait SimpleSAML\XML\ExtendableAttributesTrait requires some properties which are not provided by SimpleSAML\SAML2\XML\saml\SubjectConfirmationData: $localName, $nodeValue, $namespaceURI, $prefix, $attributes
Loading history...
30
    use ExtendableElementTrait;
1 ignored issue
show
introduced by
The trait SimpleSAML\XML\ExtendableElementTrait requires some properties which are not provided by SimpleSAML\SAML2\XML\saml\SubjectConfirmationData: $namespaceURI, $localName, $childNodes
Loading history...
31
32
    /** The namespace-attribute for the xs:any element */
33
    public const XS_ANY_ELT_NAMESPACE = NS::ANY;
34
35
    /** The namespace-attribute for the xs:anyAttribute element */
36
    public const XS_ANY_ATTR_NAMESPACE = NS::OTHER;
37
38
39
    /**
40
     * Initialize (and parse) a SubjectConfirmationData element.
41
     *
42
     * @param \DateTimeImmutable|null $notBefore
43
     * @param \DateTimeImmutable|null $notOnOrAfter
44
     * @param string|null $recipient
45
     * @param string|null $inResponseTo
46
     * @param string|null $address
47
     * @param \SimpleSAML\XML\SerializableElementInterface[] $children
48
     * @param list<\SimpleSAML\XML\Attribute> $namespacedAttributes
0 ignored issues
show
Bug introduced by
The type SimpleSAML\SAML2\XML\saml\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
49
     */
50
    public function __construct(
51
        protected ?DateTimeImmutable $notBefore = null,
52
        protected ?DateTimeImmutable $notOnOrAfter = null,
53
        protected ?string $recipient = null,
54
        protected ?string $inResponseTo = null,
55
        protected ?string $address = null,
56
        array $children = [],
57
        array $namespacedAttributes = [],
58
    ) {
59
        Assert::nullOrSame($notBefore?->getTimeZone()->getName(), 'Z', ProtocolViolationException::class);
60
        Assert::nullOrSame($notOnOrAfter?->getTimeZone()->getName(), 'Z', ProtocolViolationException::class);
61
        Assert::nullOrNotWhitespaceOnly($recipient);
62
        Assert::nullOrValidNCName($inResponseTo); // Covers the empty string
63
64
        if (!is_null($address) && !filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6)) {
65
            Utils::getContainer()->getLogger()->warning(
66
                sprintf('Provided argument (%s) is not a valid IP address.', $address),
67
            );
68
        }
69
70
        $this->setElements($children);
71
        $this->setAttributesNS($namespacedAttributes);
72
    }
73
74
75
    /**
76
     * Collect the value of the NotBefore-property
77
     *
78
     * @return \DateTimeImmutable|null
79
     */
80
    public function getNotBefore(): ?DateTimeImmutable
81
    {
82
        return $this->notBefore;
83
    }
84
85
86
    /**
87
     * Collect the value of the NotOnOrAfter-property
88
     *
89
     * @return \DateTimeImmutable|null
90
     */
91
    public function getNotOnOrAfter(): ?DateTimeImmutable
92
    {
93
        return $this->notOnOrAfter;
94
    }
95
96
97
    /**
98
     * Collect the value of the Recipient-property
99
     *
100
     * @return string|null
101
     */
102
    public function getRecipient(): ?string
103
    {
104
        return $this->recipient;
105
    }
106
107
108
    /**
109
     * Collect the value of the InResponseTo-property
110
     *
111
     * @return string|null
112
     */
113
    public function getInResponseTo(): ?string
114
    {
115
        return $this->inResponseTo;
116
    }
117
118
119
    /**
120
     * Collect the value of the Address-property
121
     *
122
     * @return string|null
123
     */
124
    public function getAddress(): ?string
125
    {
126
        return $this->address;
127
    }
128
129
130
    /**
131
     * Test if an object, at the state it's in, would produce an empty XML-element
132
     *
133
     * @return bool
134
     */
135
    public function isEmptyElement(): bool
136
    {
137
        return empty($this->notBefore)
138
            && empty($this->notOnOrAfter)
139
            && empty($this->recipient)
140
            && empty($this->inResponseTo)
141
            && empty($this->address)
142
            && empty($this->elements)
143
            && empty($this->namespacedAttributes);
144
    }
145
146
147
    /**
148
     * Convert XML into a SubjectConfirmationData
149
     *
150
     * @param \DOMElement $xml The XML element we should load
151
     * @return static
152
     *
153
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
154
     *   if the qualified name of the supplied element is wrong
155
     * @throws \SimpleSAML\XML\Exception\MissingAttributeException
156
     *   if the supplied element is missing any of the mandatory attributes
157
     * @throws \SimpleSAML\Assert\AssertionFailedException
158
     *   if NotBefore or NotOnOrAfter contain an invalid date.
159
     */
160
    public static function fromXML(DOMElement $xml): static
161
    {
162
        Assert::same($xml->localName, 'SubjectConfirmationData', InvalidDOMElementException::class);
163
        Assert::same($xml->namespaceURI, SubjectConfirmationData::NS, InvalidDOMElementException::class);
164
165
        $NotBefore = self::getOptionalAttribute($xml, 'NotBefore', null);
166
        if ($NotBefore !== null) {
167
            // Strip sub-seconds - See paragraph 1.3.3 of SAML core specifications
168
            $NotBefore = preg_replace('/([.][0-9]+Z)$/', 'Z', $NotBefore, 1);
169
170
            SAMLAssert::validDateTime($NotBefore, ProtocolViolationException::class);
171
            $NotBefore = new DateTimeImmutable($NotBefore);
172
        }
173
174
        $NotOnOrAfter = self::getOptionalAttribute($xml, 'NotOnOrAfter', null);
175
        if ($NotOnOrAfter !== null) {
176
            // Strip sub-seconds - See paragraph 1.3.3 of SAML core specifications
177
            $NotOnOrAfter = preg_replace('/([.][0-9]+Z)$/', 'Z', $NotOnOrAfter, 1);
178
179
            SAMLAssert::validDateTime($NotOnOrAfter, ProtocolViolationException::class);
180
            $NotOnOrAfter = new DateTimeImmutable($NotOnOrAfter);
181
        }
182
183
        $Recipient = self::getOptionalAttribute($xml, 'Recipient', null);
184
        $InResponseTo = self::getOptionalAttribute($xml, 'InResponseTo', null);
185
        $Address = self::getOptionalAttribute($xml, 'Address', null);
186
187
        return new static(
188
            $NotBefore,
189
            $NotOnOrAfter,
190
            $Recipient,
191
            $InResponseTo,
192
            $Address,
193
            self::getChildElementsFromXML($xml),
194
            self::getAttributesNSFromXML($xml),
195
        );
196
    }
197
198
199
    /**
200
     * Convert this element to XML.
201
     *
202
     * @param  \DOMElement|null $parent The parent element we should append this element to.
203
     * @return \DOMElement This element, as XML.
204
     */
205
    public function toXML(DOMElement $parent = null): DOMElement
206
    {
207
        $e = $this->instantiateParentElement($parent);
208
209
        if ($this->getNotBefore() !== null) {
210
            $e->setAttribute('NotBefore', $this->getNotBefore()->format(C::DATETIME_FORMAT));
211
        }
212
        if ($this->getNotOnOrAfter() !== null) {
213
            $e->setAttribute('NotOnOrAfter', $this->getNotOnOrAfter()->format(C::DATETIME_FORMAT));
214
        }
215
        if ($this->getRecipient() !== null) {
216
            $e->setAttribute('Recipient', $this->getRecipient());
217
        }
218
        if ($this->getInResponseTo() !== null) {
219
            $e->setAttribute('InResponseTo', $this->getInResponseTo());
220
        }
221
        if ($this->getAddress() !== null) {
222
            $e->setAttribute('Address', $this->getAddress());
223
        }
224
225
        foreach ($this->getAttributesNS() as $attr) {
226
            $attr->toXML($e);
227
        }
228
229
        foreach ($this->getElements() as $n) {
230
            $n->toXML($e);
231
        }
232
233
        return $e;
234
    }
235
}
236