Passed
Pull Request — master (#306)
by Tim
04:06 queued 01:42
created

AbstractRoleDescriptor::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 11
dl 0
loc 26
rs 9.9
c 0
b 0
f 0

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\SAML2\XML\IDNameQualifiersTrait;
15
use SimpleSAML\XML\Chunk;
16
use SimpleSAML\XML\Exception\InvalidDOMElementException;
17
use SimpleSAML\XML\Exception\SchemaViolationException;
18
use SimpleSAML\XMLSecurity\Backend\EncryptionBackend;
19
use SimpleSAML\XMLSecurity\XML\EncryptableElementInterface;
20
use SimpleSAML\XMLSecurity\XML\EncryptableElementTrait;
21
22
use function count;
23
use function explode;
24
25
/**
26
 * SAML Metadata RoleDescriptor element.
27
 *
28
 * @package simplesamlphp/saml2
29
 */
30
abstract class AbstractRoleDescriptor extends AbstractRoleDescriptorType implements ExtensionPointInterface
31
{
32
    use ExtensionPointTrait;
33
34
    /** @var string */
35
    public const LOCALNAME = 'RoleDescriptor';
36
37
    /** @var string */
38
    protected string $type;
39
40
41
    /**
42
     * Initialize a saml:RoleDescriptor from scratch
43
     *
44
     * @param string $type
45
     * @param string[] $protocolSupportEnumeration A set of URI specifying the protocols supported.
46
     * @param string|null $ID The ID for this document. Defaults to null.
47
     * @param int|null $validUntil Unix time of validity for this document. Defaults to null.
48
     * @param string|null $cacheDuration Maximum time this document can be cached. Defaults to null.
49
     * @param \SimpleSAML\SAML2\XML\md\Extensions|null $extensions An Extensions object. Defaults to null.
50
     * @param string|null $errorURL An URI where to redirect users for support. Defaults to null.
51
     * @param \SimpleSAML\SAML2\XML\md\KeyDescriptor[] $keyDescriptors An array of KeyDescriptor elements. Defaults to an empty array.
52
     * @param \SimpleSAML\SAML2\XML\md\Organization|null $organization The organization running this entity. Defaults to null.
53
     * @param \SimpleSAML\SAML2\XML\md\ContactPerson[] $contacts An array of contacts for this entity. Defaults to an empty array.
54
     * @param \DOMAttr[] $namespacedAttributes
55
     */
56
    protected function __construct(
57
        string $type,
58
        array $protocolSupportEnumeration,
59
        ?string $ID = null,
60
        ?int $validUntil = null,
61
        ?string $cacheDuration = null,
62
        ?Extensions $extensions = null,
63
        ?string $errorURL = null,
64
        array $keyDescriptors = [],
65
        ?Organization $organization = null,
66
        array $contacts = [],
67
        array $namespacedAttributes = []
68
    ) {
69
        parent::__construct(
70
            $protocolSupportEnumeration,
71
            $ID,
72
            $validUntil,
73
            $cacheDuration,
74
            $extensions,
75
            $errorURL,
76
            $keyDescriptors,
77
            $organization,
78
            $contacts
79
        );
80
81
        $this->type = $type;
82
    }
83
84
85
    /**
86
     * @inheritDoc
87
     */
88
    public function getXsiType(): string
89
    {
90
        return $this->type;
91
    }
92
93
94
    /**
95
     * Convert XML into an RoleDescriptor
96
     *
97
     * @param \DOMElement $xml The XML element we should load
98
     * @return \SimpleSAML\SAML2\XML\saml\AbstractRoleDescriptor
0 ignored issues
show
Bug introduced by
The type SimpleSAML\SAML2\XML\saml\AbstractRoleDescriptor 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...
99
     *
100
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException 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 identifier
130
            $protocols = self::getAttribute($xml, 'protocolSupportEnumeration');
131
132
            $validUntil = self::getAttribute($xml, 'validUntil', null);
133
            $orgs = Organization::getChildrenOfClass($xml);
134
            Assert::maxCount($orgs, 1, 'More than one Organization found in this descriptor', TooManyElementsException::class);
0 ignored issues
show
Bug introduced by
The type SimpleSAML\SAML2\XML\md\TooManyElementsException 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...
135
136
            $extensions = Extensions::getChildrenOfClass($xml);
137
            Assert::maxCount($extensions, 1, 'Only one md:Extensions element is allowed.', TooManyElementsException::class);
138
139
            return new UnknownRoleDescriptor(
0 ignored issues
show
Bug Best Practice introduced by
The expression return new SimpleSAML\SA...tChildrenOfClass($xml)) returns the type SimpleSAML\SAML2\XML\md\UnknownRoleDescriptor which is incompatible with the documented return type SimpleSAML\SAML2\XML\saml\AbstractRoleDescriptor.
Loading history...
140
                new Chunk($xml),
141
                $type,
0 ignored issues
show
Bug introduced by
$type of type string is incompatible with the type array expected by parameter $protocolSupportEnumeration of SimpleSAML\SAML2\XML\md\...scriptor::__construct(). ( Ignorable by Annotation )

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

141
                /** @scrutinizer ignore-type */ $type,
Loading history...
142
                preg_split('/[\s]+/', trim($protocols)),
0 ignored issues
show
Bug introduced by
preg_split('/[\s]+/', trim($protocols)) of type string[] is incompatible with the type null|string expected by parameter $ID of SimpleSAML\SAML2\XML\md\...scriptor::__construct(). ( Ignorable by Annotation )

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

142
                /** @scrutinizer ignore-type */ preg_split('/[\s]+/', trim($protocols)),
Loading history...
143
                self::getAttribute($xml, 'ID', null),
0 ignored issues
show
Bug introduced by
It seems like self::getAttribute($xml, 'ID', null) can also be of type string; however, parameter $validUntil of SimpleSAML\SAML2\XML\md\...scriptor::__construct() does only seem to accept integer|null, maybe add an additional type check? ( Ignorable by Annotation )

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

143
                /** @scrutinizer ignore-type */ self::getAttribute($xml, 'ID', null),
Loading history...
144
                $validUntil !== null ? XMLUtils::xsDateTimeToTimestamp($validUntil) : null,
0 ignored issues
show
Bug introduced by
The type SimpleSAML\SAML2\XML\md\XMLUtils 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...
145
                self::getAttribute($xml, 'cacheDuration', null),
0 ignored issues
show
Bug introduced by
It seems like self::getAttribute($xml, 'cacheDuration', null) can also be of type string; however, parameter $extensions of SimpleSAML\SAML2\XML\md\...scriptor::__construct() does only seem to accept SimpleSAML\SAML2\XML\md\Extensions|null, maybe add an additional type check? ( Ignorable by Annotation )

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

145
                /** @scrutinizer ignore-type */ self::getAttribute($xml, 'cacheDuration', null),
Loading history...
146
                !empty($extensions) ? $extensions[0] : null,
147
                self::getAttribute($xml, 'errorURL', null),
0 ignored issues
show
Bug introduced by
self::getAttribute($xml, 'errorURL', null) of type null|string is incompatible with the type array expected by parameter $keyDescriptors of SimpleSAML\SAML2\XML\md\...scriptor::__construct(). ( Ignorable by Annotation )

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

147
                /** @scrutinizer ignore-type */ self::getAttribute($xml, 'errorURL', null),
Loading history...
148
                KeyDescriptor::getChildrenOfClass($xml),
0 ignored issues
show
Bug introduced by
SimpleSAML\SAML2\XML\md\...etChildrenOfClass($xml) of type array is incompatible with the type SimpleSAML\SAML2\XML\md\Organization|null expected by parameter $organization of SimpleSAML\SAML2\XML\md\...scriptor::__construct(). ( Ignorable by Annotation )

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

148
                /** @scrutinizer ignore-type */ KeyDescriptor::getChildrenOfClass($xml),
Loading history...
149
                !empty($orgs) ? $orgs[0] : null,
0 ignored issues
show
Bug introduced by
It seems like ! empty($orgs) ? $orgs[0] : null can also be of type null; however, parameter $contacts of SimpleSAML\SAML2\XML\md\...scriptor::__construct() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

149
                /** @scrutinizer ignore-type */ !empty($orgs) ? $orgs[0] : null,
Loading history...
150
                ContactPerson::getChildrenOfClass($xml),
151
            );
152
        }
