From 2a697b35ca48319be136625b460c27645e8765ce Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Fri, 29 Dec 2023 23:52:12 +0100 Subject: [PATCH] Add securitypolicy classes --- src/XML/sp/AbstractKeyValueTokenType.php | 156 ++++++++++++++++++ src/XML/sp/KeyValueToken.php | 16 ++ tests/WSSecurity/XML/sp/IssuedTokenTest.php | 2 +- tests/WSSecurity/XML/sp/KeyValueTokenTest.php | 84 ++++++++++ tests/resources/xml/sp_KeyValueToken.xml | 3 + 5 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 src/XML/sp/AbstractKeyValueTokenType.php create mode 100644 src/XML/sp/KeyValueToken.php create mode 100644 tests/WSSecurity/XML/sp/KeyValueTokenTest.php create mode 100644 tests/resources/xml/sp_KeyValueToken.xml diff --git a/src/XML/sp/AbstractKeyValueTokenType.php b/src/XML/sp/AbstractKeyValueTokenType.php new file mode 100644 index 00000000..500bbf8d --- /dev/null +++ b/src/XML/sp/AbstractKeyValueTokenType.php @@ -0,0 +1,156 @@ + $elts + * @param list<\SimpleSAML\XML\Attribute> $namespacedAttributes + */ + final public function __construct( + ?IncludeToken $includeToken = null, + array $elts = [], + array $namespacedAttributes = [] + ) { + $this->setIncludeToken($includeToken); + $this->setElements($elts); + $this->setAttributesNS($namespacedAttributes); + } + + + /** + * Test if an object, at the state it's in, would produce an empty XML-element + * + * @return bool + */ + public function isEmptyElement(): bool + { + return empty($this->getIncludeToken()) + && empty($this->getAttributesNS()) + && empty($this->getElements()); + } + + + /** + * Initialize an KeyValueTokenType. + * + * Note: this method cannot be used when extending this class, if the constructor has a different signature. + * + * @param \DOMElement $xml The XML element we should load. + * @return static + * + * @throws \SimpleSAML\XML\Exception\InvalidDOMElementException + * if the qualified name of the supplied element is wrong + */ + public static function fromXML(DOMElement $xml): static + { + $qualifiedName = static::getClassName(static::class); + Assert::eq( + $xml->localName, + $qualifiedName, + sprintf('Unexpected name for KeyValueTokenType: %s. Expected: %s.', $xml->localName, $qualifiedName), + InvalidDOMElementException::class + ); + + try { + $includeToken = IncludeToken::from(self::getOptionalAttribute($xml, 'IncludeToken', null)); + } catch (ValueError) { + self::getOptionalAttribute($xml, 'IncludeToken', null); + } + + $elements = []; + foreach ($xml->childNodes as $element) { + if ($element->namespaceURI === static::NS) { + continue; + } elseif (!($element instanceof DOMElement)) { + continue; + } + + $elements[] = new Chunk($element); + } + + $namespacedAttributes = self::getAttributesNSFromXML($xml); + foreach ($namespacedAttributes as $i => $attr) { + if ($attr->getNamespaceURI() === null) { + if ($attr->getAttrName() === 'IncludeToken') { + unset($namespacedAttributes[$i]); + break; + } + } + } + + + return new static( + $includeToken, + $elements, + $namespacedAttributes, + ); + } + + + /** + * Convert this element to XML. + * + * @param \DOMElement|null $parent The element we should append this element to. + * @return \DOMElement + */ + public function toXML(DOMElement $parent = null): DOMElement + { + $e = $this->instantiateParentElement($parent); + + if ($this->getIncludeToken() !== null) { + $e->setAttribute( + 'IncludeToken', + is_string($this->getIncludeToken()) ? $this->getIncludeToken() : $this->getIncludeToken()->value, + ); + } + + foreach ($this->getElements() as $elt) { + $elt->toXML($e); + } + + foreach ($this->getAttributesNS() as $attr) { + $attr->toXML($e); + } + + return $e; + } +} diff --git a/src/XML/sp/KeyValueToken.php b/src/XML/sp/KeyValueToken.php new file mode 100644 index 00000000..eb87bc51 --- /dev/null +++ b/src/XML/sp/KeyValueToken.php @@ -0,0 +1,16 @@ +assertEquals( + "", + strval($keyValueToken), + ); + $this->assertTrue($keyValueToken->isEmptyElement()); + } + + + /** + * Test that creating a KeyValueToken from scratch works. + */ + public function testMarshalling(): void + { + $attr = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'value1'); + $chunk = new Chunk(DOMDocumentFactory::fromString( + 'some' + )->documentElement); + + $keyValueToken = new KeyValueToken(IncludeToken::Always, [$chunk], [$attr]); + $this->assertEquals( + self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), + strval($keyValueToken), + ); + } +} diff --git a/tests/resources/xml/sp_KeyValueToken.xml b/tests/resources/xml/sp_KeyValueToken.xml new file mode 100644 index 00000000..9dfa1952 --- /dev/null +++ b/tests/resources/xml/sp_KeyValueToken.xml @@ -0,0 +1,3 @@ + + some +