Passed
Pull Request — master (#306)
by Tim
03:03
created

getProtocolSupportEnumeration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
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\SAML2\Compat\ContainerSingleton;
10
use SimpleSAML\SAML2\Constants as C;
11
use SimpleSAML\SAML2\Utils;
12
use SimpleSAML\SAML2\XML\ExtensionPointInterface;
13
use SimpleSAML\SAML2\XML\ExtensionPointTrait;
14
use SimpleSAML\XML\Chunk;
15
use SimpleSAML\XML\Exception\InvalidDOMElementException;
16
use SimpleSAML\XML\Exception\SchemaViolationException;
17
use SimpleSAML\XML\Exception\TooManyElementsException;
18
use SimpleSAML\XML\Utils as XMLUtils;
19
use SimpleSAML\XMLSecurity\Backend\EncryptionBackend;
20
use SimpleSAML\XMLSecurity\XML\EncryptableElementInterface;
21
use SimpleSAML\XMLSecurity\XML\EncryptableElementTrait;
22
23
use function array_pop;
24
use function count;
25
use function explode;
26
27
/**
28
 * SAML Metadata RoleDescriptor element.
29
 *
30
 * @package simplesamlphp/saml2
31
 */
32
abstract class AbstractRoleDescriptor extends AbstractRoleDescriptorType implements ExtensionPointInterface
33
{
34
    use ExtensionPointTrait;
35
36
    /** @var string */
37
    public const LOCALNAME = 'RoleDescriptor';
38
39
40
    /**
41
     * Initialize a saml:RoleDescriptor from scratch
42
     *
43
     * @param string $type
44
     * @param string[] $protocolSupportEnumeration A set of URI specifying the protocols supported.
45
     * @param string|null $ID The ID for this document. Defaults to null.
46
     * @param int|null $validUntil Unix time of validity for this document. Defaults to null.
47
     * @param string|null $cacheDuration Maximum time this document can be cached. Defaults to null.
48
     * @param \SimpleSAML\SAML2\XML\md\Extensions|null $extensions An Extensions object. Defaults to null.
49
     * @param string|null $errorURL An URI where to redirect users for support. Defaults to null.
50
     * @param \SimpleSAML\SAML2\XML\md\KeyDescriptor[] $keyDescriptor
51
     *   An array of KeyDescriptor elements. Defaults to an empty array.
52
     * @param \SimpleSAML\SAML2\XML\md\Organization|null $organization
53
     *   The organization running this entity. Defaults to null.
54
     * @param \SimpleSAML\SAML2\XML\md\ContactPerson[] $contactPerson
55
     *   An array of contacts for this entity. Defaults to an empty array.
56
     * @param \DOMAttr[] $namespacedAttributes
57
     */
58
    protected function __construct(
59
        protected string $type,
60
        array $protocolSupportEnumeration,
61
        ?string $ID = null,
62
        ?int $validUntil = null,
63
        ?string $cacheDuration = null,
64
        ?Extensions $extensions = null,
65
        ?string $errorURL = null,
66
        array $keyDescriptor = [],
67
        ?Organization $organization = null,
68
        array $contactPerson = [],
69
        array $namespacedAttributes = [],
70
    ) {
71
        parent::__construct(
72
            $protocolSupportEnumeration,
73
            $ID,
74
            $validUntil,
75
            $cacheDuration,
76
            $extensions,
77
            $errorURL,
78
            $keyDescriptor,
79
            $organization,
80
            $contactPerson,
81
            $namespacedAttributes
82
        );
83
    }
84
85
86
    /**
87
     * @inheritDoc
88
     */
89
    public function getXsiType(): string
90
    {
91
        return $this->type;
92
    }
93
94
95
    /**
96
     * Convert XML into an RoleDescriptor
97
     *
98
     * @param \DOMElement $xml The XML element we should load
99
     * @return \SimpleSAML\SAML2\XML\md\AbstractRoleDescriptor
100
     *
101
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException if the qualified name of the supplied element is wrong
102
     */
103
    public static function fromXML(DOMElement $xml): static
104
    {
105
        Assert::same($xml->localName, 'RoleDescriptor', InvalidDOMElementException::class);
106
        Assert::same($xml->namespaceURI, C::NS_MD, InvalidDOMElementException::class);
107
        Assert::true(
108
            $xml->hasAttributeNS(C::NS_XSI, 'type'),
109
            'Missing required xsi:type in <saml:RoleDescriptor> element.',
110
            SchemaViolationException::class
111
        );
112
113
        $type = $xml->getAttributeNS(C::NS_XSI, 'type');
114
        Assert::validQName($type, SchemaViolationException::class);
115
116
        // first, try to resolve the type to a full namespaced version
117
        $qname = explode(':', $type, 2);
118
        if (count($qname) === 2) {
119
            list($prefix, $element) = $qname;
120
        } else {
121
            $prefix = null;
122
            list($element) = $qname;
123
        }
124
        $ns = $xml->lookupNamespaceUri($prefix);
125
        $type = ($ns === null ) ? $element : implode(':', [$ns, $element]);
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
            $protocols = self::getAttribute($xml, 'protocolSupportEnumeration');
132
133
            $validUntil = self::getAttribute($xml, 'validUntil', null);
134
            $orgs = Organization::getChildrenOfClass($xml);
135
            Assert::maxCount($orgs, 1, 'More than one Organization found in this descriptor', TooManyElementsException::class);
136
137
            $extensions = Extensions::getChildrenOfClass($xml);
138
            Assert::maxCount($extensions, 1, 'Only one md:Extensions element is allowed.', TooManyElementsException::class);
139
140
            return new UnknownRoleDescriptor(
141
                new Chunk($xml),
142
                $type,
143
                preg_split('/[\s]+/', trim($protocols)),
144
                self::getAttribute($xml, 'ID', null),
145
                $validUntil !== null ? XMLUtils::xsDateTimeToTimestamp($validUntil) : null,
146
                self::getAttribute($xml, 'cacheDuration', null),
147
                array_pop($extensions),
148
                self::getAttribute($xml, 'errorURL', null),
149
                KeyDescriptor::getChildrenOfClass($xml),
150
                array_pop($orgs),
151
                ContactPerson::getChildrenOfClass($xml),
0 ignored issues
show
Bug introduced by
The type SimpleSAML\SAML2\XML\md\ContactPerson 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...
152
            );
153
        }
154
155
        Assert::subclassOf(
156
            $handler,
157
            AbstractRoleDescriptor::class,
158
            'Elements implementing RoleDescriptor must extend \SimpleSAML\SAML2\XML\saml\AbstractRoleDescriptor.',
159
        );
160
161
        return $handler::fromXML($xml);
162
    }
163
164
165
    /**
166
     * Convert this RoleDescriptor to XML.
167
     *
168
     * @param \DOMElement|null $parent The element we are converting to XML.
169
     * @return \DOMElement The XML element after adding the data corresponding to this RoleDescriptor.
170
     */
171
    public function toUnsignedXML(?DOMElement $parent = null): DOMElement
172
    {
173
        $e = parent::toUnsignedXML($parent);
174
175
//        $xsiType = $e->ownerDocument->createAttributeNS(C::NS_XSI, 'xsi:type');
176
//        $xsiType->value = $this->getXsiType();
177
178
//        $e->setAttributeNodeNS($xsiType);
179
        $e->setAttribute('xmlns:' . static::getXsiTypePrefix(), static::getXsiTypeNamespaceURI());
180
        $e->setAttributeNS(C::NS_XSI, 'xsi:type', $this->getXsiType());
181
182
        return $e;
183
    }
184
}
185