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

IDPSSODescriptor::getAttributeProfile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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