-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
339 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace SimpleSAML\SAML11\XML\saml; | ||
|
||
use DOMElement; | ||
use SimpleSAML\Assert\Assert; | ||
use SimpleSAML\SAML11\Constants as C; | ||
use SimpleSAML\SAML11\Utils; | ||
use SimpleSAML\SAML11\XML\ExtensionPointInterface; | ||
use SimpleSAML\SAML11\XML\ExtensionPointTrait; | ||
use SimpleSAML\XML\Attribute as XMLAttribute; | ||
use SimpleSAML\XML\Chunk; | ||
use SimpleSAML\XML\Exception\InvalidDOMElementException; | ||
use SimpleSAML\XML\Exception\MissingElementException; | ||
use SimpleSAML\XML\Exception\TooManyDOMElementsException; | ||
use SimpleSAML\XML\Exception\SchemaViolationException; | ||
|
||
use function count; | ||
use function explode; | ||
|
||
/** | ||
* Class implementing the <saml:SubjectStatement> extension point. | ||
* | ||
* @package simplesamlphp/saml11 | ||
*/ | ||
abstract class AbstractSubjectStatement extends AbstractSubjectStatementType implements ExtensionPointInterface | ||
{ | ||
use ExtensionPointTrait; | ||
|
||
/** @var string */ | ||
public const LOCALNAME = 'SubjectStatement'; | ||
|
||
|
||
/** | ||
* Initialize a custom saml:SubjectStatement element. | ||
* | ||
* @param string $type | ||
*/ | ||
protected function __construct( | ||
protected string $type, | ||
Subject $subject, | ||
) { | ||
parent::__construct($subject); | ||
} | ||
|
||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
public function getXsiType(): string | ||
{ | ||
return $this->type; | ||
} | ||
|
||
|
||
/** | ||
* Convert an XML element into a SubjectStatement. | ||
* | ||
* @param \DOMElement $xml The root XML element | ||
* @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, 'SubjectStatement', InvalidDOMElementException::class); | ||
Assert::same($xml->namespaceURI, C::NS_SAML, InvalidDOMElementException::class); | ||
Assert::true( | ||
$xml->hasAttributeNS(C::NS_XSI, 'type'), | ||
'Missing required xsi:type in <saml:SubjectStatement> element.', | ||
SchemaViolationException::class, | ||
); | ||
|
||
$type = $xml->getAttributeNS(C::NS_XSI, 'type'); | ||
Assert::validQName($type, SchemaViolationException::class); | ||
|
||
// first, try to resolve the type to a full namespaced version | ||
$qname = explode(':', $type, 2); | ||
if (count($qname) === 2) { | ||
list($prefix, $element) = $qname; | ||
} else { | ||
$prefix = null; | ||
list($element) = $qname; | ||
} | ||
$ns = $xml->lookupNamespaceUri($prefix); | ||
$type = ($ns === null) ? $element : implode(':', [$ns, $element]); | ||
|
||
// now check if we have a handler registered for it | ||
$handler = Utils::getContainer()->getExtensionHandler($type); | ||
if ($handler === null) { | ||
$subject = Subject::getChildrenOfClass($xml); | ||
Assert::minCount($subject, 1, MissingElementException::class); | ||
Assert::maxCount($subject, 1, TooManyElementsException::class); | ||
|
||
// we don't have a handler, proceed with unknown SubjectStatement | ||
return new UnknownSubjectStatement(new Chunk($xml), $type, array_pop($subject)); | ||
} | ||
|
||
Assert::subclassOf( | ||
$handler, | ||
AbstractSubjectStatement::class, | ||
'Elements implementing SubjectStatement must extend \SimpleSAML\SAML11\XML\saml\AbstractSubjectStatementType.', | ||
); | ||
return $handler::fromXML($xml); | ||
} | ||
|
||
|
||
/** | ||
* Convert this SubjectStatement to XML. | ||
* | ||
* @param \DOMElement $parent The element we are converting to XML. | ||
* @return \DOMElement The XML element after adding the data corresponding to this SubjectStatement. | ||
*/ | ||
public function toXML(DOMElement $parent = null): DOMElement | ||
{ | ||
$e = parent::toXML($parent); | ||
$e->setAttributeNS( | ||
'http://www.w3.org/2000/xmlns/', | ||
'xmlns:' . static::getXsiTypePrefix(), | ||
static::getXsiTypeNamespaceURI(), | ||
); | ||
|
||
$type = new XMLAttribute(C::NS_XSI, 'xsi', 'type', $this->getXsiType()); | ||
$type->toXML($e); | ||
|
||
return $e; | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace SimpleSAML\SAML11\XML\saml; | ||
|
||
use DOMElement; | ||
use SimpleSAML\XML\Chunk; | ||
|
||
/** | ||
* Class for unknown SubjectStatements. | ||
* | ||
* @package simplesamlphp/saml11 | ||
*/ | ||
final class UnknownSubjectStatement extends AbstractSubjectStatement | ||
{ | ||
/** | ||
* @param \SimpleSAML\XML\Chunk $chunk The whole SubjectStatement element as a chunk object. | ||
* @param string $type The xsi:type of this SubjectStatement | ||
*/ | ||
public function __construct( | ||
protected Chunk $chunk, | ||
string $type, | ||
protected Subject $subject, | ||
) { | ||
parent::__construct($type, $subject); | ||
} | ||
|
||
|
||
/** | ||
* Get the raw version of this SubjectStatement as a Chunk. | ||
* | ||
* @return \SimpleSAML\XML\Chunk | ||
*/ | ||
public function getRawSubjectStatement(): Chunk | ||
{ | ||
return $this->chunk; | ||
} | ||
|
||
|
||
/** | ||
* Convert this unknown SubjectStatement to XML. | ||
* | ||
* @param \DOMElement|null $parent The element we are converting to XML. | ||
* @return \DOMElement The XML element after adding the data corresponding to this unknown SubjectStatement. | ||
*/ | ||
public function toXML(DOMElement $parent = null): DOMElement | ||
{ | ||
return $this->getRawSubjectStatement()->toXML($parent); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace SimpleSAML\Test\SAML11; | ||
|
||
use DOMElement; | ||
use SimpleSAML\Assert\Assert; | ||
use SimpleSAML\SAML11\XML\saml\AbstractSubjectStatement; | ||
use SimpleSAML\SAML11\XML\saml\Audience; | ||
use SimpleSAML\SAML11\XML\saml\Subject; | ||
use SimpleSAML\SAML11\Constants as C; | ||
use SimpleSAML\XML\Exception\InvalidDOMElementException; | ||
|
||
/** | ||
* Example class to demonstrate how SubjectStatement can be extended. | ||
* | ||
* @package simplesamlphp\saml11 | ||
*/ | ||
final class CustomSubjectStatement extends AbstractSubjectStatement | ||
{ | ||
/** @var string */ | ||
protected const XSI_TYPE_NAME = 'CustomSubjectStatementType'; | ||
|
||
/** @var string */ | ||
protected const XSI_TYPE_NAMESPACE = 'urn:x-simplesamlphp:namespace'; | ||
|
||
/** @var string */ | ||
protected const XSI_TYPE_PREFIX = 'ssp'; | ||
|
||
|
||
/** | ||
* CustomSubjectStatement constructor. | ||
* | ||
* @param \SimpleSAML\SAML11\XML\saml\Subject $subject | ||
* @param \SimpleSAML\SAML11\XML\saml\Audience[] $audience | ||
*/ | ||
public function __construct( | ||
Subject $subject, | ||
protected array $audience, | ||
) { | ||
Assert::allIsInstanceOf($audience, Audience::class); | ||
|
||
parent::__construct(self::XSI_TYPE_PREFIX . ':' . self::XSI_TYPE_NAME, $subject); | ||
} | ||
|
||
|
||
/** | ||
* Get the value of the audience-attribute. | ||
* | ||
* @return \SimpleSAML\SAML11\XML\saml\Audience[] | ||
*/ | ||
public function getAudience(): array | ||
{ | ||
return $this->audience; | ||
} | ||
|
||
|
||
/** | ||
* Convert XML into an SubjectStatement | ||
* | ||
* @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, 'SubjectStatement', InvalidDOMElementException::class); | ||
Assert::notNull($xml->namespaceURI, InvalidDOMElementException::class); | ||
Assert::same($xml->namespaceURI, AbstractSubjectStatement::NS, InvalidDOMElementException::class); | ||
Assert::true( | ||
$xml->hasAttributeNS(C::NS_XSI, 'type'), | ||
'Missing required xsi:type in <saml:SubjectStatement> element.', | ||
InvalidDOMElementException::class, | ||
); | ||
|
||
$type = $xml->getAttributeNS(C::NS_XSI, 'type'); | ||
Assert::same($type, self::XSI_TYPE_PREFIX . ':' . self::XSI_TYPE_NAME); | ||
|
||
$subject = Subject::getChildrenOfClass($xml); | ||
Assert::minCount($subject, 1, MissingElementException::class); | ||
Assert::maxCount($subject, 1, TooManyElementsException::class); | ||
|
||
$audience = Audience::getChildrenOfClass($xml); | ||
|
||
return new static(array_pop($subject), $audience); | ||
} | ||
|
||
|
||
/** | ||
* Convert this SubjectStatement to XML. | ||
* | ||
* @param \DOMElement $parent The element we are converting to XML. | ||
* @return \DOMElement The XML element after adding the data corresponding to this SubjectStatement. | ||
*/ | ||
public function toXML(DOMElement $parent = null): DOMElement | ||
{ | ||
$e = parent::toXML($parent); | ||
|
||
foreach ($this->audience as $audience) { | ||
$audience->toXML($e); | ||
} | ||
|
||
return $e; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.