Passed
Pull Request — master (#280)
by Tim
02:41
created

PDPDescriptor::toXML()   A

Complexity

Conditions 5
Paths 16

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

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