Signature::fromXML()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 49
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 32
nc 1
nop 1
dl 0
loc 49
rs 9.408
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XMLSecurity\XML\ds;
6
7
use DOMElement;
8
use SimpleSAML\XML\SchemaValidatableElementInterface;
9
use SimpleSAML\XML\SchemaValidatableElementTrait;
10
use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException;
11
use SimpleSAML\XMLSchema\Exception\MissingElementException;
12
use SimpleSAML\XMLSchema\Exception\TooManyElementsException;
13
use SimpleSAML\XMLSchema\Type\IDValue;
14
use SimpleSAML\XMLSecurity\Assert\Assert;
15
use SimpleSAML\XMLSecurity\Constants as C;
0 ignored issues
show
Bug introduced by
The type SimpleSAML\XMLSecurity\Constants 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...
16
17
use function array_pop;
18
use function strval;
19
20
/**
21
 * Class representing a ds:Signature element.
22
 *
23
 * @package simplesamlphp/xml-security
24
 */
25
final class Signature extends AbstractDsElement implements SchemaValidatableElementInterface
0 ignored issues
show
Bug introduced by
The type SimpleSAML\XMLSecurity\XML\ds\AbstractDsElement 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...
26
{
27
    use SchemaValidatableElementTrait;
28
29
30
    /**
31
     * Signature constructor.
32
     *
33
     * @param \SimpleSAML\XMLSecurity\XML\ds\SignedInfo $signedInfo
34
     * @param \SimpleSAML\XMLSecurity\XML\ds\SignatureValue $signatureValue
35
     * @param \SimpleSAML\XMLSecurity\XML\ds\KeyInfo|null $keyInfo
36
     * @param \SimpleSAML\XMLSecurity\XML\ds\DsObject[] $objects
37
     * @param \SimpleSAML\XMLSchema\Type\IDValue|null $Id
38
     */
39
    public function __construct(
40
        protected SignedInfo $signedInfo,
41
        protected SignatureValue $signatureValue,
42
        protected ?KeyInfo $keyInfo = null,
43
        protected array $objects = [],
44
        protected ?IDValue $Id = null,
45
    ) {
46
        Assert::maxCount($objects, C::UNBOUNDED_LIMIT);
47
        Assert::allIsInstanceOf($objects, DsObject::class);
0 ignored issues
show
Bug introduced by
The type SimpleSAML\XMLSecurity\XML\ds\DsObject 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...
48
    }
49
50
51
    /**
52
     * Get the Id used for this signature.
53
     *
54
     * @return \SimpleSAML\XMLSchema\Type\IDValue|null
55
     */
56
    public function getId(): ?IDValue
57
    {
58
        return $this->Id;
59
    }
60
61
62
    /**
63
     * @return \SimpleSAML\XMLSecurity\XML\ds\SignedInfo
64
     */
65
    public function getSignedInfo(): SignedInfo
66
    {
67
        return $this->signedInfo;
68
    }
69
70
71
    /**
72
     * @return \SimpleSAML\XMLSecurity\XML\ds\SignatureValue
73
     */
74
    public function getSignatureValue(): SignatureValue
75
    {
76
        return $this->signatureValue;
77
    }
78
79
80
    /**
81
     * @return \SimpleSAML\XMLSecurity\XML\ds\KeyInfo|null
82
     */
83
    public function getKeyInfo(): ?KeyInfo
84
    {
85
        return $this->keyInfo;
86
    }
87
88
89
    /**
90
     * Get the array of ds:Object elements attached to this signature.
91
     *
92
     * @return \SimpleSAML\XMLSecurity\XML\ds\DsObject[]
93
     */
94
    public function getObjects(): array
95
    {
96
        return $this->objects;
97
    }
98
99
100
    /**
101
     * Convert XML into a Signature element
102
     *
103
     * @param \DOMElement $xml
104
     *
105
     * @throws \SimpleSAML\XMLSchema\Exception\InvalidDOMElementException
106
     *   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, 'Signature', InvalidDOMElementException::class);
111
        Assert::same($xml->namespaceURI, Signature::NS, InvalidDOMElementException::class);
112
113
        $signedInfo = SignedInfo::getChildrenOfClass($xml);
114
        Assert::minCount(
115
            $signedInfo,
116
            1,
117
            'ds:Signature needs exactly one ds:SignedInfo element.',
118
            MissingElementException::class,
119
        );
120
        Assert::maxCount(
121
            $signedInfo,
122
            1,
123
            'ds:Signature needs exactly one ds:SignedInfo element.',
124
            TooManyElementsException::class,
125
        );
126
127
        $signatureValue = SignatureValue::getChildrenOfClass($xml);
128
        Assert::minCount(
129
            $signatureValue,
130
            1,
131
            'ds:Signature needs exactly one ds:SignatureValue element.',
132
            MissingElementException::class,
133
        );
134
        Assert::maxCount(
135
            $signatureValue,
136
            1,
137
            'ds:Signature needs exactly one ds:SignatureValue element.',
138
            TooManyElementsException::class,
139
        );
140
141
        $keyInfo = KeyInfo::getChildrenOfClass($xml);
142
        Assert::maxCount(
143
            $keyInfo,
144
            1,
145
            'ds:Signature can hold a maximum of one ds:KeyInfo element.',
146
            TooManyElementsException::class,
147
        );
148
149
        $objects = DsObject::getChildrenOfClass($xml);
150
151
        return new static(
152
            array_pop($signedInfo),
153
            array_pop($signatureValue),
154
            empty($keyInfo) ? null : array_pop($keyInfo),
155
            $objects,
156
            self::getOptionalAttribute($xml, 'Id', IDValue::class, null),
157
        );
158
    }
159
160
161
    /**
162
     * Convert this Signature element to XML.
163
     *
164
     * @param \DOMElement|null $parent The element we should append this Signature element to.
165
     */
166
    public function toXML(?DOMElement $parent = null): DOMElement
167
    {
168
        $e = $this->instantiateParentElement($parent);
169
170
        if ($this->getId() !== null) {
171
            $e->setAttribute('Id', strval($this->getId()));
172
        }
173
174
        $this->getSignedInfo()->toXML($e);
175
        $this->getSignatureValue()->toXML($e);
176
        $this->getKeyInfo()?->toXML($e);
177
178
        foreach ($this->getObjects() as $o) {
179
            $o->toXML($e);
180
        }
181
182
        return $e;
183
    }
184
}
185