Passed
Pull Request — master (#374)
by Tim
02:32
created

IDPSSODescriptor::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 63
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 37
nc 1
nop 19
dl 0
loc 63
rs 9.328
c 0
b 0
f 0

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\SAML2\Assert\Assert;
9
use SimpleSAML\SAML2\Type\{SAMLAnyURIValue, SAMLDateTimeValue};
10
use SimpleSAML\SAML2\XML\saml\Attribute;
11
use SimpleSAML\XML\Constants as C;
12
use SimpleSAML\XML\Exception\{InvalidDOMElementException, TooManyElementsException};
13
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
14
use SimpleSAML\XML\Type\{BooleanValue, DurationValue, IDValue};
15
use SimpleSAML\XMLSecurity\XML\ds\Signature;
16
17
use function preg_split;
18
use function var_export;
19
20
/**
21
 * Class representing SAML 2 IDPSSODescriptor.
22
 *
23
 * @package simplesamlphp/saml2
24
 */
25
final class IDPSSODescriptor extends AbstractSSODescriptor implements SchemaValidatableElementInterface
26
{
27
    use SchemaValidatableElementTrait;
28
29
    /**
30
     * IDPSSODescriptor constructor.
31
     *
32
     * @param \SimpleSAML\SAML2\XML\md\SingleSignOnService[] $singleSignOnService
33
     * @param string[] $protocolSupportEnumeration
34
     * @param \SimpleSAML\XML\Type\BooleanValue|null $wantAuthnRequestsSigned
35
     * @param \SimpleSAML\SAML2\XML\md\NameIDMappingService[] $nameIDMappingService
36
     * @param \SimpleSAML\SAML2\XML\md\AssertionIDRequestService[] $assertionIDRequestService
37
     * @param \SimpleSAML\SAML2\XML\md\AttributeProfile[] $attributeProfile
38
     * @param \SimpleSAML\SAML2\XML\saml\Attribute[] $attribute
39
     * @param \SimpleSAML\XML\Type\IDValue|null $ID
40
     * @param \SimpleSAML\SAML2\Type\SAMLDateTimeValue|null $validUntil
41
     * @param \SimpleSAML\XML\Type\DurationValue|null $cacheDuration
42
     * @param \SimpleSAML\SAML2\XML\md\Extensions|null $extensions
43
     * @param \SimpleSAML\SAML2\Type\SAMLAnyURIValue|null $errorURL
44
     * @param \SimpleSAML\SAML2\XML\md\KeyDescriptor[] $keyDescriptor
45
     * @param \SimpleSAML\SAML2\XML\md\Organization|null $organization
46
     * @param \SimpleSAML\SAML2\XML\md\ContactPerson[] $contact
47
     * @param \SimpleSAML\SAML2\XML\md\ArtifactResolutionService[] $artifactResolutionService
48
     * @param \SimpleSAML\SAML2\XML\md\SingleLogoutService[] $singleLogoutService
49
     * @param \SimpleSAML\SAML2\XML\md\ManageNameIDService[] $manageNameIDService
50
     * @param \SimpleSAML\SAML2\XML\md\NameIDFormat[] $nameIDFormat
51
     */
52
    public function __construct(
53
        protected array $singleSignOnService,
54
        array $protocolSupportEnumeration,
55
        protected ?BooleanValue $wantAuthnRequestsSigned = null,
56
        protected array $nameIDMappingService = [],
57
        protected array $assertionIDRequestService = [],
58
        protected array $attributeProfile = [],
59
        protected array $attribute = [],
60
        ?IDValue $ID = null,
61
        ?SAMLDateTimeValue $validUntil = null,
62
        ?DurationValue $cacheDuration = null,
63
        ?Extensions $extensions = null,
64
        ?SAMLAnyURIValue $errorURL = null,
65
        array $keyDescriptor = [],
66
        ?Organization $organization = null,
67
        array $contact = [],
68
        array $artifactResolutionService = [],
69
        array $singleLogoutService = [],
70
        array $manageNameIDService = [],
71
        array $nameIDFormat = [],
72
    ) {
73
        Assert::maxCount($singleSignOnService, C::UNBOUNDED_LIMIT);
74
        Assert::minCount($singleSignOnService, 1, 'At least one SingleSignOnService must be specified.');
75
        Assert::allIsInstanceOf(
76
            $singleSignOnService,
77
            SingleSignOnService::class,
78
            'All md:SingleSignOnService endpoints must be an instance of SingleSignOnService.',
79
        );
80
        Assert::maxCount($nameIDMappingService, C::UNBOUNDED_LIMIT);
81
        Assert::allIsInstanceOf(
82
            $nameIDMappingService,
83
            NameIDMappingService::class,
84
            'All md:NameIDMappingService endpoints must be an instance of NameIDMappingService.',
85
        );
86
        Assert::maxCount($assertionIDRequestService, C::UNBOUNDED_LIMIT);
87
        Assert::allIsInstanceOf(
88
            $assertionIDRequestService,
89
            AssertionIDRequestService::class,
90
            'All md:AssertionIDRequestService endpoints must be an instance of AssertionIDRequestService.',
91
        );
92
        Assert::maxCount($attributeProfile, C::UNBOUNDED_LIMIT);
93
        Assert::allIsInstanceOf($attributeProfile, AttributeProfile::class);
94
        Assert::maxCount($attribute, C::UNBOUNDED_LIMIT);
95
        Assert::allIsInstanceOf(
96
            $attribute,
97
            Attribute::class,
98
            'All md:Attribute elements must be an instance of Attribute.',
99
        );
100
101
        parent::__construct(
102
            $protocolSupportEnumeration,
103
            $ID,
104
            $validUntil,
105
            $cacheDuration,
106
            $extensions,
107
            $errorURL,
108
            $keyDescriptor,
109
            $organization,
110
            $contact,
111
            $artifactResolutionService,
112
            $singleLogoutService,
113
            $manageNameIDService,
114
            $nameIDFormat,
115
        );
116
    }
117
118
119
    /**
120
     * Collect the value of the WantAuthnRequestsSigned-property
121
     *
122
     * @return \SimpleSAML\XML\Type\BooleanValue|null
123
     */
124
    public function wantAuthnRequestsSigned(): ?BooleanValue
125
    {
126
        return $this->wantAuthnRequestsSigned;
127
    }
128
129
130
    /**
131
     * Get the SingleSignOnService endpoints
132
     *
133
     * @return \SimpleSAML\SAML2\XML\md\SingleSignOnService[]
134
     */
135
    public function getSingleSignOnService(): array
136
    {
137
        return $this->singleSignOnService;
138
    }
139
140
141
    /**
142
     * Get the NameIDMappingService endpoints
143
     *
144
     * @return \SimpleSAML\SAML2\XML\md\NameIDMappingService[]
145
     */
146
    public function getNameIDMappingService(): array
147
    {
148
        return $this->nameIDMappingService;
149
    }
150
151
152
    /**
153
     * Collect the AssertionIDRequestService endpoints
154
     *
155
     * @return \SimpleSAML\SAML2\XML\md\AssertionIDRequestService[]
156
     */
157
    public function getAssertionIDRequestService(): array
158
    {
159
        return $this->assertionIDRequestService;
160
    }
161
162
163
    /**
164
     * Get the attribute profiles supported
165
     *
166
     * @return \SimpleSAML\SAML2\XML\md\AttributeProfile[]
167
     */
168
    public function getAttributeProfile(): array
169
    {
170
        return $this->attributeProfile;
171
    }
172
173
174
    /**
175
     * Get the attributes supported by this IdP
176
     *
177
     * @return \SimpleSAML\SAML2\XML\saml\Attribute[]
178
     */
179
    public function getSupportedAttribute(): array
180
    {
181
        return $this->attribute;
182
    }
183
184
185
    /**
186
     * Initialize an IDPSSODescriptor.
187
     *
188
     * @param \DOMElement $xml The XML element we should load.
189
     * @return static
190
     *
191
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
192
     *   if the qualified name of the supplied element is wrong
193
     * @throws \SimpleSAML\XML\Exception\MissingElementException
194
     *   if one of the mandatory child-elements is missing
195
     * @throws \SimpleSAML\XML\Exception\TooManyElementsException
196
     *   if too many child-elements of a type are specified
197
     */
198
    public static function fromXML(DOMElement $xml): static
199
    {
200
        Assert::same($xml->localName, 'IDPSSODescriptor', InvalidDOMElementException::class);
201
        Assert::same($xml->namespaceURI, IDPSSODescriptor::NS, InvalidDOMElementException::class);
202
203
        $protocols = self::getAttribute($xml, 'protocolSupportEnumeration');
204
205
        $orgs = Organization::getChildrenOfClass($xml);
206
        Assert::maxCount(
207
            $orgs,
208
            1,
209
            'More than one Organization found in this descriptor',
210
            TooManyElementsException::class,
211
        );
212
213
        $extensions = Extensions::getChildrenOfClass($xml);
214
        Assert::maxCount(
215
            $extensions,
216
            1,
217
            'Only one md:Extensions element is allowed.',
218
            TooManyElementsException::class,
219
        );
220
221
        $signature = Signature::getChildrenOfClass($xml);
222
        Assert::maxCount(
223
            $signature,
224
            1,
225
            'Only one ds:Signature element is allowed.',
226
            TooManyElementsException::class,
227
        );
228
229
        $idpssod = new static(
230
            SingleSignOnService::getChildrenOfClass($xml),
231
            preg_split('/[\s]+/', trim($protocols->getValue())),
232
            self::getOptionalAttribute($xml, 'WantAuthnRequestsSigned', BooleanValue::class, null),
233
            NameIDMappingService::getChildrenOfClass($xml),
234
            AssertionIDRequestService::getChildrenOfClass($xml),
235
            AttributeProfile::getChildrenOfClass($xml),
236
            Attribute::getChildrenOfClass($xml),
237
            self::getOptionalAttribute($xml, 'ID', IDValue::class, null),
238
            self::getOptionalAttribute($xml, 'validUntil', SAMLDateTimeValue::class, null),
239
            self::getOptionalAttribute($xml, 'cacheDuration', DurationValue::class, null),
240
            !empty($extensions) ? $extensions[0] : null,
241
            self::getOptionalAttribute($xml, 'errorURL', SAMLAnyURIValue::class, null),
242
            KeyDescriptor::getChildrenOfClass($xml),
243
            !empty($orgs) ? $orgs[0] : null,
244
            ContactPerson::getChildrenOfClass($xml),
245
            ArtifactResolutionService::getChildrenOfClass($xml),
246
            SingleLogoutService::getChildrenOfClass($xml),
247
            ManageNameIDService::getChildrenOfClass($xml),
248
            NameIDFormat::getChildrenOfClass($xml),
249
        );
250
251
        if (!empty($signature)) {
252
            $idpssod->setSignature($signature[0]);
253
            $idpssod->setXML($xml);
254
        }
255
        return $idpssod;
256
    }
257
258
259
    /**
260
     * Convert this assertion to an unsigned XML document.
261
     * This method does not sign the resulting XML document.
262
     *
263
     * @return \DOMElement The root element of the DOM tree
264
     */
265
    public function toUnsignedXML(?DOMElement $parent = null): DOMElement
266
    {
267
        $e = parent::toUnsignedXML($parent);
268
269
        if ($this->wantAuthnRequestsSigned() !== null) {
270
            $e->setAttribute(
271
                'WantAuthnRequestsSigned',
272
                var_export($this->wantAuthnRequestsSigned()->toBoolean(), true),
273
            );
274
        }
275
276
        foreach ($this->getSingleSignOnService() as $ep) {
277
            $ep->toXML($e);
278
        }
279
280
        foreach ($this->getNameIDMappingService() as $ep) {
281
            $ep->toXML($e);
282
        }
283
284
        foreach ($this->getAssertionIDRequestService() as $ep) {
285
            $ep->toXML($e);
286
        }
287
288
        foreach ($this->getAttributeProfile() as $ap) {
289
            $ap->toXML($e);
290
        }
291
292
        foreach ($this->getSupportedAttribute() as $a) {
293
            $a->toXML($e);
294
        }
295
296
        return $e;
297
    }
298
}
299