Passed
Push — master ( eb6d7f...017f7a )
by Tim
02:40
created

IDPSSODescriptor::getAssertionIDRequestServices()   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 SimpleSAML\SAML2\XML\md;
6
7
use DOMElement;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\SAML2\XML\saml\Attribute;
10
use SimpleSAML\XML\Exception\InvalidDOMElementException;
11
use SimpleSAML\XML\Exception\TooManyElementsException;
12
use SimpleSAML\XML\Utils as XMLUtils;
13
use SimpleSAML\XMLSecurity\XML\ds\Signature;
14
15
use function preg_split;
16
17
/**
18
 * Class representing SAML 2 IDPSSODescriptor.
19
 *
20
 * @package simplesamlphp/saml2
21
 */
22
final class IDPSSODescriptor extends AbstractSSODescriptor
23
{
24
    /**
25
     * Whether AuthnRequests sent to this IdP should be signed.
26
     *
27
     * @var bool|null
28
     */
29
    protected ?bool $wantAuthnRequestsSigned = null;
30
31
    /**
32
     * List of SingleSignOnService endpoints.
33
     *
34
     * @var \SimpleSAML\SAML2\XML\md\SingleSignOnService[]
35
     */
36
    protected array $ssoServiceEndpoints = [];
37
38
    /**
39
     * List of NameIDMappingService endpoints.
40
     *
41
     * @var \SimpleSAML\SAML2\XML\md\NameIDMappingService[]
42
     */
43
    protected array $nameIDMappingServiceEndpoints = [];
44
45
    /**
46
     * List of AssertionIDRequestService endpoints.
47
     *
48
     * @var \SimpleSAML\SAML2\XML\md\AssertionIDRequestService[]
49
     */
50
    protected array $assertionIDRequestServiceEndpoints = [];
51
52
    /**
53
     * List of supported attribute profiles.
54
     *
55
     * @var \SimpleSAML\SAML2\XML\md\AttributeProfile[]
56
     */
57
    protected array $attributeProfiles = [];
58
59
    /**
60
     * List of supported attributes.
61
     *
62
     * @var \SimpleSAML\SAML2\XML\saml\Attribute[]
63
     */
64
    protected array $attributes = [];
65
66
67
    /**
68
     * IDPSSODescriptor constructor.
69
     *
70
     * @param \SimpleSAML\SAML2\XML\md\SingleSignOnService[] $ssoServiceEndpoints
71
     * @param string[] $protocolSupportEnumeration
72
     * @param bool|null $wantAuthnRequestsSigned
73
     * @param \SimpleSAML\SAML2\XML\md\NameIDMappingService[] $nameIDMappingServiceEndpoints
74
     * @param \SimpleSAML\SAML2\XML\md\AssertionIDRequestService[] $assertionIDRequestServiceEndpoints
75
     * @param \SimpleSAML\SAML2\XML\md\AttributeProfile[] $attributeProfiles
76
     * @param \SimpleSAML\SAML2\XML\saml\Attribute[] $attributes
77
     * @param string|null $ID
78
     * @param int|null $validUntil
79
     * @param string|null $cacheDuration
80
     * @param \SimpleSAML\SAML2\XML\md\Extensions|null $extensions
81
     * @param string|null $errorURL
82
     * @param \SimpleSAML\SAML2\XML\md\KeyDescriptor[] $keyDescriptors
83
     * @param \SimpleSAML\SAML2\XML\md\Organization|null $organization
84
     * @param \SimpleSAML\SAML2\XML\md\ContactPerson[] $contacts
85
     * @param \SimpleSAML\SAML2\XML\md\ArtifactResolutionService[] $artifactResolutionService
86
     * @param \SimpleSAML\SAML2\XML\md\SingleLogoutService[] $singleLogoutService
87
     * @param \SimpleSAML\SAML2\XML\md\ManageNameIDService[] $manageNameIDService
88
     * @param \SimpleSAML\SAML2\XML\md\NameIDFormat[] $nameIDFormat
89
     */
90
    public function __construct(
91
        array $ssoServiceEndpoints,
92
        array $protocolSupportEnumeration,
93
        ?bool $wantAuthnRequestsSigned = null,
94
        array $nameIDMappingServiceEndpoints = [],
95
        array $assertionIDRequestServiceEndpoints = [],
96
        array $attributeProfiles = [],
97
        array $attributes = [],
98
        ?string $ID = null,
99
        ?int $validUntil = null,
100
        ?string $cacheDuration = null,
101
        ?Extensions $extensions = null,
102
        ?string $errorURL = null,
103
        array $keyDescriptors = [],
104
        ?Organization $organization = null,
105
        array $contacts = [],
106
        array $artifactResolutionService = [],
107
        array $singleLogoutService = [],
108
        array $manageNameIDService = [],
109
        array $nameIDFormat = []
110
    ) {
111
        parent::__construct(
112
            $protocolSupportEnumeration,
113
            $ID,
114
            $validUntil,
115
            $cacheDuration,
116
            $extensions,
117
            $errorURL,
118
            $keyDescriptors,
119
            $organization,
120
            $contacts,
121
            $artifactResolutionService,
122
            $singleLogoutService,
123
            $manageNameIDService,
124
            $nameIDFormat
125
        );
126
        $this->setSingleSignOnServices($ssoServiceEndpoints);
127
        $this->setWantAuthnRequestsSigned($wantAuthnRequestsSigned);
128
        $this->setNameIDMappingServices($nameIDMappingServiceEndpoints);
129
        $this->setAssertionIDRequestService($assertionIDRequestServiceEndpoints);
130
        $this->setAttributeProfiles($attributeProfiles);
131
        $this->setSupportedAttributes($attributes);
132
    }
133
134
135
    /**
136
     * Collect the value of the WantAuthnRequestsSigned-property
137
     *
138
     * @return bool|null
139
     */
140
    public function wantAuthnRequestsSigned(): ?bool
141
    {
142
        return $this->wantAuthnRequestsSigned;
143
    }
144
145
146
    /**
147
     * Set the value of the WantAuthnRequestsSigned-property
148
     *
149
     * @param bool|null $flag
150
     */
151
    protected function setWantAuthnRequestsSigned(?bool $flag = null): void
152
    {
153
        $this->wantAuthnRequestsSigned = $flag;
154
    }
155
156
157
    /**
158
     * Get the SingleSignOnService endpoints
159
     *
160
     * @return \SimpleSAML\SAML2\XML\md\SingleSignOnService[]
161
     */
162
    public function getSingleSignOnServices(): array
163
    {
164
        return $this->ssoServiceEndpoints;
165
    }
166
167
168
    /**
169
     * Set the SingleSignOnService endpoints
170
     *
171
     * @param \SimpleSAML\SAML2\XML\md\SingleSignOnService[] $singleSignOnServices
172
     */
173
    protected function setSingleSignOnServices(array $singleSignOnServices): void
174
    {
175
        Assert::minCount($singleSignOnServices, 1, 'At least one SingleSignOnService must be specified.');
176
        Assert::allIsInstanceOf(
177
            $singleSignOnServices,
178
            SingleSignOnService::class,
179
            'All md:SingleSignOnService endpoints must be an instance of SingleSignOnService.'
180
        );
181
        $this->ssoServiceEndpoints = $singleSignOnServices;
182
    }
183
184
185
    /**
186
     * Get the NameIDMappingService endpoints
187
     *
188
     * @return \SimpleSAML\SAML2\XML\md\NameIDMappingService[]
189
     */
190
    public function getNameIDMappingServices(): array
191
    {
192
        return $this->nameIDMappingServiceEndpoints;
193
    }
194
195
196
    /**
197
     * Set the NameIDMappingService endpoints
198
     *
199
     * @param \SimpleSAML\SAML2\XML\md\NameIDMappingService[] $nameIDMappingServices
200
     */
201
    protected function setNameIDMappingServices(array $nameIDMappingServices): void
202
    {
203
        Assert::allIsInstanceOf(
204
            $nameIDMappingServices,
205
            NameIDMappingService::class,
206
            'All md:NameIDMappingService endpoints must be an instance of NameIDMappingService.'
207
        );
208
        $this->nameIDMappingServiceEndpoints = $nameIDMappingServices;
209
    }
210
211
212
    /**
213
     * Collect the AssertionIDRequestService endpoints
214
     *
215
     * @return \SimpleSAML\SAML2\XML\md\AssertionIDRequestService[]
216
     */
217
    public function getAssertionIDRequestServices(): array
218
    {
219
        return $this->assertionIDRequestServiceEndpoints;
220
    }
221
222
223
    /**
224
     * Set the AssertionIDRequestService endpoints
225
     *
226
     * @param \SimpleSAML\SAML2\XML\md\AssertionIDRequestService[] $assertionIDRequestServices
227
     */
228
    protected function setAssertionIDRequestService(array $assertionIDRequestServices): void
229
    {
230
        Assert::allIsInstanceOf(
231
            $assertionIDRequestServices,
232
            AssertionIDRequestService::class,
233
            'All md:AssertionIDRequestService endpoints must be an instance of AssertionIDRequestService.'
234
        );
235
        $this->assertionIDRequestServiceEndpoints = $assertionIDRequestServices;
236
    }
237
238
239
    /**
240
     * Get the attribute profiles supported
241
     *
242
     * @return \SimpleSAML\SAML2\XML\md\AttributeProfile[]
243
     */
244
    public function getAttributeProfiles(): array
245
    {
246
        return $this->attributeProfiles;
247
    }
248
249
250
    /**
251
     * Set the attribute profiles supported
252
     *
253
     * @param \SimpleSAML\SAML2\XML\md\AttributeProfile[] $attributeProfiles
254
     */
255
    protected function setAttributeProfiles(array $attributeProfiles): void
256
    {
257
        Assert::allIsInstanceOf($attributeProfiles, AttributeProfile::class);
258
        $this->attributeProfiles = $attributeProfiles;
259
    }
260
261
262
    /**
263
     * Get the attributes supported by this IdP
264
     *
265
     * @return \SimpleSAML\SAML2\XML\saml\Attribute[]
266
     */
267
    public function getSupportedAttributes(): array
268
    {
269
        return $this->attributes;
270
    }
271
272
273
    /**
274
     * Set the attributes supported by this IdP
275
     *
276
     * @param \SimpleSAML\SAML2\XML\saml\Attribute[] $attributes
277
     */
278
    protected function setSupportedAttributes(array $attributes): void
279
    {
280
        Assert::allIsInstanceOf(
281
            $attributes,
282
            Attribute::class,
283
            'All md:Attribute elements must be an instance of Attribute.'
284
        );
285
        $this->attributes = $attributes;
286
    }
287
288
289
    /**
290
     * Initialize an IDPSSODescriptor.
291
     *
292
     * @param \DOMElement $xml The XML element we should load.
293
     * @return \SimpleSAML\SAML2\XML\md\IDPSSODescriptor
294
     *
295
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException if the qualified name of the supplied element is wrong
296
     * @throws \SimpleSAML\XML\Exception\MissingElementException if one of the mandatory child-elements is missing
297
     * @throws \SimpleSAML\XML\Exception\TooManyElementsException if too many child-elements of a type are specified
298
     */
299
    public static function fromXML(DOMElement $xml): static
300
    {
301
        Assert::same($xml->localName, 'IDPSSODescriptor', InvalidDOMElementException::class);
302
        Assert::same($xml->namespaceURI, IDPSSODescriptor::NS, InvalidDOMElementException::class);
303
304
        $protocols = self::getAttribute($xml, 'protocolSupportEnumeration');
305
        $validUntil = self::getAttribute($xml, 'validUntil', null);
306
        $orgs = Organization::getChildrenOfClass($xml);
307
        Assert::maxCount($orgs, 1, 'More than one Organization found in this descriptor', TooManyElementsException::class);
308
309
        $extensions = Extensions::getChildrenOfClass($xml);
310
        Assert::maxCount($extensions, 1, 'Only one md:Extensions element is allowed.', TooManyElementsException::class);
311
312
        $signature = Signature::getChildrenOfClass($xml);
313
        Assert::maxCount($signature, 1, 'Only one ds:Signature element is allowed.', TooManyElementsException::class);
314
315
        $idpssod = new static(
316
            SingleSignOnService::getChildrenOfClass($xml),
317
            preg_split('/[\s]+/', trim($protocols)),
318
            self::getBooleanAttribute($xml, 'WantAuthnRequestsSigned', null),
319
            NameIDMappingService::getChildrenOfClass($xml),
320
            AssertionIDRequestService::getChildrenOfClass($xml),
321
            AttributeProfile::getChildrenOfClass($xml),
322
            Attribute::getChildrenOfClass($xml),
323
            self::getAttribute($xml, 'ID', null),
324
            $validUntil !== null ? XMLUtils::xsDateTimeToTimestamp($validUntil) : null,
325
            self::getAttribute($xml, 'cacheDuration', null),
326
            !empty($extensions) ? $extensions[0] : null,
327
            self::getAttribute($xml, 'errorURL', null),
328
            KeyDescriptor::getChildrenOfClass($xml),
329
            !empty($orgs) ? $orgs[0] : null,
330
            ContactPerson::getChildrenOfClass($xml),
331
            ArtifactResolutionService::getChildrenOfClass($xml),
332
            SingleLogoutService::getChildrenOfClass($xml),
333
            ManageNameIDService::getChildrenOfClass($xml),
334
            NameIDFormat::getChildrenOfClass($xml)
335
        );
336
        if (!empty($signature)) {
337
            $idpssod->setSignature($signature[0]);
338
        }
339
        return $idpssod;
340
    }
341
342
343
    /**
344
     * Convert this assertion to an unsigned XML document.
345
     * This method does not sign the resulting XML document.
346
     *
347
     * @return \DOMElement The root element of the DOM tree
348
     */
349
    public function toUnsignedXML(?DOMElement $parent = null): DOMElement
350
    {
351
        $e = parent::toUnsignedXML($parent);
352
353
        if (is_bool($this->wantAuthnRequestsSigned)) {
354
            $e->setAttribute('WantAuthnRequestsSigned', $this->wantAuthnRequestsSigned ? 'true' : 'false');
355
        }
356
357
        foreach ($this->ssoServiceEndpoints as $ep) {
358
            $ep->toXML($e);
359
        }
360
361
        foreach ($this->nameIDMappingServiceEndpoints as $ep) {
362
            $ep->toXML($e);
363
        }
364
365
        foreach ($this->assertionIDRequestServiceEndpoints as $ep) {
366
            $ep->toXML($e);
367
        }
368
369
        foreach ($this->attributeProfiles as $ap) {
370
            $ap->toXML($e);
371
        }
372
373
        foreach ($this->attributes as $a) {
374
            $a->toXML($e);
375
        }
376
377
        return $e;
378
    }
379
}
380