Skip to content

Commit

Permalink
Add support for xs:dateTime AttributeValue and improve tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Sep 2, 2024
1 parent a30604e commit 166cd28
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 3 deletions.
30 changes: 27 additions & 3 deletions src/SAML2/XML/saml/AttributeValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace SimpleSAML\SAML2\XML\saml;

use DateTimeImmutable;
use DateTimeInterface;
use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML2\Constants as C;
Expand All @@ -27,7 +29,7 @@ class AttributeValue extends AbstractSamlElement
/**
* Create an AttributeValue.
*
* @param string|int|null|\SimpleSAML\XML\AbstractElement $value The value of this element. Can be one of:
* @param string|int|null|\DateTimeInterface|\SimpleSAML\XML\AbstractElement $value The value of this element. Can be one of:
* - string
* - int
* - null
Expand All @@ -36,7 +38,7 @@ class AttributeValue extends AbstractSamlElement
* @throws \SimpleSAML\Assert\AssertionFailedException if the supplied value is neither a string or a DOMElement
*/
final public function __construct(
protected string|int|null|AbstractElement $value,
protected string|int|null|DateTimeInterface|AbstractElement $value,
) {
}

Expand All @@ -56,6 +58,10 @@ public function getXsiType(): string
case "NULL":
return "xs:nil";
case "object":
if ($this->value instanceof DateTimeInterface) {
return 'xs:dateTime';
}

return sprintf(
'%s:%s',
$this->value::getNamespacePrefix(),
Expand Down Expand Up @@ -111,14 +117,25 @@ public static function fromXML(DOMElement $xml): static
$xml->hasAttributeNS(C::NS_XSI, "type") &&
$xml->getAttributeNS(C::NS_XSI, "type") === "xs:integer"
) {
Assert::numeric($xml->textContent);

// we have an integer as value
$value = intval($xml->textContent);
} elseif (
$xml->hasAttributeNS(C::NS_XSI, "type") &&
$xml->getAttributeNS(C::NS_XSI, "type") === "xs:dateTime"
) {
Assert::validDateTime($xml->textContent);

// we have a dateTime as value
$value = new DateTimeImmutable($xml->textContent);
} elseif (
// null value
$xml->hasAttributeNS(C::NS_XSI, "nil") &&
($xml->getAttributeNS(C::NS_XSI, "nil") === "1" ||
$xml->getAttributeNS(C::NS_XSI, "nil") === "true")
) {
Assert::isEmpty($xml->textContent);
$value = null;
} else {
$value = $xml->textContent;
Expand Down Expand Up @@ -155,7 +172,14 @@ public function toXML(DOMElement $parent = null): DOMElement
$e->textContent = '';
break;
case "object":
$this->getValue()->toXML($e);
if ($this->value instanceof DateTimeInterface) {
$e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C::NS_XSI);
$e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xs', C::NS_XS);
$e->setAttributeNS(C::NS_XSI, 'xsi:type', 'xs:dateTime');
$e->textContent = $this->value->format(C::DATETIME_FORMAT);
} else {
$this->getValue()->toXML($e);
}
break;
default: // string
$e->textContent = $this->getValue();
Expand Down
4 changes: 4 additions & 0 deletions tests/SAML2/XML/saml/AttributeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace SimpleSAML\Test\SAML2\XML\saml;

use DateTimeImmutable;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -88,6 +89,9 @@ public function testMarshalling(): void
[
new AttributeValue('FirstValue'),
new AttributeValue('SecondValue'),
new AttributeValue(3),
new AttributeValue(new DateTimeImmutable('2024-04-04T04:44:44Z')),
new AttributeValue(null),
],
[$attr1, $attr2],
);
Expand Down
25 changes: 25 additions & 0 deletions tests/SAML2/XML/saml/AttributeValueTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace SimpleSAML\Test\SAML2\XML\saml;

use DateTimeImmutable;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -77,6 +78,30 @@ public function testMarshallingString(): void
}


/**
* Test creating an AttributeValue from scratch using an integer.
*/
public function testMarshallingInteger(): void
{
$av = new AttributeValue(3);

$this->assertEquals(3, $av->getValue());
$this->assertEquals('xs:integer', $av->getXsiType());
}


/**
* Test creating an AttributeValue from scratch using an dateTime.
*/
public function testMarshallingDateTime(): void
{
$av = new AttributeValue(new DateTimeImmutable("2024-04-04T04:44:44Z"));

$this->assertEquals('2024-04-04T04:44:44Z', $av->getValue()->format(C::DATETIME_FORMAT));
$this->assertEquals('xs:dateTime', $av->getXsiType());
}


/**
*/
public function testMarshallingNull(): void
Expand Down
3 changes: 3 additions & 0 deletions tests/resources/xml/saml_Attribute.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<saml:Attribute xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Name="TheName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" FriendlyName="TheFriendlyName" test:attr1="testval1" test:attr2="testval2" xmlns:test="urn:test:something">
<saml:AttributeValue>FirstValue</saml:AttributeValue>
<saml:AttributeValue>SecondValue</saml:AttributeValue>
<saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:integer">3</saml:AttributeValue>
<saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:dateTime">2024-04-04T04:44:44Z</saml:AttributeValue>
<saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="1"/>
</saml:Attribute>

0 comments on commit 166cd28

Please sign in to comment.