Passed
Push — master ( 045039...d7835c )
by Tim
02:26
created

IDPSSODescriptor::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 42
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 20
nc 1
nop 19
dl 0
loc 42
rs 9.6
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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
296
     *   if the qualified name of the supplied element is wrong
297
     * @throws \SimpleSAML\XML\Exception\MissingElementException
298
     *   if one of the mandatory child-elements is missing
299
     * @throws \SimpleSAML\XML\Exception\TooManyElementsException
300
     *   if too many child-elements of a type are specified
301
     */
302
    public static function fromXML(DOMElement $xml): static
303
    {
304
        Assert::same($xml->localName, 'IDPSSODescriptor', InvalidDOMElementException::class);
305
        Assert::same($xml->namespaceURI, IDPSSODescriptor::NS, InvalidDOMElementException::class);
306
307
        $protocols = self::getAttribute($xml, 'protocolSupportEnumeration');
308
        $validUntil = self::getAttribute($xml, 'validUntil', null);
309
        $orgs = Organization::getChildrenOfClass($xml);
310
        Assert::maxCount(
311
            $orgs,
312
            1,
313
            'More than one Organization found in this descriptor',
314
            TooManyElementsException::class
315
        );
316
317
        $extensions = Extensions::getChildrenOfClass($xml);
318
        Assert::maxCount(
319
            $extensions,
320
            1,
321
            'Only one md:Extensions element is allowed.',
322
            TooManyElementsException::class
323
        );
324
325
        $signature = Signature::getChildrenOfClass($xml);
326
        Assert::maxCount(
327
            $signature,
328
            1,
329
            'Only one ds:Signature element is allowed.',
330
            TooManyElementsException::class
331
        );
332
333
        $idpssod = new static(
334
            SingleSignOnService::getChildrenOfClass($xml),
335
            preg_split('/[\s]+/', trim($protocols)),
336
            self::getBooleanAttribute($xml, 'WantAuthnRequestsSigned', null),
337
            NameIDMappingService::getChildrenOfClass($xml),
338
            AssertionIDRequestService::getChildrenOfClass($xml),
339
            AttributeProfile::getChildrenOfClass($xml),
340
            Attribute::getChildrenOfClass($xml),
341
            self::getAttribute($xml, 'ID', null),
342
            $validUntil !== null ? XMLUtils::xsDateTimeToTimestamp($validUntil) : null,
343
            self::getAttribute($xml, 'cacheDuration', null),
344
            !empty($extensions) ? $extensions[0] : null,
345
            self::getAttribute($xml, 'errorURL', null),
346
            KeyDescriptor::getChildrenOfClass($xml),
347
            !empty($orgs) ? $orgs[0] : null,
348
            ContactPerson::getChildrenOfClass($xml),
349
            ArtifactResolutionService::getChildrenOfClass($xml),
350
            SingleLogoutService::getChildrenOfClass($xml),
351
            ManageNameIDService::getChildrenOfClass($xml),
352
            NameIDFormat::getChildrenOfClass($xml)
353
        );
354
355
        if (!empty($signature)) {
356
            $idpssod->setSignature($signature[0]);
357
            $idpssod->setXML($xml);
358
        }
359
        return $idpssod;
360
    }
361
362
363
    /**
364
     * Convert this assertion to an unsigned XML document.
365
     * This method does not sign the resulting XML document.
366
     *
367
     * @return \DOMElement The root element of the DOM tree
368
     */
369
    public function toUnsignedXML(?DOMElement $parent = null): DOMElement
370
    {
371
        $e = parent::toUnsignedXML($parent);
372
373
        if (is_bool($this->wantAuthnRequestsSigned)) {
374
            $e->setAttribute('WantAuthnRequestsSigned', $this->wantAuthnRequestsSigned ? 'true' : 'false');
375
        }
376
377
        foreach ($this->getSingleSignOnServices() as $ep) {
378
            $ep->toXML($e);
379
        }
380
381
        foreach ($this->getNameIDMappingServices() as $ep) {
382
            $ep->toXML($e);
383
        }
384
385
        foreach ($this->getAssertionIDRequestServices() as $ep) {
386
            $ep->toXML($e);
387
        }
388
389
        foreach ($this->getAttributeProfiles() as $ap) {
390
            $ap->toXML($e);
391
        }
392
393
        foreach ($this->getSupportedAttributes() as $a) {
394
            $a->toXML($e);
395
        }
396
397
        return $e;
398
    }
399
}
400