Skip to content

Commit 388c2f9

Browse files
committed
Add AnyURIList-type
1 parent 4733ff8 commit 388c2f9

20 files changed

Lines changed: 244 additions & 130 deletions

src/Type/AnyURIListValue.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\SAML2\Type;
6+
7+
use SimpleSAML\SAML2\Assert\Assert;
8+
use SimpleSAML\SAML2\Constants as C;
9+
use SimpleSAML\SAML2\Type\SAMLAnyURIValue;
10+
use SimpleSAML\XML\Exception\SchemaViolationException;
11+
use SimpleSAML\XML\Type\ListTypeInterface;
12+
13+
use function array_map;
14+
use function preg_split;
15+
use function str_replace;
16+
use function trim;
17+
18+
/**
19+
* @package simplesaml/saml2
20+
*/
21+
class AnyURIListValue extends SAMLAnyURIValue implements ListTypeInterface
22+
{
23+
/** @var string */
24+
public const SCHEMA_TYPE = 'AnyURIList';
25+
26+
27+
/**
28+
* Validate the value.
29+
*
30+
* @param string $value
31+
* @throws \SimpleSAML\XML\Exception\SchemaViolationException on failure
32+
* @return void
33+
*/
34+
protected function validateValue(string $value): void
35+
{
36+
$uris = preg_split('/[\s]+/', $this->sanitizeValue($value), C::UNBOUNDED_LIMIT);
37+
38+
Assert::allValidAnyURI($uris, SchemaViolationException::class);
39+
}
40+
41+
42+
/**
43+
* Convert an array of xs:anyURI items into a saml:AnyURIList
44+
*
45+
* @param string[] $uris
46+
* @return static
47+
*/
48+
public static function fromArray(array $uris): static
49+
{
50+
$str = '';
51+
foreach ($uris as $uri) {
52+
$str .= str_replace(' ', '+', $uri) . ' ';
53+
}
54+
55+
return new static(trim($str));
56+
}
57+
58+
59+
/**
60+
* Convert this saml:AnyURIList to an array of xs:anyURI items
61+
*
62+
* @return array<\SimpleSAML\SAML2\Type\SAMLAnyURIValue>
63+
*/
64+
public function toArray(): array
65+
{
66+
$uris = preg_split('/[\s]+/', $this->getValue(), C::UNBOUNDED_LIMIT);
67+
$uris = str_replace('+', ' ', $uris);
68+
69+
return array_map([SAMLAnyURIValue::class, 'fromString'], $uris);
70+
}
71+
}

src/XML/md/AbstractRoleDescriptor.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
use DOMElement;
88
use SimpleSAML\SAML2\Assert\Assert;
99
use SimpleSAML\SAML2\Constants as C;
10-
use SimpleSAML\SAML2\Type\{SAMLAnyURIValue, SAMLDateTimeValue, SAMLStringValue};
10+
use SimpleSAML\SAML2\Type\{AnyURIListValue, SAMLAnyURIValue, SAMLDateTimeValue};
1111
use SimpleSAML\SAML2\Utils;
1212
use SimpleSAML\SAML2\XML\{ExtensionPointInterface, ExtensionPointTrait};
1313
use SimpleSAML\XML\Chunk;
1414
use SimpleSAML\XML\Exception\{InvalidDOMElementException, SchemaViolationException, TooManyElementsException};
1515
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
16-
use SimpleSAML\XML\Type\{DurationValue, IDValue, QNameValue, StringValue};
16+
use SimpleSAML\XML\Type\{DurationValue, IDValue, QNameValue};
1717

1818
use function array_pop;
1919

