Skip to content

Commit adabfe4

Browse files
committed
Refactor AttributeValue + remove psalm-annotations
1 parent 39ab84d commit adabfe4

File tree

58 files changed

+210
-291
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+210
-291
lines changed

phpstan-baseline-dev.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ parameters:
195195
-
196196
message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''SimpleSAML\\\\SAML2\\\\XML\\\\saml\\\\NameID'' and array\<SimpleSAML\\SAML2\\XML\\saml\\AttributeValue\|SimpleSAML\\SAML2\\XML\\saml\\IdentifierInterface\> will always evaluate to false\.$#'
197197
identifier: method.impossibleType
198-
count: 4
198+
count: 2
199199
path: tests/SAML2/XML/saml/AssertionTest.php
200200

201201
-

src/Binding/HTTPArtifact.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ public function receive(ServerRequestInterface $request): AbstractMessage
134134
throw new Exception('Missing SAMLart parameter.');
135135
}
136136

137-
/** @psalm-suppress UndefinedClass */
138137
$metadataHandler = MetaDataStorageHandler::getMetadataHandler(Configuration::getInstance());
139138

140139
$idpMetadata = $metadataHandler->getMetaDataConfigForSha1($sourceId, 'saml20-idp-remote');
@@ -159,10 +158,6 @@ public function receive(ServerRequestInterface $request): AbstractMessage
159158
"ArtifactResolutionService endpoint being used is := " . $endpoint['Location'],
160159
);
161160

162-
/**
163-
* @psalm-suppress UndefinedClass
164-
* @psalm-suppress DocblockTypeContradiction
165-
*/
166161
Assert::notEmpty($this->spMetadata, 'Cannot process received message without SP metadata.');
167162

168163
/**
@@ -174,7 +169,6 @@ public function receive(ServerRequestInterface $request): AbstractMessage
174169
$ar = new ArtifactResolve(new Artifact($artifact), null, $issuer, null, '2.0', $endpoint['Location']);
175170

176171
// sign the request
177-
/** @psalm-suppress UndefinedClass */
178172
MSG::addSign($this->spMetadata, $idpMetadata, $ar); // Shoaib - moved from the SOAPClient.
179173

180174
$soap = new SOAPClient();

