Skip to content

Commit

Permalink
Add exclusion-list
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Sep 12, 2024
1 parent 25679ce commit 7d10ca7
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 33 deletions.
76 changes: 46 additions & 30 deletions src/ExtendableElementTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ trait ExtendableElementTrait
protected static function getChildElementsFromXML(DOMElement $xml, NS|array $namespace = null): array
{
$namespace = $namespace ?? static::XS_ANY_ELT_NAMESPACE;
$exclusionList = static::getElementExclusions();
$registry = ElementRegistry::getInstance();
$elements = [];

Expand All @@ -53,34 +54,21 @@ protected static function getChildElementsFromXML(DOMElement $xml, NS|array $nam
// Must be one of the predefined values
Assert::oneOf($namespace, NS::cases());

if ($namespace === NS::ANY) {
foreach ($xml->childElements as $elt) {
if ($elt instanceof DOMElement) {
$handler = $registry->getElementHandler($elt->namespaceURI, $elt->localName);
$elements[] = ($handler === null) ? Chunk::fromXML($xml) : $handler::fromXML($xml);
}
}
} elseif ($namespace === NS::LOCAL) {
foreach ($xml->childElements as $elt) {
if (($elt instanceof DOMElement) && ($elt->namespaceURI === null)) {
$handler = $registry->getElementHandler($elt->namespaceURI, $elt->localName);
$elements[] = ($handler === null) ? Chunk::fromXML($xml) : $handler::fromXML($xml);
}
}
} elseif ($namespace === NS::OTHER) {
foreach ($xml->childElements as $elt) {
if (($elt instanceof DOMElement) && !in_array($elt->namespaceURI, [static::NS, null], true)) {
$handler = $registry->getElementHandler($elt->namespaceURI, $elt->localName);
$elements[] = ($handler === null) ? Chunk::fromXML($xml) : $handler::fromXML($xml);
}
}
} elseif ($namespace === NS::TARGET) {
foreach ($xml->childElements as $elt) {
if (($elt instanceof DOMElement) && ($elt->namespaceURI === static::NS)) {
$handler = $registry->getElementHandler($elt->namespaceURI, $elt->localName);
$elements[] = ($handler === null) ? Chunk::fromXML($xml) : $handler::fromXML($xml);
}
foreach ($xml->childNodes as $elt) {
if (!($elt instanceof DOMElement)) {
continue;
} elseif (in_array([$elt->namespaceURI, $elt->localName], $exclusionList, true)) {
continue;
} elseif ($namespace === NS::OTHER && in_array($elt->namespaceURI, [static::NS, null], true)) {
continue;
} elseif ($namespace === NS::TARGET && $elt->namespaceURI !== static::NS) {
continue;
} elseif ($namespace === NS::LOCAL && $elt->namespaceURI !== null) {
continue;
}

$handler = $registry->getElementHandler($elt->namespaceURI, $elt->localName);
$elements[] = ($handler === null) ? Chunk::fromXML($xml) : $handler::fromXML($xml);
}
} else {
// Array must be non-empty and cannot contain ##any or ##other
Expand All @@ -100,10 +88,16 @@ protected static function getChildElementsFromXML(DOMElement $xml, NS|array $nam
}

foreach ($xml->childElements as $elt) {
if (($elt instanceof DOMElement) && in_array($elt->namespaceURI, $namespace, true)) {
$handler = $registry->getElementHandler($elt->namespaceURI, $elt->localName);
$elements[] = ($handler === null) ? Chunk::fromXML($xml) : $handler::fromXML($xml);
if (!($elt instanceof DOMElement)) {
continue;
} elseif (in_array([$elt->namespaceURI, $ely->localName], $exclusionList, true)) {
continue;
} elseif (!in_array($elt->namespaceURI, $namespace, true)) {
continue;
}

$handler = $registry->getElementHandler($elt->namespaceURI, $elt->localName);
$elements[] = ($handler === null) ? Chunk::fromXML($xml) : $handler::fromXML($xml);
}
}

Expand Down Expand Up @@ -183,6 +177,13 @@ function (SerializableElementInterface $elt) {
// XS_ANY_NS_ANY
}

$exclusionList = static::getElementExclusions();
foreach ($elements as $i => $elt) {
if (in_array([$elt->getNamespaceURI(), $elt->getLocalName()], $exclusionList, true)) {
unset($elements[$i]);
}
}

$this->elements = $elements;
}

Expand Down Expand Up @@ -212,4 +213,19 @@ public function getElementNamespace(): array|NS

return static::XS_ANY_ELT_NAMESPACE;
}


/**
* Get the exclusions list for getChildElementsFromXML.
*
* @return array<string, string>
*/
public static function getElementExclusions(): array
{
if (defined('static::XS_ANY_ELT_EXCLUSIONS')) {
return static::XS_ANY_ELT_EXCLUSIONS;
}

return [];
}
}
5 changes: 5 additions & 0 deletions tests/Utils/ExtendableElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ class ExtendableElement extends AbstractElement
/** @var \SimpleSAML\XML\XsNamespace|array<int, \SimpleSAML\XML\XsNamespace> */
public const XS_ANY_ELT_NAMESPACE = NS::ANY;

/** @var array{array{string, string}} */
public const XS_ANY_ELT_EXCLUSIONS = [
['urn:custom:other', 'Chunk'],
];


/**
* Get the namespace for the element.
Expand Down
35 changes: 33 additions & 2 deletions tests/XML/ExtendableElementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,28 @@ public static function setUpBeforeClass(): void
*/
public function testMarshalling(): void
{
$dummyDocument1 = DOMDocumentFactory::fromString('<ssp:Chunk xmlns:ssp="urn:x-simplesamlphp:namespace">some</ssp:Chunk>');
$dummyDocument2 = DOMDocumentFactory::fromString('<dummy:Chunk xmlns:dummy="urn:custom:dummy">some</dummy:Chunk>');
$dummyDocument1 = DOMDocumentFactory::fromString(
'<ssp:Chunk xmlns:ssp="urn:x-simplesamlphp:namespace">some</ssp:Chunk>',
);
$dummyDocument2 = DOMDocumentFactory::fromString(
'<dummy:Chunk xmlns:dummy="urn:custom:dummy">some</dummy:Chunk>',
);
$dummyDocument3 = DOMDocumentFactory::fromString(
'<other:Chunk xmlns:other="urn:custom:other">some</other:Chunk>',
);

/** @var \DOMElement $dummyElement1 */
$dummyElement1 = $dummyDocument1->documentElement;
/** @var \DOMElement $dummyElement2 */
$dummyElement2 = $dummyDocument2->documentElement;
/** @var \DOMElement $dummyElement3 */
$dummyElement3 = $dummyDocument3->documentElement;

$extendableElement = new ExtendableElement(
[
new Chunk($dummyElement1),
new Chunk($dummyElement2),
new Chunk($dummyElement3),
],
);

Expand All @@ -65,4 +75,25 @@ public function testMarshalling(): void
strval($extendableElement),
);
}


