Skip to content

Commit

Permalink
Add securitypolicy classes
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Dec 29, 2023
1 parent 243c288 commit 2a697b3
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 1 deletion.
156 changes: 156 additions & 0 deletions src/XML/sp/AbstractKeyValueTokenType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\sp;

use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\MissingElementException;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\Exception\TooManyElementsException;
use SimpleSAML\XML\ExtendableAttributesTrait;
use SimpleSAML\XML\ExtendableElementTrait;
use SimpleSAML\XML\XsNamespace as NS;
use ValueError;

use function array_pop;
use function is_string;
use function sprintf;

/**
* Class representing WS security policy KeyValueTokenType.
*
* @package tvdijen/ws-security
*/
abstract class AbstractKeyValueTokenType extends AbstractSpElement
{
use ExtendableAttributesTrait;
use ExtendableElementTrait;
use IncludeTokenTypeTrait;

/** The namespace-attribute for the xs:any element */
public const XS_ANY_ELT_NAMESPACE = NS::OTHER;

/** The namespace-attribute for the xs:anyAttribute element */
public const XS_ANY_ATTR_NAMESPACE = NS::ANY;


/**
* KeyValueTokenType constructor.
*
* @param \SimpleSAML\WSSecurity\XML\sp\IncludeToken|null $includeToken
* @param list<\SimpleSAML\XML\ElementInterface> $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;
}
}
16 changes: 16 additions & 0 deletions src/XML/sp/KeyValueToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\sp;

use SimpleSAML\Assert\Assert;

/**
* An KeyValueToken element
*
* @package tvdijen/ws-security
*/
final class KeyValueToken extends AbstractKeyValueTokenType
{
}
2 changes: 1 addition & 1 deletion tests/WSSecurity/XML/sp/IssuedTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public function testMarshallingElementOrdering(): void


/**
* Test that creating a RequiredParts from scratch works.
* Test that creating a IssuedToken from scratch works.
*/
public function testMarshalling(): void
{
Expand Down
84 changes: 84 additions & 0 deletions tests/WSSecurity/XML/sp/KeyValueTokenTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\Test\WSSecurity\XML\sp;

use DOMDocument;
use PHPUnit\Framework\TestCase;
use SimpleSAML\Test\WSSecurity\Constants as C;
use SimpleSAML\WSSecurity\Utils\XPath;
use SimpleSAML\WSSecurity\XML\sp\IncludeToken;
use SimpleSAML\WSSecurity\XML\sp\KeyValueToken;
use SimpleSAML\XML\Attribute as XMLAttribute;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\DOMDocumentFactory;
use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait;
use SimpleSAML\XML\TestUtils\SerializableElementTestTrait;

use function dirname;

/**
* Class \SimpleSAML\WSSecurity\XML\sp\KeyValueTokenTest
*
* @covers \SimpleSAML\WSSecurity\XML\sp\KeyValueToken
* @covers \SimpleSAML\WSSecurity\XML\sp\AbstractKeyValueTokenType
* @covers \SimpleSAML\WSSecurity\XML\sp\AbstractSpElement
*
* @package tvdijen/ws-security
*/
final class KeyValueTokenTest extends TestCase
{
use SchemaValidationTestTrait;
use SerializableElementTestTrait;


/**
*/
public static function setUpBeforeClass(): void
{
self::$schemaFile = dirname(__FILE__, 5) . '/resources/schemas/ws-securitypolicy-1.2.xsd';

self::$testedClass = KeyValueToken::class;

self::$xmlRepresentation = DOMDocumentFactory::fromFile(
dirname(__FILE__, 4) . '/resources/xml/sp_KeyValueToken.xml',
);
}


// test marshalling


/**
* Adding an empty KeyValueToken element should yield an empty element.
*/
public function testMarshallingEmptyElement(): void
{
$spns = C::NS_SEC_POLICY;
$keyValueToken = new KeyValueToken();
$this->assertEquals(
"<sp:KeyValueToken xmlns:sp=\"$spns\"/>",
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(
'<ssp:Chunk xmlns:ssp="urn:x-simplesamlphp:namespace">some</ssp:Chunk>'
)->documentElement);

$keyValueToken = new KeyValueToken(IncludeToken::Always, [$chunk], [$attr]);
$this->assertEquals(
self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
strval($keyValueToken),
);
}
}
3 changes: 3 additions & 0 deletions tests/resources/xml/sp_KeyValueToken.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<sp:KeyValueToken xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" xmlns:ssp="urn:x-simplesamlphp:namespace" IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Always" ssp:attr1="value1">
<ssp:Chunk>some</ssp:Chunk>
</sp:KeyValueToken>

0 comments on commit 2a697b3

Please sign in to comment.