Issues (88)

src/XML/ds/Reference.php (1 issue)

Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XMLSecurity\XML\ds;
6
7
use DOMElement;
8
use SimpleSAML\XML\Exception\InvalidDOMElementException;
9
use SimpleSAML\XML\Exception\MissingElementException;
10
use SimpleSAML\XML\Exception\TooManyElementsException;
11
use SimpleSAML\XML\SchemaValidatableElementInterface;
12
use SimpleSAML\XML\SchemaValidatableElementTrait;
13
use SimpleSAML\XMLSecurity\Assert\Assert;
14
15
use function array_pop;
16
17
/**
18
 * Class representing a ds:Reference element.
19
 *
20
 * @package simplesamlphp/xml-security
21
 */
22
final class Reference extends AbstractDsElement implements SchemaValidatableElementInterface
23
{
24
    use SchemaValidatableElementTrait;
0 ignored issues
show
The trait SimpleSAML\XML\SchemaValidatableElementTrait requires some properties which are not provided by SimpleSAML\XMLSecurity\XML\ds\Reference: $message, $line
Loading history...
25
26
    /**
27
     * Initialize a ds:Reference
28
     *
29
     * @param \SimpleSAML\XMLSecurity\XML\ds\DigestMethod $digestMethod
30
     * @param \SimpleSAML\XMLSecurity\XML\ds\DigestValue $digestValue
31
     * @param \SimpleSAML\XMLSecurity\XML\ds\Transforms|null $transforms
32
     * @param string|null $Id
33
     * @param string|null $Type
34
     * @param string|null $URI
35
     */
36
    public function __construct(
37
        protected DigestMethod $digestMethod,
38
        protected DigestValue $digestValue,
39
        protected ?Transforms $transforms = null,
40
        protected ?string $Id = null,
41
        protected ?string $Type = null,
42
        protected ?string $URI = null,
43
    ) {
44
        Assert::nullOrValidNCName($Id);
45
        Assert::nullOrValidURI($Type);
46
        Assert::nullOrValidURI($URI);
47
    }
48
49
50
    /**
51
     * @return \SimpleSAML\XMLSecurity\XML\ds\Transforms|null
52
     */
53
    public function getTransforms(): ?Transforms
54
    {
55
        return $this->transforms;
56
    }
57
58
59
    /**
60
     * @return \SimpleSAML\XMLSecurity\XML\ds\DigestMethod
61
     */
62
    public function getDigestMethod(): DigestMethod
63
    {
64
        return $this->digestMethod;
65
    }
66
67
68
    /**
69
     * @return \SimpleSAML\XMLSecurity\XML\ds\DigestValue
70
     */
71
    public function getDigestValue(): DigestValue
72
    {
73
        return $this->digestValue;
74
    }
75
76
77
    /**
78
     * @return string|null
79
     */
80
    public function getId(): ?string
81
    {
82
        return $this->Id;
83
    }
84
85
86
    /**
87
     * @return string|null
88
     */
89
    public function getType(): ?string
90
    {
91
        return $this->Type;
92
    }
93
94
95
    /**
96
     * @return string|null
97
     */
98
    public function getURI(): ?string
99
    {
100
        return $this->URI;
101
    }
102
103
104
    /**
105
     * Determine whether this is an xpointer reference.
106
     *
107
     * @return bool
108
     */
109
    public function isXPointer(): bool
110
    {
111
        return !empty($this->URI) && str_starts_with($this->URI, '#xpointer');
112
    }
113
114
115
    /**
116
     * Convert XML into a Reference element
117
     *
118
     * @param \DOMElement $xml The XML element we should load
119
     * @return static
120
     *
121
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
122
     *   If the qualified name of the supplied element is wrong
123
     */
124
    public static function fromXML(DOMElement $xml): static
125
    {
126
        Assert::same($xml->localName, 'Reference', InvalidDOMElementException::class);
127
        Assert::same($xml->namespaceURI, Reference::NS, InvalidDOMElementException::class);
128
129
        $Id = self::getOptionalAttribute($xml, 'Id', null);
130
        $Type = self::getOptionalAttribute($xml, 'Type', null);
131
        $URI = self::getOptionalAttribute($xml, 'URI', null);
132
133
        $transforms = Transforms::getChildrenOfClass($xml);
134
        Assert::maxCount(
135
            $transforms,
136
            1,
137
            'A <ds:Reference> may contain just one <ds:Transforms>.',
138
            TooManyElementsException::class,
139
        );
140
141
        $digestMethod = DigestMethod::getChildrenOfClass($xml);
142
        Assert::count(
143
            $digestMethod,
144
            1,
145
            'A <ds:Reference> must contain a <ds:DigestMethod>.',
146
            MissingElementException::class,
147
        );
148
149
        $digestValue = DigestValue::getChildrenOfClass($xml);
150
        Assert::count(
151
            $digestValue,
152
            1,
153
            'A <ds:Reference> must contain a <ds:DigestValue>.',
154
            MissingElementException::class,
155
        );
156
157
        return new static(
158
            array_pop($digestMethod),
159
            array_pop($digestValue),
160
            empty($transforms) ? null : array_pop($transforms),
161
            $Id,
162
            $Type,
163
            $URI,
164
        );
165
    }
166
167
168
    /**
169
     * Convert this Reference element to XML.
170
     *
171
     * @param \DOMElement|null $parent The element we should append this Reference element to.
172
     * @return \DOMElement
173
     */
174
    public function toXML(?DOMElement $parent = null): DOMElement
175
    {
176
        $e = $this->instantiateParentElement($parent);
177
        if ($this->getId() !== null) {
178
            $e->setAttribute('Id', $this->getId());
179
        }
180
        if ($this->getType() !== null) {
181
            $e->setAttribute('Type', $this->getType());
182
        }
183
        if ($this->getURI() !== null) {
184
            $e->setAttribute('URI', $this->getURI());
185
        }
186
187
        $this->getTransforms()?->toXML($e);
188
        $this->getDigestMethod()->toXML($e);
189
        $this->getDigestValue()->toXML($e);
190
191
        return $e;
192
    }
193
}
194