src/SOAPClient.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ class SOAPClient
4444
* @param \SimpleSAML\Configuration $dstMetadata The metadata of the destination of the message.
4545
* @throws \Exception
4646
* @return \SimpleSAML\SAML2\XML\samlp\AbstractMessage The response we received.
47-
*
48-
* @psalm-suppress UndefinedClass
4947
*/
5048
public function send(
5149
AbstractMessage $msg,
@@ -232,7 +230,6 @@ public static function validateSSL(string $data, XMLSecurityKey $key): void
232230
{
233231
$container = ContainerSingleton::getInstance();
234232

235-
/** @psalm-suppress PossiblyNullArgument */
236233
$keyInfo = openssl_pkey_get_details($key->key);
237234
if ($keyInfo === false) {
238235
throw new Exception('Unable to get key details from XMLSecurityKey.');
@@ -259,7 +256,6 @@ public static function validateSSL(string $data, XMLSecurityKey $key): void
259256
*/
260257
private function getSOAPFault(DOMDocument $soapMessage): ?Fault
261258
{
262-
/** @psalm-suppress PossiblyNullArgument */
263259
$soapFault = XPath::xpQuery(
264260
$soapMessage->firstChild,
265261
'/env:Envelope/env:Body/env:Fault',

src/XML/IdentifierTrait.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ protected static function getIdentifierFromXML(DOMElement $xml): ?IdentifierInte
9494
TooManyElementsException::class,
9595
);
9696

97-
/** @psalm-var \SimpleSAML\SAML2\XML\saml\IdentifierInterface|null $identifier */
9897
$identifier = array_pop($identifiers);
9998

10099
return $identifier;

src/XML/saml/Advice.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ public function toXML(?DOMElement $parent = null): DOMElement
160160
}
161161

162162
foreach ($this->getElements() as $element) {
163-
/** @psalm-var \SimpleSAML\XML\SerializableElementInterface $element */
164163
$element->toXML($e);
165164
}
166165

src/XML/saml/Assertion.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use SimpleSAML\SAML2\Constants as C;
1010
use SimpleSAML\SAML2\Exception\Protocol\RequestVersionTooHighException;
1111
use SimpleSAML\SAML2\Exception\Protocol\RequestVersionTooLowException;
12+
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
1213
use SimpleSAML\SAML2\Type\SAMLDateTimeValue;
1314
use SimpleSAML\SAML2\Type\SAMLStringValue;
1415
use SimpleSAML\SAML2\Utils\XPath;

src/XML/saml/AttributeValue.php

Lines changed: 67 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,23 @@
44

55
namespace SimpleSAML\SAML2\XML\saml;
66

7-
use DateTimeImmutable;
8-
use DateTimeInterface;
97
use DOMElement;
108
use SimpleSAML\SAML2\Assert\Assert;
11-
use SimpleSAML\SAML2\Constants as C;
9+
use SimpleSAML\SAML2\Exception\RuntimeException;
1210
use SimpleSAML\XML\AbstractElement;
1311
use SimpleSAML\XML\Chunk;
12+
use SimpleSAML\XML\Registry\ElementRegistry;
1413
use SimpleSAML\XML\SchemaValidatableElementInterface;
1514
use SimpleSAML\XML\SchemaValidatableElementTrait;
1615
use SimpleSAML\XMLSchema\Constants as C_XSI;
1716
use SimpleSAML\XMLSchema\Exception\InvalidDOMElementException;
17+
use SimpleSAML\XMLSchema\Type\DateTimeValue;
18+
use SimpleSAML\XMLSchema\Type\IntegerValue;
19+
use SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface;
20+
use SimpleSAML\XMLSchema\Type\StringValue;
1821

19-
use function class_exists;
20-
use function explode;
21-
use function gettype;
22-
use function intval;
23-
use function str_contains;
22+
use function sprintf;
23+
use function strval;
2424

2525
/**
2626
* Serializable class representing an AttributeValue.
@@ -35,11 +35,14 @@ class AttributeValue extends AbstractSamlElement implements SchemaValidatableEle
3535
/**
3636
* Create an AttributeValue.
3737
*
38-
* @param string|int|null|\DateTimeInterface|\SimpleSAML\XML\AbstractElement $value
39-
* @throws \SimpleSAML\Assert\AssertionFailedException if the supplied value is neither a string or a DOMElement
38+
* @param (
39+
* \SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface|
40+
* \SimpleSAML\XML\AbstractElement|
41+
* null
42+
* ) $value
4043
*/
4144
final public function __construct(
42-
protected string|int|null|DateTimeInterface|AbstractElement $value,
45+
protected ValueTypeInterface|AbstractElement|null $value,
4346
) {
4447
}
4548

@@ -50,35 +53,31 @@ final public function __construct(
5053
public function getXsiType(): string
5154
{
5255
$value = $this->getValue();
53-
$type = gettype($value);
54-
55-
switch ($type) {
56-
case "integer":
57-
return "xs:integer";
58-
case "NULL":
59-
return "xs:nil";
60-
case "object":
61-
if ($value instanceof DateTimeInterface) {
62-
return 'xs:dateTime';
63-
}
64-
65-
return sprintf(
66-
'%s:%s',
67-
$value::getNamespacePrefix(),
68-
AbstractElement::getClassName(get_class($value)),
69-
);
70-
default:
71-
return "xs:string";
56+
57+
if ($value === null) {
58+
return 'xs:nil';
59+
} elseif ($value instanceof AbstractElement) {
60+
return sprintf(
61+
'%s:%s',
62+
$value::getNamespacePrefix(),
63+
AbstractElement::getClassName(get_class($value)),
64+
);
7265
}
66+
67+
return $value->getType();
7368
}
7469

7570

7671
/**
7772
* Get this attribute value.
7873
*
79-
* @return string|int|\SimpleSAML\XML\AbstractElement|null
74+
* @return (
75+
* \SimpleSAML\XMLSchema\Type\Interface\ValueTypeInterface|
76+
* \SimpleSAML\XML\AbstractElement|
77+
* null
78+
* )
8079
*/
81-
public function getValue()
80+
public function getValue(): ValueTypeInterface|AbstractElement|null
8281
{
8382
return $this->value;
8483
}
@@ -92,52 +91,40 @@ public function getValue()
9291
*/
9392
public static function fromXML(DOMElement $xml): static
9493
{
95-
Assert::same($xml->localName, 'AttributeValue', InvalidDOMElementException::class);
94+
Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
9695
Assert::same($xml->namespaceURI, AttributeValue::NS, InvalidDOMElementException::class);
9796

9897
if ($xml->childElementCount > 0) {
9998
$node = $xml->firstElementChild;
10099

101-
if (str_contains($node->tagName, ':')) {
102-
list($prefix, $eltName) = explode(':', $node->tagName);
103-
$className = sprintf('\SimpleSAML\SAML2\XML\%s\%s', $prefix, $eltName);
104-
105-
if (class_exists($className)) {
106-
$value = $className::fromXML($node);
107-
} else {
108-
$value = Chunk::fromXML($node);
109-
}
110-
} else {
111-
$value = Chunk::fromXML($node);
112-
}
113-
} elseif (
114-
$xml->hasAttributeNS(C_XSI::NS_XSI, "type") &&
115-
$xml->getAttributeNS(C_XSI::NS_XSI, "type") === "xs:integer"
116-
) {
117-
Assert::numeric($xml->textContent);
118-
119-
// we have an integer as value
120-
$value = intval($xml->textContent);
121-
} elseif (
122-
$xml->hasAttributeNS(C_XSI::NS_XSI, "type") &&
123-
$xml->getAttributeNS(C_XSI::NS_XSI, "type") === "xs:dateTime"
124-
) {
125-
Assert::validDateTime($xml->textContent);
126-
127-
// we have a dateTime as value
128-
$value = new DateTimeImmutable($xml->textContent);
129-
} elseif (
130-
// null value
131-
$xml->hasAttributeNS(C_XSI::NS_XSI, "nil") &&
132-
($xml->getAttributeNS(C_XSI::NS_XSI, "nil") === "1" ||
133-
$xml->getAttributeNS(C_XSI::NS_XSI, "nil") === "true")
134-
) {
100+
$registry = ElementRegistry::getInstance();
101+
$handler = $registry->getElementHandler($node->namespaceURI, $node->localName);
102+
103+
$value = $handler ? $handler::fromXML($node) : Chunk::fromXML($node);
104+
} elseif ($xml->hasAttributeNS(C_XSI::NS_XSI, 'nil')) {
105+
Assert::oneOf($xml->getAttributeNS(C_XSI::NS_XSI, 'nil'), ['1', 'true']);
135106
Assert::isEmpty($xml->nodeValue);
136107
Assert::isEmpty($xml->textContent);
137108

138109
$value = null;
110+
} elseif ($xml->hasAttributeNS(C_XSI::NS_XSI, 'type')) {
111+
$type = $xml->getAttributeNS(C_XSI::NS_XSI, 'type');
112+
113+
switch ($type) {
114+
case 'xs:dateTime':
115+
$value = DateTimeValue::fromString($xml->textContent);
116+
break;
117+
case 'xs:integer':
118+
$value = IntegerValue::fromString($xml->textContent);
119+
break;
120+
case 'xs:string':
121+
$value = StringValue::fromString($xml->textContent);
122+
break;
123+
default:
124+
throw new RuntimeException(sprintf("Cannot process xsi:type '%s'", $type));
125+
}
139126
} else {
140-
$value = $xml->textContent;
127+
$value = StringValue::fromString($xml->textContent);
141128
}
142129

143130
return new static($value);
@@ -152,33 +139,18 @@ public function toXML(?DOMElement $parent = null): DOMElement
152139
$e = parent::instantiateParentElement($parent);
153140

154141
$value = $this->getValue();
155-
$type = gettype($value);
156-
157-
switch ($type) {
158-
case "integer":
159-
// make sure that the xs namespace is available in the AttributeValue
160-
$e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C_XSI::NS_XSI);
161-
$e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xs', C_XSI::NS_XS);
162-
$e->setAttributeNS(C_XSI::NS_XSI, 'xsi:type', 'xs:integer');
163-
$e->textContent = strval($value);
164-
break;
165-
case "NULL":
166-
$e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C_XSI::NS_XSI);
167-
$e->setAttributeNS(C_XSI::NS_XSI, 'xsi:nil', '1');
168-
break;
169-
case "object":
170-
if ($value instanceof DateTimeInterface) {
171-
$e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C_XSI::NS_XSI);
172-
$e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xs', C_XSI::NS_XS);
173-
$e->setAttributeNS(C_XSI::NS_XSI, 'xsi:type', 'xs:dateTime');
174-
$e->textContent = $value->format(C::DATETIME_FORMAT);
175-
} else {
176-
$value->toXML($e);
177-
}
178-
break;
179-
default: // string
180-
$e->textContent = $value;
181-
break;
142+
if ($value === null) {
143+
$e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C_XSI::NS_XSI);
144+
$e->setAttributeNS(C_XSI::NS_XSI, 'xsi:nil', '1');
145+
} elseif ($value instanceof AbstractElement) {
146+
$value->toXML($e);
147+
} elseif ($value instanceof StringValue) {
148+
$e->textContent = strval($value);
149+
} else {
150+
$e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xs', C_XSI::NS_XS);
151+
$e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C_XSI::NS_XSI);
152+
$e->setAttributeNS(C_XSI::NS_XSI, 'xsi:type', $value->getType());
153+
$e->textContent = strval($value);
182154
}
183155

184156
return $e;

src/XML/saml/AuthnContextDecl.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ public function toXML(?DOMElement $parent = null): DOMElement
8585
}
8686

8787
foreach ($this->getElements() as $element) {
88-
/** @psalm-var \SimpleSAML\XML\SerializableElementInterface $element */
8988
$element->toXML($e);
9089
}
9190

src/XML/samlp/ArtifactResponse.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ public static function fromXML(DOMElement $xml): static
108108
$status = $status[0];
109109
$message = null;
110110

111-
/** @psalm-suppress RedundantCondition */
112111
for ($child = $status->nextSibling; $child !== null; $child = $child->nextSibling) {
113112
if ($child instanceof DOMElement) {
114113
$message = MessageFactory::fromXML($child);

tests/SAML2/Assertion/Validation/AssertionValidatorTest.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ public static function setUpBeforeClass(): void
109109
self::$document = DOMDocumentFactory::fromString(
110110
<<<XML
111111
<saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
112-
xmlns:xs="http://www.w3.org/2001/XMLSchema"
113112
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
114113
ID="_45e42090d8cbbfa52d5a394b01049fc2221e274182"
115114
Version="2.0"
@@ -163,7 +162,6 @@ public function testAssertionNonValidation(): void
163162
$document = DOMDocumentFactory::fromString(
164163
<<<XML
165164
<saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
166-
xmlns:xs="http://www.w3.org/2001/XMLSchema"
167165
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
168166
ID="_45e42090d8cbbfa52d5a394b01049fc2221e274182"
169167
Version="2.0"

0 commit comments

Comments
 (0)