Passed
Push — master ( 0af655...b179bb )
by Tim
02:15
created

AuthnAuthorityDescriptor::setAuthnQueryServices()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 1
dl 0
loc 9
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\Assert\Assert;
9
use SimpleSAML\XML\Exception\InvalidDOMElementException;
10
use SimpleSAML\XML\Exception\TooManyElementsException;
11
use SimpleSAML\XML\Utils as XMLUtils;
12
use SimpleSAML\XMLSecurity\XML\ds\Signature;
13
14
use function preg_split;
15
16
/**
17
 * Class representing SAML 2 metadata AuthnAuthorityDescriptor.
18
 *
19
 * @package simplesamlphp/saml2
20
 */
21
final class AuthnAuthorityDescriptor extends AbstractRoleDescriptor
22
{
23
    /**
24
     * List of AuthnQueryService endpoints.
25
     *
26
     * @var \SimpleSAML\SAML2\XML\md\AbstractEndpointType[]
27
     */
28
    protected array $AuthnQueryServices = [];
29
30
    /**
31
     * List of AssertionIDRequestService endpoints.
32
     *
33
     * @var \SimpleSAML\SAML2\XML\md\AbstractEndpointType[]
34
     */
35
    protected array $AssertionIDRequestServices = [];
36
37
    /**
38
     * List of supported NameID formats.
39
     *
40
     * Array of strings.
41
     *
42
     * @var \SimpleSAML\SAML2\XML\md\NameIDFormat[]
43
     */
44
    protected array $NameIDFormats = [];
45
46
47
    /**
48
     * AuthnAuthorityDescriptor constructor.
49
     *
50
     * @param array $authnQueryServices
51
     * @param array $protocolSupportEnumeration
52
     * @param array $assertionIDRequestServices
53
     * @param array $nameIDFormats
54
     * @param string|null $ID
55
     * @param int|null $validUntil
56
     * @param string|null $cacheDuration
57
     * @param \SimpleSAML\SAML2\XML\md\Extensions|null $extensions
58
     * @param string|null $errorURL
59
     * @param \SimpleSAML\SAML2\XML\md\Organization|null $organization
60
     * @param array $keyDescriptors
61
     * @param array $contacts
62
     */
63
    public function __construct(
64
        array $authnQueryServices,
65
        array $protocolSupportEnumeration,
66
        array $assertionIDRequestServices = [],
67
        array $nameIDFormats = [],
68
        string $ID = null,
69
        ?int $validUntil = null,
70
        ?string $cacheDuration = null,
71
        ?Extensions $extensions = null,
72
        ?string $errorURL = null,
73
        ?Organization $organization = null,
74
        array $keyDescriptors = [],
75
        array $contacts = []
76
    ) {
77
        parent::__construct(
78
            $protocolSupportEnumeration,
79
            $ID,
80
            $validUntil,
81
            $cacheDuration,
82
            $extensions,
83
            $errorURL,
84
            $keyDescriptors,
85
            $organization,
86
            $contacts
87
        );
88
        $this->setAuthnQueryServices($authnQueryServices);
89
        $this->setAssertionIDRequestService($assertionIDRequestServices);
90
        $this->setNameIDFormat($nameIDFormats);
91
    }
92
93
94
    /**
95
     * Collect the AuthnQueryService endpoints
96
     *
97
     * @return \SimpleSAML\SAML2\XML\md\AbstractEndpointType[]
98
     */
99
    public function getAuthnQueryServices(): array
100
    {
101
        return $this->AuthnQueryServices;
102
    }
103
104
105
    /**
106
     * Set the AuthnQueryService endpoints
107
     *
108
     * @param \SimpleSAML\SAML2\XML\md\AbstractEndpointType[] $authnQueryServices
109
     * @throws \SimpleSAML\Assert\AssertionFailedException
110
     */
111
    protected function setAuthnQueryServices(array $authnQueryServices): void
112
    {
113
        Assert::minCount($authnQueryServices, 1, 'Missing at least one AuthnQueryService in AuthnAuthorityDescriptor.');
114
        Assert::allIsInstanceOf(
115
            $authnQueryServices,
116
            AbstractEndpointType::class,
117
            'AuthnQueryService must be an instance of EndpointType'
118
        );
119
        $this->AuthnQueryServices = $authnQueryServices;
120
    }
121
122
123
    /**
124
     * Collect the AssertionIDRequestService endpoints
125
     *
126
     * @return \SimpleSAML\SAML2\XML\md\AbstractEndpointType[]
127
     */
128
    public function getAssertionIDRequestServices(): array
129
    {
130
        return $this->AssertionIDRequestServices;
131
    }
132
133
134
    /**
135
     * Set the AssertionIDRequestService endpoints
136
     *
137
     * @param \SimpleSAML\SAML2\XML\md\AbstractEndpointType[] $assertionIDRequestServices
138
     * @throws \SimpleSAML\Assert\AssertionFailedException
139
     */
140
    protected function setAssertionIDRequestService(array $assertionIDRequestServices = []): void
141
    {
142
        Assert::allIsInstanceOf(
143
            $assertionIDRequestServices,
144
            AbstractEndpointType::class,
145
            'AssertionIDRequestServices must be an instance of EndpointType'
146
        );
147
        $this->AssertionIDRequestServices = $assertionIDRequestServices;
148
    }
149
150
151
    /**
152
     * Collect the values of the NameIDFormat
153
     *
154
     * @return \SimpleSAML\SAML2\XML\md\NameIDFormat[]
155
     */
156
    public function getNameIDFormats(): array
157
    {
158
        return $this->NameIDFormats;
159
    }
160
161
162
    /**
163
     * Set the values of the NameIDFormat
164
     *
165
     * @param \SimpleSAML\SAML2\XML\md\NameIDFormat[] $nameIDFormats
166
     * @throws \SimpleSAML\Assert\AssertionFailedException
167
     */
168
    protected function setNameIDFormat(array $nameIDFormats): void
169
    {
170
        Assert::allIsInstanceOf($nameIDFormats, NameIDFormat::class);
171
        $this->NameIDFormats = $nameIDFormats;
172
    }
173
174
175
    /**
176
     * Initialize an IDPSSODescriptor from an existing XML document.
177
     *
178
     * @param \DOMElement $xml The XML element we should load.
179
     * @return self
180
     *
181
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException if the qualified name of the supplied element is wrong
182
     * @throws \SimpleSAML\XML\Exception\MissingAttributeException if the supplied element is missing one of the mandatory attributes
183
     * @throws \SimpleSAML\XML\Exception\TooManyElementsException if too many child-elements of a type are specified
184
     */
185
    public static function fromXML(DOMElement $xml): static
186
    {
187
        Assert::same($xml->localName, 'AuthnAuthorityDescriptor', InvalidDOMElementException::class);
188
        Assert::same($xml->namespaceURI, AuthnAuthorityDescriptor::NS, InvalidDOMElementException::class);
189
190
        $protocols = self::getAttribute($xml, 'protocolSupportEnumeration');
191
192
        $authnQueryServices = AuthnQueryService::getChildrenOfClass($xml);
193
        $assertionIDRequestServices = AssertionIDRequestService::getChildrenOfClass($xml);
194
        $nameIDFormats = NameIDFormat::getChildrenOfClass($xml);
195
196
        $validUntil = self::getAttribute($xml, 'validUntil', null);
197
198
        $orgs = Organization::getChildrenOfClass($xml);
199
        Assert::maxCount($orgs, 1, 'More than one Organization found in this descriptor', TooManyElementsException::class);
200
201
        $extensions = Extensions::getChildrenOfClass($xml);
202
        Assert::maxCount($extensions, 1, 'Only one md:Extensions element is allowed.', TooManyElementsException::class);
203
204
        $signature = Signature::getChildrenOfClass($xml);
205
        Assert::maxCount($signature, 1, 'Only one ds:Signature element is allowed.', TooManyElementsException::class);
206
207
        $authority = new static(
208
            $authnQueryServices,
209
            preg_split('/[\s]+/', trim($protocols)),
210
            $assertionIDRequestServices,
211
            $nameIDFormats,
212
            self::getAttribute($xml, 'ID', null),
213
            $validUntil !== null ? XMLUtils::xsDateTimeToTimestamp($validUntil) : null,
214
            self::getAttribute($xml, 'cacheDuration', null),
215
            !empty($extensions) ? $extensions[0] : null,
216
            self::getAttribute($xml, 'errorURL', null),
217
            !empty($orgs) ? $orgs[0] : null,
218
            KeyDescriptor::getChildrenOfClass($xml),
219
            ContactPerson::getChildrenOfClass($xml)
220
        );
221
        if (!empty($signature)) {
222
            $authority->setSignature($signature[0]);
223
        }
224
        return $authority;
225
    }
226
227
228
    /**
229
     * Add this IDPSSODescriptor to an EntityDescriptor.
230
     *
231
     * @param \DOMElement|null $parent The EntityDescriptor we should append this AuthnAuthorityDescriptor to.
232
     *
233
     * @return \DOMElement
234
     * @throws \Exception
235
     */
236
    public function toUnsignedXML(?DOMElement $parent = null): DOMElement
237
    {
238
        $e = parent::toUnsignedXML($parent);
239
240
        foreach ($this->getAuthnQueryServices() as $ep) {
241
            $ep->toXML($e);
242
        }
243
244
        foreach ($this->getAssertionIDRequestServices() as $ep) {
245
            $ep->toXML($e);
246
        }
247
248
        foreach ($this->getNameIDFormats() as $nidFormat) {
249
            $nidFormat->toXML($e);
250
        }
251
252
        return $e;
253
    }
254
}
255