SamlMessage::fromXML()   B
last analyzed

Complexity

Conditions 8
Paths 11

Size

Total Lines 46
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 28
c 1
b 0
f 0
dl 0
loc 46
rs 8.4444
cc 8
nc 11
nop 2
1
<?php
2
3
/*
4
 * This file is part of the LightSAML-Core package.
5
 *
6
 * (c) Milos Tomic <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace LightSaml\Model\Protocol;
13
14
use LightSaml\Error\LightSamlXmlException;
15
use LightSaml\Helper;
16
use LightSaml\Model\AbstractSamlModel;
17
use LightSaml\Model\Assertion\Issuer;
18
use LightSaml\Model\Context\DeserializationContext;
19
use LightSaml\Model\Context\SerializationContext;
20
use LightSaml\Model\SamlElementInterface;
21
use LightSaml\Model\XmlDSig\Signature;
22
use LightSaml\SamlConstants;
23
24
abstract class SamlMessage extends AbstractSamlModel
25
{
26
    /** @var string */
27
    protected $id;
28
29
    /** @var string */
30
    protected $version = SamlConstants::VERSION_20;
31
32
    /** @var int */
33
    protected $issueInstant;
34
35
    /** @var string|null */
36
    protected $destination;
37
38
    /** @var Issuer|null */
39
    protected $issuer;
40
41
    /** @var string|null */
42
    protected $consent;
43
44
    /** @var Signature|null */
45
    protected $signature;
46
47
    /** @var string|null */
48
    protected $relayState;
49
50
    /**
51
     * @param string $xml
52
     *
53
     * @return AuthnRequest|LogoutRequest|LogoutResponse|Response|SamlMessage
54
     *
55
     * @throws \Exception
56
     */
57
    public static function fromXML($xml, DeserializationContext $context)
58
    {
59
        if (false == is_string($xml)) {
0 ignored issues
show
introduced by
The condition false == is_string($xml) is always false.
Loading history...
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
60
            throw new \InvalidArgumentException('Expecting string');
61
        }
62
63
        $context->getDocument()->loadXML($xml);
64
65
        $node = $context->getDocument()->firstChild;
66
        while ($node && $node instanceof \DOMComment) {
67
            $node = $node->nextSibling;
68
        }
69
        if (null === $node) {
70
            throw new LightSamlXmlException('Empty XML');
71
        }
72
73
        if (SamlConstants::NS_PROTOCOL !== $node->namespaceURI) {
74
            throw new LightSamlXmlException(sprintf("Invalid namespace '%s' of the root XML element, expected '%s'", $context->getDocument()->namespaceURI, SamlConstants::NS_PROTOCOL));
75
        }
76
77
        $map = [
78
            'AttributeQuery' => null,
79
            'AuthnRequest' => '\LightSaml\Model\Protocol\AuthnRequest',
80
            'LogoutResponse' => '\LightSaml\Model\Protocol\LogoutResponse',
81
            'LogoutRequest' => '\LightSaml\Model\Protocol\LogoutRequest',
82
            'Response' => '\LightSaml\Model\Protocol\Response',
83
            'ArtifactResponse' => null,
84
            'ArtifactResolve' => null,
85
        ];
86
87
        $rootElementName = $node->localName;
88
89
        if (array_key_exists($rootElementName, $map)) {
90
            if ($class = $map[$rootElementName]) {
91
                /** @var SamlElementInterface $result */
92
                $result = new $class();
93
            } else {
94
                throw new \LogicException('Deserialization of %s root element is not implemented');
95
            }
96
        } else {
97
            throw new LightSamlXmlException(sprintf("Unknown SAML message '%s'", $rootElementName));
98
        }
99
100
        $result->deserialize($node, $context);
101
102
        return $result;
103
    }
104
105
    /**
106
     * @param string $id
107
     *
108
     * @return SamlMessage
109
     */
110
    public function setID($id)
111
    {
112
        $this->id = (string) $id;
113
114
        return $this;
115
    }
116
117
    /**
118
     * @return string
119
     */
120
    public function getID()
121
    {
122
        return $this->id;
123
    }
124
125
    /**
126
     * @param int|string|\DateTime $issueInstant
127
     *
128
     * @return SamlMessage
129
     */
