Passed
Push — master ( 6db269...70aff8 )
by Jaime Pérez
02:49
created

SubjectConfirmationData::getNotOnOrAfter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SAML2\XML\saml;
6
7
use DOMElement;
8
use RobRichards\XMLSecLibs\XMLSecurityDSig;
9
use SAML2\Constants;
10
use SAML2\Utils;
11
use SAML2\XML\Chunk;
12
use SAML2\XML\ds\KeyInfo;
13
use Webmozart\Assert\Assert;
14
15
/**
16
 * Class representing SAML 2 SubjectConfirmationData element.
17
 *
18
 * @package simplesamlphp/saml2
19
 */
20
final class SubjectConfirmationData extends AbstractSamlElement
21
{
22
    /**
23
     * The time before this element is valid, as an unix timestamp.
24
     *
25
     * @var int|null
26
     */
27
    private $NotBefore = null;
28
29
    /**
30
     * The time after which this element is invalid, as an unix timestamp.
31
     *
32
     * @var int|null
33
     */
34
    private $NotOnOrAfter = null;
35
36
    /**
37
     * The Recipient this Subject is valid for. Either an entity or a location.
38
     *
39
     * @var string|null
40
     */
41
    private $Recipient = null;
42
43
    /**
44
     * The ID of the AuthnRequest this is a response to.
45
     *
46
     * @var string|null
47
     */
48
    private $InResponseTo = null;
49
50
    /**
51
     * The IP(v6) address of the user.
52
     *
53
     * @var string|null
54
     */
55
    private $Address = null;
56
57
    /**
58
     * The various key information elements.
59
     *
60
     * Array with various elements describing this key.
61
     * Unknown elements will be represented by \SAML2\XML\Chunk.
62
     *
63
     * @var (\SAML2\XML\ds\KeyInfo|\SAML2\XML\Chunk)[]
64
     */
65
    private $info = [];
66
67
68
    /**
69
     * Initialize (and parse) a SubjectConfirmationData element.
70
     *
71
     * @param int|null $notBefore
72
     * @param int|null $notOnOrAfter
73
     * @param string|null $recipient
74
     * @param string|null $inResponseTo
75
     * @param string|null $address
76
     * @param (\SAML2\XML\ds\KeyInfo|\SAML2\XML\Chunk)[] $info
77
     */
78
    public function __construct(
79
        ?int $notBefore = null,
80
        ?int $notOnOrAfter = null,
81
        ?string $recipient = null,
82
        ?string $inResponseTo = null,
83
        ?string $address = null,
84
        array $info = []
85
    ) {
86
        $this->setNotBefore($notBefore);
87
        $this->setNotOnOrAfter($notOnOrAfter);
88
        $this->setRecipient($recipient);
89
        $this->setInResponseTo($inResponseTo);
90
        $this->setAddress($address);
91
        $this->setInfo($info);
92
    }
93
94
95
    /**
96
     * Collect the value of the NotBefore-property
97
     *
98
     * @return int|null
99
     */
100
    public function getNotBefore(): ?int
101
    {
102
        return $this->NotBefore;
103
    }
104
105
106
    /**
107
     * Set the value of the NotBefore-property
108
     *
109
     * @param int|null $notBefore
110
     * @return void
111
     */
112
    private function setNotBefore(?int $notBefore): void
113
    {
114
        $this->NotBefore = $notBefore;
115
    }
116
117
118
    /**
119
     * Collect the value of the NotOnOrAfter-property
120
     *
121
     * @return int|null
122
     */
123
    public function getNotOnOrAfter(): ?int
124
    {
125
        return $this->NotOnOrAfter;
126
    }
127
128
129
    /**
130
     * Set the value of the NotOnOrAfter-property
131
     *
132
     * @param int|null $notOnOrAfter
133
     * @return void
134
     */
135
    private function setNotOnOrAfter(?int $notOnOrAfter): void
136
    {
137
        $this->NotOnOrAfter = $notOnOrAfter;
138
    }
139
140
141
    /**
142
     * Collect the value of the Recipient-property
143
     *
144
     * @return string|null
145
     */
146
    public function getRecipient(): ?string
147
    {
148
        return $this->Recipient;
149
    }
150
151
152
    /**
153
     * Set the value of the Recipient-property
154
     *
155
     * @param string|null $recipient
156
     * @return void
157
     */
158
    private function setRecipient(?string $recipient): void
159
    {
160
        $this->Recipient = $recipient;
161
    }
162
163
164
    /**
165
     * Collect the value of the InResponseTo-property
166
     *
167
     * @return string|null
168
     */
169
    public function getInResponseTo(): ?string
170
    {
171
        return $this->InResponseTo;
172
    }
173
174
175
    /**
176
     * Set the value of the InResponseTo-property
177
     *
178
     * @param string|null $inResponseTo
179
     * @return void
180
     */
181
    private function setInResponseTo(?string $inResponseTo): void
182
    {
183
        $this->InResponseTo = $inResponseTo;
184
    }
185
186
187
    /**
188
     * Collect the value of the Address-property
189
     *
190
     * @return string|null
191
     */
192
    public function getAddress(): ?string
193
    {
194
        return $this->Address;
195
    }
196
197
198
    /**
199
     * Set the value of the Address-property
200
     *
201
     * @param string|null $address
202
     * @return void
203
     */
204
    private function setAddress(?string $address): void
205
    {
206
        if (!is_null($address) && !filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6)) {
207
            Utils::getContainer()->getLogger()->warning(
208
                sprintf('Provided argument (%s) is not a valid IP address.', $address)
209
            );
210
        }
211
        $this->Address = $address;
212
    }
