Passed
Push — master ( c2ab36...decaf7 )
by Tim
01:44
created

Extensions   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 42
dl 0
loc 74
rs 10
c 0
b 0
f 0
wmc 4
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\Utils\XPath;
10
use SimpleSAML\SAML2\XML\alg\AbstractAlgElement as ALG;
11
use SimpleSAML\SAML2\XML\alg\DigestMethod;
12
use SimpleSAML\SAML2\XML\alg\SigningMethod;
13
use SimpleSAML\SAML2\XML\emd\RepublishRequest;
14
use SimpleSAML\SAML2\XML\ExtensionsTrait;
15
use SimpleSAML\SAML2\XML\idpdisc\DiscoveryResponse;
16
use SimpleSAML\SAML2\XML\init\RequestInitiator;
17
use SimpleSAML\SAML2\XML\mdattr\EntityAttributes;
18
use SimpleSAML\SAML2\XML\mdrpi\AbstractMdrpiElement as MDRPI;
19
use SimpleSAML\SAML2\XML\mdrpi\PublicationInfo;
20
use SimpleSAML\SAML2\XML\mdrpi\PublicationPath;
21
use SimpleSAML\SAML2\XML\mdrpi\RegistrationInfo;
22
use SimpleSAML\SAML2\XML\mdui\AbstractMduiElement as MDUI;
23
use SimpleSAML\SAML2\XML\mdui\DiscoHints;
24
use SimpleSAML\SAML2\XML\mdui\UIInfo;
25
use SimpleSAML\SAML2\XML\shibmd\Scope;
26
use SimpleSAML\XML\Chunk;
27
use SimpleSAML\XML\SchemaValidatableElementInterface;
28
use SimpleSAML\XML\SchemaValidatableElementTrait;
29
use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException;
30
use SimpleSAML\XMLSchema\XML\Constants\NS;
31
32
use function array_key_exists;
33
34
/**
35
 * Class for handling SAML2 metadata extensions.
36
 *
37
 * @package simplesamlphp/saml2
38
 */
39
final class Extensions extends AbstractMdElement implements SchemaValidatableElementInterface
40
{
41
    use ExtensionsTrait;
42
    use SchemaValidatableElementTrait;
43
44
45
    /** The namespace-attribute for the xs:any element */
46
    public const string XS_ANY_ELT_NAMESPACE = NS::OTHER;
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_STRING, expecting '=' on line 46 at column 24
Loading history...
47
48
    /**
49
     * The exclusions for the xs:any element
50
     *
51
     * @var array<int, array<int, string>>
52
     */
53
    public const array XS_ANY_ELT_EXCLUSIONS = [
54
        ['urn:oasis:names:tc:SAML:2.0:assertion', '*'],
55
        ['urn:oasis:names:tc:SAML:2.0:metadata', '*'],
56
        ['urn:oasis:names:tc:SAML:2.0:protocol', '*'],
57
    ];
58
59
60
    /**
61
     * Create an Extensions object from its md:Extensions XML representation.
62
     *
63
     * For those supported extensions, an object of the corresponding class will be created.
64
     * The rest will be added as a \SimpleSAML\XML\Chunk object.
65
     *
66
     * @throws \SimpleSAML\XMLSchema\Exception\InvalidDOMElementException
67
     *   if the qualified name of the supplied element is wrong
68
     */
69
    public static function fromXML(DOMElement $xml): static
70
    {
71
        Assert::eq(
72
            $xml->namespaceURI,
73
            self::NS,
74
            'Unknown namespace \'' . strval($xml->namespaceURI) . '\' for Extensions element.',
75
            InvalidDOMElementException::class,
76
        );
77
        Assert::eq(
78
            $xml->localName,
79
            static::getClassName(static::class),
80
            'Invalid Extensions element \'' . $xml->localName . '\'',
81
            InvalidDOMElementException::class,
82
        );
83
        $ret = [];
84
        $supported = [
85
            RepublishRequest::NS => [
86
                'RepublishRequest' => RepublishRequest::class,
87
            ],
88
            DiscoveryResponse::NS => [
89
                'DiscoveryResponse' => DiscoveryResponse::class,
90
            ],
91
            Scope::NS => [
92
                'Scope' => Scope::class,
93
            ],
94
            EntityAttributes::NS => [
95
                'EntityAttributes' => EntityAttributes::class,
96
            ],
97
            MDRPI::NS => [
98
                'RegistrationInfo' => RegistrationInfo::class,
99
                'PublicationInfo' => PublicationInfo::class,
100
                'PublicationPath' => PublicationPath::class,
101
            ],
102
            MDUI::NS => [
103
                'UIInfo' => UIInfo::class,
104
                'DiscoHints' => DiscoHints::class,
105
            ],
106
            ALG::NS => [
107
                'DigestMethod' => DigestMethod::class,
108
                'SigningMethod' => SigningMethod::class,
109
            ],
110
            RequestInitiator::NS => [
111
                'RequestInitiator' => RequestInitiator::class,
112
            ],
113
        ];
114
115
        /** @var \DOMElement $node */
116
        foreach (XPath::xpQuery($xml, './*', XPath::getXPath($xml)) as $node) {
117
            if (
118
                array_key_exists($node->namespaceURI, $supported)
119
                && array_key_exists($node->localName, $supported[$node->namespaceURI])
120
            ) {
121
                $ret[] = $supported[$node->namespaceURI][$node->localName]::fromXML($node);
122
            } else {
123
                $ret[] = new Chunk($node);
124
            }
125
        }
126
127
        return new static($ret);
128
    }
129
}
130