Passed
Push — master ( 98820b...d17f13 )
by Tim
03:56 queued 01:31
created

LogoutResponse::toXML()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 8
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 16
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML2\XML\samlp;
6
7
use DOMElement;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\SAML2\Exception\Protocol\RequestVersionTooHighException;
10
use SimpleSAML\SAML2\Exception\Protocol\RequestVersionTooLowException;
11
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
12
use SimpleSAML\SAML2\XML\saml\Issuer;
13
use SimpleSAML\XML\Exception\InvalidDOMElementException;
14
use SimpleSAML\XML\Utils as XMLUtils;
15
use SimpleSAML\XMLSecurity\XML\ds\Signature;
16
17
use function array_pop;
18
19
/**
20
 * Class for SAML 2 LogoutResponse messages.
21
 *
22
 * @package simplesamlphp/saml2
23
 */
24
class LogoutResponse extends AbstractStatusResponse
25
{
26
    /**
27
     * Constructor for SAML 2 LogoutResponse.
28
     *
29
     * @param \SimpleSAML\SAML2\XML\samlp\Status $status
30
     * @param \SimpleSAML\SAML2\XML\saml\Issuer|null $issuer
31
     * @param string|null $id
32
     * @param int|null $issueInstant
33
     * @param string|null $inResponseTo
34
     * @param string|null $destination
35
     * @param string|null $consent
36
     * @param \SimpleSAML\SAML2\XML\samlp\Extensions|null $extensions
37
     * @param string|null $relayState
38
     *
39
     * @throws \Exception
40
     */
41
    public function __construct(
42
        Status $status,
43
        ?Issuer $issuer = null,
44
        ?string $id = null,
45
        ?int $issueInstant = null,
46
        ?string $inResponseTo = null,
47
        ?string $destination = null,
48
        ?string $consent = null,
49
        ?Extensions $extensions = null,
50
        ?string $relayState = null
51
    ) {
52
        parent::__construct($status, $issuer, $id, $issueInstant, $inResponseTo, $destination, $consent, $extensions, $relayState);
53
    }
54
55
56
    /**
57
     * Convert XML into an LogoutResponse
58
     *
59
     * @param \DOMElement $xml
60
     * @return self
61
     *
62
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException if the qualified name of the supplied element is wrong
63
     * @throws \SimpleSAML\XML\Exception\MissingAttributeException if the supplied element is missing one of the mandatory attributes
64
     */
65
    public static function fromXML(DOMElement $xml): object
66
    {
67
        Assert::same($xml->localName, 'LogoutResponse', InvalidDOMElementException::class);
68
        Assert::same($xml->namespaceURI, LogoutResponse::NS, InvalidDOMElementException::class);
69
70
        Assert::true(version_compare('2.0', self::getAttribute($xml, 'Version'), '<='), RequestVersionTooLowException::class);
71
        Assert::true(version_compare('2.0', self::getAttribute($xml, 'Version'), '>='), RequestVersionTooHighException::class);
72
73
        $issueInstant = self::getAttribute($xml, 'IssueInstant');
74
        Assert::validDateTimeZulu($issueInstant, ProtocolViolationException::class);
75
        $issueInstant = XMLUtils::xsDateTimeToTimestamp($issueInstant);
76
77
        $issuer = Issuer::getChildrenOfClass($xml);
78
        Assert::countBetween($issuer, 0, 1);
79
80
        $status = Status::getChildrenOfClass($xml);
81
        Assert::count($status, 1);
82
83
        $extensions = Extensions::getChildrenOfClass($xml);
84
        Assert::maxCount($extensions, 1, 'Only one saml:Extensions element is allowed.');
85
86
        $signature = Signature::getChildrenOfClass($xml);
87
        Assert::maxCount($signature, 1, 'Only one ds:Signature element is allowed.');
88
89
        $response = new self(
90
            array_pop($status),
91
            array_pop($issuer),
92
            self::getAttribute($xml, 'ID'),
93
            $issueInstant,
94
            self::getAttribute($xml, 'InResponseTo', null),
95
            self::getAttribute($xml, 'Destination', null),
96
            self::getAttribute($xml, 'Consent', null),
97
            empty($extensions) ? null : array_pop($extensions)
98
        );
99
100
        if (!empty($signature)) {
101
            $response->setSignature($signature[0]);
102
            $response->messageContainedSignatureUponConstruction = true;
103
        }
104
105
        return $response;
106
    }
107
108
109
    /**
110
     * Convert status response message to an XML element.
111
     *
112
     * @inheritDoc
113
     * @return \DOMElement This status response.
114
     */
115
    public function toXML(?DOMElement $parent = null): DOMElement
116
    {
117
        $e = parent::toXML($parent);
118
119
        if ($this->signer !== null) {
120
            $signedXML = $this->doSign($e);
121
122
            // Test for an Issuer
123
            $responseElements = XPath::xpQuery($signedXML, './saml_assertion:Issuer', XPath::getXPath($signedXML));
0 ignored issues
show
Bug introduced by
The type SimpleSAML\SAML2\XML\samlp\XPath 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...
124
            $issuer = array_pop($responseElements);
125
126
            $signedXML->insertBefore($this->signature->toXML($signedXML), $issuer->nextSibling);
127
            return $signedXML;
128
        }
129
130
        return $e;
131
    }
132
}
133