213
214
215
    /**
216
     * Collect the value of the info-property
217
     *
218
     * @return (\SAML2\XML\ds\KeyInfo|\SAML2\XML\Chunk)[]
219
     */
220
    public function getInfo(): array
221
    {
222
        return $this->info;
223
    }
224
225
226
    /**
227
     * Set the value of the info-property
228
     *
229
     * @param (\SAML2\XML\ds\KeyInfo|\SAML2\XML\Chunk)[] $info
230
     * @return void
231
     */
232
    private function setInfo(array $info): void
233
    {
234
        $this->info = $info;
235
    }
236
237
238
    /**
239
     * Add the value to the info-property
240
     *
241
     * @param \SAML2\XML\Chunk|\SAML2\XML\ds\KeyInfo $info
242
     * @return void
243
     * @throws \InvalidArgumentException
244
     */
245
    public function addInfo(object $info): void
246
    {
247
        Assert::isInstanceOfAny($info, [Chunk::class, KeyInfo::class]);
248
        $this->info[] = $info;
249
    }
250
251
252
    /**
253
     * Test if an object, at the state it's in, would produce an empty XML-element
254
     *
255
     * @return bool
256
     */
257
    public function isEmptyElement(): bool
258
    {
259
        return (
260
            empty($this->NotBefore)
261
            && empty($this->NotOnOrAfter)
262
            && empty($this->Recipient)
263
            && empty($this->InResponseTo)
264
            && empty($this->Address)
265
            && empty($this->info)
266
        );
267
    }
268
269
270
    /**
271
     * Convert XML into a SubjectConfirmationData
272
     *
273
     * @param \DOMElement $xml The XML element we should load
274
     * @return self
275
     * @throws \InvalidArgumentException if the qualified name of the supplied element is wrong
276
     */
277
    public static function fromXML(DOMElement $xml): object
278
    {
279
        Assert::same($xml->localName, 'SubjectConfirmationData');
280
        Assert::same($xml->namespaceURI, SubjectConfirmationData::NS);
281
282
        $NotBefore = $xml->hasAttribute('NotBefore')
283
            ? Utils::xsDateTimeToTimestamp($xml->getAttribute('NotBefore'))
284
            : null;
285
286
        $NotOnOrAfter = $xml->hasAttribute('NotOnOrAfter')
287
            ? Utils::xsDateTimeToTimestamp($xml->getAttribute('NotOnOrAfter'))
288
            : null;
289
290
        $Recipient = $xml->hasAttribute('Recipient') ? $xml->getAttribute('Recipient') : null;
291
        $InResponseTo = $xml->hasAttribute('InResponseTo') ? $xml->getAttribute('InResponseTo') : null;
292
        $Address = $xml->hasAttribute('Address') ? $xml->getAttribute('Address') : null;
293
294
        $info = [];
295
        foreach ($xml->childNodes as $n) {
296
            if (!($n instanceof DOMElement)) {
297
                continue;
298
            } elseif ($n->namespaceURI !== XMLSecurityDSig::XMLDSIGNS) {
299
                $info[] = new Chunk($n);
300
                continue;
301
            }
302
303
            switch ($n->localName) {
304
                case 'KeyInfo':
305
                    $info[] = KeyInfo::fromXML($n);
306
                    break;
307
                default:
308
                    $info[] = new Chunk($n);
309
                    break;
310
            }
311
        }
312
313
        return new self(
314
            $NotBefore,
315
            $NotOnOrAfter,
316
            $Recipient,
317
            $InResponseTo,
318
            $Address,
319
            $info
320
        );
321
    }
322
323
324
    /**
325
     * Convert this element to XML.
326
     *
327
     * @param  \DOMElement|null $parent The parent element we should append this element to.
328
     * @return \DOMElement This element, as XML.
329
     */
330
    public function toXML(DOMElement $parent = null): DOMElement
331
    {
332
        $e = $this->instantiateParentElement($parent);
333
334
        if ($this->NotBefore !== null) {
335
            $e->setAttribute('NotBefore', gmdate('Y-m-d\TH:i:s\Z', $this->NotBefore));
336
        }
337
        if ($this->NotOnOrAfter !== null) {
338
            $e->setAttribute('NotOnOrAfter', gmdate('Y-m-d\TH:i:s\Z', $this->NotOnOrAfter));
339
        }
340
        if ($this->Recipient !== null) {
341
            $e->setAttribute('Recipient', $this->Recipient);
342
        }
343
        if ($this->InResponseTo !== null) {
344
            $e->setAttribute('InResponseTo', $this->InResponseTo);
345
        }
346
        if ($this->Address !== null) {
347
            $e->setAttribute('Address', $this->Address);
348
        }
349
350
        foreach ($this->info as $n) {
351
            $n->toXML($e);
352
        }
353
354
        return $e;
355
    }
356
}
357