Skip to content

Commit

Permalink
WIP: create fed classes
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Jan 6, 2024
1 parent dc144d9 commit 034288c
Show file tree
Hide file tree
Showing 7 changed files with 510 additions and 0 deletions.
195 changes: 195 additions & 0 deletions src/XML/fed/AbstractReferenceTokenType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\fed;

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

/**
* A ReferenceTokenType
*
* @package tvdijen/ws-security
*/
abstract class AbstractReferenceTokenType extends AbstractFedElement
{
use ExtendableAttributesTrait;
use ExtendableElementTrait;

/** 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;


/**
* ReferenceTokenType constructor.
*
* @param \SimpleSAML\WSSecurity\XML\fed\ReferenceEPR[] $referenceEPR
* @param \SimpleSAML\WSSecurity\XML\fed\ReferenceDigest|null $referenceDigest
* @param \SimpleSAML\WSSecurity\XML\fed\ReferenceType|null $referenceType
* @param \SimpleSAML\WSSecurity\XML\fed\SerialNo|null $serialNo
* @param \SimpleSAML\XML\ElementInterface[] $children
* @param \SimpleSAML\XML\Attribute[] $namespacedAttributes
*/
final public function __construct(
protected array $referenceEPR = [],
protected ?ReferenceDigest $referenceDigest = null,
protected ?ReferenceType $referenceType = null,
protected ?SerialNo $serialNo = null,
array $children = [],
array $namespacedAttributes = [],
) {
Assert::minCount($referenceEPR, 1, MissingElementException::class);
Assert::allIsInstanceOf(
$referenceEPR,
ReferenceEPR::class,
SchemaViolationException::class,
);

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


/**
* Collect the value of the referenceEPR-property
*
* @return \SimpleSAML\WSSecurity\XML\fed\ReferenceEPR[]
*/
public function getReferenceEPR(): array
{
return $this->referenceEPR;
}


/**
* Collect the value of the referenceDigest-property
*
* @return \SimpleSAML\WSSecurity\XML\fed\ReferenceDigest|null
*/
public function getReferenceDigest(): ?ReferenceDigest
{
return $this->referenceDigest;
}


/**
* Collect the value of the referenceType-property
*
* @return \SimpleSAML\WSSecurity\XML\fed\ReferenceType|null
*/
public function getReferenceType(): ?ReferenceType
{
return $this->referenceType;
}


/**
* Collect the value of the serialNo-property
*
* @return \SimpleSAML\WSSecurity\XML\fed\SerialNo|null
*/
public function getSerialNo(): ?SerialNo
{
return $this->serialNo;
}


/**
* 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->getReferenceEPR())
&& empty($this->getReferenceDigest())
&& empty($this->getReferenceType())
&& empty($this->getSerialNo())
&& 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);

$referenceEPR = ReferenceEPR::getChildrenOfClass($xml);
$referenceDigest = ReferenceDigest::getChildrenOfClass($xml);
$referenceType = ReferenceType::getChildrenOfClass($xml);
$serialNo = SerialNo::getChildrenOfClass($xml);

$children = [];
foreach ($xml->childNodes as $child) {
if (!($child instanceof DOMElement)) {
continue;
} elseif ($child->namespaceURI === static::NS) {
continue;
}

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

return new static(
$referenceEPR,
array_pop($referenceDigest),
array_pop($referenceType),
array_pop($serialNo),
$children,
self::getAttributesNSFromXML($xml),
);
}


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

foreach ($this->getReferenceEPR() as $repr) {
$repr->toXML($e);
}

$this->getReferenceDigest()?->toXML($e);
$this->getReferenceType()?->toXML($e);
$this->getSerialNo()?->toXML($e);

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

/** @psalm-var \SimpleSAML\XML\SerializableElementInterface $child */
foreach ($this->getElements() as $child) {
if (!$child->isEmptyElement()) {
$child->toXML($e);
}
}

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

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\fed;

use SimpleSAML\WSSecurity\XML\wsa\AbstractEndpointReferenceType;

/**
* A ReferenceEPR element
*
* @package tvdijen/ws-security
*/
final class ReferenceEPR extends AbstractEndpointReferenceType
{
/** @var string */
public const NS = AbstractFedElement::NS;

/** @var string */
public const NS_PREFIX = AbstractFedElement::NS_PREFIX;
}
14 changes: 14 additions & 0 deletions src/XML/fed/ReferenceToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\fed;

/**
* A ReferenceToken element
*
* @package tvdijen/ws-security
*/
final class ReferenceToken extends AbstractReferenceTokenType
{
}
105 changes: 105 additions & 0 deletions tests/WSSecurity/XML/fed/ReferenceEPRTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\Test\WSSecurity\XML\fed;

use DOMDocument;
use DOMElement;
use PHPUnit\Framework\TestCase;
use SimpleSAML\Assert\AssertionFailedException;
use SimpleSAML\XML\TestUtils\SerializableElementTestTrait;
use SimpleSAML\WSSecurity\Constants;
use SimpleSAML\WSSecurity\XML\fed\ReferenceEPR;
use SimpleSAML\WSSecurity\XML\wsa\Address;
use SimpleSAML\WSSecurity\XML\wsa\Metadata;
use SimpleSAML\WSSecurity\XML\wsa\ReferenceParameters;
use SimpleSAML\WSSecurity\XML\wsa\ReplyTo;
use SimpleSAML\XML\Attribute;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\DOMDocumentFactory;

use function dirname;
use function strval;

/**
* Tests for fed:ReferenceEPR.
*
* @covers \SimpleSAML\WSSecurity\XML\fed\ReferenceEPR
* @covers \SimpleSAML\WSSecurity\XML\wsa\AbstractEndpointReferenceType
* @covers \SimpleSAML\WSSecurity\XML\wsa\AbstractWsaElement
*
* @package tvdijen/ws-security
*/
final class ReferenceEPRTest extends TestCase
{
use SerializableElementTestTrait;


/** @var \DOMElement $referenceParametersContent */
protected static DOMElement $referenceParametersContent;

/** @var \DOMElement $metadataContent */
protected static DOMElement $metadataContent;

/** @var \DOMElement $customContent */
protected static DOMElement $customContent;


/**
*/
public static function setUpBeforeClass(): void
{
self::$testedClass = ReferenceEPR::class;

self::$xmlRepresentation = DOMDocumentFactory::FromFile(
dirname(__FILE__, 4) . '/resources/xml/fed_ReferenceEPR.xml'
);

self::$referenceParametersContent = DOMDocumentFactory::fromString(
'<m:GetPrice xmlns:m="https://www.w3schools.com/prices"><m:Item>Pears</m:Item></m:GetPrice>'
)->documentElement;

self::$metadataContent = DOMDocumentFactory::fromString(
'<m:GetPrice xmlns:m="https://www.w3schools.com/prices"><m:Item>Apples</m:Item></m:GetPrice>'
)->documentElement;

self::$customContent = DOMDocumentFactory::fromString(
'<ssp:Chunk xmlns:ssp="urn:x-simplesamlphp:namespace">SomeChunk</ssp:Chunk>'
)->documentElement;
}


// test marshalling


/**
* Test creating an ReferenceEPR object from scratch.
*/
public function testMarshalling(): void
{
$doc = DOMDocumentFactory::fromString('<root/>');

$attr1 = new Attribute('urn:x-simplesamlphp:namespace', 'ssp', 'attr1', 'testval1');
$attr2 = new Attribute('urn:x-simplesamlphp:namespace', 'ssp', 'attr2', 'testval2');
$attr3 = new Attribute('urn:x-simplesamlphp:namespace', 'ssp', 'attr3', 'testval3');
$attr4 = new Attribute('urn:x-simplesamlphp:namespace', 'ssp', 'attr4', 'testval4');

$referenceParameters = new ReferenceParameters([new Chunk(self::$referenceParametersContent)], [$attr3]);
$metadata = new Metadata([new Chunk(self::$metadataContent)], [$attr4]);
$chunk = new Chunk(self::$customContent);

$referenceEPR = new ReferenceEPR(
new Address('https://login.microsoftonline.com/login.srf', [$attr2]),
[$referenceParameters],
[$metadata],
[$chunk],
[$attr1],
);

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

0 comments on commit 034288c

Please sign in to comment.