Passed
Push — master ( eb6d7f...017f7a )
by Tim
02:40
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 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