LogoutResponse   A
last analyzed

Complexity

Total Complexity 4

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 37
dl 0
loc 92
rs 10
c 0
b 0
f 0
wmc 4

2 Methods

Rating   Name   Duplication   Size   Complexity  
A fromXML() 0 39 3
A __construct() 0 19 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML2\XML\samlp;
6
7
use DOMElement;
8
use SimpleSAML\SAML2\Assert\Assert;
9
use SimpleSAML\SAML2\Exception\Protocol\RequestVersionTooHighException;
10
use SimpleSAML\SAML2\Exception\Protocol\RequestVersionTooLowException;
11
use SimpleSAML\SAML2\Type\SAMLAnyURIValue;
12
use SimpleSAML\SAML2\Type\SAMLDateTimeValue;
13
use SimpleSAML\SAML2\Type\SAMLStringValue;
14
use SimpleSAML\SAML2\XML\saml\Issuer;
15
use SimpleSAML\XML\SchemaValidatableElementInterface;
16
use SimpleSAML\XML\SchemaValidatableElementTrait;
17
use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException;
18
use SimpleSAML\XMLSchema\Type\IDValue;
19
use SimpleSAML\XMLSchema\Type\NCNameValue;
20
use SimpleSAML\XMLSecurity\XML\ds\Signature;
21
22
use function array_pop;
23
use function strval;
24
25
/**
26
 * Class for SAML 2 LogoutResponse messages.
27
 *
28
 * @package simplesamlphp/saml2
29
 */
30
final class LogoutResponse extends AbstractStatusResponse implements SchemaValidatableElementInterface
31
{
32
    use SchemaValidatableElementTrait;
33
34
35
    /**
36
     * Constructor for SAML 2 LogoutResponse.
37
     *
38
     * @param \SimpleSAML\XMLSchema\Type\IDValue $id
39
     * @param \SimpleSAML\SAML2\XML\samlp\Status $status
40
     * @param \SimpleSAML\SAML2\Type\SAMLDateTimeValue $issueInstant
41
     * @param \SimpleSAML\SAML2\XML\saml\Issuer|null $issuer
42
     * @param \SimpleSAML\XMLSchema\Type\NCNameValue|null $inResponseTo
43
     * @param \SimpleSAML\SAML2\Type\SAMLAnyURIValue|null $destination
44
     * @param \SimpleSAML\SAML2\Type\SAMLAnyURIValue|null $consent
45
     * @param \SimpleSAML\SAML2\XML\samlp\Extensions|null $extensions
46
     *
47
     * @throws \Exception
48
     */
49
    public function __construct(
50
        IDValue $id,
51
        Status $status,
52
        SAMLDateTimeValue $issueInstant,
53
        ?Issuer $issuer = null,
54
        ?NCNameValue $inResponseTo = null,
55
        ?SAMLAnyURIValue $destination = null,
56
        ?SAMLAnyURIValue $consent = null,
57
        ?Extensions $extensions = null,
58
    ) {
59
        parent::__construct(
60
            $id,
61
            $status,
62
            $issueInstant,
63
            $issuer,
64
            $inResponseTo,
65
            $destination,
66
            $consent,
67
            $extensions,
68
        );
69
    }
70
71
72
    /**
73
     * Convert XML into an LogoutResponse
74
     *
75
     * @param \DOMElement $xml
76
     * @return static
77
     *
78
     * @throws \SimpleSAML\XMLSchema\Exception\InvalidDOMElementException
79
     *   if the qualified name of the supplied element is wrong
80
     * @throws \SimpleSAML\XMLSchema\Exception\MissingAttributeException
81
     *   if the supplied element is missing one of the mandatory attributes
82
     */
83
    public static function fromXML(DOMElement $xml): static
84
    {
85
        Assert::same($xml->localName, 'LogoutResponse', InvalidDOMElementException::class);
86
        Assert::same($xml->namespaceURI, LogoutResponse::NS, InvalidDOMElementException::class);
87
88
        $version = self::getAttribute($xml, 'Version', SAMLStringValue::class);
89
        Assert::true(version_compare('2.0', strval($version), '<='), RequestVersionTooLowException::class);
90
        Assert::true(version_compare('2.0', strval($version), '>='), RequestVersionTooHighException::class);
91
92
        $issuer = Issuer::getChildrenOfClass($xml);
93
        Assert::countBetween($issuer, 0, 1);
94
95
        $status = Status::getChildrenOfClass($xml);
96
        Assert::count($status, 1);
97
98
        $extensions = Extensions::getChildrenOfClass($xml);
99
        Assert::maxCount($extensions, 1, 'Only one saml:Extensions element is allowed.');
100
101
        $signature = Signature::getChildrenOfClass($xml);
102
        Assert::maxCount($signature, 1, 'Only one ds:Signature element is allowed.');
103
104
        $response = new static(
105
            self::getAttribute($xml, 'ID', IDValue::class),
106
            array_pop($status),
107
            self::getAttribute($xml, 'IssueInstant', SAMLDateTimeValue::class),
108
            array_pop($issuer),
109
            self::getOptionalAttribute($xml, 'InResponseTo', NCNameValue::class, null),
110
            self::getOptionalAttribute($xml, 'Destination', SAMLAnyURIValue::class, null),
111
            self::getOptionalAttribute($xml, 'Consent', SAMLAnyURIValue::class, null),
112
            empty($extensions) ? null : array_pop($extensions),
113
        );
114
115
        if (!empty($signature)) {
116
            $response->setSignature($signature[0]);
117
            $response->messageContainedSignatureUponConstruction = true;
118
            $response->setXML($xml);
119
        }
120
121
        return $response;
122
    }
123
}
124