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

Response::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 9
dl 0
loc 23
rs 9.9332
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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 response messages.
33
     *
34
     * @param \SAML2\XML\samlp\Status $status
35
     * @param \SAML2\XML\saml\Issuer $issuer
36
     * @param string $id
37
     * @param int $issueInstant
38
     * @param string $inResponseTo
39
     * @param string|null $destination
40
     * @param string|null $consent
41
     * @param \SAML2\XML\samlp\Extensions $extensions
42
     * @param (\SAML2\XML\saml\Assertion|\SAML2\XML\saml\EncryptedAssertion) $assertions
43
     */
44
    public function __construct(
45
        Status $status,
46
        ?Issuer $issuer = null,
47
        ?string $id = null,
48
        ?int $issueInstant = null,
49
        ?string $inResponseTo = null,
50
        ?string $destination = null,
51
        ?string $consent = null,
52
        ?Extensions $extensions = null,
53
        array $assertions = []
54
    ) {
55
        parent::__construct(
56
            $status,
57
            $issuer,
58
            $id,
59
            $issueInstant,
60
            $inResponseTo,
61
            $destination,
62
            $consent,
63
            $extensions
64
        );
65
66
        $this->setAssertions($assertions);
67
    }
68
69
70
    /**
71
     * Retrieve the assertions in this response.
72
     *
73
     * @return \SAML2\XML\saml\Assertion[]|\SAML2\XML\saml\EncryptedAssertion[]
74
     */
75
    public function getAssertions(): array
76
    {
77
        return $this->assertions;
78
    }
79
80
81
    /**
82
     * Set the assertions that should be included in this response.
83
     *
84
     * @param \SAML2\XML\saml\Assertion[]|\SAML2\XML\saml\EncryptedAssertion[] $assertions The assertions.
85
     * @return void
86
     */
87
    protected function setAssertions(array $assertions): void
88
    {
89
        Assert::allIsInstanceOfAny($assertions, [Assertion::class, EncryptedAssertion::class]);
90
        $this->assertions = $assertions;
91
    }
92
93
94
    /**
95
     * Convert XML into a Response element.
96
     *
97
     * @param \DOMElement $xml The input message.
98
     * @return self
99
     */
100
    public static function fromXML(DOMElement $xml): object
101
    {
102
        Assert::same($xml->localName, 'Response');
103
        Assert::same($xml->namespaceURI, Response::NS);
104
        Assert::same('2.0', self::getAttribute($xml, 'Version'));
105
106
        $id = self::getAttribute($xml, 'ID');
107
        $issueInstant = Utils::xsDateTimeToTimestamp(self::getAttribute($xml, 'IssueInstant'));
108
        $inResponseTo = self::getAttribute($xml, 'InResponseTo', null);
109
        $destination = self::getAttribute($xml, 'Destination', null);
110
        $consent = self::getAttribute($xml, 'Consent', null);
111
112
        $issuer = Issuer::getChildrenOfClass($xml);
113
        Assert::countBetween($issuer, 0, 1);
114
115
        $status = Status::getChildrenOfClass($xml);
116
        Assert::count($status, 1);
117
118
        $extensions = Extensions::getChildrenOfClass($xml);
119
        Assert::maxCount($extensions, 1, 'Only one saml:Extensions element is allowed.');
120
121
        $assertions = [];
122
        foreach ($xml->childNodes as $node) {
123
            if ($node->namespaceURI !== Constants::NS_SAML) {
124
                continue;
125
            } elseif (!($node instanceof DOMElement)) {
126
                continue;
127
            }
128
129
            if ($node->localName === 'Assertion') {
130
                $assertions[] = new Assertion($node);
131
            } elseif ($node->localName === 'EncryptedAssertion') {
132
                $assertions[] = EncryptedAssertion::fromXML($node);
133
            }
134
        }
135
136
        $signature = Signature::getChildrenOfClass($xml);
137
        Assert::maxCount($signature, 1, 'Only one ds:Signature element is allowed.');
138
139
        $response = new self(
140
            array_pop($status),
141
            empty($issuer) ? null : array_pop($issuer),
142
            $id,
143
            $issueInstant,
144
            $inResponseTo,
145
            $destination,
146
            $consent,
147
            empty($extensions) ? null : array_pop($extensions),
148
            $assertions
149
        );
150
151
        if (!empty($signature)) {
152
            $response->setSignature($signature[0]);
153
            $response->messageContainedSignatureUponConstruction = true;
154
        }
155
156
        return $response;
157
    }
158
159
160
    /**
161
     * Convert the response message to an XML element.
162
     *
163
     * @return \DOMElement This response.
164
     */
165
    public function toXML(?DOMElement $parent = null): DOMElement
166
    {
167
        $e = parent::toXML($parent);
168
169
        foreach ($this->assertions as $assertion) {
170
            $assertion->toXML($e);
171
        }
172
173
        return $this->signElement($e);
174
    }
175
}
176