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

AbstractRoleDescriptor::fromXML()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 69
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 47
c 0
b 0
f 0
nc 8
nop 1
dl 0
loc 69
rs 8.8452

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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