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

IDPSSODescriptor::fromXML()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 56
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 41
nc 2
nop 1
dl 0
loc 56
rs 9.264
c 0
b 0
f 0

How to fix   Long Method   

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:

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