/**
*/
public function testGetChildElementsFromXML(): void
{
/** @var \DOMElement $element */
$element = self::$xmlRepresentation->documentElement;

$elt = ExtendableElement::fromXML($element);
/** @var \SimpleSAML\XML\Chunk[] $elements */
$elements = $elt->getElements();

$this->assertCount(2, $elements);
$this->assertEquals($elements[0]->getNamespaceURI(), 'urn:x-simplesamlphp:namespace');
$this->assertEquals($elements[0]->getPrefix(), 'ssp');
$this->assertEquals($elements[0]->getLocalName(), 'Chunk');
$this->assertEquals($elements[1]->getNamespaceURI(), 'urn:custom:dummy');
$this->assertEquals($elements[1]->getPrefix(), 'dummy');
$this->assertEquals($elements[1]->getLocalName(), 'Chunk');
}
}
2 changes: 1 addition & 1 deletion tests/resources/schemas/simplesamlphp.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<complexType name="ExtendableElementType">
<sequence>
<element ref="ssp:Chunk"/>
<any namespace="##other" processContents="lax"/>
<any namespace="##any" processContents="lax"/>
<!-- (1,1) elements from (1,1) external namespace -->
</sequence>
</complexType>
Expand Down

0 comments on commit 7d10ca7

Please sign in to comment.