153
154
        Assert::subclassOf(
155
            $handler,
156
            AbstractRoleDescriptor::class,
157
            'Elements implementing RoleDescriptor must extend \SimpleSAML\SAML2\XML\saml\AbstractRoleDescriptor.',
158
        );
159
160
        return $handler::fromXML($xml);
161
    }
162
163
164
    /**
165
     * Convert this RoleDescriptor to XML.
166
     *
167
     * @param \DOMElement|null $parent The element we are converting to XML.
168
     * @return \DOMElement The XML element after adding the data corresponding to this RoleDescriptor.
169
     */
170
    public function toUnsignedXML(?DOMElement $parent = null): DOMElement
171
    {
172
        $e = parent::toUnsignedXML($parent);
173
174
        $e->setAttribute('protocolSupportEnumeration', implode(' ', $this->protocolSupportEnumeration));
175
176
        if ($this->getErrorURL() !== null) {
177
            $e->setAttribute('errorURL', $this->getErrorURL());
178
        }
179
180
        foreach ($this->getKeyDescriptors() as $kd) {
181
            $kd->toXML($e);
182
        }
183
184
        $this->getOrganization()?->toXML($e);
185
186
        foreach ($this->getContactPersons() as $cp) {
187
            $cp->toXML($e);
188
        }
189
190
        return $e;
191
    }
192
}
193