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

AffiliationDescriptor::toUnsignedXML()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 15
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML2\XML\md;
6
7
use DOMElement;
8
use Exception;
9
use SimpleSAML\Assert\Assert;
10
use SimpleSAML\SAML2\Constants as C;
11
use SimpleSAML\XML\Exception\InvalidDOMElementException;
12
use SimpleSAML\XML\Exception\TooManyElementsException;
13
use SimpleSAML\XML\Utils as XMLUtils;
14
use SimpleSAML\XMLSecurity\XML\ds\Signature;
15
16
/**
17
 * Class representing SAML 2 AffiliationDescriptor element.
18
 *
19
 * @package simplesamlphp/saml2
20
 */
21
final class AffiliationDescriptor extends AbstractMetadataDocument
22
{
23
    /**
24
     * The affiliationOwnerID.
25
     *
26
     * @var string
27
     */
28
    public string $affiliationOwnerID;
29
30
    /**
31
     * The AffiliateMember(s).
32
     *
33
     * Array of \SimpleSAML\SAML2\XML\md\AffiliateMember elements.
34
     *
35
     * @var \SimpleSAML\SAML2\XML\md\AffiliateMember[]
36
     */
37
    protected array $AffiliateMembers = [];
38
39
    /**
40
     * KeyDescriptor elements.
41
     *
42
     * Array of \SimpleSAML\SAML2\XML\md\KeyDescriptor elements.
43
     *
44
     * @var \SimpleSAML\SAML2\XML\md\KeyDescriptor[]
45
     */
46
    protected array $KeyDescriptors = [];
47
48
49
    /**
50
     * Generic constructor for SAML metadata documents.
51
     *
52
     * @param string $ownerID The ID of the owner of this affiliation.
53
     * @param \SimpleSAML\SAML2\XML\md\AffiliateMember[] $members A non-empty array of members of this affiliation.
54
     * @param string|null $ID The ID for this document. Defaults to null.
55
     * @param int|null $validUntil Unix time of validity for this document. Defaults to null.
56
     * @param string|null $cacheDuration Maximum time this document can be cached. Defaults to null.
57
     * @param \SimpleSAML\SAML2\XML\md\Extensions|null $extensions An array of extensions. Defaults to an empty array.
58
     * @param \SimpleSAML\SAML2\XML\md\KeyDescriptor[] $keyDescriptors An optional array of KeyDescriptors. Defaults to an empty array.
59
     * @param \DOMAttr[] $namespacedAttributes
60
     */
61
    public function __construct(
62
        string $ownerID,
63
        array $members,
64
        ?string $ID = null,
65
        ?int $validUntil = null,
66
        ?string $cacheDuration = null,
67
        ?Extensions $extensions = null,
68
        array $keyDescriptors = [],
69
        array $namespacedAttributes = []
70
    ) {
71
        parent::__construct($ID, $validUntil, $cacheDuration, $extensions, $namespacedAttributes);
72
73
        $this->setAffiliationOwnerID($ownerID);
74
        $this->setAffiliateMembers($members);
75
        $this->setKeyDescriptors($keyDescriptors);
76
    }
77
78
79
    /**
80
     * Initialize a AffiliationDescriptor.
81
     *
82
     * @param \DOMElement $xml The XML element we should load.
83
     * @return \SimpleSAML\SAML2\XML\md\AffiliationDescriptor
84
     *
85
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException if the qualified name of the supplied element is wrong
86
     * @throws \SimpleSAML\XML\Exception\MissingAttributeException if the supplied element is missing one of the mandatory attributes
87
     * @throws \SimpleSAML\XML\Exception\TooManyElementsException if too many child-elements of a type are specified
88
     */
89
    public static function fromXML(DOMElement $xml): object
90
    {
91
        Assert::same($xml->localName, 'AffiliationDescriptor', InvalidDOMElementException::class);
92
        Assert::same($xml->namespaceURI, AffiliationDescriptor::NS, InvalidDOMElementException::class);
93
94
        $owner = self::getAttribute($xml, 'affiliationOwnerID');
95
        $members = AffiliateMember::getChildrenOfClass($xml);
96
        $keyDescriptors = KeyDescriptor::getChildrenOfClass($xml);
97
98
        $validUntil = self::getAttribute($xml, 'validUntil', null);
99
        $orgs = Organization::getChildrenOfClass($xml);
100
        Assert::maxCount($orgs, 1, 'More than one Organization found in this descriptor', TooManyElementsException::class);
101
102
        $extensions = Extensions::getChildrenOfClass($xml);
103
        Assert::maxCount($extensions, 1, 'Only one md:Extensions element is allowed.', TooManyElementsException::class);
104
105
        $signature = Signature::getChildrenOfClass($xml);
106
        Assert::maxCount($signature, 1, 'Only one ds:Signature element is allowed.', TooManyElementsException::class);
107
108
        $afd = new self(
109
            $owner,
110
            $members,
111
            self::getAttribute($xml, 'ID', null),
112
            $validUntil !== null ? XMLUtils::xsDateTimeToTimestamp($validUntil) : null,
113
            self::getAttribute($xml, 'cacheDuration', null),
114
            !empty($extensions) ? $extensions[0] : null,
115
            $keyDescriptors,
116
            self::getAttributesNSFromXML($xml)
117
        );
118
119
        if (!empty($signature)) {
120
            $afd->setSignature($signature[0]);
121
        }
122
123
        $afd->setXML($xml);
124
125
        return $afd;
126
    }
127
128
129
    /**
130
     * Collect the value of the affiliationOwnerId-property
131
     *
132
     * @return string
133
     */
134
    public function getAffiliationOwnerID(): string
135
    {
136
        return $this->affiliationOwnerID;
137
    }
138
139
140
    /**
141
     * Set the value of the affiliationOwnerId-property
142
     *
143
     * @param string $affiliationOwnerId
144
     * @throws \SimpleSAML\Assert\AssertionFailedException
145
     */
146
    protected function setAffiliationOwnerID(string $affiliationOwnerId): void
147
    {
148
        Assert::notWhitespaceOnly($affiliationOwnerId, 'AffiliationOwnerID must not be empty.');
149
        Assert::maxLength(
150
            $affiliationOwnerId,
151
            C::ENTITYID_MAX_LENGTH,
152
            sprintf('The AffiliationOwnerID attribute cannot be longer than %d characters.', C::ENTITYID_MAX_LENGTH)
153
        );
154
        $this->affiliationOwnerID = $affiliationOwnerId;
155
    }
156
157
158
    /**
159
     * Collect the value of the AffiliateMember-property
160
     *
161
     * @return \SimpleSAML\SAML2\XML\md\AffiliateMember[]
162
     */
163
    public function getAffiliateMembers(): array
164
    {
165
        return $this->AffiliateMembers;
166
    }
167
168
169
    /**
170
     * Set the value of the AffiliateMember-property
171
     *
172
     * @param \SimpleSAML\SAML2\XML\md\AffiliateMember[] $affiliateMembers
173
     * @throws \SimpleSAML\Assert\AssertionFailedException
174
     */
175
    protected function setAffiliateMembers(array $affiliateMembers): void
176
    {
177
        Assert::notEmpty(
178
            $affiliateMembers,
179
            'List of affiliated members must not be empty.',
180
        );
181
        Assert::allIsInstanceOf(
182
            $affiliateMembers,
183
            AffiliateMember::class,
184
        );
185
        $this->AffiliateMembers = $affiliateMembers;
186
    }
187
188
189
    /**
190
     * Collect the value of the KeyDescriptor-property
191
     *
192
     * @return \SimpleSAML\SAML2\XML\md\KeyDescriptor[]
193
     */
194
    public function getKeyDescriptors(): array
195
    {
196
        return $this->KeyDescriptors;
197
    }
198
199
200
    /**
201
     * Set the value of the KeyDescriptor-property
202
     *
203
     * @param \SimpleSAML\SAML2\XML\md\KeyDescriptor[] $keyDescriptors
204
     */
205
    protected function setKeyDescriptors(array $keyDescriptors): void
206
    {
207
        Assert::allIsInstanceOf(
208
            $keyDescriptors,
209
            KeyDescriptor::class,
210
        );
211
        $this->KeyDescriptors = $keyDescriptors;
212
    }
213
214
215
    /**
216
     * Convert this descriptor to an unsigned XML document.
217
     * This method does not sign the resulting XML document.
218
     *
219
     * @param \DOMElement|null $parent
220
     * @return \DOMElement The root element of the DOM tree
221
     */
222
    protected function toUnsignedXML(?DOMElement $parent = null): DOMElement
223
    {
224
        $e = parent::toUnsignedXML($parent);
225
226
        $e->setAttribute('affiliationOwnerID', $this->affiliationOwnerID);
227
228
        foreach ($this->AffiliateMembers as $am) {
229
            $am->toXML($e);
230
        }
231
232
        foreach ($this->KeyDescriptors as $kd) {
233
            $kd->toXML($e);
234
        }
235
236
        return $e;
237
    }
238
}
239