Skip to content

Commit

Permalink
Add wst classes
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Jan 25, 2024
1 parent 284dc6b commit af2fbd1
Show file tree
Hide file tree
Showing 8 changed files with 373 additions and 0 deletions.
173 changes: 173 additions & 0 deletions src/XML/wst/AbstractRequestSecurityTokenType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\wst;

use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\WSSecurity\Constants as C;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\ExtendableAttributesTrait;
use SimpleSAML\XML\ExtendableElementTrait;
use SimpleSAML\XML\XsNamespace as NS;

use function array_pop;

/**
* Class defining the RequestSecurityTokenType element
*
* @package tvdijen/ws-security
*/
abstract class AbstractRequestSecurityTokenType extends AbstractWstElement
{
use ExtendableAttributesTrait;
use ExtendableElementTrait;

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

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


/**
* AbstractRequestSecurityTokenType constructor
*
* @param string|null $context
* @param \SimpleSAML\XML\SerializableElementInterface[] $children
* @param \SimpleSAML\XML\Attributes[] $namepacedAttributes
*/
final public function __construct(
protected ?string $context = null,
array $children = [],
array $namespacedAttributes = []
) {
Assert::nullOrValidURI($context, SchemaViolationException::class);

$this->setElements($children);
$this->setAttributesNS($namespacedAttributes);
}


/**
* @return string|null
*/
public function getContext(): ?string
{
return $this->context;
}


/**
* 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->getContext())
&& empty($this->getElements())
&& empty($this->getAttributesNS());
}


/**
* Create an instance of this object from its XML representation.
*
* @param \DOMElement $xml
* @return static
*
* @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
* if the qualified name of the supplied element is wrong
*/
public static function fromXML(DOMElement $xml): static
{
Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);

$children = [];
foreach ($xml->childNodes as $child) {
if (!($child instanceof DOMElement)) {
continue;
} elseif ($child->namespaceURI === C::NS_TRUST) {
$children[] = match ($child->localName) {
'AllowPostdating' => AllowPostdating::fromXML($child),
'AuthenticationType' => AuthenticationType::fromXML($child),
'Authenticator' => Authenticator::fromXML($child),
'CanonicalizationAlgorithm' => CanonicalizationAlgorithm::fromXML($child),
'Delegatable' => Delegatable::fromXML($child),
'DelegateTo' => DelegateTo::fromXML($child),
'Encryption' => Encryption::fromXML($child),
'EncryptionAlgorithm' => EncryptionAlgorithm::fromXML($child),
'EncryptWith' => EncryptWith::fromXML($child),
'Entropy' => Entropy::fromXML($child),
'Forwardable' => Forwardable::fromXML($child),
'KeySize' => KeySize::fromXML($child),
'KeyType' => KeyType::fromXML($child),
'Lifetime' => Lifetime::fromXML($child),
'OnBehalfOf' => OnBehalfOf::fromXML($child),
'ProofEncryption' => ProofEncryption::fromXML($child),
'Renewing' => Renewing::fromXML($child),
'RequestedAttachedReference' => RequestedAttachedReference::fromXML($child),
'RequestedProofToken' => RequestedProofToken::fromXML($child),
'RequestedSecurityToken' => RequestedSecurityToken::fromXML($child),
'RequestedUnattachedReference' => RequestedUnattachedReference::fromXML($child),
'RequestType' => RequestType::fromXML($child),
'SignatureAlgorithm' => SignatureAlgorithm::fromXML($child),
'SignWith' => SignWith::fromXML($child),
'Status' => Status::fromXML($child),
'UseKey' => UseKey::fromXML($child),
default => Chunk::fromXML($child),
};
continue;
} elseif ($child->namespaceURI === C::NS_POLICY) {
$children[] = match ($child->localName) {
'Policy' => Policy::fromXML($child),
'PolicyReference' => PolicyReference::fromXML($child),
'AppliesTo' => AppliesTo::fromXML($child),
default => Chunk::fromXML($child),
};
continue;
}

$children[] = new Chunk($child);
}

return new static(
self::getOptionalAttribute($xml, 'Context'),
$children,
self::getAttributesNSFromXML($xml),
);
}


/**
* Add this RequestSecurityTokenType to an XML element.
*
* @param \DOMElement $parent The element we should append this username token to.
* @return \DOMElement
*/
public function toXML(DOMElement $parent = null): DOMElement
{
$e = parent::instantiateParentElement($parent);

if ($this->getContext() !== null) {
$e->setAttribute('Context', $this->getContext());
}

foreach ($this->getAttributesNS() as $attr) {
$attr->toXML($e);
}

foreach ($this->getElements() as $child) {
if (!$child->isEmptyElement()) {
$child->toXML($e);
}
}

return $e;
}
}
30 changes: 30 additions & 0 deletions src/XML/wst/AbstractRequestTypeOpenEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\wst;

use SimpleSAML\XML\URIElementTrait;