@@ -38,7 +38,8 @@ abstract class AbstractRoleDescriptor extends AbstractRoleDescriptorType impleme
3838
* Initialize a md:RoleDescriptor from scratch.
3939
*
4040
* @param \SimpleSAML\XML\Type\QNameValue $type
41-
* @param string[] $protocolSupportEnumeration A set of URI specifying the protocols supported.
41+
* @param \SimpleSAML\SAML2\Type\AnyURIListValue $protocolSupportEnumeration
42+
* A set of URI specifying the protocols supported.
4243
* @param \SimpleSAML\XML\Type\IDValue|null $ID The ID for this document. Defaults to null.
4344
* @param \SimpleSAML\SAML2\Type\SAMLDateTimeValue|null $validUntil Unix time of validity for this document.
4445
* Defaults to null.
@@ -57,7 +58,7 @@ abstract class AbstractRoleDescriptor extends AbstractRoleDescriptorType impleme
5758
*/
5859
public function __construct(
5960
protected QNameValue $type,
60-
array $protocolSupportEnumeration,
61+
AnyURIListValue $protocolSupportEnumeration,
6162
?IDValue $ID = null,
6263
?SAMLDateTimeValue $validUntil = null,
6364
?DurationValue $cacheDuration = null,
@@ -118,8 +119,6 @@ public static function fromXML(DOMElement $xml): static
118119
$handler = Utils::getContainer()->getExtensionHandler($type);
119120
if ($handler === null) {
120121
// we don't have a handler, proceed with unknown RoleDescriptor
121-
$protocols = self::getAttribute($xml, 'protocolSupportEnumeration', SAMLStringValue::class);
122-
123122
$orgs = Organization::getChildrenOfClass($xml);
124123
Assert::maxCount(
125124
$orgs,
@@ -139,7 +138,7 @@ public static function fromXML(DOMElement $xml): static
139138
return new UnknownRoleDescriptor(
140139
new Chunk($xml),
141140
$type,
142-
preg_split('/[\s]+/', trim($protocols->getValue())),
141+
self::getAttribute($xml, 'protocolSupportEnumeration', AnyURIListValue::class),
143142
self::getOptionalAttribute($xml, 'ID', IDValue::class, null),
144143
self::getOptionalAttribute($xml, 'validUntil', SAMLDateTimeValue::class, null),
145144
self::getOptionalAttribute($xml, 'cacheDuration', DurationValue::class, null),

src/XML/md/AbstractRoleDescriptorType.php

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@
66

77
use DOMElement;
88
use SimpleSAML\SAML2\Assert\Assert;
9-
use SimpleSAML\SAML2\Assert\Assert as SAMLAssert;
109
use SimpleSAML\SAML2\Constants as C;
11-
use SimpleSAML\SAML2\Type\{SAMLAnyURIValue, SAMLDateTimeValue};
12-
use SimpleSAML\XML\Exception\SchemaViolationException;
10+
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
11+
use SimpleSAML\SAML2\Type\{AnyURIListValue, SAMLAnyURIValue, SAMLDateTimeValue};
1312
use SimpleSAML\XML\ExtendableAttributesTrait;
1413
use SimpleSAML\XML\Type\{DurationValue, IDValue};
1514
use SimpleSAML\XML\XsNamespace as NS;
1615

17-
use function implode;
16+
use function strval;
1817

1918
/**
2019
* Class representing SAML2 RoleDescriptorType.
@@ -33,7 +32,8 @@ abstract class AbstractRoleDescriptorType extends AbstractMetadataDocument
3332
/**
3433
* Initialize a RoleDescriptor.
3534
*
36-
* @param string[] $protocolSupportEnumeration A set of URI specifying the protocols supported.
35+
* @param \SimpleSAML\SAML2\Type\AnyURIListValue $protocolSupportEnumeration
36+
* A set of URI specifying the protocols supported.
3737
* @param \SimpleSAML\XML\Type\IDValue|null $ID The ID for this document. Defaults to null.
3838
* @param \SimpleSAML\SAML2\Type\SAMLDateTimeValue|null $validUntil Unix time of validity for this document.
3939
* Defaults to null.
@@ -51,7 +51,7 @@ abstract class AbstractRoleDescriptorType extends AbstractMetadataDocument
5151
* @param list<\SimpleSAML\XML\Attribute> $namespacedAttributes
5252
*/
5353
public function __construct(
54-
protected array $protocolSupportEnumeration,
54+
protected AnyURIListValue $protocolSupportEnumeration,
5555
?IDValue $ID = null,
5656
?SAMLDateTimeValue $validUntil = null,
5757
?DurationValue $cacheDuration = null,
@@ -62,13 +62,18 @@ public function __construct(
6262
protected array $contact = [],
6363
array $namespacedAttributes = [],
6464
) {
65-
Assert::maxCount($protocolSupportEnumeration, C::UNBOUNDED_LIMIT);
66-
Assert::minCount(
67-
$protocolSupportEnumeration,
68-
1,
69-
'At least one protocol must be supported by this ' . static::NS_PREFIX . ':' . static::getLocalName() . '.',
65+
/**
66+
* A whitespace-delimited set of URIs that identify the set of protocol specifications supported by the
67+
* role element. For SAML V2.0 entities, this set MUST include the SAML protocol namespace URI,
68+
* urn:oasis:names:tc:SAML:2.0:protocol.
69+
*/
70+
Assert::contains(
71+
strval($protocolSupportEnumeration),
72+
C::NS_SAMLP,
73+
'SAML v2.0 entities MUST include the SAML protocol namespace URI in their'
74+
. ' protocolSupportEnumeration attribute',
75+
ProtocolViolationException::class,
7076
);
71-
SAMLAssert::allValidURI($protocolSupportEnumeration, SchemaViolationException::class);
7277
Assert::maxCount($contact, C::UNBOUNDED_LIMIT);
7378
Assert::allIsInstanceOf(
7479
$contact,
@@ -102,9 +107,9 @@ public function getErrorURL(): ?SAMLAnyURIValue
102107
/**
103108
* Collect the value of the protocolSupportEnumeration property.
104109
*
105-
* @return string[]
110+
* @return \SimpleSAML\SAML2\Type\AnyURIListValue
106111
*/
107-
public function getProtocolSupportEnumeration(): array
112+
public function getProtocolSupportEnumeration(): AnyURIListValue
108113
{
109114
return $this->protocolSupportEnumeration;
110115
}
@@ -152,10 +157,10 @@ public function getKeyDescriptor(): array
152157
public function toUnsignedXML(?DOMElement $parent = null): DOMElement
153158
{
154159
$e = parent::toUnsignedXML($parent);
155-
$e->setAttribute('protocolSupportEnumeration', implode(' ', $this->getProtocolSupportEnumeration()));
160+
$e->setAttribute('protocolSupportEnumeration', strval($this->getProtocolSupportEnumeration()));
156161

157162
if ($this->getErrorURL() !== null) {
158-
$e->setAttribute('errorURL', $this->getErrorURL()->getValue());
163+
$e->setAttribute('errorURL', strval($this->getErrorURL()));
159164
}
160165

161166
foreach ($this->getKeyDescriptor() as $kd) {

src/XML/md/AbstractSSODescriptor.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use DOMElement;
88
use SimpleSAML\SAML2\Assert\Assert;
99
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
10-
use SimpleSAML\SAML2\Type\{SAMLAnyURIValue, SAMLDateTimeValue};
10+
use SimpleSAML\SAML2\Type\{AnyURIListValue, SAMLAnyURIValue, SAMLDateTimeValue};
1111
use SimpleSAML\XML\Constants as C;
1212
use SimpleSAML\XML\Type\{IDValue, DurationValue};
1313

@@ -21,7 +21,8 @@ abstract class AbstractSSODescriptor extends AbstractRoleDescriptorType
2121
/**
2222
* Initialize a RoleDescriptor.
2323
*
24-
* @param string[] $protocolSupportEnumeration A set of URI specifying the protocols supported.
24+
* @param \SimpleSAML\SAML2\Type\AnyURIListValue $protocolSupportEnumeration
25+
* A set of URI specifying the protocols supported.
2526
* @param \SimpleSAML\XML\Type\IDValue|null $ID The ID for this document. Defaults to null.
2627
* @param \SimpleSAML\SAML2\Type\SAMLDateTimeValue|null $validUntil Unix time of validity for this document.
2728
* Defaults to null.
@@ -46,7 +47,7 @@ abstract class AbstractSSODescriptor extends AbstractRoleDescriptorType
4647
* Defaults to an empty array.
4748
*/
4849
public function __construct(
49-
array $protocolSupportEnumeration,
50+
AnyURIListValue $protocolSupportEnumeration,
5051
?IDValue $ID = null,
5152
?SAMLDateTimeValue $validUntil = null,
5253
?DurationValue $cacheDuration = null,

src/XML/md/AttributeAuthorityDescriptor.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@
66

77
use DOMElement;
88
use SimpleSAML\SAML2\Assert\Assert;
9-
use SimpleSAML\SAML2\Type\{SAMLAnyURIValue, SAMLDateTimeValue, SAMLStringValue};
9+
use SimpleSAML\SAML2\Type\{AnyURIListValue, SAMLAnyURIValue, SAMLDateTimeValue};
1010
use SimpleSAML\SAML2\XML\saml\Attribute;
1111
use SimpleSAML\XML\Constants as C;
1212
use SimpleSAML\XML\Exception\{InvalidDOMElementException, MissingElementException, TooManyElementsException};
1313
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
1414
use SimpleSAML\XML\Type\{DurationValue, IDValue};
1515
use SimpleSAML\XMLSecurity\XML\ds\Signature;
1616

17-
use function preg_split;
18-
1917
/**
2018
* Class representing SAML 2 metadata AttributeAuthorityDescriptor.
2119
*
@@ -31,7 +29,7 @@ final class AttributeAuthorityDescriptor extends AbstractRoleDescriptorType impl
3129
* AttributeAuthorityDescriptor constructor.
3230
*
3331
* @param \SimpleSAML\SAML2\XML\md\AttributeService[] $attributeService
34-
* @param string[] $protocolSupportEnumeration
32+
* @param \SimpleSAML\SAML2\Type\AnyURIListValue $protocolSupportEnumeration
3533
* @param \SimpleSAML\SAML2\XML\md\AssertionIDRequestService[] $assertionIDRequestService
3634
* @param \SimpleSAML\SAML2\XML\md\NameIDFormat[] $nameIDFormat
3735
* @param \SimpleSAML\SAML2\XML\md\AttributeProfile[] $attributeProfile
@@ -48,7 +46,7 @@ final class AttributeAuthorityDescriptor extends AbstractRoleDescriptorType impl
4846
*/
4947
public function __construct(
5048
protected array $attributeService,
51-
array $protocolSupportEnumeration,
49+
AnyURIListValue $protocolSupportEnumeration,
5250
protected array $assertionIDRequestService = [],
5351
protected array $nameIDFormat = [],
5452
protected array $attributeProfile = [],
@@ -175,8 +173,6 @@ public static function fromXML(DOMElement $xml): static
175173
Assert::same($xml->localName, 'AttributeAuthorityDescriptor', InvalidDOMElementException::class);
176174
Assert::same($xml->namespaceURI, AttributeAuthorityDescriptor::NS, InvalidDOMElementException::class);
177175

178-
$protocols = self::getAttribute($xml, 'protocolSupportEnumeration', SAMLStringValue::class);
179-
180176
$attrServices = AttributeService::getChildrenOfClass($xml);
181177
Assert::notEmpty(
182178
$attrServices,
@@ -215,7 +211,7 @@ public static function fromXML(DOMElement $xml): static
215211

216212
$authority = new static(
217213
$attrServices,
218-
preg_split('/[\s]+/', $protocols->getValue()),
214+
self::getAttribute($xml, 'protocolSupportEnumeration', AnyURIListValue::class),
219215
$assertIDReqServices,
220216
$nameIDFormats,
221217
$attrProfiles,

src/XML/md/AuthnAuthorityDescriptor.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,13 @@
66

77
use DOMElement;
88
use SimpleSAML\SAML2\Assert\Assert;
9-
use SimpleSAML\SAML2\Type\{SAMLAnyURIValue, SAMLDateTimeValue};
9+
use SimpleSAML\SAML2\Type\{AnyURIListValue, SAMLAnyURIValue, SAMLDateTimeValue};
1010
use SimpleSAML\XML\Constants as C;
1111
use SimpleSAML\XML\Exception\{InvalidDOMElementException, TooManyElementsException};
1212
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
1313
use SimpleSAML\XML\Type\{DurationValue, IDValue};
1414
use SimpleSAML\XMLSecurity\XML\ds\Signature;
1515

16-
use function preg_split;
17-
1816
/**
1917
* Class representing SAML 2 metadata AuthnAuthorityDescriptor.
2018
*
@@ -29,7 +27,7 @@ final class AuthnAuthorityDescriptor extends AbstractRoleDescriptorType implemen
2927
* AuthnAuthorityDescriptor constructor.
3028
*
3129
* @param array $authnQueryService
32-
* @param array $protocolSupportEnumeration
30+
* @param \SimpleSAML\SAML2\Type\AnyURIListValue $protocolSupportEnumeration
3331
* @param array $assertionIDRequestService
3432
* @param array $nameIDFormat
3533
* @param \SimpleSAML\XML\Type\IDValue|null $ID
@@ -44,7 +42,7 @@ final class AuthnAuthorityDescriptor extends AbstractRoleDescriptorType implemen
4442
*/
4543
public function __construct(
4644
protected array $authnQueryService,
47-
array $protocolSupportEnumeration,
45+
AnyURIListValue $protocolSupportEnumeration,
4846
protected array $assertionIDRequestService = [],
4947
protected array $nameIDFormat = [],
5048
?IDValue $ID = null,
@@ -139,8 +137,6 @@ public static function fromXML(DOMElement $xml): static
139137
Assert::same($xml->localName, 'AuthnAuthorityDescriptor', InvalidDOMElementException::class);
140138
Assert::same($xml->namespaceURI, AuthnAuthorityDescriptor::NS, InvalidDOMElementException::class);
141139

142-
$protocols = self::getAttribute($xml, 'protocolSupportEnumeration');
143-
144140
$authnQueryServices = AuthnQueryService::getChildrenOfClass($xml);
145141
$assertionIDRequestServices = AssertionIDRequestService::getChildrenOfClass($xml);
146142
$nameIDFormats = NameIDFormat::getChildrenOfClass($xml);
@@ -171,7 +167,7 @@ public static function fromXML(DOMElement $xml): static
171167

172168
$authority = new static(
173169
$authnQueryServices,
174-
preg_split('/[\s]+/', trim($protocols->getValue())),
170+
self::getAttribute($xml, 'protocolSupportEnumeration', AnyURIListValue::class),
175171
$assertionIDRequestServices,
176172
$nameIDFormats,
177173
self::getOptionalAttribute($xml, 'ID', IDValue::class, null),

0 commit comments

Comments
 (0)