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

AbstractRoleDescriptor   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 52
dl 0
loc 136
rs 10
c 0
b 0
f 0
wmc 4

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 24 1
A getXsiType() 0 3 1
A fromXML() 0 55 2
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\Constants as C;
10
use SimpleSAML\SAML2\Type\AnyURIListValue;
11
use SimpleSAML\SAML2\Type\SAMLAnyURIValue;
12
use SimpleSAML\SAML2\Type\SAMLDateTimeValue;
13
use SimpleSAML\SAML2\Utils;
14
use SimpleSAML\SAML2\XML\ExtensionPointInterface;
15
use SimpleSAML\SAML2\XML\ExtensionPointTrait;
16
use SimpleSAML\XML\Chunk;
17
use SimpleSAML\XML\SchemaValidatableElementInterface;
18
use SimpleSAML\XML\SchemaValidatableElementTrait;
19
use SimpleSAML\XMLSchema\Constants as C_XSI;
20
use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException;
21
use SimpleSAML\XMLSchema\Exception\SchemaViolationException;
22
use SimpleSAML\XMLSchema\Exception\TooManyElementsException;
23
use SimpleSAML\XMLSchema\Type\DurationValue;
24
use SimpleSAML\XMLSchema\Type\IDValue;
25
use SimpleSAML\XMLSchema\Type\QNameValue;
26
27
use function array_pop;
28
29
/**
30
 * Class representing a SAML2 RoleDescriptor element.
31
 *
32
 * @package simplesamlphp/saml2
33
 */
34
abstract class AbstractRoleDescriptor extends AbstractRoleDescriptorType implements
35
    ExtensionPointInterface,
36
    SchemaValidatableElementInterface
37
{
38
    use ExtensionPointTrait;
39
    use SchemaValidatableElementTrait;
40
41
42
    /** @var string */
43
    public const LOCALNAME = 'RoleDescriptor';
44
45
46
    /**
47
     * Initialize a md:RoleDescriptor from scratch.
48
     *
49
     * @param \SimpleSAML\XMLSchema\Type\QNameValue $type
50
     * @param \SimpleSAML\SAML2\Type\AnyURIListValue $protocolSupportEnumeration
51
     *   A set of URI specifying the protocols supported.
52
     * @param \SimpleSAML\XMLSchema\Type\IDValue|null $ID The ID for this document. Defaults to null.
53
     * @param \SimpleSAML\SAML2\Type\SAMLDateTimeValue|null $validUntil Unix time of validity for this document.
54
     *   Defaults to null.
55
     * @param \SimpleSAML\XMLSchema\Type\DurationValue|null $cacheDuration Maximum time this document can be cached.
56
     *   Defaults to null.
57
     * @param \SimpleSAML\SAML2\XML\md\Extensions|null $extensions An Extensions object. Defaults to null.
58
     * @param \SimpleSAML\SAML2\Type\SAMLAnyURIValue|null $errorURL An URI where to redirect users for support.
59
     *   Defaults to null.
60
     * @param \SimpleSAML\SAML2\XML\md\KeyDescriptor[] $keyDescriptor
61
     *   An array of KeyDescriptor elements. Defaults to an empty array.
62
     * @param \SimpleSAML\SAML2\XML\md\Organization|null $organization
63
     *   The organization running this entity. Defaults to null.
64
     * @param \SimpleSAML\SAML2\XML\md\ContactPerson[] $contactPerson
65
     *   An array of contacts for this entity. Defaults to an empty array.
66
     * @param list<\SimpleSAML\XML\Attribute> $namespacedAttributes
0 ignored issues
show
Bug introduced by
The type SimpleSAML\SAML2\XML\md\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
67
     */
68
    public function __construct(
69
        protected QNameValue $type,
70
        AnyURIListValue $protocolSupportEnumeration,
71
        ?IDValue $ID = null,
72
        ?SAMLDateTimeValue $validUntil = null,
73
        ?DurationValue $cacheDuration = null,
74
        ?Extensions $extensions = null,
75
        ?SAMLAnyURIValue $errorURL = null,
76
        array $keyDescriptor = [],
77
        ?Organization $organization = null,
78
        array $contactPerson = [],
79
        array $namespacedAttributes = [],
80
    ) {
81
        parent::__construct(
82
            $protocolSupportEnumeration,
83
            $ID,
84
            $validUntil,
85
            $cacheDuration,
86
            $extensions,
87
            $errorURL,
88
            $keyDescriptor,
89
            $organization,
90
            $contactPerson,
91
            $namespacedAttributes,
92
        );
93
    }
94
95
96
    /**
97
     * Return the xsi:type value corresponding this element.
98
     *
99
     * @return \SimpleSAML\XMLSchema\Type\QNameValue
100
     */
101
    public function getXsiType(): QNameValue
102
    {
103
        return $this->type;
104
    }
105
106
107
    /**
108
     * Convert XML into an RoleDescriptor
109
     * @param \DOMElement $xml The XML element we should load
110
     * @return static
111
     *
112
     * @throws \SimpleSAML\XMLSchema\Exception\InvalidDOMElementException
113
     *   if the qualified name of the supplied element is wrong
114
     */
115
    public static function fromXML(DOMElement $xml): static
116
    {
117
        Assert::same($xml->localName, 'RoleDescriptor', InvalidDOMElementException::class);
118
        Assert::same($xml->namespaceURI, C::NS_MD, InvalidDOMElementException::class);
119
        Assert::true(
120
            $xml->hasAttributeNS(C_XSI::NS_XSI, 'type'),
121
            'Missing required xsi:type in <md:RoleDescriptor> element.',
122
            SchemaViolationException::class,
123
        );
124
125
        $type = QNameValue::fromDocument($xml->getAttributeNS(C_XSI::NS_XSI, 'type'), $xml);
126
127
        // now check if we have a handler registered for it
128
        $handler = Utils::getContainer()->getExtensionHandler($type);
129
        if ($handler === null) {
130
            // we don't have a handler, proceed with unknown RoleDescriptor
131
            $orgs = Organization::getChildrenOfClass($xml);
132
            Assert::maxCount(
133
                $orgs,
134
                1,
135
                'More than one Organization found in this descriptor',
136
                TooManyElementsException::class,
137
            );
138
139
            $extensions = Extensions::getChildrenOfClass($xml);
140
            Assert::maxCount(
141
                $extensions,
142
                1,
143
                'Only one md:Extensions element is allowed.',
144
                TooManyElementsException::class,
145
            );
146
147
            return new UnknownRoleDescriptor(
148
                new Chunk($xml),
149
                $type,
150
                self::getAttribute($xml, 'protocolSupportEnumeration', AnyURIListValue::class),
151
                self::getOptionalAttribute($xml, 'ID', IDValue::class, null),
152
                self::getOptionalAttribute($xml, 'validUntil', SAMLDateTimeValue::class, null),
153
                self::getOptionalAttribute($xml, 'cacheDuration', DurationValue::class, null),
154
                array_pop($extensions),
155
                self::getOptionalAttribute($xml, 'errorURL', SAMLAnyURIValue::class, null),
156
                KeyDescriptor::getChildrenOfClass($xml),
157
                array_pop($orgs),
158
                ContactPerson::getChildrenOfClass($xml),
159
                self::getAttributesNSFromXML($xml),
160
            );
161
        }
162
163
        Assert::subclassOf(
164
            $handler,
165
            AbstractRoleDescriptor::class,
166
            'Elements implementing RoleDescriptor must extend \SimpleSAML\SAML2\XML\saml\AbstractRoleDescriptor.',
167
        );
168
169
        return $handler::fromXML($xml);
170
    }
171
}
172