Skip to content

Commit

Permalink
Add wsp-elements
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Jan 2, 2024
1 parent a1001ac commit acc7c18
Show file tree
Hide file tree
Showing 22 changed files with 1,464 additions and 0 deletions.
140 changes: 140 additions & 0 deletions src/XML/wsp/AbstractOperatorContentType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\wsp;

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

/**
* Class representing a wsp:OperatorContentType element.
*
* @package tvdijen/ws-security
*/
abstract class AbstractOperatorContentType extends AbstractWspElement
{
use ExtendableElementTrait;

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


/**
* Initialize a wsp:OperatorContentType
*
* @param (\SimpleSAML\WSSecurity\XML\wsp\All|
* \SimpleSAML\WSSecurity\XML\wsp\ExactlyOne|
* \SimpleSAML\WSSecurity\XML\wsp\Policy|
* \SimpleSAML\WSSecurity\XML\wsp\PolicyReference)[] $operatorContent
* @param \SimpleSAML\XML\Chunk[] $children
*/
public function __construct(
protected array $operatorContent = [],
array $children = []
) {
Assert::maxCount($operatorContent, C::UNBOUNDED_LIMIT);
Assert::maxCount($children, C::UNBOUNDED_LIMIT);
Assert::allIsInstanceOfAny(
$operatorContent,
[All::class, ExactlyOne::class, Policy::class, PolicyReference::class],
InvalidDOMElementException::class,
);
Assert::allIsInstanceOfAny(
$children,
[Chunk::class],
InvalidArgumentException::class,
);

$this->setElements($children);
}


/**
* @return (\SimpleSAML\XML\Chunk|
* \SimpleSAML\WSSecurity\XML\wsp\All|
* \SimpleSAML\WSSecurity\XML\wsp\ExactlyOne|
* \SimpleSAML\WSSecurity\XML\wsp\Policy|
* \SimpleSAML\WSSecurity\XML\wsp\PolicyReference)[] $operatorContent
*/
public function getOperatorContent(): array
{
return $this->operatorContent;
}


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


/*
* Convert XML into an wsp:OperatorContentType element
*
* @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
{
Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);

$operatorContent = $children = [];
for ($n = $xml->firstChild; $n !== null; $n = $n->nextSibling) {
if (!($n instanceof DOMElement)) {
continue;
} elseif ($n->namespaceURI !== self::NS) {
$children[] = new Chunk($n);
continue;
}

$operatorContent[] = match ($n->localName) {
'All' => All::fromXML($n),
'ExactlyOne' => ExactlyOne::fromXML($n),
'Policy' => Policy::fromXML($n),
'PolicyReference' => PolicyReference::fromXML($n),
};
}

return new static($operatorContent, $children);
}


/**
* Convert this wsp:OperatorContentType to XML.
*
* @param \DOMElement|null $parent The element we should add this wsp:OperatorContentType to.
* @return \DOMElement This wsp:AbstractOperatorContentType element.
*/
public function toXML(DOMElement $parent = null): DOMElement
{
$e = $this->instantiateParentElement($parent);

foreach ($this->getOperatorContent() as $n) {
$n->toXML($e);
}

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

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

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\wsp;

use SimpleSAML\XML\AbstractElement;
use SimpleSAML\WSSecurity\Constants as C;

/**
* Abstract class to be implemented by all the classes in this namespace
*
* @package tvdijen/ws-security
*/
abstract class AbstractWspElement extends AbstractElement
{
/** @var string */
public const NS = C::NS_POLICY;

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

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\wsp;

/**
* Class defining the All element
*
* @package tvdijen/ws-security
*/
final class All extends AbstractOperatorContentType
{
}
110 changes: 110 additions & 0 deletions src/XML/wsp/AppliesTo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\wsp;

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

/**
* Class representing a wsp:AppliesTo element.
*
* @package tvdijen/ws-security
*/
final class AppliesTo extends AbstractWspElement
{
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::ANY;


/**
* Initialize a wsp:AppliesTo
*
* @param \SimpleSAML\XML\Chunk[] $children
* @param list<\SimpleSAML\XML\Attribute> $namespacedAttributes
*/
public function __construct(array $children = [], array $namespacedAttributes = [])
{
$this->setElements($children);
$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->elements) && empty($this->namespacedAttributes);
}


/*
* Convert XML into an wsp:AppliesTo element
*
* @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
{
Assert::same($xml->localName, 'AppliesTo', InvalidDOMElementException::class);
Assert::same($xml->namespaceURI, AppliesTo::NS, InvalidDOMElementException::class);

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

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

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


/**
* Convert this wsp:AppliesTo to XML.
*
* @param \DOMElement|null $parent The element we should add this wsp:AppliesTo to.
* @return \DOMElement This wsp:AppliesTo element.
*/
public function toXML(DOMElement $parent = null): DOMElement
{
$e = $this->instantiateParentElement($parent);

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;
}
}
14 changes: 14 additions & 0 deletions src/XML/wsp/ExactlyOne.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\wsp;

/**
* Class defining the ExactlyOne element
*
* @package tvdijen/ws-security
*/
final class ExactlyOne extends AbstractOperatorContentType
{
}
42 changes: 42 additions & 0 deletions src/XML/wsp/OptionalTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\WSSecurity\XML\wsp;

/**
* Trait grouping common functionality for elements that can hold an Optional attribute.
*
* @package tvdijen/ws-security
*/
trait OptionalTrait
{
/**
* The Optional.
*
* @var bool
*/
protected bool $Optional;


/**
* Collect the value of the Optional-property
*
* @return bool
*/
public function getOptional(): bool
{
return $this->Optional;
}


/**
* Set the value of the Optional-property
*
* @param bool $Optional
*/
protected function setOptional(?bool $Optional): void
{
$this->Optional = $Optional ?? false;
}
}
Loading

0 comments on commit acc7c18

Please sign in to comment.