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

AbstractRoleDescriptor::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 12
c 0
b 0
f 0
nc 1
nop 11
dl 0
loc 27
rs 9.8666

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

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

180
        /** @scrutinizer ignore-call */ 
181
        $xsiType = $e->ownerDocument->createAttributeNS(C::NS_XSI, 'xsi:type');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
181
        $xsiType->value = $this->getXsiType();
182
        $e->setAttributeNodeNS($xsiType);
183
184
        $e->setAttribute('xmlns:' . static::getXsiTypePrefix(), static::getXsiTypeNamespaceURI());
185
186
        return $e;
187
    }
188
}
189