130
    public function setIssueInstant($issueInstant)
131
    {
132
        $this->issueInstant = Helper::getTimestampFromValue($issueInstant);
133
134
        return $this;
135
    }
136
137
    /**
138
     * @return int|null
139
     */
140
    public function getIssueInstantTimestamp()
141
    {
142
        return $this->issueInstant;
143
    }
144
145
    /**
146
     * @return string|null
147
     */
148
    public function getIssueInstantString()
149
    {
150
        if ($this->issueInstant) {
151
            return Helper::time2string($this->issueInstant);
152
        }
153
154
        return null;
155
    }
156
157
    /**
158
     * @return \DateTime|null
159
     */
160
    public function getIssueInstantDateTime()
161
    {
162
        if ($this->issueInstant) {
163
            return new \DateTime('@'.$this->issueInstant);
164
        }
165
166
        return null;
167
    }
168
169
    /**
170
     * @param string $version
171
     *
172
     * @return SamlMessage
173
     */
174
    public function setVersion($version)
175
    {
176
        $this->version = (string) $version;
177
178
        return $this;
179
    }
180
181
    /**
182
     * @return string
183
     */
184
    public function getVersion()
185
    {
186
        return $this->version;
187
    }
188
189
    /**
190
     * @param string|null $destination
191
     *
192
     * @return SamlMessage
193
     */
194
    public function setDestination($destination)
195
    {
196
        $this->destination = $destination;
197
198
        return $this;
199
    }
200
201
    /**
202
     * @return string|null
203
     */
204
    public function getDestination()
205
    {
206
        return $this->destination;
207
    }
208
209
    /**
210
     * @return SamlMessage
211
     */
212
    public function setIssuer(Issuer $issuer = null)
213
    {
214
        $this->issuer = $issuer;
215
216
        return $this;
217
    }
218
219
    /**
220
     * @return \LightSaml\Model\Assertion\NameID|null
221
     */
222
    public function getIssuer()
223
    {
224
        return $this->issuer;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->issuer also could return the type LightSaml\Model\Assertion\Issuer which is incompatible with the documented return type LightSaml\Model\Assertion\NameID|null.
Loading history...
225
    }
226
227
    /**
228
     * @param string|null $consent
229
     *
230
     * @return StatusResponse
231
     */
232
    public function setConsent($consent)
233
    {
234
        $this->consent = $consent;
235
236
        return $this;
237
    }
238
239
    /**
240
     * @return string|null
241
     */
242
    public function getConsent()
243
    {
244
        return $this->consent;
245
    }
246
247
    /**
248
     * @return SamlMessage
249
     */
250
    public function setSignature(Signature $signature = null)
251
    {
252
        $this->signature = $signature;
253
254
        return $this;
255
    }
256
257
    /**
258
     * @return Signature|null
259
     */
260
    public function getSignature()
261
    {
262
        return $this->signature;
263
    }
264
265
    /**
266
     * @param string|null $relayState
267
     *
268
     * @return SamlMessage
269
     */
270
    public function setRelayState($relayState)
271
    {
272
        $this->relayState = $relayState;
273
274
        return $this;
275
    }
276
277
    /**
278
     * @return string|null
279
     */
280
    public function getRelayState()
281
    {
282
        return $this->relayState;
283
    }
284
285
    /**
286
     * @return void
287
     */
288
    public function serialize(\DOMNode $parent, SerializationContext $context)
289
    {
290
        $this->attributesToXml(['ID', 'Version', 'IssueInstant', 'Destination', 'Consent'], $parent);
291
292
        $this->singleElementsToXml(['Issuer'], $parent, $context);
293
    }
294
295
    public function deserialize(\DOMNode $node, DeserializationContext $context)
296
    {
297
        $this->attributesFromXml($node, ['ID', 'Version', 'IssueInstant', 'Destination', 'Consent']);
298
299
        $this->singleElementsFromXml($node, $context, [
300
            'Issuer' => ['saml', 'LightSaml\Model\Assertion\Issuer'],
301
            'Signature' => ['ds', 'LightSaml\Model\XmlDSig\SignatureXmlReader'],
302
        ]);
303
    }
304
}
305