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