Skip to content

Commit

Permalink
Create fed classes
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Jan 21, 2024
1 parent 718dad7 commit cfadcb9
Show file tree
Hide file tree
Showing 9 changed files with 519 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/autolock-conversations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v4
- uses: dessant/lock-threads@v5
with:
issue-inactive-days: '90'
pr-inactive-days: '90'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ jobs:

- name: Save coverage data
if: ${{ matrix.php-versions == '8.3' }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: coverage-data
path: ${{ github.workspace }}/build
Expand Down
155 changes: 155 additions & 0 deletions src/XML/fed/AbstractFilterPseudonymsType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\fed;

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\MissingElementException;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\ExtendableAttributesTrait;
use SimpleSAML\XML\ExtendableElementTrait;
use SimpleSAML\XML\XsNamespace as NS;

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

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

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


/**
* FilterPseudonymsType constructor.
*
* @param \SimpleSAML\WSSecurity\XML\fed\PseudonymBasis|null $pseudonymBasis
* @param \SimpleSAML\WSSecurity\XML\fed\RelativeTo|null $relativeTo
* @param \SimpleSAML\XML\SerializableElementInterface[] $childeren
* @param \SimpleSAML\XML\Attribute[] $namespacedAttributes
*/
final public function __construct(
protected ?PseudonymBasis $pseudonymBasis = null,
protected ?RelativeTo $relativeTo = null,
array $children = [],
array $namespacedAttributes = [],
) {
$this->setElements($children);
$this->setAttributesNS($namespacedAttributes);
}


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


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


/**
* 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->getPseudonymBasis())
&& empty($this->getRelativeTo())
&& 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);

$pseudonymBasis = PseudonymBasis::getChildrenOfClass($xml);
Assert::maxCount($pseudonymBasis, 1, TooManyElementsException::class);

$relativeTo = RelativeTo::getChildrenOfClass($xml);
Assert::maxCount($relativeTo, 1, TooManyElementsException::class);

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

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

return new static(
array_pop($pseudonymBasis),
array_pop($relativeTo),
$children,
self::getAttributesNSFromXML($xml),
);
}


/**
* Add this PseudonymType 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);

$this->getPseudonymBasis()?->toXML($e);
$this->getRelativeTo()?->toXML($e);

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

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

return $e;
}
}
10 changes: 9 additions & 1 deletion src/XML/fed/AbstractPseudonymType.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@
use SimpleSAML\Assert\Assert;
use SimpleSAML\WSSecurity\XML\wsu\Expires;
use SimpleSAML\WSSecurity\Constants as C;
use SimpleSAML\XML\Attribute as XMLAttribute;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
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 PseudonymType
Expand Down Expand Up @@ -156,7 +160,11 @@ public static function fromXML(DOMElement $xml): static
}
continue;
} elseif ($child->namespaceURI === C::NS_SEC_UTIL) {
$expires[] = Expires::fromXML($child);
if ($child->localName === 'Expires') {
$expires[] = Expires::fromXML($child);
} else {
$children[] = new Chunk($child);
}
continue;
}

Expand Down
14 changes: 14 additions & 0 deletions src/XML/fed/FilterPseudonyms.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 FilterPseudonyms element
*
* @package tvdijen/ws-security
*/
final class FilterPseudonyms extends AbstractFilterPseudonymsType
{
}
126 changes: 126 additions & 0 deletions tests/WSSecurity/XML/fed/FilterPseudonymsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\Test\WSSecurity\XML\fed;

use DateTimeImmutable;
use DOMElement;
use PHPUnit\Framework\TestCase;
use SimpleSAML\Assert\AssertionFailedException;
use SimpleSAML\WSSecurity\Constants as C;
use SimpleSAML\WSSecurity\XML\fed\FilterPseudonyms;
use SimpleSAML\WSSecurity\XML\fed\PseudonymBasis;
use SimpleSAML\WSSecurity\XML\fed\RelativeTo;
use SimpleSAML\WSSecurity\XML\sp\NoPassword;
use SimpleSAML\XML\Attribute;
use SimpleSAML\XML\Chunk;
use SimpleSAML\XML\DOMDocumentFactory;
use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait;
use SimpleSAML\XML\TestUtils\SerializableElementTestTrait;

use function dirname;
use function strval;

/**
* Tests for fed:FilterPseudonyms.
*
* @covers \SimpleSAML\WSSecurity\XML\fed\FilterPseudonyms
* @covers \SimpleSAML\WSSecurity\XML\wsa\AbstractFilterPseudonymsType
* @covers \SimpleSAML\WSSecurity\XML\wsa\AbstractFedElement
*
* @package tvdijen/ws-security
*/
final class FilterPseudonymsTest extends TestCase
{
use SchemaValidationTestTrait;
use SerializableElementTestTrait;

/** @var \SimpleSAML\XML\Chunk $chunk */
protected static Chunk $chunk;

/** @var \SimpleSAML\XML\Chunk $basis */
protected static Chunk $basis;

/** @var \SimpleSAML\XML\Chunk $relative */
protected static Chunk $relative;


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

self::$testedClass = FilterPseudonyms::class;

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

self::$chunk = new Chunk(DOMDocumentFactory::fromString(
'<ssp:Chunk xmlns:ssp="urn:x-simplesamlphp:namespace">Some</ssp:Chunk>'
)->documentElement);

self::$basis = new Chunk(DOMDocumentFactory::fromString(
'<ssp:Chunk xmlns:ssp="urn:x-simplesamlphp:namespace">Basis</ssp:Chunk>'
)->documentElement);

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


// test marshalling


/**
* Adding an empty FilterPseudonyms element should yield an empty element.
*/
public function testMarshallingEmptyElement(): void
{
$fedns = C::NS_FED;
$filterPseudonyms = new FilterPseudonyms();
$this->assertEquals(
"<fed:FilterPseudonyms xmlns:fed=\"$fedns\"/>",
strval($filterPseudonyms),
);
$this->assertTrue($filterPseudonyms->isEmptyElement());
}


/**
* Test creating an FilterPseudonyms object from scratch.
*/
public function testMarshalling(): void
{
$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');

$pseudonymBasis = new PseudonymBasis(
self::$basis,
[$attr2],
);

$relativeTo = new RelativeTo(
[self::$relative],
[$attr3],
);

$noPassword = new NoPassword([$attr4]);
$filterPseudonyms = new FilterPseudonyms(
$pseudonymBasis,
$relativeTo,
[$noPassword],
[$attr1],
);

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

0 comments on commit cfadcb9

Please sign in to comment.