Passed
Push — master ( 6db269...70aff8 )
by Jaime Pérez
02:49
created

EntityDescriptor::__construct()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 26
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 10
c 1
b 0
f 0
nc 2
nop 10
dl 0
loc 26
rs 9.9332

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace SAML2\XML\md;
6
7
use DOMElement;
8
use SAML2\Constants;
9
use SAML2\Utils;
10
use SAML2\XML\ds\Signature;
11
use Webmozart\Assert\Assert;
12
13
/**
14
 * Class representing SAML 2 EntityDescriptor element.
15
 *
16
 * @package simplesamlphp/saml2
17
 */
18
final class EntityDescriptor extends AbstractMetadataDocument
19
{
20
    /**
21
     * The entityID this EntityDescriptor represents.
22
     *
23
     * @var string
24
     */
25
    protected $entityID;
26
27
    /**
28
     * Array with all roles for this entity.
29
     *
30
     * Array of \SAML2\XML\md\RoleDescriptor objects (and subclasses of RoleDescriptor).
31
     *
32
     * @var \SAML2\XML\md\AbstractRoleDescriptor[]
33
     */
34
    protected $RoleDescriptor = [];
35
36
    /**
37
     * AffiliationDescriptor of this entity.
38
     *
39
     * @var \SAML2\XML\md\AffiliationDescriptor|null
40
     */
41
    protected $AffiliationDescriptor = null;
42
43
    /**
44
     * Organization of this entity.
45
     *
46
     * @var \SAML2\XML\md\Organization|null
47
     */
48
    protected $Organization = null;
49
50
    /**
51
     * ContactPerson elements for this entity.
52
     *
53
     * @var \SAML2\XML\md\ContactPerson[]
54
     */
55
    protected $ContactPerson = [];
56
57
    /**
58
     * AdditionalMetadataLocation elements for this entity.
59
     *
60
     * @var \SAML2\XML\md\AdditionalMetadataLocation[]
61
     */
62
    protected $AdditionalMetadataLocation = [];
63
64
65
    /**
66
     * Initialize an EntitiyDescriptor.
67
     *
68
     * @param string $entityID The entityID of the entity described by this descriptor.
69
     * @param string|null $id The ID for this document. Defaults to null.
70
     * @param int|null $validUntil Unix time of validify for this document. Defaults to null.
71
     * @param string|null $cacheDuration Maximum time this document can be cached. Defaults to null.
72
     * @param \SAML2\XML\md\Extensions|null $extensions An array of extensions.
73
     * @param \SAML2\XML\md\AbstractRoleDescriptor[]|null $roleDescriptors An array of role descriptors.
74
     * @param \SAML2\XML\md\AffiliationDescriptor|null $affiliationDescriptor An affiliation descriptor to
75
     *   use instead of role descriptors.
76
     * @param \SAML2\XML\md\Organization|null $organization The organization responsible for the SAML entity.
77
     * @param \SAML2\XML\md\ContactPerson[] $contacts A list of contact persons for this SAML entity.
78
     * @param \SAML2\XML\md\AdditionalMetadataLocation[] $additionalMdLocations A list of
79
     *   additional metadata locations.
80
     *
81
     * @throws \Exception
82
     */
83
    public function __construct(
84
        string $entityID,
85
        ?string $id = null,
86
        ?int $validUntil = null,
87
        ?string $cacheDuration = null,
88
        Extensions $extensions = null,
89
        ?array $roleDescriptors = [],
90
        ?AffiliationDescriptor $affiliationDescriptor = null,
91
        ?Organization $organization = null,
92
        array $contacts = [],
93
        array $additionalMdLocations = []
94
    ) {
95
        if (empty($roleDescriptors) && $affiliationDescriptor === null) {
96
            throw new \InvalidArgumentException(
97
                'Must have either one of the RoleDescriptors or an AffiliationDescriptor in EntityDescriptor.'
98
            );
99
        }
100
101
        parent::__construct($id, $validUntil, $cacheDuration, $extensions);
102
103
        $this->setEntityID($entityID);
104
        $this->setRoleDescriptors($roleDescriptors);
105
        $this->setAffiliationDescriptor($affiliationDescriptor);
106
        $this->setOrganization($organization);
107
        $this->setContactPersons($contacts);
108
        $this->setAdditionalMetadataLocations($additionalMdLocations);
109
    }
110
111
112
    /**
113
     * Convert an existing XML into an EntityDescriptor object
114
     *
115
     * @param \DOMElement $xml An existing EntityDescriptor XML document.
116
     * @return \SAML2\XML\md\EntityDescriptor An object representing the given document.
117
     * @throws \InvalidArgumentException if the qualified name of the supplied element is wrong
118
     * @throws \Exception
119
     */
120
    public static function fromXML(DOMElement $xml): object
121
    {
122
        Assert::same($xml->localName, 'EntityDescriptor');
123
        Assert::same($xml->namespaceURI, EntityDescriptor::NS);
124
125
        $validUntil = self::getAttribute($xml, 'validUntil', null);
126
        $extensions = Extensions::getChildrenOfClass($xml);
127
        Assert::maxCount($extensions, 1, 'Only one md:Extensions element is allowed.');
128
129
        $signature = Signature::getChildrenOfClass($xml);
130
        Assert::maxCount($signature, 1, 'Only one ds:Signature element is allowed.');
131
132
        $roleDescriptors = [];
133
        $affiliationDescriptor = null;
134
        $organization = null;
135
        $contactPersons = [];
136
        $additionalMetadataLocation = [];
137
        foreach ($xml->childNodes as $node) {
138
            if (!($node instanceof DOMElement)) {
139
                continue;
140
            } elseif ($node->namespaceURI !== Constants::NS_MD) {
141
                continue;
142
            }
143
144
            switch ($node->localName) {
145
                case 'Extensions':
146
                    continue 2;
147
                case 'IDPSSODescriptor':
148
                    $roleDescriptors[] = IDPSSODescriptor::fromXML($node);
149
                    break;
150
                case 'SPSSODescriptor':
151
                    $roleDescriptors[] = SPSSODescriptor::fromXML($node);
152
                    break;
153
                case 'AuthnAuthorityDescriptor':
154
                    $roleDescriptors[] = AuthnAuthorityDescriptor::fromXML($node);
155
                    break;
156
                case 'AttributeAuthorityDescriptor':
157
                    $roleDescriptors[] = AttributeAuthorityDescriptor::fromXML($node);
158
                    break;
159
                case 'PDPDescriptor':
160
                    $roleDescriptors[] = PDPDescriptor::fromXML($node);
161
                    break;
162
                case 'AffiliationDescriptor':
163
                    if ($affiliationDescriptor !== null) {
164
                        throw new \InvalidArgumentException('More than one AffiliationDescriptor in the entity.');
165
                    }
166
                    $affiliationDescriptor = AffiliationDescriptor::fromXML($node);
167
                    break;
168
                case 'Organization':
169
                    if ($organization !== null) {
170
                        throw new \InvalidArgumentException('More than one Organization in the entity.');
171
                    }
172
                    $organization = Organization::fromXML($node);
173
                    break;
174
                case 'ContactPerson':
175
                    $contactPersons[] = ContactPerson::fromXML($node);
176
                    break;
177
                case 'AdditionalMetadataLocation':
178
                    $additionalMetadataLocation[] = AdditionalMetadataLocation::fromXML($node);
179
                    break;
180
                default:
181
                    $roleDescriptors[] = UnknownRoleDescriptor::fromXML($node);
182
            }
183
        }
184
185
        if (empty($roleDescriptors) && is_null($affiliationDescriptor)) {
186
            throw new \InvalidArgumentException(
187
                'Must have either one of the RoleDescriptors or an AffiliationDescriptor in EntityDescriptor.'
188
            );
189
        } elseif (!empty($roleDescriptors) && !is_null($affiliationDescriptor)) {
190
            throw new \InvalidArgumentException(
191
                'AffiliationDescriptor cannot be combined with other RoleDescriptor elements in EntityDescriptor.'
192
            );
193
        }
194
195
        $entity = new self(
196
            self::getAttribute($xml, 'entityID'),
197
            self::getAttribute($xml, 'ID', null),
198
            $validUntil !== null ? Utils::xsDateTimeToTimestamp($validUntil) : null,
199
            self::getAttribute($xml, 'cacheDuration', null),
200
            !empty($extensions) ? $extensions[0] : null,
201
            $roleDescriptors,
202
            $affiliationDescriptor,
203
            $organization,
204
            $contactPersons,
205
            $additionalMetadataLocation
206
        );
207
        if (!empty($signature)) {
208
            $entity->setSignature($signature[0]);
209
        }
210
        return $entity;
211
    }
212
213
214
    /**
215
     * Collect the value of the entityID property.
216
     *
217
     * @return string
218
     * @throws \InvalidArgumentException
219
     */
220
    public function getEntityID(): string
221
    {
222
        Assert::notEmpty($this->entityID);
223
224
        return $this->entityID;
225
    }
226
227
228
    /**
229
     * Set the value of the entityID-property
230
     * @param string $entityId
231
     * @return void
232
     */
233
    protected function setEntityID(string $entityId): void
234
    {
235
        Assert::notEmpty($entityId, 'The entityID attribute cannot be empty.');
236
        Assert::maxLength($entityId, 1024, 'The entityID attribute cannot be longer than 1024 characters.');
237
        $this->entityID = $entityId;
238
    }
239
240
241
    /**
242
     * Collect the value of the RoleDescriptor property.
243
     *
244
     * @return \SAML2\XML\md\AbstractRoleDescriptor[]
245
     */
246
    public function getRoleDescriptors(): array
247
    {
248
        return $this->RoleDescriptor;
249
    }
250
251
252
    /**
253
     * Set the value of the RoleDescriptor property.
254
     *
255
     * @param \SAML2\XML\md\AbstractRoleDescriptor[] $roleDescriptors
256
     * @return void
257
     */
258
    protected function setRoleDescriptors(array $roleDescriptors): void
259
    {
260
        Assert::allIsInstanceOf(
261
            $roleDescriptors,
262
            AbstractRoleDescriptor::class,
263
            'All role descriptors must extend AbstractRoleDescriptor.'
264
        );
265
        $this->RoleDescriptor = $roleDescriptors;
266
    }
267
268
269
    /**
270
     * Collect the value of the AffiliationDescriptor property.
271
     *
272
     * @return \SAML2\XML\md\AffiliationDescriptor|null
273
     */
274
    public function getAffiliationDescriptor(): ?AffiliationDescriptor
275
    {
276
        return $this->AffiliationDescriptor;
277
    }
278
279
280
    /**
281
     * Set the value of the AffliationDescriptor property.
282
     *
283
     * @param \SAML2\XML\md\AffiliationDescriptor|null $affiliationDescriptor
284
     * @return void
285
     */
286
    protected function setAffiliationDescriptor(?AffiliationDescriptor $affiliationDescriptor = null): void
287
    {
288
        $this->AffiliationDescriptor = $affiliationDescriptor;
289
    }
290
291
292
    /**
293
     * Collect the value of the Organization property.
294
     *
295
     * @return \SAML2\XML\md\Organization|null
296
     */
297
    public function getOrganization(): ?Organization
298
    {
299
        return $this->Organization;
300
    }
301
302
303
    /**
304
     * Set the value of the Organization property.
305
     *
306
     * @param \SAML2\XML\md\Organization|null $organization
307
     * @return void
308
     */
309
    protected function setOrganization(?Organization $organization = null): void
310
    {
311
        $this->Organization = $organization;
312
    }
313
314
315
    /**
316
     * Collect the value of the ContactPerson property.
317
     *
318
     * @return \SAML2\XML\md\ContactPerson[]
319
     */
320
    public function getContactPersons(): array
321
    {
322
        return $this->ContactPerson;
323
    }
324
325
326
    /**
327
     * Set the value of the ContactPerson property.
328
     *
329
     * @param array $contactPerson
330
     * @return void
331
     */
332
    protected function setContactPersons(array $contactPerson): void
333
    {
334
        Assert::allIsInstanceOf(
335
            $contactPerson,
336
            ContactPerson::class,
337
            'All md:ContactPerson elements must be an instance of ContactPerson.'
338
        );
339
        $this->ContactPerson = $contactPerson;
340
    }
341
342
343
    /**
344
     * Collect the value of the AdditionalMetadataLocation property.
345
     *
346
     * @return \SAML2\XML\md\AdditionalMetadataLocation[]
347
     */
348
    public function getAdditionalMetadataLocations(): array
349
    {
350
        return $this->AdditionalMetadataLocation;
351
    }
352
353
354
    /**
355
     * Set the value of the AdditionalMetadataLocation property.
356
     *
357
     * @param array $additionalMetadataLocation
358
     * @return void
359
     */
360
    protected function setAdditionalMetadataLocations(array $additionalMetadataLocation): void
361
    {
362
        Assert::allIsInstanceOf(
363
            $additionalMetadataLocation,
364
            AdditionalMetadataLocation::class,
365
            'All md:AdditionalMetadataLocation elements must be an instance of AdditionalMetadataLocation'
366
        );
367
        $this->AdditionalMetadataLocation = $additionalMetadataLocation;
368
    }
369
370
371
    /**
372
     * Create this EntityDescriptor.
373
     *
374
     * @param \DOMElement|null $parent The EntitiesDescriptor we should append this EntityDescriptor to.
375
     * @return \DOMElement
376
     * @throws \Exception
377
     */
378
    public function toXML(DOMElement $parent = null): DOMElement
379
    {
380
        $e = parent::toXML($parent);
381
        $e->setAttribute('entityID', $this->entityID);
382
383
        foreach ($this->RoleDescriptor as $n) {
384
            $n->toXML($e);
385
        }
386
387
        if ($this->AffiliationDescriptor !== null) {
388
            $this->AffiliationDescriptor->toXML($e);
389
        }
390
391
        if ($this->Organization !== null) {
392
            $this->Organization->toXML($e);
393
        }
394
395
        foreach ($this->ContactPerson as $cp) {
396
            $cp->toXML($e);
397
        }
398
399
        foreach ($this->AdditionalMetadataLocation as $n) {
400
            $n->toXML($e);
401
        }
402
403
        return $this->signElement($e);
404
    }
405
}
406