Passed
Pull Request — master (#280)
by Tim
02:30
created

ArtifactResponse::__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 SimpleSAML\SAML2\XML\samlp;
6
7
use DOMElement;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
10
use SimpleSAML\SAML2\Utils\XPath;
11
use SimpleSAML\SAML2\XML\saml\Issuer;
12
use SimpleSAML\XML\Exception\InvalidDOMElementException;
13
use SimpleSAML\XML\Exception\TooManyElementsException;
14
use SimpleSAML\XML\Utils as XMLUtils;
15
use SimpleSAML\XMLSecurity\XML\ds\Signature;
16
17
use function array_pop;
18
19
/**
20
 * The \SimpleSAML\SAML2\XML\samlp\ArtifactResponse,
21
 *  is the response to the \SimpleSAML\SAML2\XML\samlp\ArtifactResolve.
22
 *
23
 * @package simplesamlphp/saml2
24
 */
25
class ArtifactResponse extends AbstractStatusResponse
26
{
27
    /** @var \SimpleSAML\SAML2\XML\samlp\AbstractMessage|null */
28
    protected ?AbstractMessage $message;
29
30
31
    /**
32
     * Constructor for SAML 2 ArtifactResponse.
33
     *
34
     * @param \SimpleSAML\SAML2\XML\samlp\Status $status
35
     * @param \SimpleSAML\SAML2\XML\saml\Issuer|null $issuer
36
     * @param string|null $id
37
     * @param int|null $issueInstant
38
     * @param string|null $inResponseTo
39
     * @param string|null $destination
40
     * @param string|null $consent
41
     * @param \SimpleSAML\SAML2\XML\samlp\Extensions|null $extensions
42
     * @param \SimpleSAML\SAML2\XML\samlp\AbstractMessage|null $message
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
        ?AbstractMessage $message = null
54
    ) {
55
        parent::__construct(
56
            $status,
57
            $issuer,
58
            $id,
59
            $issueInstant,
60
            $inResponseTo,
61
            $destination,
62
            $consent,
63
            $extensions
64
        );
65
66
        $this->setMessage($message);
67
    }
68
69
70
    /**
71
     * Collect the value of the any-property
72
     *
73
     * @return \SimpleSAML\SAML2\XML\samlp\AbstractMessage|null
74
     */
75
    public function getMessage(): ?AbstractMessage
76
    {
77
        return $this->message;
78
    }
79
80
81
    /**
82
     * Set the value of the any-property
83
     *
84
     * @param \SimpleSAML\SAML2\XML\samlp\AbstractMessage|null $message
85
     */
86
    private function setMessage(?AbstractMessage $message): void
87
    {
88
        $this->message = $message;
89
    }
90
91
92
    /**
93
     * Convert XML into an ArtifactResponse
94
     *
95
     * @param \DOMElement $xml
96
     * @return self
97
     *
98
     * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException if the qualified name of the supplied element is wrong
99
     * @throws \SimpleSAML\XML\Exception\MissingAttributeException if the supplied element is missing one of the mandatory attributes
100
     */
101
    public static function fromXML(DOMElement $xml): object
102
    {
103
        Assert::same($xml->localName, 'ArtifactResponse', InvalidDOMElementException::class);
104
        Assert::same($xml->namespaceURI, ArtifactResponse::NS, InvalidDOMElementException::class);
105
        Assert::same('2.0', self::getAttribute($xml, 'Version'));
106
107
        $id = self::getAttribute($xml, 'ID');
108
        $inResponseTo = self::getAttribute($xml, 'InResponseTo', null);
109
        $destination = self::getAttribute($xml, 'Destination', null);
110
        $consent = self::getAttribute($xml, 'Consent', null);
111
112
        $issueInstant = self::getAttribute($xml, 'IssueInstant');
113
        Assert::validDateTimeZulu($issueInstant, ProtocolViolationException::class);
114
        $issueInstant = XMLUtils::xsDateTimeToTimestamp($issueInstant);
115
116
        $issuer = Issuer::getChildrenOfClass($xml);
117
        Assert::countBetween($issuer, 0, 1);
118
119
        // find message; it should come last, after the Status-element
120
        $status = XPath::xpQuery($xml, './saml_protocol:Status', XPath::getXPath($xml));
121
        $status = $status[0];
122
        $message = null;
123
124
        /** @psalm-suppress RedundantCondition */
125
        for ($child = $status->nextSibling; $child !== null; $child = $child->nextSibling) {
126
            if ($child instanceof DOMElement) {
127
                $message = MessageFactory::fromXML($child);
128
                break;
129
            }
130
            /* Ignore comments and text nodes. */
131
        }
132
133
        $status = Status::getChildrenOfClass($xml);
134
        Assert::count($status, 1);
135
136
        $extensions = Extensions::getChildrenOfClass($xml);
137
        Assert::maxCount($extensions, 1, 'Only one saml:Extensions element is allowed.', TooManyElementsException::class);
138
139
        $signature = Signature::getChildrenOfClass($xml);
140
        Assert::maxCount($signature, 1, 'Only one ds:Signature element is allowed.', TooManyElementsException::class);
141
142
        $response = new self(
143
            array_pop($status),
144
            empty($issuer) ? null : array_pop($issuer),
145
            $id,
146
            $issueInstant,
147
            $inResponseTo,
148
            $destination,
149
            $consent,
150
            empty($extensions) ? null : array_pop($extensions),
151
            $message
152
        );
153
154
        if (!empty($signature)) {
155
            $response->setSignature($signature[0]);
156
        }
157
158
        $response->setXML($xml);
159
        return $response;
160
    }
161
162
163
    /**
164
     * Convert this message to an unsigned XML document.
165
     * This method does not sign the resulting XML document.
166
     *
167
     * @return \DOMElement The root element of the DOM tree
168
     */
169
    protected function toUnsignedXML(?DOMElement $parent = null): DOMElement
170
    {
171
        $e = parent::toUnsignedXML($parent);
172
173
        if ($this->message !== null) {
174
            $this->message->toXML($e);
175
        }
176
177
        return $e;
178
    }
179
}
180