/**
* A RequestTypeOpenEnum element
*
* @package tvdijen/ws-security
*/
abstract class AbstractRequestTypeOpenEnum extends AbstractWstElement
{
use URIElementTrait;


/**
* @param \SimpleSAML\WSSecurity\XML\wst\RequestTypeEnum|string $content
*/
public function __construct(RequestTypeEnum|string $content)
{
if ($content instanceof RequestTypeEnum) {
$content = $content->value;
}

$this->setContent($content);
}
}
14 changes: 14 additions & 0 deletions src/XML/wst/RequestSecurityToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\wst;

/**
* A RequestSecurityToken element
*
* @package tvdijen/ws-security
*/
final class RequestSecurityToken extends AbstractRequestSecurityTokenType
{
}
14 changes: 14 additions & 0 deletions src/XML/wst/RequestType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\wst;

/**
* A RequestType element
*
* @package tvdijen/ws-security
*/
final class RequestType extends AbstractRequestTypeOpenEnum
{
}
78 changes: 78 additions & 0 deletions tests/WSSecurity/XML/wst/RequestSecurityTokenTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\Test\WSSecurity\XML\wst;

use PHPUnit\Framework\TestCase;
use SimpleSAML\SOAP\Constants as SOAP;
use SimpleSAML\Test\WSSecurity\Constants as C;
use SimpleSAML\WSSecurity\XML\wsa\MessageID;
use SimpleSAML\WSSecurity\XML\wst\RequestSecurityToken;
use SimpleSAML\XML\Attribute as XMLAttribute;
use SimpleSAML\XML\DOMDocumentFactory;
use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait;
use SimpleSAML\XML\TestUtils\SerializableElementTestTrait;

use function dirname;

/**
* Class \SimpleSAML\WSSecurity\XML\wst\RequestSecurityTokenTest
*
* @covers \SimpleSAML\WSSecurity\XML\wst\RequestSecurityToken
* @covers \SimpleSAML\WSSecurity\XML\wst\AbstractRequestSecurityTokenType
* @covers \SimpleSAML\WSSecurity\XML\wst\AbstractWstElement
*
* @package tvdijen/ws-security
*/
final class RequestSecurityTokenTest extends TestCase
{
use SchemaValidationTestTrait;
use SerializableElementTestTrait;


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

self::$testedClass = RequestSecurityToken::class;

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


// test marshalling


/**
* Test creating a RequestSecurityToken object from scratch.
*/
public function testMarshalling(): void
{
$attr1 = new XMLAttribute(SOAP::NS_SOAP_ENV_11, 'soapenv', 'mustUnderstand', '1');
$attr2 = new XMLAttribute(C::NAMESPACE, 'ssp', 'attr1', 'testval1');
$msgId = new MessageID('uuid:d0ccf3cd-2dce-4c1a-a5d6-be8912ecd7de', [$attr1]);

$RequestSecurityToken = new RequestSecurityToken(C::NAMESPACE, [$msgId], [$attr2]);

$this->assertEquals(
self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
strval($RequestSecurityToken),
);
}


/**
* Test creating an empty RequestSecurityToken object from scratch.
*/
public function testMarshallingEmpty(): void
{
$RequestSecurityToken = new RequestSecurityToken();

$this->assertTrue($RequestSecurityToken->isEmptyElement());
}
}
60 changes: 60 additions & 0 deletions tests/WSSecurity/XML/wst/RequestTypeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\Test\WSSecurity\XML\wst;

use PHPUnit\Framework\TestCase;
use SimpleSAML\WSSecurity\XML\wst\RequestType;
use SimpleSAML\WSSecurity\XML\wst\RequestTypeEnum;
use SimpleSAML\XML\DOMDocumentFactory;
use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait;
use SimpleSAML\XML\TestUtils\SerializableElementTestTrait;

use function dirname;

/**
* Class \SimpleSAML\WSSecurity\XML\wst\RequestTypeTest
*
* @covers \SimpleSAML\WSSecurity\XML\wst\RequestType
* @covers \SimpleSAML\WSSecurity\XML\wst\AbstractRequestTypeOpenEnum
* @covers \SimpleSAML\WSSecurity\XML\wst\AbstractWstElement
*
* @package tvdijen/ws-security
*/
final class RequestTypeTest extends TestCase
{
use SchemaValidationTestTrait;
use SerializableElementTestTrait;


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

self::$testedClass = RequestType::class;

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


// test marshalling


/**
* Test creating a RequestType object from scratch.
*/
public function testMarshalling(): void
{
$requestType = new RequestType(RequestTypeEnum::Issue);

$this->assertEquals(
self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
strval($requestType),
);
}
}
3 changes: 3 additions & 0 deletions tests/resources/xml/wst_RequestSecurityToken.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<wst:RequestSecurityToken xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512/" xmlns:ssp="urn:x-simplesamlphp:namespace" Context="urn:x-simplesamlphp:namespace" ssp:attr1="testval1">
<wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" soapenv:mustUnderstand="1">uuid:d0ccf3cd-2dce-4c1a-a5d6-be8912ecd7de</wsa:MessageID>
</wst:RequestSecurityToken>
1 change: 1 addition & 0 deletions tests/resources/xml/wst_RequestType.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<wst:RequestType xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512/">http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</wst:RequestType>

0 comments on commit af2fbd1

Please sign in to comment.