From 217d89c8db3a4cfa45621505cfc634f75ab371c0 Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Tue, 31 Jan 2023 22:28:36 +0100 Subject: [PATCH 1/2] Implement saml:Evidence element --- src/SAML2/XML/saml/AbstractEvidenceType.php | 151 ++++++++++++++++++++ src/SAML2/XML/saml/Evidence.php | 14 ++ tests/SAML2/XML/saml/EvidenceTest.php | 107 ++++++++++++++ tests/resources/xml/saml_Evidence.xml | 59 ++++++++ 4 files changed, 331 insertions(+) create mode 100644 src/SAML2/XML/saml/AbstractEvidenceType.php create mode 100644 src/SAML2/XML/saml/Evidence.php create mode 100644 tests/SAML2/XML/saml/EvidenceTest.php create mode 100644 tests/resources/xml/saml_Evidence.xml diff --git a/src/SAML2/XML/saml/AbstractEvidenceType.php b/src/SAML2/XML/saml/AbstractEvidenceType.php new file mode 100644 index 000000000..e5dd6c41a --- /dev/null +++ b/src/SAML2/XML/saml/AbstractEvidenceType.php @@ -0,0 +1,151 @@ +assertionIDRef) + && empty($this->assertionURIRef) + && empty($this->assertion) + && empty($this->encryptedAssertion) + ); + } + + + /** + * @return \SimpleSAML\SAML2\XML\saml\AssertionIDRef[] + */ + public function getAssertionIDRef(): array + { + return $this->assertionIDRef; + } + + + /** + * @return \SimpleSAML\SAML2\XML\saml\AssertionURIRef[] + */ + public function getAssertionURIRef(): array + { + return $this->assertionURIRef; + } + + + /** + * @return \SimpleSAML\SAML2\XML\saml\Assertion[] + */ + public function getAssertion(): array + { + return $this->assertion; + } + + + /** + * @return \SimpleSAML\SAML2\XML\saml\EncryptedAssertion[] + */ + public function getEncryptedAssertion(): array + { + return $this->encryptedAssertion; + } + + + /** + * Convert XML into an AbstractEvidenceType + * + * @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, + 'Unexpected name for endpoint: ' . $xml->localName . '. Expected: ' . $qualifiedName . '.', + InvalidDOMElementException::class, + ); + + $assertionIDRef = AssertionIDRef::getChildrenOfClass($xml); + $assertionURIRef = AssertionURIRef::getChildrenOfClass($xml); + $assertion = Assertion::getChildrenOfClass($xml); + $encryptedAssertion = EncryptedAssertion::getChildrenOfClass($xml); + + return new static( + $assertionIDRef, + $assertionURIRef, + $assertion, + $encryptedAssertion, + ); + } + + + /** + * Convert this AbstractEvidenceType to XML. + * + * @param \DOMElement $parent The element we are converting to XML. + * @return \DOMElement The XML element after adding the data corresponding to this Condition. + */ + public function toXML(DOMElement $parent = null): DOMElement + { + $e = $this->instantiateParentElement($parent); + + foreach ($this->getAssertionIDRef() as $assertionIDRef) { + $assertionIDRef->toXML($e); + } + + foreach ($this->getAssertionURIRef() as $assertionURIRef) { + $assertionURIRef->toXML($e); + } + + foreach ($this->getAssertion() as $assertion) { + $assertion->toXML($e); + } + + foreach ($this->getEncryptedAssertion() as $encryptedAssertion) { + $encryptedAssertion->toXML($e); + } + + return $e; + } +} diff --git a/src/SAML2/XML/saml/Evidence.php b/src/SAML2/XML/saml/Evidence.php new file mode 100644 index 000000000..5c5f0be7e --- /dev/null +++ b/src/SAML2/XML/saml/Evidence.php @@ -0,0 +1,14 @@ +schema = dirname(__FILE__, 5) . '/schemas/saml-schema-assertion-2.0.xsd'; + + $this->testedClass = Evidence::class; + + $this->xmlRepresentation = DOMDocumentFactory::fromFile( + dirname(__FILE__, 4) . '/resources/xml/saml_Evidence.xml', + ); + + $this->assertionIDRef = DOMDocumentFactory::fromFile( + dirname(__FILE__, 4) . '/resources/xml/saml_AssertionIDRef.xml', + ); + + $this->assertionURIRef = DOMDocumentFactory::fromFile( + dirname(__FILE__, 4) . '/resources/xml/saml_AssertionURIRef.xml', + ); + + $this->assertion = DOMDocumentFactory::fromFile( + dirname(__FILE__, 4) . '/resources/xml/saml_Assertion.xml', + ); + + $this->encryptedAssertion = DOMDocumentFactory::fromFile( + dirname(__FILE__, 4) . '/resources/xml/saml_EncryptedAssertion.xml', + ); + } + + + /** + */ + public function testMarshalling(): void + { + $evidence = new Evidence( + [AssertionIDRef::fromXML($this->assertionIDRef->documentElement)], + [AssertionURIRef::fromXML($this->assertionURIRef->documentElement)], + [Assertion::fromXML($this->assertion->documentElement)], + [EncryptedAssertion::fromXML($this->encryptedAssertion->documentElement)], + ); + + $this->assertEquals( + $this->xmlRepresentation->saveXML($this->xmlRepresentation->documentElement), + strval($evidence), + ); + } + + + /** + */ + public function testUnmarshalling(): void + { + $evidence = Evidence::fromXML($this->xmlRepresentation->documentElement); + + $this->assertEquals( + $this->xmlRepresentation->saveXML($this->xmlRepresentation->documentElement), + strval($evidence), + ); + } +} diff --git a/tests/resources/xml/saml_Evidence.xml b/tests/resources/xml/saml_Evidence.xml new file mode 100644 index 000000000..fdb888884 --- /dev/null +++ b/tests/resources/xml/saml_Evidence.xml @@ -0,0 +1,59 @@ + + _Test + urn:x-simplesamlphp:reference + + Provider + + SomeNameIDValue + + SomeOtherNameIDValue + + + + + + https://simplesamlphp.org/sp/metadata + + + + + + urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport + + + + + 1 + + + 1 + + + 1 + + + + + + + + + + + sNLWjwyj/R0oPwSgNnqowahiOwM0YU3YaH3jsH0t2YUDcHkcgouvW5x6YbNdgvGq0ImsNrkjI//0hrL4HvrOX33+DkhCo2FX5+a7UCdftfBfSjvt0houF8z3Zq/XOm6HxBUbWt5MULYpMKMZ9iAY6+raydxk2tFWgnAyHaBfzvU= + + + + + + self::xenc:CipherValue[@Id="example1"] + + + + + + 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 + + + + From 08cc25943ef32cc46ec79b6a68666b40c43f266e Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Tue, 31 Jan 2023 23:06:50 +0100 Subject: [PATCH 2/2] Some fixes --- src/SAML2/XML/saml/AbstractEvidenceType.php | 8 ++++---- tests/SAML2/XML/saml/EvidenceTest.php | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/SAML2/XML/saml/AbstractEvidenceType.php b/src/SAML2/XML/saml/AbstractEvidenceType.php index e5dd6c41a..2e4f9ff31 100644 --- a/src/SAML2/XML/saml/AbstractEvidenceType.php +++ b/src/SAML2/XML/saml/AbstractEvidenceType.php @@ -23,10 +23,10 @@ abstract class AbstractEvidenceType extends AbstractSamlElement * @param \SimpleSAML\SAML2\XML\saml\EncryptedAssertion[] $encryptedAssertion */ final public function __construct( - protected array $assertionIDRef, - protected array $assertionURIRef, - protected array $assertion, - protected array $encryptedAssertion, + protected array $assertionIDRef = [], + protected array $assertionURIRef = [], + protected array $assertion = [], + protected array $encryptedAssertion = [], ) { Assert::allIsInstanceOf($assertionIDRef, AssertionIDRef::class, SchemaViolationException::class); Assert::allIsInstanceOf($assertionURIRef, AssertionURIRef::class, SchemaViolationException::class); diff --git a/tests/SAML2/XML/saml/EvidenceTest.php b/tests/SAML2/XML/saml/EvidenceTest.php index 1ec787d07..4a0c6c8b7 100644 --- a/tests/SAML2/XML/saml/EvidenceTest.php +++ b/tests/SAML2/XML/saml/EvidenceTest.php @@ -86,6 +86,8 @@ public function testMarshalling(): void [EncryptedAssertion::fromXML($this->encryptedAssertion->documentElement)], ); + $this->assertFalse($evidence->isEmptyElement()); + $this->assertEquals( $this->xmlRepresentation->saveXML($this->xmlRepresentation->documentElement), strval($evidence), @@ -93,6 +95,19 @@ public function testMarshalling(): void } + /** + */ + public function testMarshallingWithNoContent(): void + { + $evidence = new Evidence(); + $this->assertEquals( + '', + strval($evidence) + ); + $this->assertTrue($evidence->isEmptyElement()); + } + + /** */ public function testUnmarshalling(): void