Passed
Pull Request — master (#226)
by Jaime Pérez
02:37
created

Response::toXML()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SAML2\XML\samlp;
6
7
use DOMElement;
8
use SAML2\Constants;
9
use SAML2\Utils;
10
use SAML2\XML\ds\Signature;
11
use SAML2\XML\saml\Assertion;
12
use SAML2\XML\saml\EncryptedAssertion;
13
use SAML2\XML\saml\Issuer;
14
use Webmozart\Assert\Assert;
15
16
/**
17
 * Class for SAML 2 Response messages.
18
 *
19
 * @package SimpleSAMLphp
20
 */
21
class Response extends AbstractStatusResponse
22
{
23
    /**
24
     * The assertions in this response.
25
     *
26
     * @var (\SAML2\XML\saml\Assertion|\SAML2\XML\saml\EncryptedAssertion)[]
27
     */
28
    protected $assertions = [];
29
30
31
    /**
32
     * Constructor for SAML 2 ArtifactResponse.
33
     *
34
     * @param \SAML2\XML\samlp\Status $status
35
     * @param \SAML2\XML\saml\Issuer $issuer
36
     * @param string $id
37
     * @param string $version
38
     * @param int $issueInstant
39
     * @param string $inResponseTo
40
     * @param string|null $destination
41
     * @param string|null $consent
42
     * @param \SAML2\XML\samlp\Extensions $extensions
43
     * @param (\SAML2\XML\saml\Assertion|\SAML2\EncryptedAssertion) $assertions
0 ignored issues
show
Bug introduced by
The type SAML2\EncryptedAssertion 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...
44
     */
45
    public function __construct(
46
        Status $status,
47
        ?Issuer $issuer = null,
48
        ?string $id = null,
49
        ?string $version = null,
50
        ?int $issueInstant = null,
51
        ?string $inResponseTo = null,
52
        ?string $destination = null,
53
        ?string $consent = null,
54
        ?Extensions $extensions = null,
55
        array $assertions = []
56
    ) {
57
        parent::__construct(
58
            $status,
59
            $issuer,
60
            $id,
61
            $version,
62
            $issueInstant,
63
            $inResponseTo,
64
            $destination,
65
            $consent,
66
            $extensions
67
        );
68
69
        $this->setAssertions($assertions);
70
    }
71
72
73
    /**
74
     * Retrieve the assertions in this response.
75
     *
76
     * @return \SAML2\XML\saml\Assertion[]|\SAML2\XML\saml\EncryptedAssertion[]
77
     */
78
    public function getAssertions(): array
79
    {
80
        return $this->assertions;
81
    }
82
83
84
    /**
85
     * Set the assertions that should be included in this response.
86
     *
87
     * @param \SAML2\XML\saml\Assertion[]|\SAML2\XML\saml\EncryptedAssertion[] $assertions The assertions.
88
     * @return void
89
     */
90
    protected function setAssertions(array $assertions): void
91
    {
92
        $this->assertions = $assertions;
93
    }
94
95
96
    /**
97
     * Convert XML into a Response element.
98
     *
99
     * @param \DOMElement $xml The input message.
100
     * @return self
101
     */
102
    public static function fromXML(DOMElement $xml): object
103
    {
104
        Assert::same($xml->localName, 'Response');
105
        Assert::same($xml->namespaceURI, Response::NS);
106
107
        $id = self::getAttribute($xml, 'ID');
108
        $version = self::getAttribute($xml, 'Version');
109
        $issueInstant = Utils::xsDateTimeToTimestamp(self::getAttribute($xml, 'IssueInstant'));
110
        $inResponseTo = self::getAttribute($xml, 'InResponseTo', null);
111
        $destination = self::getAttribute($xml, 'Destination', null);
112
        $consent = self::getAttribute($xml, 'Consent', null);
113
114
        $issuer = Issuer::getChildrenOfClass($xml);
115
        Assert::countBetween($issuer, 0, 1);
116
117
        $status = Status::getChildrenOfClass($xml);
118
        Assert::count($status, 1);
119
120
        $extensions = Extensions::getChildrenOfClass($xml);
121
        Assert::maxCount($extensions, 1, 'Only one saml:Extensions element is allowed.');
122
123
        $assertions = [];
124
        foreach ($xml->childNodes as $node) {
125
            if ($node->namespaceURI !== Constants::NS_SAML) {
126
                continue;
127
            } elseif (!($node instanceof DOMElement)) {
128
                continue;
129
            }
130
131
            if ($node->localName === 'Assertion') {
132
                $assertions[] = new Assertion($node);
133
            } elseif ($node->localName === 'EncryptedAssertion') {
134
                $assertions[] = EncryptedAssertion::fromXML($node);
135
            }
136
        }
137
138
        $signature = Signature::getChildrenOfClass($xml);
139
        Assert::maxCount($signature, 1, 'Only one ds:Signature element is allowed.');
140
141
        $response = new self(
142
            array_pop($status),
143
            empty($issuer) ? null : array_pop($issuer),
144
            $id,
145
            $version,
146
            $issueInstant,
147
            $inResponseTo,
148
            $destination,
149
            $consent,
150
            empty($extensions) ? null : array_pop($extensions),
151
            $assertions
152
        );
153
154
        if (!empty($signature)) {
155
            $response->setSignature($signature[0]);
156
            $response->messageContainedSignatureUponConstruction = true;
157
        }
158
159
        return $response;
160
    }
161
162
163
    /**
164
     * Convert the response message to an XML element.
165
     *
166
     * @return \DOMElement This response.
167
     */
168
    public function toXML(?DOMElement $parent = null): DOMElement
169
    {
170
        $e = parent::toXML($parent);
171
172
        foreach ($this->assertions as $assertion) {
173
            $assertion->toXML($e);
174
        }
175
176
        return $this->signElement($e);
177
    }
178
}
179