diff --git a/composer.json b/composer.json index 39882e2..47f8ac3 100644 --- a/composer.json +++ b/composer.json @@ -18,8 +18,8 @@ "psr/clock": "^1.0", "psr/log": "^2.0 | ^3.0", "simplesamlphp/assert": "^1.8", - "simplesamlphp/xml-common": "~1.24.0", - "simplesamlphp/xml-security": "~1.13.0" + "simplesamlphp/xml-common": "dev-feature/xsd-types", + "simplesamlphp/xml-security": "dev-feature/xsd-types" }, "require-dev": { "beste/clock": "^3.0", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon deleted file mode 100644 index 3c94f85..0000000 --- a/phpstan-baseline.neon +++ /dev/null @@ -1,76 +0,0 @@ -parameters: - ignoreErrors: - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\saml\\\\AbstractCondition\\)\\:\\:XSI_TYPE_NAME\\.$#" - count: 2 - path: src/SAML11/XML/saml/AbstractCondition.php - - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\saml\\\\AbstractCondition\\)\\:\\:XSI_TYPE_NAMESPACE\\.$#" - count: 2 - path: src/SAML11/XML/saml/AbstractCondition.php - - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\saml\\\\AbstractCondition\\)\\:\\:XSI_TYPE_PREFIX\\.$#" - count: 2 - path: src/SAML11/XML/saml/AbstractCondition.php - - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\saml\\\\AbstractStatement\\)\\:\\:XSI_TYPE_NAME\\.$#" - count: 2 - path: src/SAML11/XML/saml/AbstractStatement.php - - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\saml\\\\AbstractStatement\\)\\:\\:XSI_TYPE_NAMESPACE\\.$#" - count: 2 - path: src/SAML11/XML/saml/AbstractStatement.php - - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\saml\\\\AbstractStatement\\)\\:\\:XSI_TYPE_PREFIX\\.$#" - count: 2 - path: src/SAML11/XML/saml/AbstractStatement.php - - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\saml\\\\AbstractSubjectStatement\\)\\:\\:XSI_TYPE_NAME\\.$#" - count: 2 - path: src/SAML11/XML/saml/AbstractSubjectStatement.php - - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\saml\\\\AbstractSubjectStatement\\)\\:\\:XSI_TYPE_NAMESPACE\\.$#" - count: 2 - path: src/SAML11/XML/saml/AbstractSubjectStatement.php - - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\saml\\\\AbstractSubjectStatement\\)\\:\\:XSI_TYPE_PREFIX\\.$#" - count: 2 - path: src/SAML11/XML/saml/AbstractSubjectStatement.php - - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\samlp\\\\AbstractQuery\\)\\:\\:XSI_TYPE_NAME\\.$#" - count: 2 - path: src/SAML11/XML/samlp/AbstractQuery.php - - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\samlp\\\\AbstractQuery\\)\\:\\:XSI_TYPE_NAMESPACE\\.$#" - count: 2 - path: src/SAML11/XML/samlp/AbstractQuery.php - - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\samlp\\\\AbstractQuery\\)\\:\\:XSI_TYPE_PREFIX\\.$#" - count: 2 - path: src/SAML11/XML/samlp/AbstractQuery.php - - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\samlp\\\\AbstractSubjectQuery\\)\\:\\:XSI_TYPE_NAME\\.$#" - count: 2 - path: src/SAML11/XML/samlp/AbstractSubjectQuery.php - - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\samlp\\\\AbstractSubjectQuery\\)\\:\\:XSI_TYPE_NAMESPACE\\.$#" - count: 2 - path: src/SAML11/XML/samlp/AbstractSubjectQuery.php - - - - message: "#^Access to undefined constant static\\(SimpleSAML\\\\SAML11\\\\XML\\\\samlp\\\\AbstractSubjectQuery\\)\\:\\:XSI_TYPE_PREFIX\\.$#" - count: 2 - path: src/SAML11/XML/samlp/AbstractSubjectQuery.php diff --git a/phpstan.neon b/phpstan.neon index e4c4cf7..21cf590 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,5 +2,3 @@ parameters: level: 1 paths: - src -includes: - - phpstan-baseline.neon diff --git a/src/SAML11/Assert/AnyURITrait.php b/src/SAML11/Assert/AnyURITrait.php new file mode 100644 index 0000000..a85a848 --- /dev/null +++ b/src/SAML11/Assert/AnyURITrait.php @@ -0,0 +1,39 @@ +getMessage()); + } + } +} diff --git a/src/SAML11/Assert/Assert.php b/src/SAML11/Assert/Assert.php index aa3a9e8..a3d7761 100644 --- a/src/SAML11/Assert/Assert.php +++ b/src/SAML11/Assert/Assert.php @@ -12,16 +12,18 @@ * @package simplesamlphp/saml11 * * @method static void validDateTime(mixed $value, string $message = '', string $exception = '') - * @method static void validURI(mixed $value, string $message = '', string $exception = '') * @method static void validEntityID(mixed $value, string $message = '', string $exception = '') + * @method static void validURI(mixed $value, string $message = '', string $exception = '') * @method static void nullOrValidDateTime(mixed $value, string $message = '', string $exception = '') - * @method static void nullOrValidURI(mixed $value, string $message = '', string $exception = '') * @method static void nullOrValidEntityID(mixed $value, string $message = '', string $exception = '') + * @method static void nullOrValidURI(mixed $value, string $message = '', string $exception = '') * @method static void allValidDateTime(mixed $value, string $message = '', string $exception = '') - * @method static void allValidURI(mixed $value, string $message = '', string $exception = '') * @method static void allValidEntityID(mixed $value, string $message = '', string $exception = '') + * @method static void allValidURI(mixed $value, string $message = '', string $exception = '') */ class Assert extends BaseAssert { - use CustomAssertionTrait; + use AnyURITrait; + use DateTimeTrait; + use StringTrait; } diff --git a/src/SAML11/Assert/CustomAssertionTrait.php b/src/SAML11/Assert/CustomAssertionTrait.php deleted file mode 100644 index 18e2571..0000000 --- a/src/SAML11/Assert/CustomAssertionTrait.php +++ /dev/null @@ -1,63 +0,0 @@ -getMessage()); - } - } - - - /** - * @param string $value - * @param string $message - */ - protected static function validURI(string $value, string $message = ''): void - { - parent::validURI($value, $message, SchemaViolationException::class); - - try { - static::notWhitespaceOnly($value, $message ?: '%s is not a SAML1.1-compliant URI'); - // If it doesn't have a scheme, it's not an absolute URI - static::regex($value, self::$scheme_regex, $message ?: '%s is not a SAML1.1-compliant URI'); - } catch (AssertionFailedException $e) { - throw new ProtocolViolationException($e->getMessage()); - } - } -} diff --git a/src/SAML11/Assert/DateTimeTrait.php b/src/SAML11/Assert/DateTimeTrait.php new file mode 100644 index 0000000..e25dd89 --- /dev/null +++ b/src/SAML11/Assert/DateTimeTrait.php @@ -0,0 +1,39 @@ +getMessage()); + } + } +} diff --git a/src/SAML11/Assert/StringTrait.php b/src/SAML11/Assert/StringTrait.php new file mode 100644 index 0000000..52b8a0e --- /dev/null +++ b/src/SAML11/Assert/StringTrait.php @@ -0,0 +1,37 @@ +getMessage()); + } + } +} diff --git a/src/SAML11/Compat/AbstractContainer.php b/src/SAML11/Compat/AbstractContainer.php index a5e25d6..5724d59 100644 --- a/src/SAML11/Compat/AbstractContainer.php +++ b/src/SAML11/Compat/AbstractContainer.php @@ -8,24 +8,23 @@ use Psr\Log\LoggerInterface; use SimpleSAML\SAML11\Assert\Assert; use SimpleSAML\SAML11\XML\ExtensionPointInterface; -use SimpleSAML\XML\AbstractElement; -use SimpleSAML\XML\Exception\SchemaViolationException; +use SimpleSAML\XML\{AbstractElement, ElementInterface}; +use SimpleSAML\XML\Type\QNameValue; use SimpleSAML\XMLSecurity\Alg\Encryption\EncryptionAlgorithmFactory; use SimpleSAML\XMLSecurity\Alg\KeyTransport\KeyTransportAlgorithmFactory; use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmFactory; use function array_key_exists; -use function implode; -use function is_subclass_of; +use function strval; abstract class AbstractContainer { - /** @var string */ - private const XSI_TYPE_PREFIX = ''; - /** @var array */ protected array $registry = []; + /** @var array */ + protected array $extRegistry = []; + /** @var array|null */ protected ?array $blacklistedEncryptionAlgorithms = [ EncryptionAlgorithmFactory::DEFAULT_BLACKLIST, @@ -46,6 +45,20 @@ public function getBlacklistedEncryptionAlgorithms(): ?array } + /** + * Register a class that can handle a given element. + * + * @param string $class The class name of a class extending AbstractElement + * @psalm-param class-string $class + */ + public function registerElementHandler(string $class): void + { + Assert::subclassOf($class, AbstractElement::class); + $key = '{' . strval($class::NS) . '}' . AbstractElement::getClassName($class); + $this->registry[$key] = $class; + } + + /** * Register a class that can handle given extension points of the standard. * @@ -54,37 +67,29 @@ public function getBlacklistedEncryptionAlgorithms(): ?array */ public function registerExtensionHandler(string $class): void { - Assert::subclassOf($class, AbstractElement::class); - if (is_subclass_of($class, ExtensionPointInterface::class, true)) { - $key = implode(':', [self::XSI_TYPE_PREFIX, $class::getXsiTypeNamespaceURI(), $class::getXsiTypeName()]); - } else { - $className = AbstractElement::getClassName($class); - $key = ($class::NS === null) ? $className : implode(':', [$class::NS, $className]); - } - $this->registry[$key] = $class; + Assert::subclassOf($class, ExtensionPointInterface::class); + $key = '{' . $class::getXsiTypeNamespaceURI() . '}' . $class::getXsiTypeName(); + $this->extRegistry[$key] = $class; } /** - * Search for a class that implements an $element in the given $namespace. + * Search for a class that implements an element in the given $namespace. * * Such classes must have been registered previously by calling registerExtensionHandler(), and they must * extend \SimpleSAML\XML\AbstractElement. * - * @param string|null $namespace The namespace URI for the given element. - * @param string $element The local name of the element. + * @param \SimpleSAML\XML\Type\QNameValue|null $qName The qualified name of the element. * * @return string|null The fully-qualified name of a class extending \SimpleSAML\XML\AbstractElement and * implementing support for the given element, or null if no such class has been registered before. * @psalm-return class-string|null */ - public function getElementHandler(?string $namespace, string $element): ?string + public function getElementHandler(QNameValue $qName): ?string { - Assert::nullOrValidURI($namespace, SchemaViolationException::class); - Assert::validNCName($element, SchemaViolationException::class); - - $key = ($namespace === null) ? $element : implode(':', [$namespace, $element]); + $key = '{' . strval($qName->getNameSpaceURI()) . '}' . strval($qName->getLocalName()); if (array_key_exists($key, $this->registry) === true) { + Assert::implementsInterface($this->registry[$key], ElementInterface::class); return $this->registry[$key]; } @@ -98,21 +103,20 @@ public function getElementHandler(?string $namespace, string $element): ?string * Such classes must have been registered previously by calling registerExtensionHandler(), and they must * implement \SimpleSAML\SAML11\XML\saml\ExtensionPointInterface. * - * @param string $type The type of the identifier (xsi:type of a BaseID element). - * + * @param \SimpleSAML\XML\Type\QNameValue $qName The qualified name of the extension. * @return string|null The fully-qualified name of a class implementing * \SimpleSAML\SAML11\XML\saml\ExtensionPointInterface or null if no such class has been registered before. * @psalm-return class-string|null */ - public function getExtensionHandler(string $type): ?string + public function getExtensionHandler(QNameValue $qName): ?string { - Assert::notEmpty($type, 'Cannot search for identifier handlers with an empty type.'); - $type = implode(':', [self::XSI_TYPE_PREFIX, $type]); - if (!array_key_exists($type, $this->registry)) { - return null; + $key = '{' . strval($qName->getNameSpaceURI()) . '}' . strval($qName->getLocalName()); + if (array_key_exists($key, $this->extRegistry) === true) { + Assert::implementsInterface($this->extRegistry[$key], ExtensionPointInterface::class); + return $this->extRegistry[$key]; } - Assert::implementsInterface($this->registry[$type], ExtensionPointInterface::class); - return $this->registry[$type]; + + return null; } diff --git a/src/SAML11/Constants.php b/src/SAML11/Constants.php index 8660be4..2a14e5f 100644 --- a/src/SAML11/Constants.php +++ b/src/SAML11/Constants.php @@ -71,11 +71,6 @@ class Constants extends \SimpleSAML\XMLSecurity\Constants */ public const CM_BEARER = 'urn:oasis:names:tc:SAML:1.0:cm:bearer'; - /** - * The format to express a timestamp in SAML 1.1 - */ - public const DATETIME_FORMAT = 'Y-m-d\\TH:i:sp'; - /** * Email address NameID format. */ @@ -182,4 +177,18 @@ class Constants extends \SimpleSAML\XMLSecurity\Constants * Top-level status code. */ public const STATUS_VERSION_MISMATCH = 'samlp:VersionMismatch'; + + /** @var string[] */ + public static array $STATUS_CODES = [ + self::STATUS_REQUEST_DENIED, + self::STATUS_REQUEST_VERSION_DEPRECATED, + self::STATUS_REQUEST_VERSION_TOO_HIGH, + self::STATUS_REQUEST_VERSION_TOO_LOW, + self::STATUS_REQUESTER, + self::STATUS_RESOURCE_NOT_RECOGNIZED, + self::STATUS_RESPONDER, + self::STATUS_SUCCESS, + self::STATUS_TOO_MANY_RESPONSES, + self::STATUS_VERSION_MISMATCH, + ]; } diff --git a/src/SAML11/Type/AnyURIValue.php b/src/SAML11/Type/AnyURIValue.php new file mode 100644 index 0000000..87de10f --- /dev/null +++ b/src/SAML11/Type/AnyURIValue.php @@ -0,0 +1,26 @@ +sanitizeValue($value)); + } +} diff --git a/src/SAML11/Type/DateTimeValue.php b/src/SAML11/Type/DateTimeValue.php new file mode 100644 index 0000000..7aecaca --- /dev/null +++ b/src/SAML11/Type/DateTimeValue.php @@ -0,0 +1,30 @@ +sanitizeValue($value)); + } +} diff --git a/src/SAML11/Type/StringValue.php b/src/SAML11/Type/StringValue.php new file mode 100644 index 0000000..514f621 --- /dev/null +++ b/src/SAML11/Type/StringValue.php @@ -0,0 +1,26 @@ +sanitizeValue($value)); + } +} diff --git a/src/SAML11/XML/ExtensionPointInterface.php b/src/SAML11/XML/ExtensionPointInterface.php index 74bec7a..57f8056 100644 --- a/src/SAML11/XML/ExtensionPointInterface.php +++ b/src/SAML11/XML/ExtensionPointInterface.php @@ -4,6 +4,8 @@ namespace SimpleSAML\SAML11\XML; +use SimpleSAML\XML\Type\{AnyURIValue, NCNameValue, QNameValue}; + /** * Interface for several extension points objects. * @@ -14,31 +16,31 @@ interface ExtensionPointInterface /** * Get the local name for the element's xsi:type. * - * @return string + * @return \SimpleSAML\XML\Type\NCNameValue */ - public static function getXsiTypeName(): string; + public static function getXsiTypeName(): NCNameValue; /** * Get the namespace for the element's xsi:type. * - * @return string + * @return \SimpleSAML\XML\Type\AnyURIValue */ - public static function getXsiTypeNamespaceURI(): string; + public static function getXsiTypeNamespaceURI(): AnyURIValue; /** * Get the namespace-prefix for the element's xsi:type. * - * @return string + * @return \SimpleSAML\XML\Type\NCNameValue */ - public static function getXsiTypePrefix(): string; + public static function getXsiTypePrefix(): NCNameValue; /** * Return the xsi:type value corresponding this element. * - * @return string + * @return \SimpleSAML\XML\Type\QNameValue */ - public function getXsiType(): string; + public function getXsiType(): QNameValue; } diff --git a/src/SAML11/XML/ExtensionPointTrait.php b/src/SAML11/XML/ExtensionPointTrait.php index 30530e1..8247d29 100644 --- a/src/SAML11/XML/ExtensionPointTrait.php +++ b/src/SAML11/XML/ExtensionPointTrait.php @@ -6,7 +6,11 @@ use RuntimeException; use SimpleSAML\SAML11\Assert\Assert; -use SimpleSAML\XML\Exception\SchemaViolationException; +use SimpleSAML\XML\Type\{AnyURIValue, NCNameValue, QNameValue}; + +use function constant; +use function defined; +use function sprintf; /** * Trait for several extension points objects. @@ -16,9 +20,9 @@ trait ExtensionPointTrait { /** - * @inheritDoc + * @return \SimpleSAML\XML\Type\QNameValue */ - public function getXsiType(): string + public function getXsiType(): QNameValue { return $this->type; } @@ -27,9 +31,9 @@ public function getXsiType(): string /** * Get the local name for the element's xsi:type. * - * @return string + * @return \SimpleSAML\XML\Type\NCNameValue */ - public static function getXsiTypeName(): string + public static function getXsiTypeName(): NCNameValue { Assert::true( defined('static::XSI_TYPE_NAME'), @@ -38,17 +42,16 @@ public static function getXsiTypeName(): string RuntimeException::class, ); - Assert::validNCName(static::XSI_TYPE_NAME, SchemaViolationException::class); - return static::XSI_TYPE_NAME; + return NCNameValue::fromString(constant('static::XSI_TYPE_NAME')); } /** * Get the namespace for the element's xsi:type. * - * @return string + * @return \SimpleSAML\XML\Type\AnyURIValue */ - public static function getXsiTypeNamespaceURI(): string + public static function getXsiTypeNamespaceURI(): AnyURIValue { Assert::true( defined('static::XSI_TYPE_NAMESPACE'), @@ -57,17 +60,16 @@ public static function getXsiTypeNamespaceURI(): string RuntimeException::class, ); - Assert::validURI(static::XSI_TYPE_NAMESPACE, SchemaViolationException::class); - return static::XSI_TYPE_NAMESPACE; + return AnyURIValue::fromString(constant('static::XSI_TYPE_NAMESPACE')); } /** * Get the namespace-prefix for the element's xsi:type. * - * @return string + * @return \SimpleSAML\XML\Type\NCNameValue */ - public static function getXsiTypePrefix(): string + public static function getXsiTypePrefix(): NCNameValue { Assert::true( defined('static::XSI_TYPE_PREFIX'), @@ -78,7 +80,6 @@ public static function getXsiTypePrefix(): string RuntimeException::class, ); - Assert::validNCName(static::XSI_TYPE_PREFIX, SchemaViolationException::class); - return static::XSI_TYPE_PREFIX; + return NCNameValue::fromString(constant('static::XSI_TYPE_PREFIX')); } } diff --git a/src/SAML11/XML/SignableElementTrait.php b/src/SAML11/XML/SignableElementTrait.php index 806ce9e..1a2db79 100644 --- a/src/SAML11/XML/SignableElementTrait.php +++ b/src/SAML11/XML/SignableElementTrait.php @@ -8,19 +8,21 @@ use SimpleSAML\Assert\Assert; use SimpleSAML\SAML11\Compat\ContainerSingleton; use SimpleSAML\XML\DOMDocumentFactory; +use SimpleSAML\XML\Type\{AnyURIValue, Base64BinaryValue}; use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmInterface; use SimpleSAML\XMLSecurity\Constants as C; -use SimpleSAML\XMLSecurity\Exception\RuntimeException; -use SimpleSAML\XMLSecurity\Exception\UnsupportedAlgorithmException; +use SimpleSAML\XMLSecurity\Exception\{RuntimeException, UnsupportedAlgorithmException}; use SimpleSAML\XMLSecurity\Utils\XML; -use SimpleSAML\XMLSecurity\XML\ds\CanonicalizationMethod; -use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; -use SimpleSAML\XMLSecurity\XML\ds\Signature; -use SimpleSAML\XMLSecurity\XML\ds\SignatureMethod; -use SimpleSAML\XMLSecurity\XML\ds\SignatureValue; -use SimpleSAML\XMLSecurity\XML\ds\SignedInfo; -use SimpleSAML\XMLSecurity\XML\ds\Transform; -use SimpleSAML\XMLSecurity\XML\ds\Transforms; +use SimpleSAML\XMLSecurity\XML\ds\{ + CanonicalizationMethod, + KeyInfo, + Signature, + SignatureMethod, + SignatureValue, + SignedInfo, + Transform, + Transforms, +}; use SimpleSAML\XMLSecurity\XML\SignableElementTrait as BaseSignableElementTrait; use function base64_encode; @@ -60,12 +62,7 @@ public function sign( $this->keyInfo = $keyInfo; Assert::oneOf( $canonicalizationAlg, - [ - C::C14N_INCLUSIVE_WITH_COMMENTS, - C::C14N_INCLUSIVE_WITHOUT_COMMENTS, - C::C14N_EXCLUSIVE_WITH_COMMENTS, - C::C14N_EXCLUSIVE_WITHOUT_COMMENTS, - ], + C::$CANONICALIZATION_ALGORITHMS, 'Unsupported canonicalization algorithm: %s', UnsupportedAlgorithmException::class, ); @@ -105,26 +102,44 @@ protected function doSign(DOMElement $xml): DOMElement * 5.4.1: SAML assertions and protocols MUST use enveloped signatures when * signing assertions and protocol messages */ - new Transform(C::XMLDSIG_ENVELOPED), - new Transform($this->c14nAlg), + new Transform( + AnyURIValue::fromString(C::XMLDSIG_ENVELOPED), + ), + new Transform( + AnyURIValue::fromString($this->c14nAlg), + ), ]); $canonicalDocument = XML::processTransforms($transforms, $xml); $signedInfo = new SignedInfo( - new CanonicalizationMethod($this->c14nAlg), - new SignatureMethod($algorithm), + new CanonicalizationMethod( + AnyURIValue::fromString($this->c14nAlg), + ), + new SignatureMethod( + AnyURIValue::fromString($algorithm), + ), [$this->getReference($digest, $transforms, $xml, $canonicalDocument)], ); $signingData = $signedInfo->canonicalize($this->c14nAlg); $signedData = base64_encode($this->signer->sign($signingData)); - $this->signature = new Signature($signedInfo, new SignatureValue($signedData), $this->keyInfo); + $this->signature = new Signature( + $signedInfo, + new SignatureValue( + Base64BinaryValue::fromString($signedData), + ), + $this->keyInfo, + ); + return DOMDocumentFactory::fromString($canonicalDocument)->documentElement; } + /** + * @return array|null + */ public function getBlacklistedAlgorithms(): ?array { $container = ContainerSingleton::getInstance(); diff --git a/src/SAML11/XML/SignedElementTrait.php b/src/SAML11/XML/SignedElementTrait.php index 7f1825c..7dc53d0 100644 --- a/src/SAML11/XML/SignedElementTrait.php +++ b/src/SAML11/XML/SignedElementTrait.php @@ -38,9 +38,8 @@ protected function setSignature(Signature $signature): void $reference = array_pop($references); Assert::notNull($reference->getURI(), "URI attribute not found.", ReferenceValidationFailedException::class); - Assert::validURI($reference->getURI(), ReferenceValidationFailedException::class); Assert::startsWith( - $reference->getURI(), + $reference->getURI()->getValue(), '#', "Reference must contain a same-document reference to the ID-attribute of the root element.", ReferenceValidationFailedException::class, diff --git a/src/SAML11/XML/StringElementTrait.php b/src/SAML11/XML/StringElementTrait.php deleted file mode 100644 index 11dcf60..0000000 --- a/src/SAML11/XML/StringElementTrait.php +++ /dev/null @@ -1,39 +0,0 @@ -setContent($value); + } + + + /** + * Collect the value of the element + * + * @return \SimpleSAML\SAML11\Type\StringValue|null + */ + public function getValue(): StringValue + { + return $this->value; } /** * Collect the value of the Namespace-property * - * @return string|null + * @return \SimpleSAML\SAML11\Type\AnyURIValue|null */ - public function getNamespace(): ?string + public function getNamespace(): ?AnyURIValue { return $this->Namespace; } @@ -60,9 +67,10 @@ public static function fromXML(DOMElement $xml): static Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class); Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class); - $Namespace = self::getOptionalAttribute($xml, 'Namespace'); - - return new static($xml->textContent, $Namespace); + return new static( + StringValue::fromString($xml->textContent), + self::getOptionalAttribute($xml, 'Namespace', AnyURIValue::class), + ); } @@ -75,10 +83,10 @@ public static function fromXML(DOMElement $xml): static public function toXML(?DOMElement $parent = null): DOMElement { $e = $this->instantiateParentElement($parent); - $e->textContent = $this->getContent(); + $e->textContent = strval($this->getValue()); if ($this->getNamespace() !== null) { - $e->setAttribute('Namespace', $this->getNamespace()); + $e->setAttribute('Namespace', strval($this->getNamespace())); } return $e; diff --git a/src/SAML11/XML/saml/AbstractAdviceType.php b/src/SAML11/XML/saml/AbstractAdviceType.php index c6ddb0f..1c6c6d3 100644 --- a/src/SAML11/XML/saml/AbstractAdviceType.php +++ b/src/SAML11/XML/saml/AbstractAdviceType.php @@ -8,8 +8,7 @@ use SimpleSAML\Assert\Assert; use SimpleSAML\SAML11\Constants as C; use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, SchemaViolationException}; use SimpleSAML\XML\ExtendableElementTrait; use SimpleSAML\XML\XsNamespace as NS; diff --git a/src/SAML11/XML/saml/AbstractAssertionType.php b/src/SAML11/XML/saml/AbstractAssertionType.php index 56db8de..47947ff 100644 --- a/src/SAML11/XML/saml/AbstractAssertionType.php +++ b/src/SAML11/XML/saml/AbstractAssertionType.php @@ -4,28 +4,29 @@ namespace SimpleSAML\SAML11\XML\saml; -use DateTimeImmutable; use DOMElement; use SimpleSAML\SAML11\Assert\Assert; use SimpleSAML\SAML11\Compat\ContainerSingleton; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\Exception\ProtocolViolationException; +use SimpleSAML\SAML11\Exception\VersionMismatchException; use SimpleSAML\SAML11\Utils\XPath; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; -use SimpleSAML\XML\Exception\TooManyElementsException; +use SimpleSAML\SAML11\Type\{DateTimeValue, StringValue}; +use SimpleSAML\XML\Exception\{ + InvalidDOMElementException, + MissingElementException, + SchemaViolationException, + TooManyElementsException, +}; +use SimpleSAML\XML\Type\{IDValue, NonNegativeIntegerValue}; use SimpleSAML\XMLSecurity\XML\ds\Signature; -use SimpleSAML\XMLSecurity\XML\SignableElementInterface; -use SimpleSAML\XMLSecurity\XML\SignableElementTrait; -use SimpleSAML\XMLSecurity\XML\SignedElementInterface; -use SimpleSAML\XMLSecurity\XML\SignedElementTrait; +use SimpleSAML\XMLSecurity\XML\{SignableElementInterface, SignableElementTrait}; +use SimpleSAML\XMLSecurity\XML\{SignedElementInterface, SignedElementTrait}; use function array_filter; use function array_merge; use function array_pop; use function array_values; -use function preg_replace; +use function strval; /** * SAML Assertion Type abstract data type. @@ -51,37 +52,63 @@ abstract class AbstractAssertionType extends AbstractSamlElement implements /** * Initialize a saml:AssertionType from scratch * - * @param string $assertionID - * @param string $issuer - * @param \DateTimeImmutable $issueInstant + * @param \SimpleSAML\XML\Type\NonNegativeIntegerValue $majorVersion + * @param \SimpleSAML\XML\Type\NonNegativeIntegerValue $minorVersion + * @param \SimpleSAML\XML\Type\IDValue $assertionID + * @param \SimpleSAML\SAML11\Type\StringValue $issuer + * @param \SimpleSAML\SAML11\Type\DateTimeValue $issueInstant * @param \SimpleSAML\SAML11\XML\saml\Conditions|null $conditions * @param \SimpleSAML\SAML11\XML\saml\Advice|null $advice * @param array<\SimpleSAML\SAML11\XML\saml\AbstractStatementType> $statements */ final public function __construct( - protected string $assertionID, - protected string $issuer, - protected DateTimeImmutable $issueInstant, + protected NonNegativeIntegerValue $majorVersion, + protected NonNegativeIntegerValue $minorVersion, + protected IDValue $assertionID, + protected StringValue $issuer, + protected DateTimeValue $issueInstant, protected ?Conditions $conditions = null, protected ?Advice $advice = null, protected array $statements = [], ) { - Assert::same($issueInstant->getTimeZone()->getName(), 'Z', ProtocolViolationException::class); - Assert::validNCName($assertionID, SchemaViolationException::class); + Assert::same($majorVersion->getValue(), '1', VersionMismatchException::class); + Assert::same($minorVersion->getValue(), '1', VersionMismatchException::class); Assert::minCount($statements, 1, MissingElementException::class); Assert::maxCount($statements, C::UNBOUNDED_LIMIT); Assert::allIsInstanceOf($statements, AbstractStatementType::class, SchemaViolationException::class); } + /** + * Collect the value of the majorVersion-property + * + * @return \SimpleSAML\XML\Type\NonNegativeIntegerValue + */ + public function getMajorVersion(): NonNegativeIntegerValue + { + return $this->majorVersion; + } + + + /** + * Collect the value of the minorVersion-property + * + * @return \SimpleSAML\XML\Type\NonNegativeIntegerValue + */ + public function getMinorVersion(): NonNegativeIntegerValue + { + return $this->minorVersion; + } + + /** * Collect the value of the assertionID-property * * Note: the name of this method is not consistent, but it has to be named getId for xml-security to work. * - * @return string + * @return \SimpleSAML\XML\Type\IDValue */ - public function getId(): string + public function getId(): IDValue { return $this->assertionID; } @@ -90,9 +117,9 @@ public function getId(): string /** * Collect the value of the issuer-property * - * @return string + * @return \SimpleSAML\SAML11\Type\StringValue */ - public function getIssuer(): string + public function getIssuer(): StringValue { return $this->issuer; } @@ -101,9 +128,9 @@ public function getIssuer(): string /** * Collect the value of the issueInstant-property * - * @return \DateTimeImmutable + * @return \SimpleSAML\SAML11\Type\DateTimeValue */ - public function getIssueInstant(): DateTimeImmutable + public function getIssueInstant(): DateTimeValue { return $this->issueInstant; } @@ -238,19 +265,6 @@ public static function fromXML(DOMElement $xml): static Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class); Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class); - Assert::same(self::getIntegerAttribute($xml, 'MajorVersion'), 1, 'Unsupported major version: %s'); - Assert::same(self::getIntegerAttribute($xml, 'MinorVersion'), 1, 'Unsupported minor version: %s'); - - $assertionID = self::getAttribute($xml, 'AssertionID'); - Assert::validNCName($assertionID); // Covers the empty string - - $issueInstant = self::getAttribute($xml, 'IssueInstant'); - // Strip sub-seconds - See paragraph 1.2.2 of SAML core specifications - $issueInstant = preg_replace('/([.][0-9]+Z)$/', 'Z', $issueInstant, 1); - - Assert::validDateTime($issueInstant, ProtocolViolationException::class); - $issueInstant = new DateTimeImmutable($issueInstant); - $conditions = Conditions::getChildrenOfClass($xml); Assert::maxCount( $conditions, @@ -277,9 +291,11 @@ public static function fromXML(DOMElement $xml): static Assert::maxCount($signature, 1, 'Only one element is allowed.', TooManyElementsException::class); $assertion = new static( - $assertionID, - self::getAttribute($xml, 'Issuer'), - $issueInstant, + self::getAttribute($xml, 'MajorVersion', NonNegativeIntegerValue::class), + self::getAttribute($xml, 'MinorVersion', NonNegativeIntegerValue::class), + self::getAttribute($xml, 'AssertionID', IDValue::class), + self::getAttribute($xml, 'Issuer', StringValue::class), + self::getAttribute($xml, 'IssueInstant', DateTimeValue::class), array_pop($conditions), array_pop($advice), array_merge($statements, $subjectStatement, $authnStatement, $authzDecisionStatement, $attrStatement), @@ -304,11 +320,11 @@ protected function toUnsignedXML(?DOMElement $parent = null): DOMElement { $e = $this->instantiateParentElement($parent); - $e->setAttribute('MajorVersion', '1'); - $e->setAttribute('MinorVersion', '1'); - $e->setAttribute('AssertionID', $this->getId()); - $e->setAttribute('Issuer', $this->getIssuer()); - $e->setAttribute('IssueInstant', $this->getIssueInstant()->format(C::DATETIME_FORMAT)); + $e->setAttribute('MajorVersion', strval($this->getMajorVersion())); + $e->setAttribute('MinorVersion', strval($this->getMinorVersion())); + $e->setAttribute('AssertionID', strval($this->getId())); + $e->setAttribute('Issuer', strval($this->getIssuer())); + $e->setAttribute('IssueInstant', strval($this->getIssueInstant())); $this->getConditions()?->toXML($e); $this->getAdvice()?->toXML($e); diff --git a/src/SAML11/XML/saml/AbstractAttributeDesignatorType.php b/src/SAML11/XML/saml/AbstractAttributeDesignatorType.php index dd3b5db..3886166 100644 --- a/src/SAML11/XML/saml/AbstractAttributeDesignatorType.php +++ b/src/SAML11/XML/saml/AbstractAttributeDesignatorType.php @@ -5,8 +5,9 @@ namespace SimpleSAML\SAML11\XML\saml; use DOMElement; -use SimpleSAML\Assert\Assert; -use SimpleSAML\XML\Exception\SchemaViolationException; +use SimpleSAML\SAML11\Type\{AnyURIValue, StringValue}; + +use function strval; /** * SAML AttributeDesignatorType abstract data type. @@ -18,24 +19,22 @@ abstract class AbstractAttributeDesignatorType extends AbstractSamlElement /** * Initialize a saml:AttributeDesignatorType from scratch * - * @param string $AttributeName - * @param string $AttributeNamespace + * @param \SimpleSAML\SAML11\Type\StringValue $AttributeName + * @param \SimpleSAML\SAML11\Type\AnyURIValue $AttributeNamespace */ public function __construct( - protected string $AttributeName, - protected string $AttributeNamespace, + protected StringValue $AttributeName, + protected AnyURIValue $AttributeNamespace, ) { - Assert::nullOrNotWhitespaceOnly($AttributeName, SchemaViolationException::class); - Assert::nullOrValidURI($AttributeNamespace, SchemaViolationException::class); // Covers the empty string } /** * Collect the value of the AttributeName-property * - * @return string + * @return \SimpleSAML\SAML11\Type\StringValue */ - public function getAttributeName(): string + public function getAttributeName(): StringValue { return $this->AttributeName; } @@ -44,9 +43,9 @@ public function getAttributeName(): string /** * Collect the value of the AttributeNamespace-property * - * @return string + * @return \SimpleSAML\SAML11\Type\AnyURIValue */ - public function getAttributeNamespace(): string + public function getAttributeNamespace(): AnyURIValue { return $this->AttributeNamespace; } @@ -62,8 +61,8 @@ public function toXML(?DOMElement $parent = null): DOMElement { $e = $this->instantiateParentElement($parent); - $e->setAttribute('AttributeName', $this->getAttributeName()); - $e->setAttribute('AttributeNamespace', $this->getAttributeNamespace()); + $e->setAttribute('AttributeName', strval($this->getAttributeName())); + $e->setAttribute('AttributeNamespace', strval($this->getAttributeNamespace())); return $e; } diff --git a/src/SAML11/XML/saml/AbstractAttributeStatementType.php b/src/SAML11/XML/saml/AbstractAttributeStatementType.php index 944e41c..5dcb9e8 100644 --- a/src/SAML11/XML/saml/AbstractAttributeStatementType.php +++ b/src/SAML11/XML/saml/AbstractAttributeStatementType.php @@ -7,9 +7,7 @@ use DOMElement; use SimpleSAML\Assert\Assert; use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; -use SimpleSAML\XML\Exception\TooManyElementsException; +use SimpleSAML\XML\Exception\{MissingElementException, SchemaViolationException, TooManyElementsException}; /** * SAML AttributeStatementType abstract data type. diff --git a/src/SAML11/XML/saml/AbstractAttributeType.php b/src/SAML11/XML/saml/AbstractAttributeType.php index a210770..8d97e08 100644 --- a/src/SAML11/XML/saml/AbstractAttributeType.php +++ b/src/SAML11/XML/saml/AbstractAttributeType.php @@ -6,8 +6,8 @@ use DOMElement; use SimpleSAML\Assert\Assert; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; +use SimpleSAML\SAML11\Type\{AnyURIValue, StringValue}; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, SchemaViolationException}; /** * SAML AttributeType abstract data type. @@ -19,13 +19,13 @@ abstract class AbstractAttributeType extends AbstractAttributeDesignatorType /** * Initialize a saml:AttributeType from scratch * - * @param string $AttributeName - * @param string $AttributeNamespace + * @param \SimpleSAML\SAML11\Type\StringValue $AttributeName + * @param \SimpleSAML\SAML11\Type\AnyURIValue $AttributeNamespace * @param array<\SimpleSAML\SAML11\XML\saml\AttributeValue> $attributeValue */ final public function __construct( - string $AttributeName, - string $AttributeNamespace, + StringValue $AttributeName, + AnyURIValue $AttributeNamespace, protected array $attributeValue, ) { Assert::allIsInstanceOf($attributeValue, AttributeValue::class, SchemaViolationException::class); @@ -60,8 +60,8 @@ public static function fromXML(DOMElement $xml): static Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class); $attributeValue = AttributeValue::getChildrenOfClass($xml); - $AttributeName = self::getAttribute($xml, 'AttributeName'); - $AttributeNamespace = self::getAttribute($xml, 'AttributeNamespace'); + $AttributeName = self::getAttribute($xml, 'AttributeName', StringValue::class); + $AttributeNamespace = self::getAttribute($xml, 'AttributeNamespace', AnyURIValue::class); return new static($AttributeName, $AttributeNamespace, $attributeValue); } diff --git a/src/SAML11/XML/saml/AbstractAudienceRestrictionConditionType.php b/src/SAML11/XML/saml/AbstractAudienceRestrictionConditionType.php index 09cfe24..035181b 100644 --- a/src/SAML11/XML/saml/AbstractAudienceRestrictionConditionType.php +++ b/src/SAML11/XML/saml/AbstractAudienceRestrictionConditionType.php @@ -6,11 +6,7 @@ use DOMElement; use SimpleSAML\Assert\Assert; -use SimpleSAML\SAML11\XML\saml\AbstractConditionType; -use SimpleSAML\SAML11\XML\saml\Audience; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, MissingElementException, SchemaViolationException}; /** * @package simplesamlphp\saml11 diff --git a/src/SAML11/XML/saml/AbstractAuthenticationStatementType.php b/src/SAML11/XML/saml/AbstractAuthenticationStatementType.php index 35d95a0..32b290a 100644 --- a/src/SAML11/XML/saml/AbstractAuthenticationStatementType.php +++ b/src/SAML11/XML/saml/AbstractAuthenticationStatementType.php @@ -4,16 +4,15 @@ namespace SimpleSAML\SAML11\XML\saml; -use DateTimeImmutable; use DOMElement; use SimpleSAML\Assert\Assert; -use SimpleSAML\SAML11\Assert\Assert as SAMLAssert; -use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\Exception\ProtocolViolationException; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; -use SimpleSAML\XML\Exception\TooManyElementsException; +use SimpleSAML\SAML11\Type\{AnyURIValue, DateTimeValue}; +use SimpleSAML\XML\Exception\{ + InvalidDOMElementException, + MissingElementException, + SchemaViolationException, + TooManyElementsException, +}; /** * SAML AuthenticationStatementType abstract data type. @@ -26,19 +25,18 @@ abstract class AbstractAuthenticationStatementType extends AbstractSubjectStatem * Initialize a saml:AuthenticationStatementType from scratch * * @param \SimpleSAML\SAML11\XML\saml\Subject $subject - * @param string $authenticationMethod - * @param \DateTimeImmutable $authenticationInstant + * @param \SimpleSAML\SAML11\Type\AnyURIValue $authenticationMethod + * @param \SimpleSAML\SAML11\Type\DateTimeValue $authenticationInstant * @param \SimpleSAML\SAML11\XML\saml\SubjectLocality|null $subjectLocality * @param array<\SimpleSAML\SAML11\XML\saml\AuthorityBinding> $authorityBinding */ final public function __construct( Subject $subject, - protected string $authenticationMethod, - protected DateTimeImmutable $authenticationInstant, + protected AnyURIValue $authenticationMethod, + protected DateTimeValue $authenticationInstant, protected ?SubjectLocality $subjectLocality = null, protected array $authorityBinding = [], ) { - SAMLAssert::validURI($authenticationMethod); Assert::allIsInstanceOf($authorityBinding, AuthorityBinding::class, SchemaViolationException::class); parent::__construct($subject); @@ -70,9 +68,9 @@ public function getSubjectLocality(): ?SubjectLocality /** * Collect the value of the authenticationMethod-property * - * @return string + * @return \SimpleSAML\SAML11\Type\AnyURIValue */ - public function getAuthenticationMethod(): string + public function getAuthenticationMethod(): AnyURIValue { return $this->authenticationMethod; } @@ -81,9 +79,9 @@ public function getAuthenticationMethod(): string /** * Collect the value of the authenticationInstant-property * - * @return \DateTimeImmutable + * @return \SimpleSAML\SAML11\Type\DateTimeValue */ - public function getAuthenticationInstant(): DateTimeImmutable + public function getAuthenticationInstant(): DateTimeValue { return $this->authenticationInstant; } @@ -103,13 +101,6 @@ public static function fromXML(DOMElement $xml): static Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class); Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class); - $authenticationInstant = self::getAttribute($xml, 'AuthenticationInstant'); - // Strip sub-seconds - See paragraph 1.2.2 of SAML core specifications - $authenticationInstant = preg_replace('/([.][0-9]+Z)$/', 'Z', $authenticationInstant, 1); - - SAMLAssert::validDateTime($authenticationInstant, ProtocolViolationException::class); - $authenticationInstant = new DateTimeImmutable($authenticationInstant); - $authorityBinding = AuthorityBinding::getChildrenOfClass($xml); $subjectLocality = SubjectLocality::getChildrenOfClass($xml); Assert::maxCount($subjectLocality, 1, TooManyElementsException::class); @@ -120,8 +111,8 @@ public static function fromXML(DOMElement $xml): static return new static( array_pop($subject), - self::getAttribute($xml, 'AuthenticationMethod'), - $authenticationInstant, + self::getAttribute($xml, 'AuthenticationMethod', AnyURIValue::class), + self::getAttribute($xml, 'AuthenticationInstant', DateTimeValue::class), array_pop($subjectLocality), $authorityBinding, ); @@ -138,8 +129,8 @@ public function toXML(?DOMElement $parent = null): DOMElement { $e = parent::toXML($parent); - $e->setAttribute('AuthenticationMethod', $this->getAuthenticationMethod()); - $e->setAttribute('AuthenticationInstant', $this->getAuthenticationInstant()->format(C::DATETIME_FORMAT)); + $e->setAttribute('AuthenticationMethod', strval($this->getAuthenticationMethod())); + $e->setAttribute('AuthenticationInstant', strval($this->getAuthenticationInstant())); $this->getSubjectLocality()?->toXML($e); diff --git a/src/SAML11/XML/saml/AbstractAuthorityBindingType.php b/src/SAML11/XML/saml/AbstractAuthorityBindingType.php index 052dd16..6a78d81 100644 --- a/src/SAML11/XML/saml/AbstractAuthorityBindingType.php +++ b/src/SAML11/XML/saml/AbstractAuthorityBindingType.php @@ -6,8 +6,11 @@ use DOMElement; use SimpleSAML\SAML11\Assert\Assert; -use SimpleSAML\SAML11\Constants as C; +use SimpleSAML\SAML11\Type\AnyURIValue; use SimpleSAML\XML\Exception\InvalidDOMElementException; +use SimpleSAML\XML\Type\QNameValue; + +use function strval; /** * SAML AuthorityBindingType abstract data type. @@ -19,27 +22,24 @@ abstract class AbstractAuthorityBindingType extends AbstractSamlElement /** * Initialize a saml:AuthorityBindingType from scratch * - * @param string $AuthorityKind - * @param string $Location - * @param string $Binding + * @param \SimpleSAML\XML\Type\QNameValue $AuthorityKind + * @param \SimpleSAML\SAML11\Type\AnyURIValue $Location + * @param \SimpleSAML\SAML11\Type\AnyURIValue $Binding */ final public function __construct( - protected string $AuthorityKind, - protected string $Location, - protected string $Binding, + protected QNameValue $AuthorityKind, + protected AnyURIValue $Location, + protected AnyURIValue $Binding, ) { - Assert::validQName($AuthorityKind); - Assert::validURI($Location); - Assert::validURI($Binding); } /** * Collect the value of the AuthorityKind-property * - * @return string + * @return \SimpleSAML\XML\Type\QNameValue */ - public function getAuthorityKind(): string + public function getAuthorityKind(): QNameValue { return $this->AuthorityKind; } @@ -48,9 +48,9 @@ public function getAuthorityKind(): string /** * Collect the value of the Location-property * - * @return string + * @return \SimpleSAML\SAML11\Type\AnyURIValue */ - public function getLocation(): string + public function getLocation(): AnyURIValue { return $this->Location; } @@ -59,9 +59,9 @@ public function getLocation(): string /** * Collect the value of the Binding-property * - * @return string + * @return \SimpleSAML\SAML11\Type\AnyURIValue */ - public function getBinding(): string + public function getBinding(): AnyURIValue { return $this->Binding; } @@ -81,9 +81,9 @@ public static function fromXML(DOMElement $xml): static Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class); Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class); - $AuthorityKind = self::getAttribute($xml, 'AuthorityKind'); - $Location = self::getAttribute($xml, 'Location'); - $Binding = self::getAttribute($xml, 'Binding'); + $AuthorityKind = self::getAttribute($xml, 'AuthorityKind', QNameValue::class); + $Location = self::getAttribute($xml, 'Location', AnyURIValue::class); + $Binding = self::getAttribute($xml, 'Binding', AnyURIValue::class); return new static($AuthorityKind, $Location, $Binding); } @@ -99,11 +99,17 @@ public function toXML(?DOMElement $parent = null): DOMElement { $e = $this->instantiateParentElement($parent); - $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:samlp', C::NS_SAMLP); - - $e->setAttribute('AuthorityKind', $this->getAuthorityKind()); - $e->setAttribute('Location', $this->getLocation()); - $e->setAttribute('Binding', $this->getBinding()); + if (!$e->lookupPrefix($this->getAuthorityKind()->getNamespaceURI()->getValue())) { + $e->setAttributeNS( + 'http://www.w3.org/2000/xmlns/', + 'xmlns:' . $this->getAuthorityKind()->getNamespacePrefix()->getValue(), + $this->getAuthorityKind()->getNamespaceURI()->getValue(), + ); + } + + $e->setAttribute('AuthorityKind', strval($this->getAuthorityKind())); + $e->setAttribute('Location', strval($this->getLocation())); + $e->setAttribute('Binding', strval($this->getBinding())); return $e; } diff --git a/src/SAML11/XML/saml/AbstractAuthorizationDecisionStatementType.php b/src/SAML11/XML/saml/AbstractAuthorizationDecisionStatementType.php index 0306177..0e1a627 100644 --- a/src/SAML11/XML/saml/AbstractAuthorizationDecisionStatementType.php +++ b/src/SAML11/XML/saml/AbstractAuthorizationDecisionStatementType.php @@ -6,11 +6,16 @@ use DOMElement; use SimpleSAML\Assert\Assert; -use SimpleSAML\SAML11\Assert\Assert as SAMLAssert; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; -use SimpleSAML\XML\Exception\TooManyElementsException; +use SimpleSAML\SAML11\Type\StringValue; +use SimpleSAML\XML\Exception\{ + InvalidDOMElementException, + MissingElementException, + SchemaViolationException, + TooManyElementsException, +}; +use SimpleSAML\XML\Type\AnyURIValue; + +use function strval; /** * SAML AuthorizationDecisionStatementType abstract data type. @@ -22,7 +27,7 @@ abstract class AbstractAuthorizationDecisionStatementType extends AbstractSubjec /** * Initialize a saml:AuthorizationDecisionStatementType from scratch * - * @param string $resource + * @param \SimpleSAML\XML\Type\AnyURIValue $resource * @param \SimpleSAML\SAML11\XML\saml\DecisionTypeEnum $decision * @param \SimpleSAML\SAML11\XML\saml\Subject $subject * @param array<\SimpleSAML\SAML11\XML\saml\Action> $action @@ -30,12 +35,12 @@ abstract class AbstractAuthorizationDecisionStatementType extends AbstractSubjec */ final public function __construct( Subject $subject, - protected string $resource, + // Uses the base AnyURIValue because the SAML specification allows this attribute to be an empty string + protected AnyURIValue $resource, protected DecisionTypeEnum $decision, protected array $action = [], protected ?Evidence $evidence = null, ) { - SAMLAssert::validURI($resource); Assert::minCount($action, 1, MissingElementException::class); Assert::allIsInstanceOf($action, Action::class, SchemaViolationException::class); @@ -46,9 +51,9 @@ final public function __construct( /** * Collect the value of the resource-property * - * @return string + * @return \SimpleSAML\SAML11\Type\AnyURIValue */ - public function getResource(): string + public function getResource(): AnyURIValue { return $this->resource; } @@ -110,8 +115,10 @@ public static function fromXML(DOMElement $xml): static return new static( array_pop($subject), - self::getAttribute($xml, 'Resource'), - DecisionTypeEnum::from(self::getAttribute($xml, 'Decision')), + self::getAttribute($xml, 'Resource', AnyURIValue::class), + DecisionTypeEnum::from( + strval(self::getAttribute($xml, 'Decision', StringValue::class)), + ), Action::getChildrenOfClass($xml), array_pop($evidence), ); @@ -129,7 +136,7 @@ public function toXML(?DOMElement $parent = null): DOMElement { $e = parent::toXML($parent); - $e->setAttribute('Resource', $this->getResource()); + $e->setAttribute('Resource', strval($this->getResource())); $e->setAttribute('Decision', $this->getDecision()->value); foreach ($this->getAction() as $action) { diff --git a/src/SAML11/XML/saml/AbstractCondition.php b/src/SAML11/XML/saml/AbstractCondition.php index add4b58..ed98e8a 100644 --- a/src/SAML11/XML/saml/AbstractCondition.php +++ b/src/SAML11/XML/saml/AbstractCondition.php @@ -8,17 +8,14 @@ use SimpleSAML\SAML11\Assert\Assert; use SimpleSAML\SAML11\Constants as C; use SimpleSAML\SAML11\Utils; -use SimpleSAML\SAML11\XML\ExtensionPointInterface; -use SimpleSAML\SAML11\XML\ExtensionPointTrait; +use SimpleSAML\SAML11\XML\{ExtensionPointInterface, ExtensionPointTrait}; use SimpleSAML\XML\Attribute as XMLAttribute; use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, SchemaViolationException}; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; +use SimpleSAML\XML\Type\QNameValue; -use function count; -use function explode; +use function strval; /** * SAML Condition data type. @@ -39,18 +36,18 @@ abstract class AbstractCondition extends AbstractConditionType implements /** * Initialize a custom saml:Condition element. * - * @param string $type + * @param \SimpleSAML\XML\Type\QNameValue $type */ protected function __construct( - protected string $type, + protected QNameValue $type, ) { } /** - * @inheritDoc + * @return \SimpleSAML\XML\Type\QNameValue */ - public function getXsiType(): string + public function getXsiType(): QNameValue { return $this->type; } @@ -75,19 +72,7 @@ public static function fromXML(DOMElement $xml): static 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]); + $type = QNameValue::fromDocument($xml->getAttributeNS(C::NS_XSI, 'type'), $xml); // now check if we have a handler registered for it $handler = Utils::getContainer()->getExtensionHandler($type); @@ -114,11 +99,14 @@ public static function fromXML(DOMElement $xml): static public function toXML(?DOMElement $parent = null): DOMElement { $e = $this->instantiateParentElement($parent); - $e->setAttributeNS( - 'http://www.w3.org/2000/xmlns/', - 'xmlns:' . static::getXsiTypePrefix(), - static::getXsiTypeNamespaceURI(), - ); + + if (!$e->lookupPrefix($this->getXsiType()->getNamespaceURI()->getValue())) { + $e->setAttributeNS( + 'http://www.w3.org/2000/xmlns/', + 'xmlns:' . static::getXsiTypePrefix(), + strval(static::getXsiTypeNamespaceURI()), + ); + } $type = new XMLAttribute(C::NS_XSI, 'xsi', 'type', $this->getXsiType()); $type->toXML($e); diff --git a/src/SAML11/XML/saml/AbstractConditionsType.php b/src/SAML11/XML/saml/AbstractConditionsType.php index 268bd91..eb432fa 100644 --- a/src/SAML11/XML/saml/AbstractConditionsType.php +++ b/src/SAML11/XML/saml/AbstractConditionsType.php @@ -4,14 +4,13 @@ namespace SimpleSAML\SAML11\XML\saml; -use DateTimeImmutable; use DOMElement; use SimpleSAML\Assert\Assert; -use SimpleSAML\SAML11\Assert\Assert as SAMLAssert; -use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\Exception\ProtocolViolationException; +use SimpleSAML\SAML11\Type\DateTimeValue; use SimpleSAML\XML\Exception\InvalidDOMElementException; +use function strval; + /** * SAML ConditionsType abstract data type. * @@ -25,15 +24,15 @@ abstract class AbstractConditionsType extends AbstractSamlElement * @param array<\SimpleSAML\SAML11\XML\saml\AudienceRestrictionCondition> $audienceRestrictionCondition * @param array<\SimpleSAML\SAML11\XML\saml\DoNotCacheCondition> $doNotCacheCondition * @param array<\SimpleSAML\SAML11\XML\saml\AbstractCondition> $condition - * @param \DateTimeImmutable|null $notBefore - * @param \DateTimeImmutable|null $notOnOrAfter + * @param \SimpleSAML\SAML11\Type\DateTimeValue|null $notBefore + * @param \SimpleSAML\SAML11\Type\DateTimeValue|null $notOnOrAfter */ final public function __construct( protected array $audienceRestrictionCondition = [], protected array $doNotCacheCondition = [], protected array $condition = [], - protected ?DateTimeImmutable $notBefore = null, - protected ?DateTimeImmutable $notOnOrAfter = null, + protected ?DateTimeValue $notBefore = null, + protected ?DateTimeValue $notOnOrAfter = null, ) { Assert::allIsInstanceOf($audienceRestrictionCondition, AudienceRestrictionCondition::class); Assert::allIsInstanceOf($doNotCacheCondition, DoNotCacheCondition::class); @@ -44,9 +43,9 @@ final public function __construct( /** * Collect the value of the notBefore-property * - * @return \DateTimeImmutable|null + * @return \SimpleSAML\SAML11\Type\DateTimeValue|null */ - public function getNotBefore(): ?DateTimeImmutable + public function getNotBefore(): ?DateTimeValue { return $this->notBefore; } @@ -55,9 +54,9 @@ public function getNotBefore(): ?DateTimeImmutable /** * Collect the value of the notOnOrAfter-property * - * @return \DateTimeImmutable|null + * @return \SimpleSAML\SAML11\Type\DateTimeValue|null */ - public function getNotOnOrAfter(): ?DateTimeImmutable + public function getNotOnOrAfter(): ?DateTimeValue { return $this->notOnOrAfter; } @@ -125,25 +124,13 @@ public static function fromXML(DOMElement $xml): static Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class); Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class); - $notBefore = self::getOptionalAttribute($xml, 'NotBefore'); - // Strip sub-seconds - See paragraph 1.2.2 of SAML core specifications - $notBefore = preg_replace('/([.][0-9]+Z)$/', 'Z', $notBefore, 1); - - SAMLAssert::validDateTime($notBefore, ProtocolViolationException::class); - $notBefore = new DateTimeImmutable($notBefore); - - $notOnOrAfter = self::getOptionalAttribute($xml, 'NotOnOrAfter'); - // Strip sub-seconds - See paragraph 1.2.2 of SAML core specifications - $notOnOrAfter = preg_replace('/([.][0-9]+Z)$/', 'Z', $notOnOrAfter, 1); - - SAMLAssert::validDateTime($notOnOrAfter, ProtocolViolationException::class); - $notOnOrAfter = new DateTimeImmutable($notOnOrAfter); - - $audienceRestrictionCondition = AudienceRestrictionCondition::getChildrenOfClass($xml); - $doNotCacheCondition = DoNotCacheCondition::getChildrenOfClass($xml); - $condition = AbstractCondition::getChildrenOfClass($xml); - - return new static($audienceRestrictionCondition, $doNotCacheCondition, $condition, $notBefore, $notOnOrAfter); + return new static( + AudienceRestrictionCondition::getChildrenOfClass($xml), + DoNotCacheCondition::getChildrenOfClass($xml), + AbstractCondition::getChildrenOfClass($xml), + self::getOptionalAttribute($xml, 'NotBefore', DateTimeValue::class), + self::getOptionalAttribute($xml, 'NotOnOrAfter', DateTimeValue::class), + ); } @@ -158,11 +145,11 @@ public function toXML(?DOMElement $parent = null): DOMElement $e = $this->instantiateParentElement($parent); if ($this->getNotBefore() !== null) { - $e->setAttribute('NotBefore', $this->getNotBefore()->format(C::DATETIME_FORMAT)); + $e->setAttribute('NotBefore', strval($this->getNotBefore())); } if ($this->getNotOnOrAfter() !== null) { - $e->setAttribute('NotOnOrAfter', $this->getNotOnOrAfter()->format(C::DATETIME_FORMAT)); + $e->setAttribute('NotOnOrAfter', strval($this->getNotOnOrAfter())); } foreach ($this->getAudienceRestrictionCondition() as $audienceRestrictionCondition) { diff --git a/src/SAML11/XML/saml/AbstractEvidenceType.php b/src/SAML11/XML/saml/AbstractEvidenceType.php index e985d45..4e72268 100644 --- a/src/SAML11/XML/saml/AbstractEvidenceType.php +++ b/src/SAML11/XML/saml/AbstractEvidenceType.php @@ -7,8 +7,7 @@ use DOMElement; use SimpleSAML\Assert\Assert; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, SchemaViolationException}; /** * SAML EvidenceType abstract data type. diff --git a/src/SAML11/XML/saml/AbstractNameIdentifierType.php b/src/SAML11/XML/saml/AbstractNameIdentifierType.php index 8bf7833..82f8a85 100644 --- a/src/SAML11/XML/saml/AbstractNameIdentifierType.php +++ b/src/SAML11/XML/saml/AbstractNameIdentifierType.php @@ -6,9 +6,11 @@ use DOMElement; use SimpleSAML\Assert\Assert; -use SimpleSAML\SAML11\XML\StringElementTrait; +use SimpleSAML\SAML11\Type\{AnyURIValue, StringValue}; use SimpleSAML\XML\Exception\InvalidDOMElementException; +use function strval; + /** * SAML NameIdentifierType abstract data type. * @@ -16,34 +18,38 @@ */ abstract class AbstractNameIdentifierType extends AbstractSamlElement { - use StringElementTrait; - - /** * Initialize a saml:NameIdentifierType from scratch * - * @param string $value - * @param string|null $Format - * @param string|null $NameQualifier + * @param \SimpleSAML\SAML11\Type\StringValue $value + * @param \SimpleSAML\SAML11\Type\StringValue|null $NameQualifier + * @param \SimpleSAML\SAML11\Type\AnyURIValue|null $Format */ final public function __construct( - string $value, - protected ?string $NameQualifier = null, - protected ?string $Format = null, + protected StringValue $value, + protected ?StringValue $NameQualifier = null, + protected ?AnyURIValue $Format = null, ) { - Assert::nullOrNotWhitespaceOnly($NameQualifier); - Assert::nullOrValidURI($Format); // Covers the empty string + } + - $this->setContent($value); + /** + * Collect the value of the value-property + * + * @return \SimpleSAML\SAML11\Type\StringValue + */ + public function getValue(): StringValue + { + return $this->value; } /** * Collect the value of the Format-property * - * @return string|null + * @return \SimpleSAML\SAML11\Type\AnyURIValue|null */ - public function getFormat(): ?string + public function getFormat(): ?AnyURIValue { return $this->Format; } @@ -52,9 +58,9 @@ public function getFormat(): ?string /** * Collect the value of the NameQualifier-property * - * @return string|null + * @return \SimpleSAML\SAML11\Type\StringValue|null */ - public function getNameQualifier(): ?string + public function getNameQualifier(): ?StringValue { return $this->NameQualifier; } @@ -74,10 +80,11 @@ public static function fromXML(DOMElement $xml): static Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class); Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class); - $NameQualifier = self::getOptionalAttribute($xml, 'NameQualifier', null); - $Format = self::getOptionalAttribute($xml, 'Format', null); - - return new static($xml->textContent, $NameQualifier, $Format); + return new static( + StringValue::fromString($xml->textContent), + self::getOptionalAttribute($xml, 'NameQualifier', StringValue::class, null), + self::getOptionalAttribute($xml, 'Format', AnyURIValue::class, null), + ); } @@ -90,14 +97,14 @@ public static function fromXML(DOMElement $xml): static public function toXML(?DOMElement $parent = null): DOMElement { $e = $this->instantiateParentElement($parent); - $e->textContent = $this->getContent(); + $e->textContent = strval($this->getValue()); if ($this->getNameQualifier() !== null) { - $e->setAttribute('NameQualifier', $this->getNameQualifier()); + $e->setAttribute('NameQualifier', strval($this->getNameQualifier())); } if ($this->getFormat() !== null) { - $e->setAttribute('Format', $this->getFormat()); + $e->setAttribute('Format', strval($this->getFormat())); } return $e; diff --git a/src/SAML11/XML/saml/AbstractStatement.php b/src/SAML11/XML/saml/AbstractStatement.php index d56a895..c86f01b 100644 --- a/src/SAML11/XML/saml/AbstractStatement.php +++ b/src/SAML11/XML/saml/AbstractStatement.php @@ -8,17 +8,14 @@ use SimpleSAML\SAML11\Assert\Assert; use SimpleSAML\SAML11\Constants as C; use SimpleSAML\SAML11\Utils; -use SimpleSAML\SAML11\XML\ExtensionPointInterface; -use SimpleSAML\SAML11\XML\ExtensionPointTrait; +use SimpleSAML\SAML11\XML\{ExtensionPointInterface, ExtensionPointTrait}; use SimpleSAML\XML\Attribute as XMLAttribute; use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, SchemaViolationException}; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; +use SimpleSAML\XML\Type\QNameValue; -use function count; -use function explode; +use function strval; /** * Class implementing the extension point. @@ -39,18 +36,18 @@ abstract class AbstractStatement extends AbstractStatementType implements /** * Initialize a custom saml:Statement element. * - * @param string $type + * @param \SimpleSAML\XML\Type\QNameValue $type */ protected function __construct( - protected string $type, + protected QNameValue $type, ) { } /** - * @inheritDoc + * @return \SimpleSAML\XML\Type\QNameValue */ - public function getXsiType(): string + public function getXsiType(): QNameValue { return $this->type; } @@ -75,19 +72,7 @@ public static function fromXML(DOMElement $xml): static 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]); + $type = QNameValue::fromDocument($xml->getAttributeNS(C::NS_XSI, 'type'), $xml); // now check if we have a handler registered for it $handler = Utils::getContainer()->getExtensionHandler($type); @@ -114,11 +99,14 @@ public static function fromXML(DOMElement $xml): static public function toXML(?DOMElement $parent = null): DOMElement { $e = $this->instantiateParentElement($parent); - $e->setAttributeNS( - 'http://www.w3.org/2000/xmlns/', - 'xmlns:' . static::getXsiTypePrefix(), - static::getXsiTypeNamespaceURI(), - ); + + if (!$e->lookupPrefix($this->getXsiType()->getNamespaceURI()->getValue())) { + $e->setAttributeNS( + 'http://www.w3.org/2000/xmlns/', + 'xmlns:' . static::getXsiTypePrefix(), + strval(static::getXsiTypeNamespaceURI()), + ); + } $type = new XMLAttribute(C::NS_XSI, 'xsi', 'type', $this->getXsiType()); $type->toXML($e); diff --git a/src/SAML11/XML/saml/AbstractSubjectConfirmationType.php b/src/SAML11/XML/saml/AbstractSubjectConfirmationType.php index 4dd8e37..357dca4 100644 --- a/src/SAML11/XML/saml/AbstractSubjectConfirmationType.php +++ b/src/SAML11/XML/saml/AbstractSubjectConfirmationType.php @@ -6,10 +6,12 @@ use DOMElement; use SimpleSAML\Assert\Assert; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; -use SimpleSAML\XML\Exception\TooManyElementsException; +use SimpleSAML\XML\Exception\{ + InvalidDOMElementException, + MissingElementException, + SchemaViolationException, + TooManyElementsException, +}; use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; /** diff --git a/src/SAML11/XML/saml/AbstractSubjectLocalityType.php b/src/SAML11/XML/saml/AbstractSubjectLocalityType.php index bf849ea..5ee8f1c 100644 --- a/src/SAML11/XML/saml/AbstractSubjectLocalityType.php +++ b/src/SAML11/XML/saml/AbstractSubjectLocalityType.php @@ -6,8 +6,11 @@ use DOMElement; use SimpleSAML\Assert\Assert; +use SimpleSAML\SAML11\Type\StringValue; use SimpleSAML\XML\Exception\InvalidDOMElementException; +use function strval; + /** * SAML SubjectLocalityType abstract data type. * @@ -18,24 +21,22 @@ abstract class AbstractSubjectLocalityType extends AbstractSamlElement /** * Initialize a saml:SubjectLocalityType from scratch * - * @param string|null $IPAddress - * @param string|null $DNSAddress + * @param \SimpleSAML\SAML11\Type\StringValue|null $IPAddress + * @param \SimpleSAML\SAML11\Type\StringValue|null $DNSAddress */ final public function __construct( - protected ?string $IPAddress = null, - protected ?string $DNSAddress = null, + protected ?StringValue $IPAddress = null, + protected ?StringValue $DNSAddress = null, ) { - Assert::nullOrNotWhitespaceOnly($IPAddress); - Assert::nullOrNotWhitespaceOnly($DNSAddress); } /** * Collect the value of the IPAddress-property * - * @return string|null + * @return \SimpleSAML\SAML11\Type\StringValue|null */ - public function getIPAddress(): ?string + public function getIPAddress(): ?StringValue { return $this->IPAddress; } @@ -44,9 +45,9 @@ public function getIPAddress(): ?string /** * Collect the value of the DNSAddress-property * - * @return string|null + * @return \SimpleSAML\SAML11\Type\StringValue|null */ - public function getDNSAddress(): ?string + public function getDNSAddress(): ?StringValue { return $this->DNSAddress; } @@ -78,8 +79,8 @@ public static function fromXML(DOMElement $xml): static Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class); Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class); - $IPAddress = self::getOptionalAttribute($xml, 'IPAddress'); - $DNSAddress = self::getOptionalAttribute($xml, 'DNSAddress'); + $IPAddress = self::getOptionalAttribute($xml, 'IPAddress', StringValue::class); + $DNSAddress = self::getOptionalAttribute($xml, 'DNSAddress', StringValue::class); return new static($IPAddress, $DNSAddress); } @@ -96,11 +97,11 @@ public function toXML(?DOMElement $parent = null): DOMElement $e = $this->instantiateParentElement($parent); if ($this->getIPAddress() !== null) { - $e->setAttribute('IPAddress', $this->getIPAddress()); + $e->setAttribute('IPAddress', strval($this->getIPAddress())); } if ($this->getDNSAddress() !== null) { - $e->setAttribute('DNSAddress', $this->getDNSAddress()); + $e->setAttribute('DNSAddress', strval($this->getDNSAddress())); } return $e; diff --git a/src/SAML11/XML/saml/AbstractSubjectStatement.php b/src/SAML11/XML/saml/AbstractSubjectStatement.php index ff4e70d..d4d8673 100644 --- a/src/SAML11/XML/saml/AbstractSubjectStatement.php +++ b/src/SAML11/XML/saml/AbstractSubjectStatement.php @@ -8,17 +8,16 @@ use SimpleSAML\SAML11\Assert\Assert; use SimpleSAML\SAML11\Constants as C; use SimpleSAML\SAML11\Utils; -use SimpleSAML\SAML11\XML\ExtensionPointInterface; -use SimpleSAML\SAML11\XML\ExtensionPointTrait; +use SimpleSAML\SAML11\XML\{ExtensionPointInterface, 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\SchemaViolationException; -use SimpleSAML\XML\Exception\TooManyElementsException; - -use function count; -use function explode; +use SimpleSAML\XML\Exception\{ + InvalidDOMElementException, + MissingElementException, + SchemaViolationException, + TooManyElementsException, +}; +use SimpleSAML\XML\Type\QNameValue; /** * Class implementing the extension point. @@ -36,10 +35,10 @@ abstract class AbstractSubjectStatement extends AbstractSubjectStatementType imp /** * Initialize a custom saml:SubjectStatement element. * - * @param string $type + * @param \SimpleSAML\XML\Type\QNameValue $type */ protected function __construct( - protected string $type, + protected QNameValue $type, Subject $subject, ) { parent::__construct($subject); @@ -47,9 +46,9 @@ protected function __construct( /** - * @inheritDoc + * @return \SimpleSAML\XML\Type\QNameValue */ - public function getXsiType(): string + public function getXsiType(): QNameValue { return $this->type; } @@ -74,19 +73,7 @@ public static function fromXML(DOMElement $xml): static 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]); + $type = QNameValue::fromDocument($xml->getAttributeNS(C::NS_XSI, 'type'), $xml); // now check if we have a handler registered for it $handler = Utils::getContainer()->getExtensionHandler($type); @@ -117,11 +104,14 @@ public static function fromXML(DOMElement $xml): static public function toXML(?DOMElement $parent = null): DOMElement { $e = parent::toXML($parent); - $e->setAttributeNS( - 'http://www.w3.org/2000/xmlns/', - 'xmlns:' . static::getXsiTypePrefix(), - static::getXsiTypeNamespaceURI(), - ); + + if (!$e->lookupPrefix($this->getXsiType()->getNamespaceURI()->getValue())) { + $e->setAttributeNS( + 'http://www.w3.org/2000/xmlns/', + 'xmlns:' . static::getXsiTypePrefix(), + static::getXsiTypeNamespaceURI()->getValue(), + ); + } $type = new XMLAttribute(C::NS_XSI, 'xsi', 'type', $this->getXsiType()); $type->toXML($e); diff --git a/src/SAML11/XML/saml/AbstractSubjectStatementType.php b/src/SAML11/XML/saml/AbstractSubjectStatementType.php index 3ab1983..96b2058 100644 --- a/src/SAML11/XML/saml/AbstractSubjectStatementType.php +++ b/src/SAML11/XML/saml/AbstractSubjectStatementType.php @@ -5,8 +5,6 @@ namespace SimpleSAML\SAML11\XML\saml; use DOMElement; -use SimpleSAML\SAML11\XML\saml\AbstractStatementType; -use SimpleSAML\SAML11\XML\saml\Subject; /** * @package simplesamlphp\saml11 diff --git a/src/SAML11/XML/saml/AbstractSubjectType.php b/src/SAML11/XML/saml/AbstractSubjectType.php index b669ca1..f1ce423 100644 --- a/src/SAML11/XML/saml/AbstractSubjectType.php +++ b/src/SAML11/XML/saml/AbstractSubjectType.php @@ -6,9 +6,7 @@ use DOMElement; use SimpleSAML\Assert\Assert; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\TooManyElementsException; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, MissingElementException, TooManyElementsException}; /** * SAML SubjectType abstract data type. diff --git a/src/SAML11/XML/saml/Action.php b/src/SAML11/XML/saml/Action.php index a705f5c..381858a 100644 --- a/src/SAML11/XML/saml/Action.php +++ b/src/SAML11/XML/saml/Action.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:Action element. diff --git a/src/SAML11/XML/saml/Advice.php b/src/SAML11/XML/saml/Advice.php index a904159..aa5d8e2 100644 --- a/src/SAML11/XML/saml/Advice.php +++ b/src/SAML11/XML/saml/Advice.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:Advice element. diff --git a/src/SAML11/XML/saml/Assertion.php b/src/SAML11/XML/saml/Assertion.php index dab25e4..1aa1092 100644 --- a/src/SAML11/XML/saml/Assertion.php +++ b/src/SAML11/XML/saml/Assertion.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:Assertion element. diff --git a/src/SAML11/XML/saml/AssertionIDReference.php b/src/SAML11/XML/saml/AssertionIDReference.php index 45bcfd6..12d48db 100644 --- a/src/SAML11/XML/saml/AssertionIDReference.php +++ b/src/SAML11/XML/saml/AssertionIDReference.php @@ -4,13 +4,9 @@ namespace SimpleSAML\SAML11\XML\saml; -use DOMElement; -use SimpleSAML\SAML11\Assert\Assert; -use SimpleSAML\SAML11\XML\StringElementTrait; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; +use SimpleSAML\XML\Type\NCNameValue; +use SimpleSAML\XML\TypedTextContentTrait; /** * Class representing a saml:AssertionIDReference element. @@ -20,60 +16,8 @@ final class AssertionIDReference extends AbstractSamlElement implements SchemaValidatableElementInterface { use SchemaValidatableElementTrait; - use StringElementTrait; + use TypedTextContentTrait; - - /** - * @param string $content - */ - public function __construct(string $content) - { - $this->setContent($content); - } - - - /** - * Validate the content of the element. - * - * @param string $content The value to go in the XML textContent - * @throws \Exception on failure - * @return void - */ - protected function validateContent(string $content): void - { - Assert::validNCName($content, SchemaViolationException::class); // Covers the empty string - } - - - /** - * Convert XML into an AssertionIDReference - * - * @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); - - return new static($xml->textContent); - } - - - /** - * Convert this AssertionIDReference to XML. - * - * @param \DOMElement $parent The element we are converting to XML. - * @return \DOMElement The XML element after adding the data corresponding to this AssertionIDReference. - */ - public function toXML(?DOMElement $parent = null): DOMElement - { - $element = $this->instantiateParentElement($parent); - $element->textContent = $this->getContent(); - - return $element; - } + /** @var string */ + public const TEXTCONTENT_TYPE = NCNameValue::class; } diff --git a/src/SAML11/XML/saml/Attribute.php b/src/SAML11/XML/saml/Attribute.php index 5c13916..e16e225 100644 --- a/src/SAML11/XML/saml/Attribute.php +++ b/src/SAML11/XML/saml/Attribute.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:Attribute element. diff --git a/src/SAML11/XML/saml/AttributeDesignator.php b/src/SAML11/XML/saml/AttributeDesignator.php index bb4297e..3c30a5e 100644 --- a/src/SAML11/XML/saml/AttributeDesignator.php +++ b/src/SAML11/XML/saml/AttributeDesignator.php @@ -6,9 +6,9 @@ use DOMElement; use SimpleSAML\Assert\Assert; +use SimpleSAML\SAML11\Type\{AnyURIValue, StringValue}; use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:AttributeDesignator element. @@ -33,9 +33,9 @@ public static function fromXML(DOMElement $xml): static Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class); Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class); - $AttributeName = self::getAttribute($xml, 'AttributeName'); - $AttributeNamespace = self::getAttribute($xml, 'AttributeNamespace'); - - return new static($AttributeName, $AttributeNamespace); + return new static( + self::getAttribute($xml, 'AttributeName', StringValue::class), + self::getAttribute($xml, 'AttributeNamespace', AnyURIValue::class), + ); } } diff --git a/src/SAML11/XML/saml/AttributeStatement.php b/src/SAML11/XML/saml/AttributeStatement.php index 86cb38a..92b3322 100644 --- a/src/SAML11/XML/saml/AttributeStatement.php +++ b/src/SAML11/XML/saml/AttributeStatement.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:AttributeStatement element. diff --git a/src/SAML11/XML/saml/AttributeValue.php b/src/SAML11/XML/saml/AttributeValue.php index b5275c4..a23c33b 100644 --- a/src/SAML11/XML/saml/AttributeValue.php +++ b/src/SAML11/XML/saml/AttributeValue.php @@ -4,21 +4,19 @@ namespace SimpleSAML\SAML11\XML\saml; -use DateTimeImmutable; -use DateTimeInterface; use DOMElement; use SimpleSAML\SAML11\Assert\Assert; use SimpleSAML\SAML11\Constants as C; +use SimpleSAML\SAML11\Type\{DateTimeValue, StringValue}; use SimpleSAML\XML\AbstractElement; use SimpleSAML\XML\Chunk; use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; +use SimpleSAML\XML\Type\{IntegerValue, ValueTypeInterface}; use function class_exists; use function explode; use function gettype; -use function intval; use function str_contains; use function strval; @@ -34,16 +32,11 @@ class AttributeValue extends AbstractSamlElement implements SchemaValidatableEle /** * Create an AttributeValue. * - * The value of this element. Can be one of: - * - string - * - int - * - \SimpleSAML\XML\AbstractElement - * - * @param string|int|\DateTimeInterface|\SimpleSAML\XML\AbstractElement $value + * @param \SimpleSAML\XML\Type\ValueTypeInterface|\SimpleSAML\XML\AbstractElement $value * @throws \SimpleSAML\Assert\AssertionFailedException if the supplied value is neither a string or a DOMElement */ final public function __construct( - protected string|int|DateTimeInterface|AbstractElement $value, + protected StringValue|IntegerValue|DateTimeValue|AbstractElement $value, ) { } @@ -56,23 +49,17 @@ final public function __construct( public function getXsiType(): string { $value = $this->getValue(); - $type = gettype($value); - - switch ($type) { - case "integer": - return "xs:integer"; - case "object": - if ($value instanceof DateTimeInterface) { - return 'xs:dateTime'; - } - return sprintf( - '%s:%s', - $this->value::getNamespacePrefix(), - AbstractElement::getClassName(get_class($value)), - ); - default: - return "xs:string"; + if ($value === null) { + return 'xs:nil'; + } elseif ($value instanceof ValueTypeInterface) { + return $value::SCHEMA_NAMESPACE_PREFIX . ':' . $value::SCHEMA_TYPE; + } else { + return sprintf( + '%s:%s', + $value::getNamespacePrefix(), + $value::getLocalName(), + ); } } @@ -80,7 +67,13 @@ public function getXsiType(): string /** * Get this attribute value. * - * @return string|int|\SimpleSAML\XML\AbstractElement[]|null + * @return ( + * \SimpleSAML\XML\Type\IntegerValue| + * \SimpleSAML\SAML11\Type\StringValue| + * \SimpleSAML\SAML11\Type\DateTimeValue| + * \SimpleSAML\XML\AbstractElement| + * null + * ) */ public function getValue() { @@ -121,10 +114,8 @@ public static function fromXML(DOMElement $xml): static $xml->hasAttributeNS(C::NS_XSI, "type") && $xml->getAttributeNS(C::NS_XSI, "type") === "xs:integer" ) { - Assert::numeric($xml->textContent); - // we have an integer as value - $value = intval($xml->textContent); + $value = IntegerValue::fromString($xml->textContent); } elseif ( $xml->hasAttributeNS(C::NS_XSI, "nil") && ($xml->getAttributeNS(C::NS_XSI, "nil") === "1" || $xml->getAttributeNS(C::NS_XSI, "nil") === "true") @@ -135,12 +126,10 @@ public static function fromXML(DOMElement $xml): static $xml->hasAttributeNS(C::NS_XSI, "type") && $xml->getAttributeNS(C::NS_XSI, "type") === "xs:dateTime" ) { - Assert::validDateTime($xml->textContent); - // we have a dateTime as value - $value = new DateTimeImmutable($xml->textContent); + $value = DateTimeValue::fromString($xml->textContent); } else { - $value = $xml->textContent; + $value = StringValue::fromString($xml->textContent); } return new static($value); @@ -162,7 +151,7 @@ public function toXML(?DOMElement $parent = null): DOMElement $type = gettype($value); switch ($type) { - case "integer": + case IntegerValue::class: // make sure that the xs namespace is available in the AttributeValue $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C::NS_XSI); $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xs', C::NS_XS); @@ -170,17 +159,24 @@ public function toXML(?DOMElement $parent = null): DOMElement $e->textContent = strval($value); break; case "object": - if ($value instanceof DateTimeInterface) { + if ($value instanceof DateTimeValue) { $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C::NS_XSI); $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xs', C::NS_XS); $e->setAttributeNS(C::NS_XSI, 'xsi:type', 'xs:dateTime'); - $e->textContent = $value->format(C::DATETIME_FORMAT); + $e->textContent = strval($value); + } elseif ($value instanceof ValueTypeInterface) { + if ($value instanceof IntegerValue) { + $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C::NS_XSI); + $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xs', C::NS_XS); + $e->setAttributeNS(C::NS_XSI, 'xsi:type', 'xs:integer'); + } + $e->textContent = strval($value); } else { $value->toXML($e); } break; default: // string - $e->textContent = $value; + $e->textContent = strval($value); break; } diff --git a/src/SAML11/XML/saml/Audience.php b/src/SAML11/XML/saml/Audience.php index 867a4da..b4bc74e 100644 --- a/src/SAML11/XML/saml/Audience.php +++ b/src/SAML11/XML/saml/Audience.php @@ -4,9 +4,9 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\SAML11\XML\URIElementTrait; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\SAML11\Type\AnyURIValue; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; +use SimpleSAML\XML\TypedTextContentTrait; /** * SAML Audience element. @@ -16,17 +16,8 @@ final class Audience extends AbstractSamlElement implements SchemaValidatableElementInterface { use SchemaValidatableElementTrait; - use URIElementTrait; + use TypedTextContentTrait; - - /** - * Initialize a saml:Audience from scratch - * - * @param string $value - */ - public function __construct( - protected string $value, - ) { - $this->setContent($value); - } + /** @var string */ + public const TEXTCONTENT_TYPE = AnyURIValue::class; } diff --git a/src/SAML11/XML/saml/AudienceRestrictionCondition.php b/src/SAML11/XML/saml/AudienceRestrictionCondition.php index 5c34a62..e5be5a2 100644 --- a/src/SAML11/XML/saml/AudienceRestrictionCondition.php +++ b/src/SAML11/XML/saml/AudienceRestrictionCondition.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:AudienceRestrictionCondition element. diff --git a/src/SAML11/XML/saml/AuthenticationStatement.php b/src/SAML11/XML/saml/AuthenticationStatement.php index 3aa0a20..d3511dd 100644 --- a/src/SAML11/XML/saml/AuthenticationStatement.php +++ b/src/SAML11/XML/saml/AuthenticationStatement.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:AuthenticationStatement element. diff --git a/src/SAML11/XML/saml/AuthorityBinding.php b/src/SAML11/XML/saml/AuthorityBinding.php index ddf1951..5f786e3 100644 --- a/src/SAML11/XML/saml/AuthorityBinding.php +++ b/src/SAML11/XML/saml/AuthorityBinding.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:AuthorityBinding element. diff --git a/src/SAML11/XML/saml/AuthorizationDecisionStatement.php b/src/SAML11/XML/saml/AuthorizationDecisionStatement.php index 606f1cf..48006e4 100644 --- a/src/SAML11/XML/saml/AuthorizationDecisionStatement.php +++ b/src/SAML11/XML/saml/AuthorizationDecisionStatement.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:AuthorizationDecisionStatement element. diff --git a/src/SAML11/XML/saml/Conditions.php b/src/SAML11/XML/saml/Conditions.php index c99ae9c..e0d230c 100644 --- a/src/SAML11/XML/saml/Conditions.php +++ b/src/SAML11/XML/saml/Conditions.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:Conditions element. diff --git a/src/SAML11/XML/saml/ConfirmationMethod.php b/src/SAML11/XML/saml/ConfirmationMethod.php index 5ea50b4..774a63a 100644 --- a/src/SAML11/XML/saml/ConfirmationMethod.php +++ b/src/SAML11/XML/saml/ConfirmationMethod.php @@ -4,9 +4,9 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\SAML11\XML\URIElementTrait; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\SAML11\Type\AnyURIValue; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; +use SimpleSAML\XML\TypedTextContentTrait; /** * Class representing a saml:ConfirmationMethod element. @@ -16,14 +16,8 @@ final class ConfirmationMethod extends AbstractSamlElement implements SchemaValidatableElementInterface { use SchemaValidatableElementTrait; - use URIElementTrait; + use TypedTextContentTrait; - - /** - * @param string $content - */ - public function __construct(string $content) - { - $this->setContent($content); - } + /** @var string */ + public const TEXTCONTENT_TYPE = AnyURIValue::class; } diff --git a/src/SAML11/XML/saml/DoNotCacheCondition.php b/src/SAML11/XML/saml/DoNotCacheCondition.php index e16abc5..44f8a76 100644 --- a/src/SAML11/XML/saml/DoNotCacheCondition.php +++ b/src/SAML11/XML/saml/DoNotCacheCondition.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:DoNotCacheCondition element. diff --git a/src/SAML11/XML/saml/Evidence.php b/src/SAML11/XML/saml/Evidence.php index c88e852..3f95306 100644 --- a/src/SAML11/XML/saml/Evidence.php +++ b/src/SAML11/XML/saml/Evidence.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:Evidence element. diff --git a/src/SAML11/XML/saml/NameIdentifier.php b/src/SAML11/XML/saml/NameIdentifier.php index 3694c9d..34773ba 100644 --- a/src/SAML11/XML/saml/NameIdentifier.php +++ b/src/SAML11/XML/saml/NameIdentifier.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:NameIdentifier element. diff --git a/src/SAML11/XML/saml/Subject.php b/src/SAML11/XML/saml/Subject.php index edcf6f0..fcec36c 100644 --- a/src/SAML11/XML/saml/Subject.php +++ b/src/SAML11/XML/saml/Subject.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:Subject element. diff --git a/src/SAML11/XML/saml/SubjectConfirmation.php b/src/SAML11/XML/saml/SubjectConfirmation.php index dce23bf..04d1fe3 100644 --- a/src/SAML11/XML/saml/SubjectConfirmation.php +++ b/src/SAML11/XML/saml/SubjectConfirmation.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:SubjectConfirmation element. diff --git a/src/SAML11/XML/saml/SubjectConfirmationData.php b/src/SAML11/XML/saml/SubjectConfirmationData.php index 14f6562..0184a18 100644 --- a/src/SAML11/XML/saml/SubjectConfirmationData.php +++ b/src/SAML11/XML/saml/SubjectConfirmationData.php @@ -7,16 +7,16 @@ use DOMElement; use SimpleSAML\Assert\Assert; use SimpleSAML\SAML11\Constants as C; +use SimpleSAML\SAML11\Type\StringValue; use SimpleSAML\XML\AbstractElement; use SimpleSAML\XML\Chunk; use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; +use SimpleSAML\XML\Type\{IntegerValue, ValueTypeInterface}; use function class_exists; use function explode; use function gettype; -use function intval; use function str_contains; use function strval; @@ -33,15 +33,15 @@ class SubjectConfirmationData extends AbstractSamlElement implements SchemaValid * Create an SubjectConfirmationData. * * @param mixed $value The value of this element. Can be one of: - * - string - * - int + * - \SimpleSAML\XML\Type\IntegerValue + * - \SimpleSAML\SAML11\Type\StringValue * - null * - \SimpleSAML\XML\AbstractElement * * @throws \SimpleSAML\Assert\AssertionFailedException if the supplied value is neither a string or a DOMElement */ final public function __construct( - protected string|int|null|AbstractElement $value, + protected StringValue|IntegerValue|null|AbstractElement $value, ) { } @@ -53,21 +53,18 @@ final public function __construct( */ public function getXsiType(): string { - $type = gettype($this->value); + $value = $this->getValue(); - switch ($type) { - case "integer": - return "xs:integer"; - case "NULL": - return "xs:nil"; - case "object": - return sprintf( - '%s:%s', - $this->value::getNamespacePrefix(), - AbstractElement::getClassName(get_class($this->value)), - ); - default: - return "xs:string"; + if ($value === null) { + return 'xs:nil'; + } elseif ($value instanceof ValueTypeInterface) { + return $value::SCHEMA_NAMESPACE_PREFIX . ':' . $value::SCHEMA_TYPE; + } else { + return sprintf( + '%s:%s', + $value::getNamespacePrefix(), + $value::getLocalName(), + ); } } @@ -77,7 +74,7 @@ public function getXsiType(): string * * @return string|int|\SimpleSAML\XML\AbstractElement[]|null */ - public function getValue() + public function getValue(): StringValue|IntegerValue|AbstractElement|null { return $this->value; } @@ -117,7 +114,7 @@ public static function fromXML(DOMElement $xml): static $xml->getAttributeNS(C::NS_XSI, "type") === "xs:integer" ) { // we have an integer as value - $value = intval($xml->textContent); + $value = IntegerValue::fromString($xml->textContent); } elseif ( // null value $xml->hasAttributeNS(C::NS_XSI, "nil") && @@ -126,7 +123,7 @@ public static function fromXML(DOMElement $xml): static ) { $value = null; } else { - $value = $xml->textContent; + $value = StringValue::fromString($xml->textContent); } return new static($value); @@ -144,7 +141,8 @@ public function toXML(?DOMElement $parent = null): DOMElement { $e = parent::instantiateParentElement($parent); - $type = gettype($this->value); + $value = $this->getValue(); + $type = gettype($value); switch ($type) { case "integer": @@ -152,7 +150,7 @@ public function toXML(?DOMElement $parent = null): DOMElement $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C::NS_XSI); $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xs', C::NS_XS); $e->setAttributeNS(C::NS_XSI, 'xsi:type', 'xs:integer'); - $e->textContent = strval($this->getValue()); + $e->textContent = strval($value); break; case "NULL": $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C::NS_XSI); @@ -160,10 +158,19 @@ public function toXML(?DOMElement $parent = null): DOMElement $e->textContent = ''; break; case "object": - $this->getValue()->toXML($e); + if ($value instanceof ValueTypeInterface) { + if ($this->value instanceof IntegerValue) { + $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', C::NS_XSI); + $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xs', C::NS_XS); + $e->setAttributeNS(C::NS_XSI, 'xsi:type', 'xs:integer'); + } + $e->textContent = strval($value); + } else { + $value->toXML($e); + } break; default: // string - $e->textContent = $this->getValue(); + $e->textContent = strval($value); break; } diff --git a/src/SAML11/XML/saml/SubjectLocality.php b/src/SAML11/XML/saml/SubjectLocality.php index f2b46f7..987d4c8 100644 --- a/src/SAML11/XML/saml/SubjectLocality.php +++ b/src/SAML11/XML/saml/SubjectLocality.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\saml; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:SubjectLocality element. diff --git a/src/SAML11/XML/saml/UnknownCondition.php b/src/SAML11/XML/saml/UnknownCondition.php index 21ba8ef..fbccc3e 100644 --- a/src/SAML11/XML/saml/UnknownCondition.php +++ b/src/SAML11/XML/saml/UnknownCondition.php @@ -6,6 +6,7 @@ use DOMElement; use SimpleSAML\XML\Chunk; +use SimpleSAML\XML\Type\QNameValue; /** * Class for unknown conditions. @@ -16,11 +17,11 @@ final class UnknownCondition extends AbstractCondition { /** * @param \SimpleSAML\XML\Chunk $chunk The whole Condition element as a chunk object. - * @param string $type The xsi:type of this condition. + * @param \SimpleSAML\XML\Type\QNameValue $type The xsi:type of this condition. */ public function __construct( protected Chunk $chunk, - string $type, + QNameValue $type, ) { parent::__construct($type); } diff --git a/src/SAML11/XML/saml/UnknownStatement.php b/src/SAML11/XML/saml/UnknownStatement.php index 8721a85..50173bb 100644 --- a/src/SAML11/XML/saml/UnknownStatement.php +++ b/src/SAML11/XML/saml/UnknownStatement.php @@ -6,6 +6,7 @@ use DOMElement; use SimpleSAML\XML\Chunk; +use SimpleSAML\XML\Type\QNameValue; /** * Class for unknown statements. @@ -16,11 +17,11 @@ final class UnknownStatement extends AbstractStatement { /** * @param \SimpleSAML\XML\Chunk $chunk The whole Statement element as a chunk object. - * @param string $type The xsi:type of this statement + * @param \SimpleSAML\XML\Type\QNameValue $type The xsi:type of this statement */ public function __construct( protected Chunk $chunk, - string $type, + QNameValue $type, ) { parent::__construct($type); } diff --git a/src/SAML11/XML/saml/UnknownSubjectStatement.php b/src/SAML11/XML/saml/UnknownSubjectStatement.php index 4e593e2..38fb511 100644 --- a/src/SAML11/XML/saml/UnknownSubjectStatement.php +++ b/src/SAML11/XML/saml/UnknownSubjectStatement.php @@ -6,6 +6,7 @@ use DOMElement; use SimpleSAML\XML\Chunk; +use SimpleSAML\XML\Type\QNameValue; /** * Class for unknown SubjectStatements. @@ -16,11 +17,11 @@ 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 + * @param \SimpleSAML\XML\Type\QNameValue $type The xsi:type of this SubjectStatement */ public function __construct( protected Chunk $chunk, - string $type, + QNameValue $type, protected Subject $subject, ) { parent::__construct($type, $subject); diff --git a/src/SAML11/XML/samlp/AbstractAttributeQueryType.php b/src/SAML11/XML/samlp/AbstractAttributeQueryType.php index 0016863..7f812b7 100644 --- a/src/SAML11/XML/samlp/AbstractAttributeQueryType.php +++ b/src/SAML11/XML/samlp/AbstractAttributeQueryType.php @@ -6,10 +6,12 @@ use DOMElement; use SimpleSAML\Assert\Assert; -use SimpleSAML\SAML11\XML\saml\AttributeDesignator; -use SimpleSAML\SAML11\XML\saml\Subject; +use SimpleSAML\SAML11\Type\AnyURIValue; +use SimpleSAML\SAML11\XML\saml\{AttributeDesignator, Subject}; use SimpleSAML\XML\Exception\SchemaViolationException; +use function strval; + /** * Abstract class to be implemented by all the attributes queries in this namespace * @@ -21,15 +23,14 @@ abstract class AbstractAttributeQueryType extends AbstractSubjectQueryAbstractTy * Initialize a samlp:AttributeQuery element. * * @param \SimpleSAML\SAML11\XML\saml\Subject $subject - * @param string|null $resource + * @param \SimpleSAML\SAML11\Type\AnyURIValue|null $resource * @param array<\SimpleSAML\SAML11\XML\saml\AttributeDesignator> $attributeDesignator */ public function __construct( Subject $subject, - protected ?string $resource = null, + protected ?AnyURIValue $resource = null, protected array $attributeDesignator = [], ) { - Assert::nullOrValidURI($resource, SchemaViolationException::class); Assert::allIsInstanceOf($attributeDesignator, AttributeDesignator::class, SchemaViolationException::class); parent::__construct($subject); @@ -37,9 +38,9 @@ public function __construct( /** - * @return string|null + * @return \SimpleSAML\SAML11\Type\AnyURIValue|null */ - public function getResource(): ?string + public function getResource(): ?AnyURIValue { return $this->resource; } @@ -65,7 +66,7 @@ public function toXML(?DOMElement $parent = null): DOMElement $e = parent::toXML($parent); if ($this->getResource() !== null) { - $e->setAttribute('Resource', $this->getResource()); + $e->setAttribute('Resource', strval($this->getResource())); } foreach ($this->getAttributeDesignator() as $attrDesignator) { diff --git a/src/SAML11/XML/samlp/AbstractAuthenticationQueryType.php b/src/SAML11/XML/samlp/AbstractAuthenticationQueryType.php index 8f2ada4..bec0b47 100644 --- a/src/SAML11/XML/samlp/AbstractAuthenticationQueryType.php +++ b/src/SAML11/XML/samlp/AbstractAuthenticationQueryType.php @@ -5,9 +5,10 @@ namespace SimpleSAML\SAML11\XML\samlp; use DOMElement; -use SimpleSAML\Assert\Assert; +use SimpleSAML\SAML11\Type\AnyURIValue; use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\XML\Exception\SchemaViolationException; + +use function strval; /** * Abstract class to be implemented by all the authentication queries in this namespace @@ -20,22 +21,20 @@ abstract class AbstractAuthenticationQueryType extends AbstractSubjectQueryAbstr * Initialize a samlp:AuthenticationQuery element. * * @param \SimpleSAML\SAML11\XML\saml\Subject $subject - * @param string $authenticationMethod + * @param \SimpleSAML\SAML11\Type\AnyURIValue $authenticationMethod */ public function __construct( Subject $subject, - protected string $authenticationMethod, + protected AnyURIValue $authenticationMethod, ) { - Assert::validURI($authenticationMethod, SchemaViolationException::class); - parent::__construct($subject); } /** - * @return string + * @return \SimpleSAML\SAML11\Type\AnyURIValue */ - public function getAuthenticationMethod(): string + public function getAuthenticationMethod(): AnyURIValue { return $this->authenticationMethod; } @@ -50,7 +49,7 @@ public function getAuthenticationMethod(): string public function toXML(?DOMElement $parent = null): DOMElement { $e = parent::toXML($parent); - $e->setAttribute('AuthenticationMethod', $this->getAuthenticationMethod()); + $e->setAttribute('AuthenticationMethod', strval($this->getAuthenticationMethod())); return $e; } diff --git a/src/SAML11/XML/samlp/AbstractAuthorizationDecisionQueryType.php b/src/SAML11/XML/samlp/AbstractAuthorizationDecisionQueryType.php index da5d778..642dd4f 100644 --- a/src/SAML11/XML/samlp/AbstractAuthorizationDecisionQueryType.php +++ b/src/SAML11/XML/samlp/AbstractAuthorizationDecisionQueryType.php @@ -6,11 +6,11 @@ use DOMElement; use SimpleSAML\Assert\Assert; -use SimpleSAML\SAML11\XML\saml\Action; -use SimpleSAML\SAML11\XML\saml\Evidence; -use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; +use SimpleSAML\SAML11\Type\AnyURIValue; +use SimpleSAML\SAML11\XML\saml\{Action, Evidence, Subject}; +use SimpleSAML\XML\Exception\{MissingElementException, SchemaViolationException}; + +use function strval; /** * Abstract class to be implemented by all the authorization decision queries in this namespace @@ -23,17 +23,16 @@ abstract class AbstractAuthorizationDecisionQueryType extends AbstractSubjectQue * Initialize a samlp:AuthorizationDecisionQuery element. * * @param \SimpleSAML\SAML11\XML\saml\Subject $subject - * @param string $resource + * @param \SimpleSAML\SAML11\Type\AnyURIValue $resource * @param \SimpleSAML\SAML11\XML\saml\Evidence|null $evidence * @param array<\SimpleSAML\SAML11\XML\saml\Action> $action */ public function __construct( Subject $subject, - protected string $resource, + protected AnyURIValue $resource, protected ?Evidence $evidence = null, protected array $action = [], ) { - Assert::validURI($resource, SchemaViolationException::class); Assert::allIsInstanceOf($action, Action::class, SchemaViolationException::class); Assert::minCount($action, 1, MissingElementException::class); @@ -42,9 +41,9 @@ public function __construct( /** - * @return string + * @return \SimpleSAML\SAML11\Type\AnyURIValue */ - public function getResource(): string + public function getResource(): AnyURIValue { return $this->resource; } @@ -77,7 +76,7 @@ public function getAction(): array public function toXML(?DOMElement $parent = null): DOMElement { $e = parent::toXML($parent); - $e->setAttribute('Resource', $this->getResource()); + $e->setAttribute('Resource', strval($this->getResource())); foreach ($this->getAction() as $action) { $action->toXML($e); diff --git a/src/SAML11/XML/samlp/AbstractMessage.php b/src/SAML11/XML/samlp/AbstractMessage.php index b76234c..d8850bb 100644 --- a/src/SAML11/XML/samlp/AbstractMessage.php +++ b/src/SAML11/XML/samlp/AbstractMessage.php @@ -4,16 +4,12 @@ namespace SimpleSAML\SAML11\XML\samlp; -use DateTimeImmutable; use DOMElement; -use SimpleSAML\Assert\Assert; -use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\Exception\ProtocolViolationException; use SimpleSAML\SAML11\Utils; -use SimpleSAML\SAML11\XML\SignableElementTrait; -use SimpleSAML\SAML11\XML\SignedElementTrait; -use SimpleSAML\XMLSecurity\XML\SignableElementInterface; -use SimpleSAML\XMLSecurity\XML\SignedElementInterface; +use SimpleSAML\SAML11\Type\DateTimeValue; +use SimpleSAML\SAML11\XML\{SignableElementTrait, SignedElementTrait}; +use SimpleSAML\XML\Type\NonNegativeIntegerValue; +use SimpleSAML\XMLSecurity\XML\{SignableElementInterface, SignedElementInterface}; use function strval; @@ -32,7 +28,6 @@ abstract class AbstractMessage extends AbstractSamlpElement implements SignableE SignedElementTrait::getBlacklistedAlgorithms insteadof SignableElementTrait; } - /** @var bool */ protected bool $messageContainedSignatureUponConstruction = false; @@ -47,27 +42,26 @@ abstract class AbstractMessage extends AbstractSamlpElement implements SignableE /** * Initialize a message. * - * @param int $majorVersion - * @param int $minorVersion - * @param \DateTimeImmutable $issueInstant + * @param \SimpleSAML\XML\Type\NonNegativeIntegerValue $majorVersion + * @param \SimpleSAML\XML\Type\NonNegativeIntegerValue $minorVersion + * @param \SimpleSAML\SAML11\Type\DateTimeValue $issueInstant * * @throws \Exception */ protected function __construct( - protected int $majorVersion, - protected int $minorVersion, - protected ?DateTimeImmutable $issueInstant, + protected NonNegativeIntegerValue $majorVersion, + protected NonNegativeIntegerValue $minorVersion, + protected ?DateTimeValue $issueInstant, ) { - Assert::nullOrSame($issueInstant?->getTimeZone()->getName(), 'Z', ProtocolViolationException::class); } /** * Retrieve the major version of this message. * - * @return int The major version of this message + * @return \SimpleSAML\XML\Type\NonNegativeIntegerValue The major version of this message */ - public function getMajorVersion(): int + public function getMajorVersion(): NonNegativeIntegerValue { return $this->majorVersion; } @@ -76,9 +70,9 @@ public function getMajorVersion(): int /** * Retrieve the minor version of this message. * - * @return int The minor version of this message + * @return \SimpleSAML\XML\Type\NonNegativeIntegerValue The minor version of this message */ - public function getMinorVersion(): int + public function getMinorVersion(): NonNegativeIntegerValue { return $this->minorVersion; } @@ -87,12 +81,12 @@ public function getMinorVersion(): int /** * Retrieve the issue timestamp of this message. * - * @return \DateTimeImmutable The issue timestamp of this message, as an UNIX timestamp + * @return \SimpleSAML\SAML11\Type\DateTimeValue The issue timestamp of this message */ - public function getIssueInstant(): DateTimeImmutable + public function getIssueInstant(): DateTimeValue { if ($this->issueInstant === null) { - return Utils::getContainer()->getClock()->now(); + return DateTimeValue::fromDateTime(Utils::getContainer()->getClock()->now()); } return $this->issueInstant; @@ -151,13 +145,9 @@ protected function toUnsignedXML(?DOMElement $parent = null): DOMElement { $e = $this->instantiateParentElement($parent); - /* Ugly hack to add another namespace declaration to the root element. */ - $e->setAttributeNS(C::NS_SAML, 'saml:tmp', 'tmp'); - $e->removeAttributeNS(C::NS_SAML, 'tmp'); - $e->setAttribute('MajorVersion', strval($this->getMajorVersion())); $e->setAttribute('MinorVersion', strval($this->getMinorVersion())); - $e->setAttribute('IssueInstant', $this->getIssueInstant()->format(C::DATETIME_FORMAT)); + $e->setAttribute('IssueInstant', strval($this->getIssueInstant())); return $e; } diff --git a/src/SAML11/XML/samlp/AbstractQuery.php b/src/SAML11/XML/samlp/AbstractQuery.php index a25cf2f..26e24e0 100644 --- a/src/SAML11/XML/samlp/AbstractQuery.php +++ b/src/SAML11/XML/samlp/AbstractQuery.php @@ -8,17 +8,12 @@ use SimpleSAML\SAML11\Assert\Assert; use SimpleSAML\SAML11\Constants as C; use SimpleSAML\SAML11\Utils; -use SimpleSAML\SAML11\XML\ExtensionPointInterface; -use SimpleSAML\SAML11\XML\ExtensionPointTrait; +use SimpleSAML\SAML11\XML\{ExtensionPointInterface, ExtensionPointTrait}; use SimpleSAML\XML\Attribute as XMLAttribute; use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\SchemaViolationException; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; - -use function count; -use function explode; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, SchemaViolationException}; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; +use SimpleSAML\XML\Type\QNameValue; /** * SAMLP Query data type. @@ -39,10 +34,10 @@ abstract class AbstractQuery extends AbstractQueryAbstractType implements /** * Initialize a custom samlp:Query element. * - * @param string $type + * @param \SimpleSAML\XML\Type\QNameValue $type */ protected function __construct( - protected string $type, + protected QNameValue $type, ) { } @@ -66,19 +61,7 @@ public static function fromXML(DOMElement $xml): static 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]); + $type = QNameValue::fromDocument($xml->getAttributeNS(C::NS_XSI, 'type'), $xml); // now check if we have a handler registered for it $handler = Utils::getContainer()->getExtensionHandler($type); @@ -105,11 +88,14 @@ public static function fromXML(DOMElement $xml): static public function toXML(?DOMElement $parent = null): DOMElement { $e = $this->instantiateParentElement($parent); - $e->setAttributeNS( - 'http://www.w3.org/2000/xmlns/', - 'xmlns:' . static::getXsiTypePrefix(), - static::getXsiTypeNamespaceURI(), - ); + + if (!$e->lookupPrefix($this->getXsiType()->getNamespaceURI()->getValue())) { + $e->setAttributeNS( + 'http://www.w3.org/2000/xmlns/', + 'xmlns:' . static::getXsiTypePrefix()->getValue(), + static::getXsiTypeNamespaceURI()->getValue(), + ); + } $type = new XMLAttribute(C::NS_XSI, 'xsi', 'type', $this->getXsiType()); $type->toXML($e); diff --git a/src/SAML11/XML/samlp/AbstractRequestAbstractType.php b/src/SAML11/XML/samlp/AbstractRequestAbstractType.php index f8b3971..f17a0af 100644 --- a/src/SAML11/XML/samlp/AbstractRequestAbstractType.php +++ b/src/SAML11/XML/samlp/AbstractRequestAbstractType.php @@ -4,13 +4,15 @@ namespace SimpleSAML\SAML11\XML\samlp; -use DateTimeImmutable; use DOMElement; use SimpleSAML\SAML11\Assert\Assert; +use SimpleSAML\SAML11\Type\DateTimeValue; use SimpleSAML\SAML11\Utils\XPath; use SimpleSAML\XML\Exception\SchemaViolationException; +use SimpleSAML\XML\Type\{IDValue, NonNegativeIntegerValue}; use function array_pop; +use function strval; /** * Base class for all SAML 1.1 requests. @@ -22,22 +24,21 @@ abstract class AbstractRequestAbstractType extends AbstractMessage /** * Initialize a request. * - * @param string $id - * @param int $majorVersion - * @param int $minorVersion - * @param \DateTimeImmutable $issueInstant + * @param \SimpleSAML\XML\Type\IDValue $id + * @param \SimpleSAML\XML\Type\NonNegativeIntegerValue $majorVersion + * @param \SimpleSAML\XML\Type\NonNegativeIntegerValue $minorVersion + * @param \SimpleSAML\SAML11\Type\DateTimeValue $issueInstant * @param array<\SimpleSAML\SAML11\XML\samlp\RespondWith> * * @throws \Exception */ protected function __construct( - protected string $id, - int $majorVersion, - int $minorVersion, - DateTimeImmutable $issueInstant, + protected IDValue $id, + protected NonNegativeIntegerValue $majorVersion, + protected NonNegativeIntegerValue $minorVersion, + protected ?DateTimeValue $issueInstant, protected array $respondWith = [], ) { - Assert::validNCName($id, SchemaViolationException::class); Assert::allIsInstanceOf($respondWith, RespondWith::class, SchemaViolationException::class); parent::__construct($majorVersion, $minorVersion, $issueInstant); @@ -47,9 +48,9 @@ protected function __construct( /** * Retrieve the ID of this request. * - * @return string The ID of this request + * @return \SimpleSAML\XML\Type\IDValue The ID of this request */ - public function getID(): string + public function getID(): IDValue { return $this->id; } @@ -73,7 +74,7 @@ public function getRespondWith(): array protected function toUnsignedXML(?DOMElement $parent = null): DOMElement { $e = parent::toUnsignedXML($parent); - $e->setAttribute('RequestID', $this->getID()); + $e->setAttribute('RequestID', strval($this->getID())); foreach ($this->getRespondWith() as $respondWith) { $respondWith->toXML($e); diff --git a/src/SAML11/XML/samlp/AbstractRequestType.php b/src/SAML11/XML/samlp/AbstractRequestType.php index 83a2960..cba6734 100644 --- a/src/SAML11/XML/samlp/AbstractRequestType.php +++ b/src/SAML11/XML/samlp/AbstractRequestType.php @@ -4,11 +4,12 @@ namespace SimpleSAML\SAML11\XML\samlp; -use DateTimeImmutable; use DOMElement; use SimpleSAML\Assert\Assert; +use SimpleSAML\SAML11\Type\DateTimeValue; use SimpleSAML\SAML11\XML\saml\AssertionIDReference; use SimpleSAML\XML\Exception\SchemaViolationException; +use SimpleSAML\XML\Type\{IDValue, NonNegativeIntegerValue}; use function array_pop; use function is_array; @@ -28,20 +29,20 @@ abstract class AbstractRequestType extends AbstractRequestAbstractType * array<\SimpleSAML\SAML11\XML\saml\AssertionIDReference>| * array<\SimpleSAML\SAML11\XML\samlp\AssertionArtifact> * ) $request - * @param string $id - * @param int $majorVersion - * @param int $minorVersion - * @param \DateTimeImmutable $issueInstant + * @param \SimpleSAML\XML\Type\IDValue $id + * @param \SimpleSAML\XML\Type\NonNegativeIntegerValue $majorVersion + * @param \SimpleSAML\XML\Type\NonNegativeIntegerValue $minorVersion + * @param \SimpleSAML\SAML11\Type\DateTimeValue $issueInstant * @param array<\SimpleSAML\SAML11\XML\samlp\RespondWith> $respondWith * * @throws \Exception */ protected function __construct( protected AbstractQueryAbstractType|array $request, - string $id, - int $majorVersion, - int $minorVersion, - DateTimeImmutable $issueInstant, + IDValue $id, + NonNegativeIntegerValue $majorVersion, + NonNegativeIntegerValue $minorVersion, + DateTimeValue $issueInstant, array $respondWith = [], ) { if (is_array($request)) { diff --git a/src/SAML11/XML/samlp/AbstractResponseAbstractType.php b/src/SAML11/XML/samlp/AbstractResponseAbstractType.php index f076249..9092aae 100644 --- a/src/SAML11/XML/samlp/AbstractResponseAbstractType.php +++ b/src/SAML11/XML/samlp/AbstractResponseAbstractType.php @@ -4,8 +4,11 @@ namespace SimpleSAML\SAML11\XML\samlp; -use DateTimeImmutable; use DOMElement; +use SimpleSAML\XML\Type\{IDValue, NonNegativeIntegerValue}; +use SimpleSAML\SAML11\Type\DateTimeValue; + +use function strval; /** * Base class for all SAML 1.1 responses. @@ -20,18 +23,18 @@ abstract class AbstractResponseAbstractType extends AbstractMessage /** * Initialize a response. * - * @param string $id - * @param int $majorVersion - * @param int $minorVersion - * @param \DateTimeImmutable|null $issueInstant + * @param \SimpleSAML\XML\Type\IDValue $id + * @param \SimpleSAML\XML\Type\NonNegativeIntegerValue $majorVersion + * @param \SimpleSAML\XML\Type\NonNegativeIntegerValue $minorVersion + * @param \SimpleSAML\SAML11\Type\DateTimeValue|null $issueInstant * * @throws \Exception */ protected function __construct( - protected string $id, - int $majorVersion = 1, - int $minorVersion = 1, - ?DateTimeImmutable $issueInstant = null, + protected IDValue $id, + NonNegativeIntegerValue $majorVersion, + NonNegativeIntegerValue $minorVersion, + ?DateTimeValue $issueInstant = null, ) { parent::__construct($majorVersion, $minorVersion, $issueInstant); } @@ -40,9 +43,9 @@ protected function __construct( /** * Retrieve the identifier of this message. * - * @return string The identifier of this message + * @return \SimpleSAML\XML\Type\IDValue The identifier of this message */ - public function getID(): string + public function getID(): IDValue { return $this->id; } @@ -57,7 +60,7 @@ public function getID(): string protected function toUnsignedXML(?DOMElement $parent = null): DOMElement { $e = parent::toUnsignedXML($parent); - $e->setAttribute('ResponseID', $this->getId()); + $e->setAttribute('ResponseID', strval($this->getId())); return $e; } diff --git a/src/SAML11/XML/samlp/AbstractResponseType.php b/src/SAML11/XML/samlp/AbstractResponseType.php index 2a63140..a8eb831 100644 --- a/src/SAML11/XML/samlp/AbstractResponseType.php +++ b/src/SAML11/XML/samlp/AbstractResponseType.php @@ -4,12 +4,15 @@ namespace SimpleSAML\SAML11\XML\samlp; -use DateTimeImmutable; use DOMElement; use SimpleSAML\SAML11\Assert\Assert; +use SimpleSAML\SAML11\Type\{AnyURIValue, DateTimeValue}; use SimpleSAML\SAML11\XML\saml\Assertion; use SimpleSAML\SAML11\XML\samlp\Status; use SimpleSAML\XML\Exception\SchemaViolationException; +use SimpleSAML\XML\Type\{IDValue, NCNameValue, NonNegativeIntegerValue}; + +use function strval; /** * Base class for all SAML 1.1 samlp:AbstractResponseAbstractType. @@ -21,29 +24,27 @@ abstract class AbstractResponseType extends AbstractResponseAbstractType /** * Initialize a response. * - * @param string $id + * @param \SimpleSAML\XML\Type\NonNegativeIntegerValue $majorVersion + * @param \SimpleSAML\XML\Type\NonNegativeIntegerValue $minorVersion + * @param \SimpleSAML\XML\Type\IDValue $id * @param \SimpleSAML\SAML11\XML\samlp\Status $status * @param array<\SimpleSAML\SAML11\XML\saml\Assertion> $assertion - * @param int $majorVersion - * @param int $minorVersion - * @param \DateTimeImmutable|null $issueInstant - * @param string|null $inResponseTo - * @param string|null $recipient + * @param \SimpleSAML\SAML11\Type\DateTimeValue|null $issueInstant + * @param \SimpleSAML\XML\Type\NCNameValue|null $inResponseTo + * @param \SimpleSAML\SAML11\Type\AnyURIValue|null $recipient * * @throws \Exception */ public function __construct( - string $id, + NonNegativeIntegerValue $majorVersion, + NonNegativeIntegerValue $minorVersion, + IDValue $id, protected Status $status, protected array $assertion = [], - int $majorVersion = 1, - int $minorVersion = 1, - ?DateTimeImmutable $issueInstant = null, - protected ?string $inResponseTo = null, - protected ?string $recipient = null, + ?DateTimeValue $issueInstant = null, + protected ?NCNameValue $inResponseTo = null, + protected ?AnyURIValue $recipient = null, ) { - Assert::nullOrValidNCName($inResponseTo, SchemaViolationException::class); - Assert::nullOrValidURI($recipient, SchemaViolationException::class); Assert::allIsInstanceOf($assertion, Assertion::class, SchemaViolationException::class); parent::__construct($id, $majorVersion, $minorVersion, $issueInstant); @@ -53,9 +54,9 @@ public function __construct( /** * Retrieve the inResponseTo of this message. * - * @return string|null The inResponseTo of this message + * @return \SimpleSAML\XML\Type\NCNameValue|null The inResponseTo of this message */ - public function getInResponseTo(): ?string + public function getInResponseTo(): ?NCNameValue { return $this->inResponseTo; } @@ -64,9 +65,9 @@ public function getInResponseTo(): ?string /** * Retrieve the recipient of this message. * - * @return string|null The recipient of this message + * @return \SimpleSAML\SAML11\Type\AnyURIValue|null The recipient of this message */ - public function getRecipient(): ?string + public function getRecipient(): ?AnyURIValue { return $this->recipient; } @@ -105,11 +106,11 @@ protected function toUnsignedXML(?DOMElement $parent = null): DOMElement $e = parent::toUnsignedXML($parent); if ($this->getRecipient() !== null) { - $e->setAttribute('Recipient', $this->getRecipient()); + $e->setAttribute('Recipient', strval($this->getRecipient())); } if ($this->getInResponseTo() !== null) { - $e->setAttribute('InResponseTo', $this->getInResponseTo()); + $e->setAttribute('InResponseTo', strval($this->getInResponseTo())); } $this->getStatus()->toXML($e); diff --git a/src/SAML11/XML/samlp/AbstractStatusCodeType.php b/src/SAML11/XML/samlp/AbstractStatusCodeType.php index ec3a6a4..e4fdce2 100644 --- a/src/SAML11/XML/samlp/AbstractStatusCodeType.php +++ b/src/SAML11/XML/samlp/AbstractStatusCodeType.php @@ -8,6 +8,9 @@ use SimpleSAML\SAML11\Assert\Assert; use SimpleSAML\SAML11\Constants as C; use SimpleSAML\XML\Exception\InvalidDOMElementException; +use SimpleSAML\XML\Type\QNameValue; + +use function strval; /** * SAML StatusCode data type. @@ -19,14 +22,14 @@ abstract class AbstractStatusCodeType extends AbstractSamlpElement /** * Initialize a samlp:StatusCode * - * @param string $Value + * @param \SimpleSAML\XML\Type\QNameValue $Value * @param \SimpleSAML\SAML11\XML\samlp\StatusCode[] $subCodes */ final public function __construct( - protected string $Value = C::STATUS_SUCCESS, + protected QNameValue $Value, protected array $subCodes = [], ) { - Assert::validQName($Value); + Assert::notNull($Value->getNamespacePrefix(), "A namespace prefix MUST be provided."); Assert::maxCount($subCodes, C::UNBOUNDED_LIMIT); Assert::allIsInstanceOf($subCodes, StatusCode::class); } @@ -35,9 +38,9 @@ final public function __construct( /** * Collect the Value * - * @return string + * @return \SimpleSAML\XML\Type\QNameValue */ - public function getValue(): string + public function getValue(): QNameValue { return $this->Value; } @@ -70,7 +73,7 @@ public static function fromXML(DOMElement $xml): static Assert::same($xml->localName, 'StatusCode', InvalidDOMElementException::class); Assert::same($xml->namespaceURI, StatusCode::NS, InvalidDOMElementException::class); - $Value = self::getAttribute($xml, 'Value'); + $Value = self::getAttribute($xml, 'Value', QNameValue::class); $subCodes = StatusCode::getChildrenOfClass($xml); return new static( @@ -89,7 +92,7 @@ public static function fromXML(DOMElement $xml): static public function toXML(?DOMElement $parent = null): DOMElement { $e = $this->instantiateParentElement($parent); - $e->setAttribute('Value', $this->getValue()); + $e->setAttribute('Value', strval($this->getValue())); foreach ($this->getSubCodes() as $subCode) { $subCode->toXML($e); diff --git a/src/SAML11/XML/samlp/AbstractStatusType.php b/src/SAML11/XML/samlp/AbstractStatusType.php index d63b01f..5608113 100644 --- a/src/SAML11/XML/samlp/AbstractStatusType.php +++ b/src/SAML11/XML/samlp/AbstractStatusType.php @@ -8,9 +8,7 @@ use SimpleSAML\Assert\Assert; use SimpleSAML\SAML11\Constants as C; use SimpleSAML\SAML11\Exception\ProtocolViolationException; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\TooManyElementsException; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, MissingElementException, TooManyElementsException}; use function array_pop; @@ -34,13 +32,8 @@ final public function __construct( protected ?StatusDetail $statusDetail = null, ) { Assert::oneOf( - $statusCode->getValue(), - [ - C::STATUS_SUCCESS, - C::STATUS_REQUESTER, - C::STATUS_RESPONDER, - C::STATUS_VERSION_MISMATCH, - ], + $statusCode->getValue()->getValue(), + C::$STATUS_CODES, 'Invalid top-level status code: %s', ProtocolViolationException::class, ); diff --git a/src/SAML11/XML/samlp/AbstractSubjectQuery.php b/src/SAML11/XML/samlp/AbstractSubjectQuery.php index 7a34e5d..8baac1e 100644 --- a/src/SAML11/XML/samlp/AbstractSubjectQuery.php +++ b/src/SAML11/XML/samlp/AbstractSubjectQuery.php @@ -8,21 +8,19 @@ use SimpleSAML\SAML11\Assert\Assert; use SimpleSAML\SAML11\Constants as C; use SimpleSAML\SAML11\Utils; -use SimpleSAML\SAML11\XML\ExtensionPointInterface; -use SimpleSAML\SAML11\XML\ExtensionPointTrait; +use SimpleSAML\SAML11\XML\{ExtensionPointInterface, ExtensionPointTrait}; use SimpleSAML\SAML11\XML\saml\Subject; -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\Exception\TooManyElementsException; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\Exception\{ + InvalidDOMElementException, + MissingElementException, + SchemaViolationException, + TooManyElementsException, +}; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; +use SimpleSAML\XML\Type\QNameValue; use function array_pop; -use function count; -use function explode; /** * SAMLP Query data type. @@ -43,10 +41,10 @@ abstract class AbstractSubjectQuery extends AbstractSubjectQueryAbstractType imp /** * Initialize a custom samlp:SubjectQuery element. * - * @param string $type + * @param \SimpleSAML\XML\Type\QNameValue $type */ protected function __construct( - protected string $type, + protected QNameValue $type, Subject $subject, ) { parent::__construct($subject); @@ -72,19 +70,7 @@ public static function fromXML(DOMElement $xml): static 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]); + $type = QNameValue::fromDocument($xml->getAttributeNS(C::NS_XSI, 'type'), $xml); // now check if we have a handler registered for it $handler = Utils::getContainer()->getExtensionHandler($type); @@ -105,31 +91,4 @@ public static function fromXML(DOMElement $xml): static return $handler::fromXML($xml); } - - - /** - * Convert this SubjectQuery to XML. - * - * @param \DOMElement $parent The element we are converting to XML. - * @return \DOMElement The XML element after adding the data corresponding to this SubjectQuery. - */ - public function toXML(?DOMElement $parent = null): DOMElement - { - // This unfortunately doesn't work because namespace attributes get messed up - //$e = parent::toXML($parent); - - $e = $this->instantiateParentElement($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); - - $this->getSubject()->toXML($e); - - return $e; - } } diff --git a/src/SAML11/XML/samlp/AssertionArtifact.php b/src/SAML11/XML/samlp/AssertionArtifact.php index 8324102..fac877b 100644 --- a/src/SAML11/XML/samlp/AssertionArtifact.php +++ b/src/SAML11/XML/samlp/AssertionArtifact.php @@ -4,9 +4,9 @@ namespace SimpleSAML\SAML11\XML\samlp; -use SimpleSAML\SAML11\XML\StringElementTrait; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\SAML11\Type\StringValue; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; +use SimpleSAML\XML\TypedTextContentTrait; /** * SAML AssertionArtifact element. @@ -17,17 +17,8 @@ final class AssertionArtifact extends AbstractSamlpElement implements SchemaValidatableElementInterface { use SchemaValidatableElementTrait; - use StringElementTrait; + use TypedTextContentTrait; - - /** - * Initialize a saml:AssertionArtifact from scratch - * - * @param string $value - */ - public function __construct( - protected string $value, - ) { - $this->setContent($value); - } + /** @var string */ + public const TEXTCONTENT_TYPE = StringValue::class; } diff --git a/src/SAML11/XML/samlp/AttributeQuery.php b/src/SAML11/XML/samlp/AttributeQuery.php index 0391214..1264585 100644 --- a/src/SAML11/XML/samlp/AttributeQuery.php +++ b/src/SAML11/XML/samlp/AttributeQuery.php @@ -6,13 +6,10 @@ use DOMElement; use SimpleSAML\Assert\Assert; -use SimpleSAML\SAML11\XML\saml\AttributeDesignator; -use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\TooManyElementsException; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\SAML11\Type\AnyURIValue; +use SimpleSAML\SAML11\XML\saml\{AttributeDesignator, Subject}; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, MissingElementException, TooManyElementsException}; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; use function array_pop; @@ -39,7 +36,7 @@ public static function fromXML(DOMElement $xml): static Assert::same($xml->localName, 'AttributeQuery', InvalidDOMElementException::class); Assert::same($xml->namespaceURI, AttributeQuery::NS, InvalidDOMElementException::class); - $resource = self::getOptionalAttribute($xml, 'Resource', null); + $resource = self::getOptionalAttribute($xml, 'Resource', AnyURIValue::class, null); $subject = Subject::getChildrenOfClass($xml); Assert::minCount($subject, 1, MissingElementException::class); diff --git a/src/SAML11/XML/samlp/AuthenticationQuery.php b/src/SAML11/XML/samlp/AuthenticationQuery.php index c34fcc9..1ac169c 100644 --- a/src/SAML11/XML/samlp/AuthenticationQuery.php +++ b/src/SAML11/XML/samlp/AuthenticationQuery.php @@ -6,12 +6,10 @@ use DOMElement; use SimpleSAML\Assert\Assert; +use SimpleSAML\SAML11\Type\AnyURIValue; use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\TooManyElementsException; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, MissingElementException, TooManyElementsException}; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; use function array_pop; @@ -38,7 +36,7 @@ public static function fromXML(DOMElement $xml): static Assert::same($xml->localName, 'AuthenticationQuery', InvalidDOMElementException::class); Assert::same($xml->namespaceURI, AuthenticationQuery::NS, InvalidDOMElementException::class); - $authenticationMethod = self::getAttribute($xml, 'AuthenticationMethod'); + $authenticationMethod = self::getAttribute($xml, 'AuthenticationMethod', AnyURIValue::class); $subject = Subject::getChildrenOfClass($xml); Assert::minCount($subject, 1, MissingElementException::class); diff --git a/src/SAML11/XML/samlp/AuthorizationDecisionQuery.php b/src/SAML11/XML/samlp/AuthorizationDecisionQuery.php index 8ad45ae..da708fe 100644 --- a/src/SAML11/XML/samlp/AuthorizationDecisionQuery.php +++ b/src/SAML11/XML/samlp/AuthorizationDecisionQuery.php @@ -6,14 +6,10 @@ use DOMElement; use SimpleSAML\Assert\Assert; -use SimpleSAML\SAML11\XML\saml\Action; -use SimpleSAML\SAML11\XML\saml\Evidence; -use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\TooManyElementsException; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\SAML11\Type\AnyURIValue; +use SimpleSAML\SAML11\XML\saml\{Action, Evidence, Subject}; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, MissingElementException, TooManyElementsException}; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; use function array_pop; @@ -41,7 +37,7 @@ public static function fromXML(DOMElement $xml): static Assert::same($xml->localName, 'AuthorizationDecisionQuery', InvalidDOMElementException::class); Assert::same($xml->namespaceURI, AuthorizationDecisionQuery::NS, InvalidDOMElementException::class); - $resource = self::getAttribute($xml, 'Resource'); + $resource = self::getAttribute($xml, 'Resource', AnyURIValue::class); $subject = Subject::getChildrenOfClass($xml); Assert::minCount($subject, 1, MissingElementException::class); diff --git a/src/SAML11/XML/samlp/Request.php b/src/SAML11/XML/samlp/Request.php index 723dd1d..e714165 100644 --- a/src/SAML11/XML/samlp/Request.php +++ b/src/SAML11/XML/samlp/Request.php @@ -4,25 +4,21 @@ namespace SimpleSAML\SAML11\XML\samlp; -use DateTimeImmutable; use DOMElement; use SimpleSAML\Assert\Assert; -use SimpleSAML\SAML11\Assert\Assert as SAMLAssert; -use SimpleSAML\SAML11\Exception\ProtocolViolationException; -use SimpleSAML\SAML11\Exception\VersionMismatchException; +use SimpleSAML\SAML11\Exception\{ProtocolViolationException, VersionMismatchException}; +use SimpleSAML\SAML11\Type\DateTimeValue; use SimpleSAML\SAML11\XML\saml\AssertionIDReference; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\TooManyElementsException; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, MissingElementException, TooManyElementsException}; +use SimpleSAML\XML\Type\{IDValue, NonNegativeIntegerValue}; use function array_merge; use function array_pop; -use function preg_replace; /** * Class representing a samlp:Request element. * - * @package simplesaml/xml-saml11 + * @package simplesaml/saml11 */ final class Request extends AbstractRequestType { @@ -80,22 +76,17 @@ public static function fromXML(DOMElement $xml): static MissingElementException::class, ); - $majorVersion = self::getIntegerAttribute($xml, 'MajorVersion'); - Assert::same($majorVersion, 1, VersionMismatchException::class); + $majorVersion = self::getAttribute($xml, 'MajorVersion', NonNegativeIntegerValue::class); + Assert::same($majorVersion->getValue(), '1', VersionMismatchException::class); - $minorVersion = self::getIntegerAttribute($xml, 'MinorVersion'); - Assert::same($minorVersion, 1, VersionMismatchException::class); + $minorVersion = self::getAttribute($xml, 'MinorVersion', NonNegativeIntegerValue::class); + Assert::same($minorVersion->getValue(), '1', VersionMismatchException::class); - $issueInstant = self::getAttribute($xml, 'IssueInstant'); - // Strip sub-seconds - See paragraph 1.3.3 of SAML core specifications - $issueInstant = preg_replace('/([.][0-9]+Z)$/', 'Z', $issueInstant, 1); - - SAMLAssert::validDateTime($issueInstant, ProtocolViolationException::class); - $issueInstant = new DateTimeImmutable($issueInstant); + $issueInstant = self::getAttribute($xml, 'IssueInstant', DateTimeValue::class); return new static( $assertionIdReference ?: $assertionArtifact ?: array_pop($query), - self::getAttribute($xml, 'RequestID'), + self::getAttribute($xml, 'RequestID', IDValue::class), $majorVersion, $minorVersion, $issueInstant, diff --git a/src/SAML11/XML/samlp/RespondWith.php b/src/SAML11/XML/samlp/RespondWith.php index 4772b2c..b8d3b0b 100644 --- a/src/SAML11/XML/samlp/RespondWith.php +++ b/src/SAML11/XML/samlp/RespondWith.php @@ -4,27 +4,18 @@ namespace SimpleSAML\SAML11\XML\samlp; -use SimpleSAML\XML\QNameElementTrait; +use SimpleSAML\XML\Type\QNameValue; +use SimpleSAML\XML\TypedTextContentTrait; /** * Class representing a samlp:RespondWith element. * - * @package simplesaml/xml-saml11 + * @package simplesaml/saml11 */ final class RespondWith extends AbstractSamlpElement { - use QNameElementTrait; + use TypedTextContentTrait; - - /** - * Initialize a samlp:RespondWith - * - * @param string $qname - * @param string|null $namespaceUri - */ - public function __construct(string $qname, ?string $namespaceUri = null) - { - $this->setContent($qname); - $this->setContentNamespaceUri($namespaceUri); - } + /** @var string */ + public const TEXTCONTENT_TYPE = QNameValue::class; } diff --git a/src/SAML11/XML/samlp/Response.php b/src/SAML11/XML/samlp/Response.php index 8a13a12..05f0321 100644 --- a/src/SAML11/XML/samlp/Response.php +++ b/src/SAML11/XML/samlp/Response.php @@ -4,26 +4,22 @@ namespace SimpleSAML\SAML11\XML\samlp; -use DateTimeImmutable; use DOMElement; use SimpleSAML\SAML11\Assert\Assert; -use SimpleSAML\SAML11\Assert\Assert as SAMLAssert; -use SimpleSAML\SAML11\Exception\ProtocolViolationException; -use SimpleSAML\SAML11\Exception\VersionMismatchException; +use SimpleSAML\SAML11\Exception\{ProtocolViolationException, VersionMismatchException}; +use SimpleSAML\SAML11\Type\{AnyURIValue, DateTimeValue}; use SimpleSAML\SAML11\XML\saml\Assertion; use SimpleSAML\SAML11\XML\samlp\Status; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\TooManyElementsException; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, MissingElementException, TooManyElementsException}; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; +use SimpleSAML\XML\Type\{IDValue, NCNameValue, NonNegativeIntegerValue}; use function array_pop; /** * Class representing a samlp:Response element. * - * @package simplesaml/xml-saml11 + * @package simplesaml/saml11 */ final class Response extends AbstractResponseType implements SchemaValidatableElementInterface { @@ -47,32 +43,25 @@ public static function fromXML(DOMElement $xml): static Assert::same($xml->localName, 'Response', InvalidDOMElementException::class); Assert::same($xml->namespaceURI, Response::NS, InvalidDOMElementException::class); - $majorVersion = self::getIntegerAttribute($xml, 'MajorVersion'); - Assert::same($majorVersion, 1, VersionMismatchException::class); + $majorVersion = self::getAttribute($xml, 'MajorVersion', NonNegativeIntegerValue::class); + Assert::same($majorVersion->getValue(), '1', VersionMismatchException::class); - $minorVersion = self::getIntegerAttribute($xml, 'MinorVersion'); - Assert::same($minorVersion, 1, VersionMismatchException::class); - - $issueInstant = self::getAttribute($xml, 'IssueInstant'); - // Strip sub-seconds - See paragraph 1.3.3 of SAML core specifications - $issueInstant = preg_replace('/([.][0-9]+Z)$/', 'Z', $issueInstant, 1); - - SAMLAssert::validDateTime($issueInstant, ProtocolViolationException::class); - $issueInstant = new DateTimeImmutable($issueInstant); + $minorVersion = self::getAttribute($xml, 'MinorVersion', NonNegativeIntegerValue::class); + Assert::same($minorVersion->getValue(), '1', VersionMismatchException::class); $status = Status::getChildrenOfClass($xml); Assert::minCount($status, 1, MissingElementException::class); Assert::maxCount($status, 1, TooManyElementsException::class); return new static( - self::getAttribute($xml, 'ResponseID'), - array_pop($status), - Assertion::getChildrenOfClass($xml), $majorVersion, $minorVersion, - $issueInstant, - $inResponseTo = self::getOptionalAttribute($xml, 'InResponseTo', null), - $recipient = self::getOptionalAttribute($xml, 'Recipient', null), + self::getAttribute($xml, 'ResponseID', IDValue::class), + array_pop($status), + Assertion::getChildrenOfClass($xml), + self::getAttribute($xml, 'IssueInstant', DateTimeValue::class), + self::getOptionalAttribute($xml, 'InResponseTo', NCNameValue::class, null), + self::getOptionalAttribute($xml, 'Recipient', AnyURIValue::class, null), ); } } diff --git a/src/SAML11/XML/samlp/Status.php b/src/SAML11/XML/samlp/Status.php index 61310d1..082fcdd 100644 --- a/src/SAML11/XML/samlp/Status.php +++ b/src/SAML11/XML/samlp/Status.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\samlp; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a samlp:Status element. diff --git a/src/SAML11/XML/samlp/StatusCode.php b/src/SAML11/XML/samlp/StatusCode.php index 9571ebe..bf1f094 100644 --- a/src/SAML11/XML/samlp/StatusCode.php +++ b/src/SAML11/XML/samlp/StatusCode.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\samlp; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:StatusCode element. diff --git a/src/SAML11/XML/samlp/StatusDetail.php b/src/SAML11/XML/samlp/StatusDetail.php index 5f3f747..1c8d8f8 100644 --- a/src/SAML11/XML/samlp/StatusDetail.php +++ b/src/SAML11/XML/samlp/StatusDetail.php @@ -4,8 +4,7 @@ namespace SimpleSAML\SAML11\XML\samlp; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; /** * Class representing a saml:StatusDetail element. diff --git a/src/SAML11/XML/samlp/StatusMessage.php b/src/SAML11/XML/samlp/StatusMessage.php index 92fd633..115ee98 100644 --- a/src/SAML11/XML/samlp/StatusMessage.php +++ b/src/SAML11/XML/samlp/StatusMessage.php @@ -4,12 +4,9 @@ namespace SimpleSAML\SAML11\XML\samlp; -use DOMElement; -use SimpleSAML\Assert\Assert; -use SimpleSAML\SAML11\XML\StringElementTrait; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\SchemaValidatableElementInterface; -use SimpleSAML\XML\SchemaValidatableElementTrait; +use SimpleSAML\SAML11\Type\StringValue; +use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait}; +use SimpleSAML\XML\TypedTextContentTrait; /** * Class representing a samlp:StatusMessage element. @@ -19,45 +16,8 @@ final class StatusMessage extends AbstractSamlpElement implements SchemaValidatableElementInterface { use SchemaValidatableElementTrait; - use StringElementTrait; + use TypedTextContentTrait; - - /** - * @param string $content - */ - public function __construct(string $content) - { - $this->setContent($content); - } - - - /** - * Validate the content of the element. - * - * @param string $content The value to go in the XML textContent - * @throws \Exception on failure - * @return void - */ - protected function validateContent(string $content): void - { - Assert::notWhitespaceOnly($content); - } - - - /** - * Convert XML into an StatusMessage - * - * @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, 'StatusMessage', InvalidDOMElementException::class); - Assert::same($xml->namespaceURI, StatusMessage::NS, InvalidDOMElementException::class); - - return new static($xml->textContent); - } + /** @var string */ + public const TEXTCONTENT_TYPE = StringValue::class; } diff --git a/src/SAML11/XML/samlp/UnknownQuery.php b/src/SAML11/XML/samlp/UnknownQuery.php index 7c6543b..978c77f 100644 --- a/src/SAML11/XML/samlp/UnknownQuery.php +++ b/src/SAML11/XML/samlp/UnknownQuery.php @@ -6,6 +6,7 @@ use DOMElement; use SimpleSAML\XML\Chunk; +use SimpleSAML\XML\Type\QNameValue; /** * Class for unknown queries. @@ -16,11 +17,11 @@ final class UnknownQuery extends AbstractQuery { /** * @param \SimpleSAML\XML\Chunk $chunk The whole Query element as a chunk object. - * @param string $type The xsi:type of this condition. + * @param \SimpleSAML\XML\Type\QNameValue $type The xsi:type of this condition. */ public function __construct( protected Chunk $chunk, - string $type, + QNameValue $type, ) { parent::__construct($type); } diff --git a/src/SAML11/XML/samlp/UnknownSubjectQuery.php b/src/SAML11/XML/samlp/UnknownSubjectQuery.php index da74743..480e70e 100644 --- a/src/SAML11/XML/samlp/UnknownSubjectQuery.php +++ b/src/SAML11/XML/samlp/UnknownSubjectQuery.php @@ -7,6 +7,7 @@ use DOMElement; use SimpleSAML\SAML11\XML\saml\Subject; use SimpleSAML\XML\Chunk; +use SimpleSAML\XML\Type\QNameValue; /** * Class for unknown subject queries. @@ -17,11 +18,11 @@ final class UnknownSubjectQuery extends AbstractSubjectQuery { /** * @param \SimpleSAML\XML\Chunk $chunk The whole SubjectQuery element as a chunk object. - * @param string $type The xsi:type of this condition. + * @param \SimpleSAML\XML\Type\QNameValue $type The xsi:type of this condition. */ public function __construct( protected Chunk $chunk, - string $type, + QNameValue $type, Subject $subject, ) { parent::__construct($type, $subject); diff --git a/tests/resources/xml/saml_AttributeStatement.xml b/tests/resources/xml/saml_AttributeStatement.xml index b40b796..496e03f 100644 --- a/tests/resources/xml/saml_AttributeStatement.xml +++ b/tests/resources/xml/saml_AttributeStatement.xml @@ -15,7 +15,7 @@ - + FirstValue SecondValue diff --git a/tests/resources/xml/saml_Conditions.xml b/tests/resources/xml/saml_Conditions.xml index 0cabf27..9273616 100644 --- a/tests/resources/xml/saml_Conditions.xml +++ b/tests/resources/xml/saml_Conditions.xml @@ -2,8 +2,8 @@ urn:x-simplesamlphp:audience - - + + urn:some:audience diff --git a/tests/resources/xml/saml_Evidence.xml b/tests/resources/xml/saml_Evidence.xml index 3f07584..9487c08 100644 --- a/tests/resources/xml/saml_Evidence.xml +++ b/tests/resources/xml/saml_Evidence.xml @@ -1,5 +1,5 @@ - _Test + _Test diff --git a/tests/resources/xml/samlp_AuthorizationDecisionQuery.xml b/tests/resources/xml/samlp_AuthorizationDecisionQuery.xml index 98e546a..6020d01 100644 --- a/tests/resources/xml/samlp_AuthorizationDecisionQuery.xml +++ b/tests/resources/xml/samlp_AuthorizationDecisionQuery.xml @@ -43,7 +43,7 @@ - + diff --git a/tests/resources/xml/samlp_Response.xml b/tests/resources/xml/samlp_Response.xml index b85aa04..645c662 100644 --- a/tests/resources/xml/samlp_Response.xml +++ b/tests/resources/xml/samlp_Response.xml @@ -1,4 +1,4 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/tests/resources/xml/samlp_SubjectQuery.xml b/tests/resources/xml/samlp_SubjectQuery.xml index 981016b..5abe1e4 100644 --- a/tests/resources/xml/samlp_SubjectQuery.xml +++ b/tests/resources/xml/samlp_SubjectQuery.xml @@ -11,7 +11,7 @@ MIICxDCCAi2gAwIBAgIUZ9QDx+SBFHednUWDFGm9tyVKrgQwDQYJKoZIhvcNAQELBQAwczElMCMGA1UEAwwcc2VsZnNpZ25lZC5zaW1wbGVzYW1scGhwLm9yZzEZMBcGA1UECgwQU2ltcGxlU0FNTHBocCBIUTERMA8GA1UEBwwISG9ub2x1bHUxDzANBgNVBAgMBkhhd2FpaTELMAkGA1UEBhMCVVMwIBcNMjIxMjAzMTAzNTQwWhgPMjEyMjExMDkxMDM1NDBaMHMxJTAjBgNVBAMMHHNlbGZzaWduZWQuc2ltcGxlc2FtbHBocC5vcmcxGTAXBgNVBAoMEFNpbXBsZVNBTUxwaHAgSFExETAPBgNVBAcMCEhvbm9sdWx1MQ8wDQYDVQQIDAZIYXdhaWkxCzAJBgNVBAYTAlVTMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDessdFRVDTMQQW3Na81B1CjJV1tmY3nopoIhZrkbDxLa+pv7jGDRcYreyu1DoQxEs06V2nHLoyOPhqJXSFivqtUwVYhR6NYgbNI6RRSsIJCweH0YOdlHna7gULPcLX0Bfbi4odStaFwG9yzDySwSEPtsKxm5pENPjNVGh+jJ+H/QIDAQABo1MwUTAdBgNVHQ4EFgQUvV75t8EoQo2fVa0E9otdtIGK5X0wHwYDVR0jBBgwFoAUvV75t8EoQo2fVa0E9otdtIGK5X0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQANQUeiwPJXkWMXuaDHToEBKcezYGqGEYnGUi9LMjeb+Kln7X8nn5iknlz4k77rWCbSwLPC/WDr0ySYQA+HagaeUaFpoiYFJKS6uFlK1HYWnM3W4PUiGHg1/xeZlMO44wTwybXVo0y9KMhchfB5XNbDdoJcqWYvi6xtmZZNRbxUyw== /CN=selfsigned.simplesamlphp.org/O=SimpleSAMLphp HQ/L=Honolulu/ST=Hawaii/C=US - some + some diff --git a/tests/src/SAML11/Assert/AnyURITest.php b/tests/src/SAML11/Assert/AnyURITest.php new file mode 100644 index 0000000..37c6268 --- /dev/null +++ b/tests/src/SAML11/Assert/AnyURITest.php @@ -0,0 +1,50 @@ +assertTrue($shouldPass); + } catch (AssertionFailedException | ProtocolViolationException | SchemaViolationException $e) { + $this->assertFalse($shouldPass); + } finally { + } + } + + + /** + * @return array + */ + public static function provideAnyURI(): array + { + return [ + 'valid' => [true, 'https://simplesamlphp.org'], + 'empty' => [false, ''], + 'whitespace' => [false, ' '], + ]; + } +} diff --git a/tests/src/SAML11/Assert/DateTimeTest.php b/tests/src/SAML11/Assert/DateTimeTest.php index 2963736..16b11a2 100644 --- a/tests/src/SAML11/Assert/DateTimeTest.php +++ b/tests/src/SAML11/Assert/DateTimeTest.php @@ -4,11 +4,10 @@ namespace SimpleSAML\SAML11\Test\Assert; -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\{CoversClass, DataProvider}; use PHPUnit\Framework\TestCase; use SimpleSAML\Assert\AssertionFailedException; -use SimpleSAML\SAML11\Assert\Assert as SAML11Assert; +use SimpleSAML\SAML11\Assert\Assert; use SimpleSAML\SAML11\Exception\ProtocolViolationException; use SimpleSAML\XML\Exception\SchemaViolationException; @@ -17,7 +16,7 @@ * * @package simplesamlphp/saml11 */ -#[CoversClass(SAML11Assert::class)] +#[CoversClass(Assert::class)] final class DateTimeTest extends TestCase { /** @@ -28,7 +27,7 @@ final class DateTimeTest extends TestCase public function testValidDateTime(bool $shouldPass, string $timestamp): void { try { - SAML11Assert::validDateTime($timestamp); + Assert::validDateTime($timestamp); $this->assertTrue($shouldPass); } catch (AssertionFailedException | ProtocolViolationException | SchemaViolationException $e) { $this->assertFalse($shouldPass); diff --git a/tests/src/SAML11/Assert/StringTest.php b/tests/src/SAML11/Assert/StringTest.php new file mode 100644 index 0000000..8435228 --- /dev/null +++ b/tests/src/SAML11/Assert/StringTest.php @@ -0,0 +1,48 @@ +assertTrue($shouldPass); + } catch (ProtocolViolationException | SchemaViolationException $e) { + $this->assertFalse($shouldPass); + } + } + + + /** + * @return array + */ + public static function provideString(): array + { + return [ + 'valid' => [true, 'dear diary'], + 'empty' => [false, ''], + 'whitespace' => [false, ' '], + ]; + } +} diff --git a/tests/src/SAML11/CustomCondition.php b/tests/src/SAML11/CustomCondition.php index 5e7e237..df68d05 100644 --- a/tests/src/SAML11/CustomCondition.php +++ b/tests/src/SAML11/CustomCondition.php @@ -7,9 +7,9 @@ use DOMElement; use SimpleSAML\Assert\Assert; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\AbstractCondition; -use SimpleSAML\SAML11\XML\saml\Audience; +use SimpleSAML\SAML11\XML\saml\{AbstractCondition, Audience}; use SimpleSAML\XML\Exception\InvalidDOMElementException; +use SimpleSAML\XML\Type\QNameValue; /** * Example class to demonstrate how Condition can be extended. @@ -38,7 +38,11 @@ public function __construct( ) { Assert::allIsInstanceOf($audience, Audience::class); - parent::__construct(self::XSI_TYPE_PREFIX . ':' . self::XSI_TYPE_NAME); + parent::__construct( + QNameValue::fromString( + '{' . self::XSI_TYPE_NAMESPACE . '}' . self::XSI_TYPE_PREFIX . ':' . self::XSI_TYPE_NAME, + ), + ); } diff --git a/tests/src/SAML11/CustomQuery.php b/tests/src/SAML11/CustomQuery.php index e9e1e5c..dd41f18 100644 --- a/tests/src/SAML11/CustomQuery.php +++ b/tests/src/SAML11/CustomQuery.php @@ -7,9 +7,9 @@ use DOMElement; use SimpleSAML\Assert\Assert; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\samlp\AbstractQuery; -use SimpleSAML\SAML11\XML\samlp\StatusMessage; +use SimpleSAML\SAML11\XML\samlp\{AbstractQuery, StatusMessage}; use SimpleSAML\XML\Exception\InvalidDOMElementException; +use SimpleSAML\XML\Type\QNameValue; /** * Example class to demonstrate how Query can be extended. @@ -38,7 +38,11 @@ public function __construct( ) { Assert::allIsInstanceOf($statusMessage, StatusMessage::class); - parent::__construct(self::XSI_TYPE_PREFIX . ':' . self::XSI_TYPE_NAME); + parent::__construct( + QNameValue::fromString( + '{' . self::XSI_TYPE_NAMESPACE . '}' . self::XSI_TYPE_PREFIX . ':' . self::XSI_TYPE_NAME, + ), + ); } diff --git a/tests/src/SAML11/CustomStatement.php b/tests/src/SAML11/CustomStatement.php index dd9d3d8..1a0e2f0 100644 --- a/tests/src/SAML11/CustomStatement.php +++ b/tests/src/SAML11/CustomStatement.php @@ -7,9 +7,9 @@ use DOMElement; use SimpleSAML\Assert\Assert; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\AbstractStatement; -use SimpleSAML\SAML11\XML\saml\Audience; +use SimpleSAML\SAML11\XML\saml\{AbstractStatement, Audience}; use SimpleSAML\XML\Exception\InvalidDOMElementException; +use SimpleSAML\XML\Type\QNameValue; /** * Example class to demonstrate how Statement can be extended. @@ -38,7 +38,11 @@ public function __construct( ) { Assert::allIsInstanceOf($audience, Audience::class); - parent::__construct(self::XSI_TYPE_PREFIX . ':' . self::XSI_TYPE_NAME); + parent::__construct( + QNameValue::fromString( + '{' . self::XSI_TYPE_NAMESPACE . '}' . self::XSI_TYPE_PREFIX . ':' . self::XSI_TYPE_NAME, + ), + ); } diff --git a/tests/src/SAML11/CustomSubjectQuery.php b/tests/src/SAML11/CustomSubjectQuery.php index 71951ef..75d3efc 100644 --- a/tests/src/SAML11/CustomSubjectQuery.php +++ b/tests/src/SAML11/CustomSubjectQuery.php @@ -8,11 +8,10 @@ use SimpleSAML\Assert\Assert; use SimpleSAML\SAML11\Constants as C; use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\SAML11\XML\samlp\AbstractSubjectQuery; -use SimpleSAML\SAML11\XML\samlp\StatusMessage; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\TooManyElementsException; +use SimpleSAML\SAML11\XML\samlp\{AbstractSubjectQuery, StatusMessage}; +use SimpleSAML\XML\Attribute as XMLAttribute; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, MissingElementException, TooManyElementsException}; +use SimpleSAML\XML\Type\QNameValue; use function array_pop; @@ -44,7 +43,12 @@ public function __construct( ) { Assert::allIsInstanceOf($statusMessage, StatusMessage::class); - parent::__construct(self::XSI_TYPE_PREFIX . ':' . self::XSI_TYPE_NAME, $subject); + parent::__construct( + QNameValue::fromString( + '{' . self::XSI_TYPE_NAMESPACE . '}' . self::XSI_TYPE_PREFIX . ':' . self::XSI_TYPE_NAME, + ), + $subject, + ); } @@ -79,8 +83,8 @@ public static function fromXML(DOMElement $xml): static InvalidDOMElementException::class, ); - $type = $xml->getAttributeNS(C::NS_XSI, 'type'); - Assert::same($type, self::XSI_TYPE_PREFIX . ':' . self::XSI_TYPE_NAME); + $type = QNameValue::fromDocument($xml->getAttributeNS(C::NS_XSI, 'type'), $xml); + Assert::same($type->getValue(), self::XSI_TYPE_PREFIX . ':' . self::XSI_TYPE_NAME); $statusMessage = StatusMessage::getChildrenOfClass($xml); @@ -100,7 +104,24 @@ public static function fromXML(DOMElement $xml): static */ public function toXML(?DOMElement $parent = null): DOMElement { - $e = parent::toXML($parent); + $e = $this->instantiateParentElement($parent); + + if (!$e->lookupPrefix($this->getXsiType()->getNamespaceURI()->getValue())) { + $namespace = new XMLAttribute( + 'http://www.w3.org/2000/xmlns/', + 'xmlns', + $this->getXsiType()->getNamespacePrefix()->getValue(), + $this->getXsiType()->getNamespaceURI(), + ); + $namespace->toXML($e); + } + + if (!$e->lookupPrefix('xsi')) { + $type = new XMLAttribute(C::NS_XSI, 'xsi', 'type', $this->getXsiType()); + $type->toXML($e); + } + + $this->getSubject()->toXML($e); foreach ($this->getStatusMessage() as $statusMessage) { $statusMessage->toXML($e); diff --git a/tests/src/SAML11/CustomSubjectStatement.php b/tests/src/SAML11/CustomSubjectStatement.php index ba94b02..5540ce3 100644 --- a/tests/src/SAML11/CustomSubjectStatement.php +++ b/tests/src/SAML11/CustomSubjectStatement.php @@ -7,12 +7,9 @@ use DOMElement; use SimpleSAML\Assert\Assert; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\AbstractSubjectStatement; -use SimpleSAML\SAML11\XML\saml\Audience; -use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\XML\Exception\InvalidDOMElementException; -use SimpleSAML\XML\Exception\MissingElementException; -use SimpleSAML\XML\Exception\TooManyElementsException; +use SimpleSAML\SAML11\XML\saml\{AbstractSubjectStatement, Audience, Subject}; +use SimpleSAML\XML\Exception\{InvalidDOMElementException, MissingElementException, TooManyElementsException}; +use SimpleSAML\XML\Type\QNameValue; /** * Example class to demonstrate how SubjectStatement can be extended. @@ -43,7 +40,12 @@ public function __construct( ) { Assert::allIsInstanceOf($audience, Audience::class); - parent::__construct(self::XSI_TYPE_PREFIX . ':' . self::XSI_TYPE_NAME, $subject); + parent::__construct( + QNameValue::fromString( + '{' . self::XSI_TYPE_NAMESPACE . '}' . self::XSI_TYPE_PREFIX . ':' . self::XSI_TYPE_NAME, + ), + $subject, + ); } diff --git a/tests/src/SAML11/Type/AnyURIValueTest.php b/tests/src/SAML11/Type/AnyURIValueTest.php new file mode 100644 index 0000000..1acdf13 --- /dev/null +++ b/tests/src/SAML11/Type/AnyURIValueTest.php @@ -0,0 +1,54 @@ +assertTrue($shouldPass); + } catch (ProtocolViolationException | SchemaViolationException $e) { + $this->assertFalse($shouldPass); + } + } + + + /** + * @return array + */ + public static function provideURI(): array + { + return [ + 'urn' => [true, 'urn:x-simplesamlphp:phpunit'], + 'same-doc' => [true, '#_53d830ab1be17291a546c95c7f1cdf8d3d23c959e6'], + 'url' => [true, 'https://www.simplesamlphp.org'], + 'diacritical' => [true, 'https://aä.com'], + 'spn' => [true, 'spn:a4cf592f-a64c-46ff-a788-b260f474525b'], + 'typos' => [true, 'https//www.uni.l/en/'], + 'spaces' => [true, 'this is silly'], + 'empty' => [false, ''], + 'azure-common' => [true, 'https://sts.windows.net/{tenantid}/'], + ]; + } +} diff --git a/tests/src/SAML11/Type/DateTimeValueTest.php b/tests/src/SAML11/Type/DateTimeValueTest.php new file mode 100644 index 0000000..ede855d --- /dev/null +++ b/tests/src/SAML11/Type/DateTimeValueTest.php @@ -0,0 +1,62 @@ +assertTrue($shouldPass); + } catch (AssertionFailedException | ProtocolViolationException | SchemaViolationException $e) { + $this->assertFalse($shouldPass); + } + } + + + /** + * @return array + */ + public static function provideDateTime(): array + { + return [ + 'valid' => [true, '2001-10-26T21:32:52Z'], + 'invalid with numeric difference' => [false, '2001-10-26T21:32:52+02:00'], + 'invalid with Zulu' => [false, '2001-10-26T19:32:52'], + 'invalid with 00:00 difference' => [false, '2001-10-26T19:32:52+00:00'], + 'valid with negative value' => [true, '-2001-10-26T21:32:52Z'], + 'valid with subseconds' => [true, '2001-10-26T21:32:52.12679Z'], + 'valid with more than four digit year' => [true, '-22001-10-26T21:32:52Z'], + 'valid with sub-seconds' => [true, '2001-10-26T21:32:52.12679Z'], + 'empty' => [false, ''], + 'whitespace collapse' => [true, ' 2001-10-26T21:32:52Z '], + 'missing time' => [false, '2001-10-26'], + 'missing second' => [false, '2001-10-26T21:32'], + 'hour out of range' => [false, '2001-10-26T25:32:52+02:00'], + 'year 0000' => [false, '0000-10-26T25:32:52+02:00'], + 'prefixed zero' => [false, '02001-10-26T25:32:52+02:00'], + 'wrong format' => [false, '01-10-26T21:32'], + ]; + } +} diff --git a/tests/src/SAML11/Type/StringValueTest.php b/tests/src/SAML11/Type/StringValueTest.php new file mode 100644 index 0000000..2bc09cf --- /dev/null +++ b/tests/src/SAML11/Type/StringValueTest.php @@ -0,0 +1,47 @@ +assertTrue($shouldPass); + } catch (ProtocolViolationException | SchemaViolationException $e) { + $this->assertFalse($shouldPass); + } + } + + + /** + * @return array + */ + public static function provideString(): array + { + return [ + 'empty string' => [false, ''], + 'some thing' => [true, 'Snoopy '], + ]; + } +} diff --git a/tests/src/SAML11/XML/saml/ActionTest.php b/tests/src/SAML11/XML/saml/ActionTest.php index e2dce88..4287117 100644 --- a/tests/src/SAML11/XML/saml/ActionTest.php +++ b/tests/src/SAML11/XML/saml/ActionTest.php @@ -4,14 +4,12 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\AbstractActionType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\Action; +use SimpleSAML\SAML11\XML\saml\{AbstractActionType, AbstractSamlElement, Action}; +use SimpleSAML\SAML11\Type\{AnyURIValue, StringValue}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -21,6 +19,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(Action::class)] #[CoversClass(AbstractActionType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -34,8 +33,6 @@ final class ActionTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = Action::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -52,7 +49,10 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $action = new Action('urn:x-simplesamlphp:action', 'urn:x-simplesamlphp:namespace'); + $action = new Action( + StringValue::fromString('urn:x-simplesamlphp:action'), + AnyURIValue::fromString('urn:x-simplesamlphp:namespace'), + ); $this->assertEquals( self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), diff --git a/tests/src/SAML11/XML/saml/AdviceTest.php b/tests/src/SAML11/XML/saml/AdviceTest.php index e60afe1..aed0643 100644 --- a/tests/src/SAML11/XML/saml/AdviceTest.php +++ b/tests/src/SAML11/XML/saml/AdviceTest.php @@ -4,47 +4,59 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use DateTimeImmutable; use DOMDocument; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\Compat\AbstractContainer; -use SimpleSAML\SAML11\Compat\ContainerSingleton; +use SimpleSAML\SAML11\Compat\{AbstractContainer, ContainerSingleton}; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\AbstractAdviceType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\AbstractStatement; -use SimpleSAML\SAML11\XML\saml\AbstractSubjectStatement; -use SimpleSAML\SAML11\XML\saml\Advice; -use SimpleSAML\SAML11\XML\saml\Assertion; -use SimpleSAML\SAML11\XML\saml\AssertionIDReference; -use SimpleSAML\SAML11\XML\saml\Attribute; -use SimpleSAML\SAML11\XML\saml\AttributeStatement; -use SimpleSAML\SAML11\XML\saml\AttributeValue; -use SimpleSAML\SAML11\XML\saml\Audience; -use SimpleSAML\SAML11\XML\saml\AuthenticationStatement; -use SimpleSAML\SAML11\XML\saml\AuthorityBinding; -//use SimpleSAML\SAML11\XML\saml\AuthorizationDecisionStatement; -use SimpleSAML\SAML11\XML\saml\Conditions; -use SimpleSAML\SAML11\XML\saml\ConfirmationMethod; -use SimpleSAML\SAML11\XML\saml\NameIdentifier; -use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmation; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmationData; -use SimpleSAML\SAML11\XML\saml\SubjectLocality; -use SimpleSAML\Test\SAML11\CustomCondition; -use SimpleSAML\Test\SAML11\CustomStatement; -use SimpleSAML\Test\SAML11\CustomSubjectStatement; -use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\SAML11\Type\{ + AnyURIValue as SAMLAnyURIValue, + DateTimeValue as SAMLDateTimeValue, + StringValue as SAMLStringValue, +}; +use SimpleSAML\SAML11\XML\saml\{ + AbstractAdviceType, + AbstractSamlElement, + AbstractStatement, + AbstractSubjectStatement, + Advice, + Assertion, + AssertionIDReference, + Attribute, + AttributeStatement, + AttributeValue, + Audience, + AuthenticationStatement, + AuthorityBinding, + //AuthorizationDecisionStatement, + Conditions, + ConfirmationMethod, + NameIdentifier, + Subject, + SubjectConfirmation, + SubjectConfirmationData, + SubjectLocality, +}; +use SimpleSAML\Test\SAML11\{CustomCondition, CustomStatement, CustomSubjectStatement}; +use SimpleSAML\XML\{Chunk, DOMDocumentFactory}; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\{ + Base64BinaryValue, + IDValue, + IntegerValue, + NCNameValue, + NonNegativeIntegerValue, + QNameValue, + StringValue +}; use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; -use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; -use SimpleSAML\XMLSecurity\XML\ds\KeyName; -use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; -use SimpleSAML\XMLSecurity\XML\ds\X509Data; -use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\ds\{ + KeyInfo, + KeyName, + X509Certificate, + X509Data, + X509SubjectName, +}; use function dirname; use function strval; @@ -54,6 +66,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(Advice::class)] #[CoversClass(AbstractAdviceType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -180,79 +193,114 @@ public static function tearDownAfterClass(): void */ public function testMarshalling(): void { - $assertionIDReference = new AssertionIDReference('_Test'); + $assertionIDReference = new AssertionIDReference( + NCNameValue::fromString('_Test'), + ); // Create SubjectStatement - $scd = new SubjectConfirmationData(2); + $scd = new SubjectConfirmationData( + IntegerValue::fromString('2'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - 'AdviceSubjectStatementID', + IDValue::fromString('AdviceSubjectStatementID'), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + SAMLStringValue::fromString('TheNameIDValue'), + SAMLStringValue::fromString('TheNameQualifier'), + SAMLAnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); - $audience = new Audience('urn:x-simplesamlphp:audience'); + $audience = new Audience( + SAMLAnyURIValue::fromString('urn:x-simplesamlphp:audience'), + ); $subjectStatement = new CustomSubjectStatement($subject, [$audience]); // Create AuthenticationStatement $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - 'AdviceAuthenticationStatementID', + IDValue::fromString('AdviceAuthenticationStatementID'), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $subject = new Subject($sc, $nameIdentifier); - $subjectLocality = new SubjectLocality('127.0.0.1', 'simplesamlphp.org'); + $subjectLocality = new SubjectLocality( + SAMLStringValue::fromString('127.0.0.1'), + SAMLStringValue::fromString('simplesamlphp.org'), + ); $authorityBinding = new AuthorityBinding( - 'samlp:AttributeQuery', - 'urn:x-simplesamlphp:location', - 'urn:x-simplesamlphp:binding', + QNameValue::fromString('{' . C::NS_SAMLP . '}samlp:AttributeQuery'), + SAMLAnyURIValue::fromString('urn:x-simplesamlphp:location'), + SAMLAnyURIValue::fromString('urn:x-simplesamlphp:binding'), ); $authenticationStatement = new AuthenticationStatement( $subject, - C::AC_PASSWORD, - new DateTimeImmutable('2023-01-24T09:42:26Z'), + SAMLAnyURIValue::fromString(C::AC_PASSWORD), + SAMLDateTimeValue::fromString('2023-01-24T09:42:26Z'), $subjectLocality, [$authorityBinding], ); @@ -260,22 +308,35 @@ public function testMarshalling(): void // Create AttributeStatement $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - 'AdviceAttributeStatementID', + IDValue::fromString('AdviceAttributeStatementID'), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); @@ -283,9 +344,16 @@ public function testMarshalling(): void $subject = new Subject($sc, $nameIdentifier); $attribute = new Attribute( - 'TheName', - 'https://example.org/', - [new AttributeValue('FirstValue'), new AttributeValue('SecondValue')], + SAMLStringValue::fromString('TheName'), + SAMLAnyURIValue::fromString('https://example.org/'), + [ + new AttributeValue( + SAMLStringValue::fromString('FirstValue'), + ), + new AttributeValue( + SAMLStringValue::fromString('SecondValue'), + ), + ], ); $attributeStatement = new AttributeStatement( @@ -295,9 +363,11 @@ public function testMarshalling(): void // Create assertion $assertion = new Assertion( - 'AdviceAssertionID', - 'urn:x-simplesamlphp:phpunit', - new DateTimeImmutable('2023-01-24T09:42:26Z'), + NonNegativeIntegerValue::fromString('1'), + NonNegativeIntegerValue::fromString('1'), + IDValue::fromString('AdviceAssertionID'), + SAMLStringValue::fromString('urn:x-simplesamlphp:phpunit'), + SAMLDateTimeValue::fromString('2023-01-24T09:42:26Z'), Conditions::fromXML(self::$conditions->documentElement), null, // null [ @@ -316,9 +386,11 @@ public function testMarshalling(): void ); $assertion = new Assertion( - '_abc123', - 'urn:x-simplesamlphp:phpunit', - new DateTimeImmutable('2023-01-24T09:42:26Z'), + NonNegativeIntegerValue::fromString('1'), + NonNegativeIntegerValue::fromString('1'), + IDValue::fromString('_abc123'), + SAMLStringValue::fromString('urn:x-simplesamlphp:phpunit'), + SAMLDateTimeValue::fromString('2023-01-24T09:42:26Z'), Conditions::fromXML(self::$conditions->documentElement), $advice, [ diff --git a/tests/src/SAML11/XML/saml/AssertionIDReferenceTest.php b/tests/src/SAML11/XML/saml/AssertionIDReferenceTest.php index 32694a1..ee5af39 100644 --- a/tests/src/SAML11/XML/saml/AssertionIDReferenceTest.php +++ b/tests/src/SAML11/XML/saml/AssertionIDReferenceTest.php @@ -4,13 +4,12 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\AssertionIDReference; +use SimpleSAML\SAML11\XML\saml\{AbstractSamlElement, AssertionIDReference}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\IDValue; use function dirname; use function strval; @@ -20,6 +19,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(AssertionIDReference::class)] #[CoversClass(AbstractSamlElement::class)] final class AssertionIDReferenceTest extends TestCase @@ -31,8 +31,6 @@ final class AssertionIDReferenceTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = AssertionIDReference::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -45,7 +43,9 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $assertionIDReference = new AssertionIDReference('_Test'); + $assertionIDReference = new AssertionIDReference( + IDValue::fromString('_Test'), + ); $this->assertEquals( self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), diff --git a/tests/src/SAML11/XML/saml/AssertionTest.php b/tests/src/SAML11/XML/saml/AssertionTest.php index c39084e..1e6d672 100644 --- a/tests/src/SAML11/XML/saml/AssertionTest.php +++ b/tests/src/SAML11/XML/saml/AssertionTest.php @@ -4,39 +4,56 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use DateTimeImmutable; use DOMDocument; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\Compat\AbstractContainer; -use SimpleSAML\SAML11\Compat\ContainerSingleton; +use SimpleSAML\SAML11\Compat\{AbstractContainer, ContainerSingleton}; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\AbstractAssertionType; -use SimpleSAML\SAML11\XML\saml\AbstractAttributeStatementType; -use SimpleSAML\SAML11\XML\saml\AbstractAuthenticationStatementType; -use SimpleSAML\SAML11\XML\saml\AbstractAuthorizationDecisionStatementType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\AbstractStatement; -use SimpleSAML\SAML11\XML\saml\AbstractStatementType; -use SimpleSAML\SAML11\XML\saml\AbstractSubjectStatement; -use SimpleSAML\SAML11\XML\saml\AbstractSubjectStatementType; -use SimpleSAML\SAML11\XML\saml\Advice; -use SimpleSAML\SAML11\XML\saml\Assertion; -use SimpleSAML\SAML11\XML\saml\AssertionIDReference; -use SimpleSAML\SAML11\XML\saml\{Attribute, AttributeStatement, AttributeValue}; -use SimpleSAML\SAML11\XML\saml\Audience; -use SimpleSAML\SAML11\XML\saml\AuthenticationStatement; -use SimpleSAML\SAML11\XML\saml\AuthorityBinding; -use SimpleSAML\SAML11\XML\saml\AuthorizationDecisionStatement; -use SimpleSAML\SAML11\XML\saml\Conditions; -use SimpleSAML\SAML11\XML\saml\ConfirmationMethod; -use SimpleSAML\SAML11\XML\saml\NameIdentifier; -use SimpleSAML\SAML11\XML\saml\{Subject, SubjectConfirmation, SubjectConfirmationData}; -use SimpleSAML\SAML11\XML\saml\SubjectLocality; +use SimpleSAML\SAML11\Type\{ + AnyURIValue as SAMLAnyURIValue, + DateTimeValue as SAMLDateTimeValue, + StringValue as SAMLStringValue, +}; +use SimpleSAML\SAML11\XML\saml\{ + AbstractAssertionType, + AbstractAttributeStatementType, + AbstractAuthenticationStatementType, + AbstractAuthorizationDecisionStatementType, + AbstractSamlElement, + AbstractStatement, + AbstractStatementType, + AbstractSubjectStatement, + AbstractSubjectStatementType, + Advice, + Assertion, + AssertionIDReference, + Attribute, + AttributeStatement, + AttributeValue, + Audience, + AuthenticationStatement, + AuthorityBinding, + AuthorizationDecisionStatement, + Conditions, + ConfirmationMethod, + NameIdentifier, + Subject, + SubjectConfirmation, + SubjectConfirmationData, + SubjectLocality, +}; use SimpleSAML\Test\SAML11\{CustomCondition, CustomStatement, CustomSubjectStatement}; -use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\DOMDocumentFactory; +use SimpleSAML\XML\{Chunk, DOMDocumentFactory}; use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\{ + Base64BinaryValue, + IDValue, + IntegerValue, + NCNameValue, + NonNegativeIntegerValue, + QNameValue, + StringValue, +}; use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; use SimpleSAML\XMLSecurity\XML\ds\{KeyInfo, KeyName}; use SimpleSAML\XMLSecurity\XML\ds\{X509Certificate, X509CertificateName, X509Data, X509SubjectName}; @@ -49,6 +66,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(Assertion::class)] #[CoversClass(AbstractAssertionType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -193,9 +211,11 @@ public function testMarshalling(): void // Create inner assertion $assertion = new Assertion( - 'AdviceAssertionID_2', - 'urn:x-simplesamlphp:phpunit', - new DateTimeImmutable('2023-01-24T09:42:26Z'), + NonNegativeIntegerValue::fromString('1'), + NonNegativeIntegerValue::fromString('1'), + IDValue::fromString('AdviceAssertionID_2'), + SAMLStringValue::fromString('urn:x-simplesamlphp:phpunit'), + SAMLDateTimeValue::fromString('2023-01-24T09:42:26Z'), Conditions::fromXML(self::$conditions->documentElement), null, // advice [ @@ -208,7 +228,9 @@ public function testMarshalling(): void ); // Create middle assertion - $assertionIDReference = new AssertionIDReference('_Test'); + $assertionIDReference = new AssertionIDReference( + NCNameValue::fromString('_Test'), + ); $advice = new Advice( [$assertionIDReference], [$assertion], @@ -225,9 +247,11 @@ public function testMarshalling(): void $attributeStatement = $this->createAttributeStatement('AdviceAttributeStatementID'); $assertion = new Assertion( - 'AdviceAssertionID', - 'urn:x-simplesamlphp:phpunit', - new DateTimeImmutable('2023-01-24T09:42:26Z'), + NonNegativeIntegerValue::fromString('1'), + NonNegativeIntegerValue::fromString('1'), + IDValue::fromString('AdviceAssertionID'), + SAMLStringValue::fromString('urn:x-simplesamlphp:phpunit'), + SAMLDateTimeValue::fromString('2023-01-24T09:42:26Z'), Conditions::fromXML(self::$conditions->documentElement), $advice, [ @@ -247,9 +271,11 @@ public function testMarshalling(): void ); $assertion = new Assertion( - 'AssertionID', - 'urn:x-simplesamlphp:phpunit', - new DateTimeImmutable('2023-01-24T09:42:26Z'), + NonNegativeIntegerValue::fromString('1'), + NonNegativeIntegerValue::fromString('1'), + IDValue::fromString('AssertionID'), + SAMLStringValue::fromString('urn:x-simplesamlphp:phpunit'), + SAMLDateTimeValue::fromString('2023-01-24T09:42:26Z'), Conditions::fromXML(self::$conditions->documentElement), $advice, [ @@ -307,38 +333,56 @@ public function testStatementGetters(): void private function createSubjectStatement(string $id): CustomSubjectStatement { // Create SubjectStatement - $scd = new SubjectConfirmationData(2); + $scd = new SubjectConfirmationData( + IntegerValue::fromString('2'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - $id, + IDValue::fromString($id), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + SAMLStringValue::fromString('TheNameIDValue'), + SAMLStringValue::fromString('TheNameQualifier'), + SAMLAnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); - $audience = new Audience('urn:x-simplesamlphp:audience'); + $audience = new Audience( + SAMLAnyURIValue::fromString('urn:x-simplesamlphp:audience'), + ); + return new CustomSubjectStatement($subject, [$audience]); } @@ -349,49 +393,68 @@ private function createSubjectStatement(string $id): CustomSubjectStatement */ private function createAuthenticationStatement(string $id): AuthenticationStatement { - $scd = new SubjectConfirmationData(2); + $scd = new SubjectConfirmationData( + IntegerValue::fromString('2'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - $id, + IDValue::fromString($id), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + SAMLStringValue::fromString('TheNameIDValue'), + SAMLStringValue::fromString('TheNameQualifier'), + SAMLAnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); - $subjectLocality = new SubjectLocality('127.0.0.1', 'simplesamlphp.org'); + $subjectLocality = new SubjectLocality( + SAMLStringValue::fromString('127.0.0.1'), + SAMLStringValue::fromString('simplesamlphp.org'), + ); + $authorityBinding = new AuthorityBinding( - 'samlp:AttributeQuery', - 'urn:x-simplesamlphp:location', - 'urn:x-simplesamlphp:binding', + QNameValue::fromString('{' . C::NS_SAMLP . '}samlp:AttributeQuery'), + SAMLAnyURIValue::fromString('urn:x-simplesamlphp:location'), + SAMLAnyURIValue::fromString('urn:x-simplesamlphp:binding'), ); return new AuthenticationStatement( $subject, - C::AC_PASSWORD, - new DateTimeImmutable('2023-01-24T09:42:26Z'), + SAMLAnyURIValue::fromString(C::AC_PASSWORD), + SAMLDateTimeValue::fromString('2023-01-24T09:42:26Z'), $subjectLocality, [$authorityBinding], ); @@ -404,42 +467,64 @@ private function createAuthenticationStatement(string $id): AuthenticationStatem */ private function createAttributeStatement(string $id): AttributeStatement { - $scd = new SubjectConfirmationData(2); + $scd = new SubjectConfirmationData( + IntegerValue::fromString('2'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - $id, + IDValue::fromString($id), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + SAMLStringValue::fromString('TheNameIDValue'), + SAMLStringValue::fromString('TheNameQualifier'), + SAMLAnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); $attribute = new Attribute( - 'TheName', - 'https://example.org/', - [new AttributeValue('FirstValue'), new AttributeValue('SecondValue')], + SAMLStringValue::fromString('TheName'), + SAMLAnyURIValue::fromString('https://example.org/'), + [ + new AttributeValue( + SAMLStringValue::fromString('FirstValue'), + ), + new AttributeValue( + SAMLStringValue::fromString('SecondValue'), + ), + ], ); return new AttributeStatement( diff --git a/tests/src/SAML11/XML/saml/AttributeDesignatorTest.php b/tests/src/SAML11/XML/saml/AttributeDesignatorTest.php index 9347049..6b69041 100644 --- a/tests/src/SAML11/XML/saml/AttributeDesignatorTest.php +++ b/tests/src/SAML11/XML/saml/AttributeDesignatorTest.php @@ -4,14 +4,12 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\AbstractAttributeDesignatorType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\AttributeDesignator; +use SimpleSAML\SAML11\XML\saml\{AbstractAttributeDesignatorType, AbstractSamlElement, AttributeDesignator}; +use SimpleSAML\SAML11\Type\{AnyURIValue, StringValue}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -21,6 +19,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(AttributeDesignator::class)] #[CoversClass(AbstractAttributeDesignatorType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -34,8 +33,6 @@ final class AttributeDesignatorTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = AttributeDesignator::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -52,8 +49,8 @@ public static function setUpBeforeClass(): void public function testMarshalling(): void { $attributeDesignator = new AttributeDesignator( - 'TheName', - 'https://example.org/', + StringValue::fromString('TheName'), + AnyURIValue::fromString('https://example.org/'), ); $this->assertEquals( diff --git a/tests/src/SAML11/XML/saml/AttributeStatementTest.php b/tests/src/SAML11/XML/saml/AttributeStatementTest.php index 377af2b..33b5f30 100644 --- a/tests/src/SAML11/XML/saml/AttributeStatementTest.php +++ b/tests/src/SAML11/XML/saml/AttributeStatementTest.php @@ -4,29 +4,36 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; +use SimpleSAML\SAML11\Type\{ + AnyURIValue as SAMLAnyURIValue, + StringValue as SAMLStringValue, +}; use SimpleSAML\SAML11\Utils\XPath; -use SimpleSAML\SAML11\XML\saml\AbstractAttributeStatementType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\Attribute; -use SimpleSAML\SAML11\XML\saml\AttributeStatement; -use SimpleSAML\SAML11\XML\saml\AttributeValue; -use SimpleSAML\SAML11\XML\saml\ConfirmationMethod; -use SimpleSAML\SAML11\XML\saml\NameIdentifier; -use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmation; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmationData; -use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\SAML11\XML\saml\{ + AbstractAttributeStatementType, + AbstractSamlElement, + Attribute, + AttributeStatement, + AttributeValue, + ConfirmationMethod, + NameIdentifier, + Subject, + SubjectConfirmation, + SubjectConfirmationData, +}; +use SimpleSAML\XML\{Chunk, DOMDocumentFactory}; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\{Base64BinaryValue, IDValue, IntegerValue, StringValue}; use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; -use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; -use SimpleSAML\XMLSecurity\XML\ds\KeyName; -use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; -use SimpleSAML\XMLSecurity\XML\ds\X509Data; -use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\ds\{ + KeyInfo, + KeyName, + X509Certificate, + X509Data, + X509SubjectName, +}; use function dirname; use function strval; @@ -36,6 +43,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(AttributeStatement::class)] #[CoversClass(AbstractAttributeStatementType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -55,8 +63,6 @@ final class AttributeStatementTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = AttributeStatement::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -97,42 +103,64 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $scd = new SubjectConfirmationData(2); + $scd = new SubjectConfirmationData( + IntegerValue::fromString('2'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - 'AttributeStatementID', + IDValue::fromString('AttributeStatementID'), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + SAMLStringValue::fromString('TheNameIDValue'), + SAMLStringValue::fromString('TheNameQualifier'), + SAMLAnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); $attribute = new Attribute( - 'TheName', - 'https://example.org/', - [new AttributeValue('FirstValue'), new AttributeValue('SecondValue')], + SAMLStringValue::fromString('TheName'), + SAMLAnyURIValue::fromString('https://example.org/'), + [ + new AttributeValue( + SAMLStringValue::fromString('FirstValue'), + ), + new AttributeValue( + SAMLStringValue::fromString('SecondValue'), + ), + ], ); $attributeStatement = new AttributeStatement( diff --git a/tests/src/SAML11/XML/saml/AttributeTest.php b/tests/src/SAML11/XML/saml/AttributeTest.php index 3e727a0..e1432f6 100644 --- a/tests/src/SAML11/XML/saml/AttributeTest.php +++ b/tests/src/SAML11/XML/saml/AttributeTest.php @@ -4,17 +4,19 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use DateTimeImmutable; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\AbstractAttributeDesignatorType; -use SimpleSAML\SAML11\XML\saml\AbstractAttributeType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\Attribute; -use SimpleSAML\SAML11\XML\saml\AttributeValue; +use SimpleSAML\SAML11\Type\{AnyURIValue, DateTimeValue, StringValue}; +use SimpleSAML\SAML11\XML\saml\{ + AbstractAttributeDesignatorType, + AbstractAttributeType, + AbstractSamlElement, + Attribute, + AttributeValue, +}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\IntegerValue; use function dirname; use function strval; @@ -24,6 +26,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(Attribute::class)] #[CoversClass(AttributeValue::class)] #[CoversClass(AbstractAttributeType::class)] @@ -39,8 +42,6 @@ final class AttributeTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = Attribute::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -57,13 +58,21 @@ public static function setUpBeforeClass(): void public function testMarshalling(): void { $attribute = new Attribute( - 'TheName', - 'https://example.org/', + StringValue::fromString('TheName'), + AnyURIValue::fromString('https://example.org/'), [ - new AttributeValue('FirstValue'), - new AttributeValue('SecondValue'), - new AttributeValue(3), - new AttributeValue(new DateTimeImmutable('2024-04-04T04:44:44Z')), + new AttributeValue( + StringValue::fromString('FirstValue'), + ), + new AttributeValue( + StringValue::fromString('SecondValue'), + ), + new AttributeValue( + IntegerValue::fromString('3'), + ), + new AttributeValue( + DateTimeValue::fromString('2024-04-04T04:44:44Z'), + ), ], ); diff --git a/tests/src/SAML11/XML/saml/AttributeValueTest.php b/tests/src/SAML11/XML/saml/AttributeValueTest.php index 74b1920..4420f52 100644 --- a/tests/src/SAML11/XML/saml/AttributeValueTest.php +++ b/tests/src/SAML11/XML/saml/AttributeValueTest.php @@ -4,16 +4,15 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use DateTimeImmutable; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\AttributeValue; -use SimpleSAML\SAML11\XML\saml\NameIdentifier; +use SimpleSAML\SAML11\Exception\ProtocolViolationException; +use SimpleSAML\SAML11\Type\{DateTimeValue, StringValue}; +use SimpleSAML\SAML11\XML\saml\{AbstractSamlElement, AttributeValue, NameIdentifier}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\IntegerValue; use TypeError; use function dirname; @@ -24,6 +23,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(AttributeValue::class)] #[CoversClass(AbstractSamlElement::class)] final class AttributeValueTest extends TestCase @@ -35,8 +35,6 @@ final class AttributeValueTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = AttributeValue::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -53,9 +51,10 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $av = new AttributeValue(2); - $this->assertIsInt($av->getValue()); - $this->assertEquals(2, $av->getValue()); + $av = new AttributeValue( + IntegerValue::fromString('2'), + ); + $this->assertEquals('2', $av->getValue()); $this->assertEquals('xs:integer', $av->getXsiType()); $this->assertEquals( @@ -70,7 +69,9 @@ public function testMarshalling(): void */ public function testMarshallingString(): void { - $av = new AttributeValue('value'); + $av = new AttributeValue( + StringValue::fromString('value'), + ); $this->assertEquals('value', $av->getValue()); $this->assertEquals('xs:string', $av->getXsiType()); @@ -82,9 +83,11 @@ public function testMarshallingString(): void */ public function testMarshallingInteger(): void { - $av = new AttributeValue(3); + $av = new AttributeValue( + IntegerValue::fromString('3'), + ); - $this->assertEquals(3, $av->getValue()); + $this->assertEquals('3', strval($av->getValue())); $this->assertEquals('xs:integer', $av->getXsiType()); $nssaml = C::NS_SAML; @@ -105,11 +108,12 @@ public function testMarshallingInteger(): void */ public function testMarshallingDateTime(): void { - $av = new AttributeValue(new DateTimeImmutable("2024-04-04T04:44:44Z")); + $av = new AttributeValue( + DateTimeValue::fromString("2024-04-04T04:44:44Z"), + ); - /** @var \DateTimeInterface $value */ $value = $av->getValue(); - $this->assertEquals('2024-04-04T04:44:44Z', $value->format(C::DATETIME_FORMAT)); + $this->assertEquals('2024-04-04T04:44:44Z', strval($value)); $this->assertEquals('xs:dateTime', $av->getXsiType()); $nssaml = C::NS_SAML; @@ -126,21 +130,12 @@ public function testMarshallingDateTime(): void /** - * Verifies that supplying an empty string as attribute value will - * generate a tag with no content (instead of e.g. an empty tag). - * + * Verifies that supplying an empty string as attribute value will throw an exception. */ public function testEmptyStringAttribute(): void { - $av = new AttributeValue(''); - $xmlRepresentation = clone self::$xmlRepresentation; - $xmlRepresentation->documentElement->textContent = ''; -// $this->assertEqualXMLStructure( -// $this->xmlRepresentation->documentElement, -// $av->toXML(), -// ); - $this->assertEquals('', $av->getValue()); - $this->assertEquals('xs:string', $av->getXsiType()); + $this->expectException(ProtocolViolationException::class); + new AttributeValue(StringValue::fromString('')); } @@ -163,7 +158,7 @@ public function testUnmarshallingNameID(): void $this->assertInstanceOf(NameIdentifier::class, $value); - $this->assertEquals('abcd-some-value-xyz', $value->getContent()); + $this->assertEquals('abcd-some-value-xyz', $value->getValue()); $this->assertEquals('urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified', $value->getFormat()); $this->assertXmlStringEqualsXmlString($document->saveXML(), $av->toXML()->ownerDocument?->saveXML()); } diff --git a/tests/src/SAML11/XML/saml/AudienceRestrictionConditionTest.php b/tests/src/SAML11/XML/saml/AudienceRestrictionConditionTest.php index 1765259..4eb599b 100644 --- a/tests/src/SAML11/XML/saml/AudienceRestrictionConditionTest.php +++ b/tests/src/SAML11/XML/saml/AudienceRestrictionConditionTest.php @@ -4,15 +4,17 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\AbstractAudienceRestrictionConditionType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\Audience; -use SimpleSAML\SAML11\XML\saml\AudienceRestrictionCondition; +use SimpleSAML\SAML11\Type\AnyURIValue; +use SimpleSAML\SAML11\XML\saml\{ + AbstractAudienceRestrictionConditionType, + AbstractSamlElement, + Audience, + AudienceRestrictionCondition, +}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -22,6 +24,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(AudienceRestrictionCondition::class)] #[CoversClass(AbstractAudienceRestrictionConditionType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -35,8 +38,6 @@ final class AudienceRestrictionConditionTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = AudienceRestrictionCondition::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -53,7 +54,9 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $audience = new Audience('urn:x-simplesamlphp:audience'); + $audience = new Audience( + AnyURIValue::fromString('urn:x-simplesamlphp:audience'), + ); $audienceRestrictionCondition = new AudienceRestrictionCondition([$audience]); $this->assertEquals( diff --git a/tests/src/SAML11/XML/saml/AudienceTest.php b/tests/src/SAML11/XML/saml/AudienceTest.php index ea83933..38da66f 100644 --- a/tests/src/SAML11/XML/saml/AudienceTest.php +++ b/tests/src/SAML11/XML/saml/AudienceTest.php @@ -4,13 +4,12 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\Audience; +use SimpleSAML\SAML11\Type\AnyURIValue; +use SimpleSAML\SAML11\XML\saml\{AbstractSamlElement, Audience}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -20,6 +19,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(Audience::class)] #[CoversClass(AbstractSamlElement::class)] final class AudienceTest extends TestCase @@ -32,8 +32,6 @@ final class AudienceTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = Audience::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -50,7 +48,9 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $audience = new Audience('urn:x-simplesamlphp:audience'); + $audience = new Audience( + AnyURIValue::fromString('urn:x-simplesamlphp:audience'), + ); $this->assertEquals( self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), diff --git a/tests/src/SAML11/XML/saml/AuthenticationStatementTest.php b/tests/src/SAML11/XML/saml/AuthenticationStatementTest.php index c575aa8..8430443 100644 --- a/tests/src/SAML11/XML/saml/AuthenticationStatementTest.php +++ b/tests/src/SAML11/XML/saml/AuthenticationStatementTest.php @@ -4,31 +4,38 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use DateTimeImmutable; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; use SimpleSAML\SAML11\Constants as C; +use SimpleSAML\SAML11\Type\{ + AnyURIValue as SAMLAnyURIValue, + DateTimeValue as SAMLDateTimeValue, + StringValue as SAMLStringValue, +}; use SimpleSAML\SAML11\Utils\XPath; -use SimpleSAML\SAML11\XML\saml\AbstractAuthenticationStatementType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\AuthenticationStatement; -use SimpleSAML\SAML11\XML\saml\AuthorityBinding; -use SimpleSAML\SAML11\XML\saml\ConfirmationMethod; -use SimpleSAML\SAML11\XML\saml\NameIdentifier; -use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmation; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmationData; -use SimpleSAML\SAML11\XML\saml\SubjectLocality; -use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\SAML11\XML\saml\{ + AbstractAuthenticationStatementType, + AbstractSamlElement, + AuthenticationStatement, + AuthorityBinding, + ConfirmationMethod, + NameIdentifier, + Subject, + SubjectConfirmation, + SubjectConfirmationData, + SubjectLocality, +}; +use SimpleSAML\XML\{Chunk, DOMDocumentFactory}; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\{Base64BinaryValue, IDValue, IntegerValue, QNameValue, StringValue}; use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; -use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; -use SimpleSAML\XMLSecurity\XML\ds\KeyName; -use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; -use SimpleSAML\XMLSecurity\XML\ds\X509Data; -use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\ds\{ + KeyInfo, + KeyName, + X509Certificate, + X509Data, + X509SubjectName, +}; use function dirname; use function strval; @@ -38,6 +45,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(AuthenticationStatement::class)] #[CoversClass(AbstractAuthenticationStatementType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -57,8 +65,6 @@ final class AuthenticationStatementTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = AuthenticationStatement::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -99,49 +105,68 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $scd = new SubjectConfirmationData(2); + $scd = new SubjectConfirmationData( + IntegerValue::fromString('2'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - 'AuthenticationStatementID', + IDValue::fromString('AuthenticationStatementID'), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + SAMLStringValue::fromString('TheNameIDValue'), + SAMLStringValue::fromString('TheNameQualifier'), + SAMLAnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); - $subjectLocality = new SubjectLocality('127.0.0.1', 'simplesamlphp.org'); + $subjectLocality = new SubjectLocality( + SAMLStringValue::fromString('127.0.0.1'), + SAMLStringValue::fromString('simplesamlphp.org'), + ); + $authorityBinding = new AuthorityBinding( - 'samlp:AttributeQuery', - 'urn:x-simplesamlphp:location', - 'urn:x-simplesamlphp:binding', + QNameValue::fromString('{' . C::NS_SAMLP . '}samlp:AttributeQuery'), + SAMLAnyURIValue::fromString('urn:x-simplesamlphp:location'), + SAMLAnyURIValue::fromString('urn:x-simplesamlphp:binding'), ); $authenticationStatement = new AuthenticationStatement( $subject, - C::AC_PASSWORD, - new DateTimeImmutable('2023-01-24T09:42:26Z'), + SAMLAnyURIValue::fromString(C::AC_PASSWORD), + SAMLDateTimeValue::fromString('2023-01-24T09:42:26Z'), $subjectLocality, [$authorityBinding], ); diff --git a/tests/src/SAML11/XML/saml/AuthorityBindingTest.php b/tests/src/SAML11/XML/saml/AuthorityBindingTest.php index deefe12..541fd7e 100644 --- a/tests/src/SAML11/XML/saml/AuthorityBindingTest.php +++ b/tests/src/SAML11/XML/saml/AuthorityBindingTest.php @@ -4,14 +4,14 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\AbstractAuthorityBindingType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\AuthorityBinding; +use SimpleSAML\SAML11\Constants as C; +use SimpleSAML\SAML11\Type\AnyURIValue; +use SimpleSAML\SAML11\XML\saml\{AbstractAuthorityBindingType, AbstractSamlElement, AuthorityBinding}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\{NCNameValue, QNameValue}; use function dirname; use function strval; @@ -21,6 +21,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(AuthorityBinding::class)] #[CoversClass(AbstractAuthorityBindingType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -34,8 +35,6 @@ final class AuthorityBindingTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = AuthorityBinding::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -53,9 +52,13 @@ public static function setUpBeforeClass(): void public function testMarshalling(): void { $ab = new AuthorityBinding( - 'samlp:AttributeQuery', - 'urn:x-simplesamlphp:location', - 'urn:x-simplesamlphp:binding', + QNameValue::fromParts( + NCNameValue::fromString('AttributeQuery'), + AnyURIValue::fromString(C::NS_SAMLP), + NCNameValue::fromString('samlp'), + ), + AnyURIValue::fromString('urn:x-simplesamlphp:location'), + AnyURIValue::fromString('urn:x-simplesamlphp:binding'), ); $this->assertEquals( diff --git a/tests/src/SAML11/XML/saml/AuthorizationDecisionStatementTest.php b/tests/src/SAML11/XML/saml/AuthorizationDecisionStatementTest.php index 268530c..5336d31 100644 --- a/tests/src/SAML11/XML/saml/AuthorizationDecisionStatementTest.php +++ b/tests/src/SAML11/XML/saml/AuthorizationDecisionStatementTest.php @@ -5,23 +5,22 @@ namespace SimpleSAML\Test\SAML11\XML\saml; use DOMDocument; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\Compat\AbstractContainer; -use SimpleSAML\SAML11\Compat\ContainerSingleton; -use SimpleSAML\SAML11\XML\saml\AbstractAuthorizationDecisionStatementType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\Action; -use SimpleSAML\SAML11\XML\saml\AuthorizationDecisionStatement; -use SimpleSAML\SAML11\XML\saml\DecisionTypeEnum; -use SimpleSAML\SAML11\XML\saml\Evidence; -use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\Test\SAML11\CustomCondition; -use SimpleSAML\Test\SAML11\CustomStatement; -use SimpleSAML\Test\SAML11\CustomSubjectStatement; +use SimpleSAML\SAML11\Compat\{AbstractContainer, ContainerSingleton}; +use SimpleSAML\SAML11\Type\AnyURIValue; +use SimpleSAML\SAML11\XML\saml\{ + AbstractAuthorizationDecisionStatementType, + AbstractSamlElement, + Action, + AuthorizationDecisionStatement, + DecisionTypeEnum, + Evidence, + Subject, +}; +use SimpleSAML\Test\SAML11\{CustomCondition, CustomStatement, CustomSubjectStatement}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -31,6 +30,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(AuthorizationDecisionStatement::class)] #[CoversClass(AbstractAuthorizationDecisionStatementType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -115,7 +115,7 @@ public function testMarshalling(): void $authzDecisionStatement = new AuthorizationDecisionStatement( $subject, - 'urn:x-simplesamlphp:resource', + AnyURIValue::fromString('urn:x-simplesamlphp:resource'), DecisionTypeEnum::Permit, [$action], $evidence, diff --git a/tests/src/SAML11/XML/saml/ConditionTest.php b/tests/src/SAML11/XML/saml/ConditionTest.php index 3996907..bd2f79d 100644 --- a/tests/src/SAML11/XML/saml/ConditionTest.php +++ b/tests/src/SAML11/XML/saml/ConditionTest.php @@ -4,20 +4,21 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\Compat\AbstractContainer; -use SimpleSAML\SAML11\Compat\ContainerSingleton; +use SimpleSAML\SAML11\Compat\{AbstractContainer, ContainerSingleton}; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\AbstractCondition; -use SimpleSAML\SAML11\XML\saml\AbstractConditionType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\Audience; -use SimpleSAML\SAML11\XML\saml\UnknownCondition; +use SimpleSAML\SAML11\Type\AnyURIValue; +use SimpleSAML\SAML11\XML\saml\{ + AbstractCondition, + AbstractConditionType, + AbstractSamlElement, + Audience, + UnknownCondition, +}; use SimpleSAML\Test\SAML11\CustomCondition; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -27,6 +28,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(UnknownCondition::class)] #[CoversClass(AbstractCondition::class)] #[CoversClass(AbstractConditionType::class)] @@ -77,7 +79,11 @@ public static function tearDownAfterClass(): void public function testMarshalling(): void { $condition = new CustomCondition( - [new Audience('urn:some:audience')], + [ + new Audience( + AnyURIValue::fromString('urn:some:audience'), + ), + ], ); $this->assertEquals( @@ -100,7 +106,10 @@ public function testUnmarshallingUnregistered(): void $condition = AbstractCondition::fromXML($element); $this->assertInstanceOf(UnknownCondition::class, $condition); - $this->assertEquals('urn:x-simplesamlphp:namespace:UnknownConditionType', $condition->getXsiType()); + $this->assertEquals( + '{urn:x-simplesamlphp:namespace}ssp:UnknownConditionType', + $condition->getXsiType()->getRawValue(), + ); $chunk = $condition->getRawCondition(); $this->assertEquals('saml', $chunk->getPrefix()); diff --git a/tests/src/SAML11/XML/saml/ConditionsTest.php b/tests/src/SAML11/XML/saml/ConditionsTest.php index 57a9bc4..91ede79 100644 --- a/tests/src/SAML11/XML/saml/ConditionsTest.php +++ b/tests/src/SAML11/XML/saml/ConditionsTest.php @@ -4,20 +4,21 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use DateTimeImmutable; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\AbstractConditionsType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\Audience; -use SimpleSAML\SAML11\XML\saml\AudienceRestrictionCondition; -use SimpleSAML\SAML11\XML\saml\Conditions; -use SimpleSAML\SAML11\XML\saml\DoNotCacheCondition; +use SimpleSAML\SAML11\Type\{AnyURIValue, DateTimeValue}; +use SimpleSAML\SAML11\XML\saml\{ + AbstractConditionsType, + AbstractSamlElement, + Audience, + AudienceRestrictionCondition, + Conditions, + DoNotCacheCondition, +}; use SimpleSAML\Test\SAML11\CustomCondition; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -27,6 +28,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(Conditions::class)] #[CoversClass(AbstractConditionsType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -58,21 +60,27 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $audience = new Audience('urn:x-simplesamlphp:audience'); + $audience = new Audience( + AnyURIValue::fromString('urn:x-simplesamlphp:audience'), + ); $audienceRestrictionCondition = new AudienceRestrictionCondition([$audience]); $doNotCacheCondition = new DoNotCacheCondition(); $condition = new CustomCondition( - [new Audience('urn:some:audience')], + [ + new Audience( + AnyURIValue::fromString('urn:some:audience'), + ), + ], ); $conditions = new Conditions( [$audienceRestrictionCondition], [$doNotCacheCondition], [$condition], - new DateTimeImmutable('2023-01-24T09:42:26Z'), - new DateTimeImmutable('2023-01-24T09:47:26Z'), + DateTimeValue::fromString('2023-01-24T09:42:26Z'), + DateTimeValue::fromString('2023-01-24T09:47:26Z'), ); $this->assertEquals( diff --git a/tests/src/SAML11/XML/saml/ConfirmationMethodTest.php b/tests/src/SAML11/XML/saml/ConfirmationMethodTest.php index 842c29b..81317f1 100644 --- a/tests/src/SAML11/XML/saml/ConfirmationMethodTest.php +++ b/tests/src/SAML11/XML/saml/ConfirmationMethodTest.php @@ -4,13 +4,12 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\ConfirmationMethod; +use SimpleSAML\SAML11\Type\AnyURIValue; +use SimpleSAML\SAML11\XML\saml\{AbstractSamlElement, ConfirmationMethod}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -20,6 +19,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(ConfirmationMethod::class)] #[CoversClass(AbstractSamlElement::class)] final class ConfirmationMethodTest extends TestCase @@ -31,8 +31,6 @@ final class ConfirmationMethodTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = ConfirmationMethod::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -45,7 +43,9 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $confirmationMethod = new ConfirmationMethod('_Test'); + $confirmationMethod = new ConfirmationMethod( + AnyURIValue::fromString('_Test'), + ); $this->assertEquals( self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), diff --git a/tests/src/SAML11/XML/saml/DoNotCacheConditionTest.php b/tests/src/SAML11/XML/saml/DoNotCacheConditionTest.php index 1982e2c..255ee58 100644 --- a/tests/src/SAML11/XML/saml/DoNotCacheConditionTest.php +++ b/tests/src/SAML11/XML/saml/DoNotCacheConditionTest.php @@ -4,14 +4,15 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\AbstractDoNotCacheConditionType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\DoNotCacheCondition; +use SimpleSAML\SAML11\XML\saml\{ + AbstractDoNotCacheConditionType, + AbstractSamlElement, + DoNotCacheCondition, +}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -21,6 +22,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(DoNotCacheCondition::class)] #[CoversClass(AbstractDoNotCacheConditionType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -34,8 +36,6 @@ final class DoNotCacheConditionTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = DoNotCacheCondition::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( diff --git a/tests/src/SAML11/XML/saml/EvidenceTest.php b/tests/src/SAML11/XML/saml/EvidenceTest.php index b1db10a..f4ea136 100644 --- a/tests/src/SAML11/XML/saml/EvidenceTest.php +++ b/tests/src/SAML11/XML/saml/EvidenceTest.php @@ -4,36 +4,57 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use DateTimeImmutable; use DOMDocument; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\Compat\AbstractContainer; -use SimpleSAML\SAML11\Compat\ContainerSingleton; +use SimpleSAML\SAML11\Compat\{AbstractContainer, ContainerSingleton}; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\AbstractEvidenceType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\AbstractStatement; -//use SimpleSAML\SAML11\XML\saml\Advice; -use SimpleSAML\SAML11\XML\saml\Assertion; -use SimpleSAML\SAML11\XML\saml\AssertionIDReference; -use SimpleSAML\SAML11\XML\saml\{Attribute, AttributeStatement, AttributeValue}; -use SimpleSAML\SAML11\XML\saml\Audience; -use SimpleSAML\SAML11\XML\saml\AuthenticationStatement; -//use SimpleSAML\SAML11\XML\saml\AuthorizationDecisionStatement; -use SimpleSAML\SAML11\XML\saml\AuthorityBinding; -use SimpleSAML\SAML11\XML\saml\Conditions; -use SimpleSAML\SAML11\XML\saml\Evidence; -use SimpleSAML\SAML11\XML\saml\ConfirmationMethod; -use SimpleSAML\SAML11\XML\saml\NameIdentifier; +use SimpleSAML\SAML11\Type\{ + AnyURIValue as SAMLAnyURIValue, + DateTimeValue as SAMLDateTimeValue, + StringValue as SAMLStringValue, +}; +use SimpleSAML\SAML11\XML\saml\{ + AbstractEvidenceType, + AbstractSamlElement, + AbstractStatement, + //Advice, + Assertion, + AssertionIDReference, + Attribute, + AttributeStatement, + AttributeValue, + Audience, + AuthenticationStatement, + //AuthorizationDecisionStatement, + AuthorityBinding, + Conditions, + ConfirmationMethod, + Evidence, + NameIdentifier, +}; use SimpleSAML\SAML11\XML\saml\{Subject, SubjectConfirmation, SubjectConfirmationData, SubjectLocality}; use SimpleSAML\Test\SAML11\{CustomCondition, CustomStatement, CustomSubjectStatement}; -use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\DOMDocumentFactory; +use SimpleSAML\XML\{Chunk, DOMDocumentFactory}; use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\{ + Base64BinaryValue, + IDValue, + IntegerValue, + NCNameValue, + NonNegativeIntegerValue, + QNameValue, + StringValue, +}; use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; -use SimpleSAML\XMLSecurity\XML\ds\{KeyInfo, KeyName}; -use SimpleSAML\XMLSecurity\XML\ds\{X509Certificate, X509CertificateName, X509Data, X509SubjectName}; +use SimpleSAML\XMLSecurity\XML\ds\{ + KeyInfo, + KeyName, + X509Certificate, + X509CertificateName, + X509Data, + X509SubjectName, +}; use function dirname; use function strval; @@ -43,6 +64,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(Evidence::class)] #[CoversClass(AbstractEvidenceType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -161,12 +183,16 @@ public function testMarshalling(): void // Create AttributeStatement $attributeStatement = $this->createAttributeStatement('EvidenceAttributeStatementID'); - $assertionIDReference = new AssertionIDReference('_Test'); + $assertionIDReference = new AssertionIDReference( + NCNameValue::fromString('_Test'), + ); $assertion = new Assertion( - 'EvidenceAssertionID', - 'urn:x-simplesamlphp:phpunit', - new DateTimeImmutable('2023-01-24T09:42:26Z'), + NonNegativeIntegerValue::fromString('1'), + NonNegativeIntegerValue::fromString('1'), + IDValue::fromString('EvidenceAssertionID'), + SAMLStringValue::fromString('urn:x-simplesamlphp:phpunit'), + SAMLDateTimeValue::fromString('2023-01-24T09:42:26Z'), Conditions::fromXML(self::$conditions->documentElement), null, // advice [ @@ -194,38 +220,57 @@ public function testMarshalling(): void private function createSubjectStatement(string $id): CustomSubjectStatement { // Create SubjectStatement - $scd = new SubjectConfirmationData(2); + $scd = new SubjectConfirmationData( + IntegerValue::fromString('2'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - $id, + IDValue::fromString($id), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + SAMLStringValue::fromString('TheNameIDValue'), + SAMLStringValue::fromString('TheNameQualifier'), + SAMLAnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); - $audience = new Audience('urn:x-simplesamlphp:audience'); + + $audience = new Audience( + SAMLAnyURIValue::fromString('urn:x-simplesamlphp:audience'), + ); + return new CustomSubjectStatement($subject, [$audience]); } @@ -236,49 +281,69 @@ private function createSubjectStatement(string $id): CustomSubjectStatement */ private function createAuthenticationStatement(string $id): AuthenticationStatement { - $scd = new SubjectConfirmationData(2); + // Create AuthenticationStatement + $scd = new SubjectConfirmationData( + IntegerValue::fromString('2'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - $id, + IDValue::fromString($id), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + SAMLStringValue::fromString('TheNameIDValue'), + SAMLStringValue::fromString('TheNameQualifier'), + SAMLAnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); - $subjectLocality = new SubjectLocality('127.0.0.1', 'simplesamlphp.org'); + $subjectLocality = new SubjectLocality( + SAMLStringValue::fromString('127.0.0.1'), + SAMLStringValue::fromString('simplesamlphp.org'), + ); + $authorityBinding = new AuthorityBinding( - 'samlp:AttributeQuery', - 'urn:x-simplesamlphp:location', - 'urn:x-simplesamlphp:binding', + QNameValue::fromString('{' . C::NS_SAMLP . '}samlp:AttributeQuery'), + SAMLAnyURIValue::fromString('urn:x-simplesamlphp:location'), + SAMLAnyURIValue::fromString('urn:x-simplesamlphp:binding'), ); return new AuthenticationStatement( $subject, - C::AC_PASSWORD, - new DateTimeImmutable('2023-01-24T09:42:26Z'), + SAMLAnyURIValue::fromString(C::AC_PASSWORD), + SAMLDateTimeValue::fromString('2023-01-24T09:42:26Z'), $subjectLocality, [$authorityBinding], ); @@ -291,42 +356,65 @@ private function createAuthenticationStatement(string $id): AuthenticationStatem */ private function createAttributeStatement(string $id): AttributeStatement { - $scd = new SubjectConfirmationData(2); + // Create AttributeStatement + $scd = new SubjectConfirmationData( + IntegerValue::fromString('2'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - $id, + IDValue::fromString($id), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + SAMLStringValue::fromString('TheNameIDValue'), + SAMLStringValue::fromString('TheNameQualifier'), + SAMLAnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); $attribute = new Attribute( - 'TheName', - 'https://example.org/', - [new AttributeValue('FirstValue'), new AttributeValue('SecondValue')], + SAMLStringValue::fromString('TheName'), + SAMLAnyURIValue::fromString('https://example.org/'), + [ + new AttributeValue( + SAMLStringValue::fromString('FirstValue'), + ), + new AttributeValue( + SAMLStringValue::fromString('SecondValue'), + ), + ], ); return new AttributeStatement( diff --git a/tests/src/SAML11/XML/saml/NameIdentifierTest.php b/tests/src/SAML11/XML/saml/NameIdentifierTest.php index 94f4726..6ab8f64 100644 --- a/tests/src/SAML11/XML/saml/NameIdentifierTest.php +++ b/tests/src/SAML11/XML/saml/NameIdentifierTest.php @@ -4,14 +4,12 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\AbstractNameIdentifierType; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\NameIdentifier; +use SimpleSAML\SAML11\Type\{AnyURIValue, StringValue}; +use SimpleSAML\SAML11\XML\saml\{AbstractNameIdentifierType, AbstractSamlElement, NameIdentifier}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -21,6 +19,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(NameIdentifier::class)] #[CoversClass(AbstractNameIdentifierType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -34,8 +33,6 @@ final class NameIdentifierTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = NameIdentifier::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -52,9 +49,9 @@ public static function setUpBeforeClass(): void public function testMarshalling(): void { $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + StringValue::fromString('TheNameIDValue'), + StringValue::fromString('TheNameQualifier'), + AnyURIValue::fromString('urn:the:format'), ); $this->assertEquals( diff --git a/tests/src/SAML11/XML/saml/StatementTest.php b/tests/src/SAML11/XML/saml/StatementTest.php index aa9653b..aae7ca2 100644 --- a/tests/src/SAML11/XML/saml/StatementTest.php +++ b/tests/src/SAML11/XML/saml/StatementTest.php @@ -4,20 +4,21 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\Compat\AbstractContainer; -use SimpleSAML\SAML11\Compat\ContainerSingleton; +use SimpleSAML\SAML11\Compat\{AbstractContainer, ContainerSingleton}; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\AbstractStatement; -use SimpleSAML\SAML11\XML\saml\AbstractStatementType; -use SimpleSAML\SAML11\XML\saml\Audience; -use SimpleSAML\SAML11\XML\saml\UnknownStatement; +use SimpleSAML\SAML11\Type\AnyURIValue; +use SimpleSAML\SAML11\XML\saml\{ + AbstractSamlElement, + AbstractStatement, + AbstractStatementType, + Audience, + UnknownStatement, +}; use SimpleSAML\Test\SAML11\CustomStatement; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -27,6 +28,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(UnknownStatement::class)] #[CoversClass(AbstractStatement::class)] #[CoversClass(AbstractStatementType::class)] @@ -77,7 +79,11 @@ public static function tearDownAfterClass(): void public function testMarshalling(): void { $statement = new CustomStatement( - [new Audience('urn:some:audience')], + [ + new Audience( + AnyURIValue::fromString('urn:some:audience'), + ), + ], ); $this->assertEquals( @@ -120,7 +126,10 @@ public function testUnmarshallingUnregistered(): void $statement = AbstractStatement::fromXML($element); $this->assertInstanceOf(UnknownStatement::class, $statement); - $this->assertEquals('urn:x-simplesamlphp:namespace:UnknownStatementType', $statement->getXsiType()); + $this->assertEquals( + '{urn:x-simplesamlphp:namespace}ssp:UnknownStatementType', + $statement->getXsiType()->getRawValue(), + ); $chunk = $statement->getRawStatement(); $this->assertEquals('saml', $chunk->getPrefix()); diff --git a/tests/src/SAML11/XML/saml/SubjectConfirmationDataTest.php b/tests/src/SAML11/XML/saml/SubjectConfirmationDataTest.php index 439e064..d8d306a 100644 --- a/tests/src/SAML11/XML/saml/SubjectConfirmationDataTest.php +++ b/tests/src/SAML11/XML/saml/SubjectConfirmationDataTest.php @@ -4,15 +4,15 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\NameIdentifier; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmationData; +use SimpleSAML\SAML11\Exception\ProtocolViolationException; +use SimpleSAML\SAML11\Type\StringValue; +use SimpleSAML\SAML11\XML\saml\{AbstractSamlElement, NameIdentifier, SubjectConfirmationData}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\IntegerValue; use function dirname; use function strval; @@ -22,6 +22,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(SubjectConfirmationData::class)] #[CoversClass(AbstractSamlElement::class)] final class SubjectConfirmationDataTest extends TestCase @@ -33,8 +34,6 @@ final class SubjectConfirmationDataTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = SubjectConfirmationData::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -51,9 +50,11 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $scd = new SubjectConfirmationData(2); - $this->assertIsInt($scd->getValue()); - $this->assertEquals(2, $scd->getValue()); + $scd = new SubjectConfirmationData( + IntegerValue::fromString('2'), + ); + $this->assertInstanceOf(IntegerValue::class, $scd->getValue()); + $this->assertEquals('2', strval($scd->getValue())); $this->assertEquals('xs:integer', $scd->getXsiType()); $this->assertEquals( @@ -68,9 +69,12 @@ public function testMarshalling(): void */ public function testMarshallingString(): void { - $scd = new SubjectConfirmationData('value'); + $scd = new SubjectConfirmationData( + StringValue::fromString('value'), + ); - $this->assertEquals('value', $scd->getValue()); + $this->assertInstanceOf(StringValue::class, $scd->getValue()); + $this->assertEquals('value', strval($scd->getValue())); $this->assertEquals('xs:string', $scd->getXsiType()); } @@ -101,15 +105,10 @@ public function testMarshallingNull(): void */ public function testEmptyStringAttribute(): void { - $scd = new SubjectConfirmationData(''); - $xmlRepresentation = clone self::$xmlRepresentation; - $xmlRepresentation->documentElement->textContent = ''; -// $this->assertEqualXMLStructure( -// $this->xmlRepresentation->documentElement, -// $scd->toXML(), -// ); - $this->assertEquals('', $scd->getValue()); - $this->assertEquals('xs:string', $scd->getXsiType()); + $this->expectException(ProtocolViolationException::class); + new SubjectConfirmationData( + StringValue::fromString(''), + ); } @@ -132,7 +131,7 @@ public function testUnmarshallingNameID(): void $this->assertInstanceOf(NameIdentifier::class, $value); - $this->assertEquals('abcd-some-value-xyz', $value->getContent()); + $this->assertEquals('abcd-some-value-xyz', $value->getValue()); $this->assertEquals('urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified', $value->getFormat()); $this->assertXmlStringEqualsXmlString($document->saveXML(), $scd->toXML()->ownerDocument?->saveXML()); } diff --git a/tests/src/SAML11/XML/saml/SubjectConfirmationTest.php b/tests/src/SAML11/XML/saml/SubjectConfirmationTest.php index 2854a27..f358acb 100644 --- a/tests/src/SAML11/XML/saml/SubjectConfirmationTest.php +++ b/tests/src/SAML11/XML/saml/SubjectConfirmationTest.php @@ -4,23 +4,27 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\AbstractSubjectConfirmationType; -use SimpleSAML\SAML11\XML\saml\ConfirmationMethod; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmation; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmationData; -use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\SAML11\Type\AnyURIValue as SAMLAnyURIValue; +use SimpleSAML\SAML11\XML\saml\{ + AbstractSamlElement, + AbstractSubjectConfirmationType, + ConfirmationMethod, + SubjectConfirmation, + SubjectConfirmationData, +}; +use SimpleSAML\XML\{Chunk, DOMDocumentFactory}; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\{Base64BinaryValue, IDValue, IntegerValue, StringValue}; use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; -use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; -use SimpleSAML\XMLSecurity\XML\ds\KeyName; -use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; -use SimpleSAML\XMLSecurity\XML\ds\X509Data; -use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\ds\{ + KeyInfo, + KeyName, + X509Certificate, + X509Data, + X509SubjectName, +}; use function dirname; use function strval; @@ -30,6 +34,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(SubjectConfirmation::class)] #[CoversClass(AbstractSubjectConfirmationType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -49,8 +54,6 @@ final class SubjectConfirmationTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = SubjectConfirmation::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -91,26 +94,41 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $scd = new SubjectConfirmationData(2); + $scd = new SubjectConfirmationData( + IntegerValue::fromString('2'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - 'fed654', + IDValue::fromString('fed654'), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); diff --git a/tests/src/SAML11/XML/saml/SubjectLocalityTest.php b/tests/src/SAML11/XML/saml/SubjectLocalityTest.php index 210f964..dc2851e 100644 --- a/tests/src/SAML11/XML/saml/SubjectLocalityTest.php +++ b/tests/src/SAML11/XML/saml/SubjectLocalityTest.php @@ -4,14 +4,12 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\AbstractSubjectLocalityType; -use SimpleSAML\SAML11\XML\saml\SubjectLocality; +use SimpleSAML\SAML11\Type\StringValue; +use SimpleSAML\SAML11\XML\saml\{AbstractSamlElement, AbstractSubjectLocalityType, SubjectLocality}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -21,6 +19,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(SubjectLocality::class)] #[CoversClass(AbstractSubjectLocalityType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -34,8 +33,6 @@ final class SubjectLocalityTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = SubjectLocality::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -52,7 +49,10 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $sl = new SubjectLocality('127.0.0.1', 'simplesamlphp.org'); + $sl = new SubjectLocality( + StringValue::fromString('127.0.0.1'), + StringValue::fromString('simplesamlphp.org'), + ); $this->assertEquals( self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), diff --git a/tests/src/SAML11/XML/saml/SubjectStatementTest.php b/tests/src/SAML11/XML/saml/SubjectStatementTest.php index 3ce619b..515783d 100644 --- a/tests/src/SAML11/XML/saml/SubjectStatementTest.php +++ b/tests/src/SAML11/XML/saml/SubjectStatementTest.php @@ -4,32 +4,39 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\Compat\AbstractContainer; -use SimpleSAML\SAML11\Compat\ContainerSingleton; +use SimpleSAML\SAML11\Compat\{AbstractContainer, ContainerSingleton}; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\AbstractStatementType; -use SimpleSAML\SAML11\XML\saml\AbstractSubjectStatement; -use SimpleSAML\SAML11\XML\saml\AbstractSubjectStatementType; -use SimpleSAML\SAML11\XML\saml\Audience; -use SimpleSAML\SAML11\XML\saml\ConfirmationMethod; -use SimpleSAML\SAML11\XML\saml\NameIdentifier; -use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmation; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmationData; -use SimpleSAML\SAML11\XML\saml\UnknownSubjectStatement; +use SimpleSAML\SAML11\Type\{ + AnyURIValue as SAMLAnyURIValue, + StringValue as SAMLStringValue, +}; +use SimpleSAML\SAML11\XML\saml\{ + AbstractSamlElement, + AbstractStatementType, + AbstractSubjectStatement, + AbstractSubjectStatementType, + Audience, + ConfirmationMethod, + NameIdentifier, + Subject, + SubjectConfirmation, + SubjectConfirmationData, + UnknownSubjectStatement, +}; use SimpleSAML\Test\SAML11\CustomSubjectStatement; -use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\DOMDocumentFactory; +use SimpleSAML\XML\{Chunk, DOMDocumentFactory}; use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\Type\{Base64BinaryValue, IDValue, IntegerValue, StringValue}; use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; -use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; -use SimpleSAML\XMLSecurity\XML\ds\KeyName; -use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; -use SimpleSAML\XMLSecurity\XML\ds\X509Data; -use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\ds\{ + KeyInfo, + KeyName, + X509Certificate, + X509Data, + X509SubjectName, +}; use function dirname; use function strval; @@ -39,6 +46,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(AbstractSubjectStatement::class)] #[CoversClass(AbstractSubjectStatementType::class)] #[CoversClass(AbstractStatementType::class)] @@ -115,38 +123,55 @@ public static function tearDownAfterClass(): void */ public function testMarshalling(): void { - $scd = new SubjectConfirmationData(2); + $scd = new SubjectConfirmationData( + IntegerValue::fromString('2'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - 'SubjectStatementID', + IDValue::fromString('SubjectStatementID'), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + SAMLStringValue::fromString('TheNameIDValue'), + SAMLStringValue::fromString('TheNameQualifier'), + SAMLAnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); - $audience = new Audience('urn:x-simplesamlphp:audience'); + $audience = new Audience( + SAMLAnyURIValue::fromString('urn:x-simplesamlphp:audience'), + ); $subjectStatement = new CustomSubjectStatement($subject, [$audience]); $this->assertEquals( @@ -187,8 +212,8 @@ public function testUnmarshallingUnregistered(): void $this->assertInstanceOf(UnknownSubjectStatement::class, $subjectStatement); $this->assertEquals( - 'urn:x-simplesamlphp:namespace:UnknownSubjectStatementType', - $subjectStatement->getXsiType(), + '{urn:x-simplesamlphp:namespace}ssp:UnknownSubjectStatementType', + $subjectStatement->getXsiType()->getRawValue(), ); $chunk = $subjectStatement->getRawSubjectStatement(); diff --git a/tests/src/SAML11/XML/saml/SubjectTest.php b/tests/src/SAML11/XML/saml/SubjectTest.php index b4e8feb..81ee6ac 100644 --- a/tests/src/SAML11/XML/saml/SubjectTest.php +++ b/tests/src/SAML11/XML/saml/SubjectTest.php @@ -4,25 +4,32 @@ namespace SimpleSAML\Test\SAML11\XML\saml; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\AbstractSamlElement; -use SimpleSAML\SAML11\XML\saml\AbstractSubjectType; -use SimpleSAML\SAML11\XML\saml\ConfirmationMethod; -use SimpleSAML\SAML11\XML\saml\NameIdentifier; -use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmation; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmationData; -use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\SAML11\Type\{ + AnyURIValue as SAMLAnyURIValue, + StringValue as SAMLStringValue, +}; +use SimpleSAML\SAML11\XML\saml\{ + AbstractSamlElement, + AbstractSubjectType, + ConfirmationMethod, + NameIdentifier, + Subject, + SubjectConfirmation, + SubjectConfirmationData, +}; +use SimpleSAML\XML\{Chunk, DOMDocumentFactory}; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\{Base64BinaryValue, IDValue, IntegerValue, StringValue}; use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; -use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; -use SimpleSAML\XMLSecurity\XML\ds\KeyName; -use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; -use SimpleSAML\XMLSecurity\XML\ds\X509Data; -use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\ds\{ + KeyInfo, + KeyName, + X509Certificate, + X509Data, + X509SubjectName, +}; use function dirname; use function strval; @@ -32,6 +39,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('saml')] #[CoversClass(Subject::class)] #[CoversClass(AbstractSubjectType::class)] #[CoversClass(AbstractSamlElement::class)] @@ -51,8 +59,6 @@ final class SubjectTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-assertion-1.1.xsd'; - self::$testedClass = Subject::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -93,34 +99,49 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $scd = new SubjectConfirmationData(2); + $scd = new SubjectConfirmationData( + IntegerValue::fromString('2'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - 'fed654', + IDValue::fromString('fed654'), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + SAMLStringValue::fromString('TheNameIDValue'), + SAMLStringValue::fromString('TheNameQualifier'), + SAMLAnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); diff --git a/tests/src/SAML11/XML/samlp/AssertionArtifactTest.php b/tests/src/SAML11/XML/samlp/AssertionArtifactTest.php index 86750d2..5986016 100644 --- a/tests/src/SAML11/XML/samlp/AssertionArtifactTest.php +++ b/tests/src/SAML11/XML/samlp/AssertionArtifactTest.php @@ -4,13 +4,12 @@ namespace Simplesamlp\Test\SAML11\XML\samlp; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\samlp\AbstractSamlpElement; -use SimpleSAML\SAML11\XML\samlp\AssertionArtifact; +use SimpleSAML\SAML11\Type\StringValue; +use SimpleSAML\SAML11\XML\samlp\{AbstractSamlpElement, AssertionArtifact}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -20,6 +19,7 @@ * * @package simplesamlpphp/saml11 */ +#[Group('samlp')] #[CoversClass(AssertionArtifact::class)] #[CoversClass(AbstractSamlpElement::class)] final class AssertionArtifactTest extends TestCase @@ -32,8 +32,6 @@ final class AssertionArtifactTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-protocol-1.1.xsd'; - self::$testedClass = AssertionArtifact::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -50,7 +48,9 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $assertionArtifact = new AssertionArtifact('AAEbuqrPjR1XORIHk5YAV8I4sM0nKP2CLV+h1CMiWbnkaWvvlJ0g4Ess'); + $assertionArtifact = new AssertionArtifact( + StringValue::fromString('AAEbuqrPjR1XORIHk5YAV8I4sM0nKP2CLV+h1CMiWbnkaWvvlJ0g4Ess'), + ); $this->assertEquals( self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), diff --git a/tests/src/SAML11/XML/samlp/AttributeQueryTest.php b/tests/src/SAML11/XML/samlp/AttributeQueryTest.php index aac351b..6a27d4e 100644 --- a/tests/src/SAML11/XML/samlp/AttributeQueryTest.php +++ b/tests/src/SAML11/XML/samlp/AttributeQueryTest.php @@ -4,29 +4,38 @@ namespace SimpleSAML\Test\SAML11\XML\samlp; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\AttributeDesignator; -use SimpleSAML\SAML11\XML\saml\ConfirmationMethod; -use SimpleSAML\SAML11\XML\saml\NameIdentifier; -use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmation; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmationData; -use SimpleSAML\SAML11\XML\samlp\AbstractAttributeQueryType; -use SimpleSAML\SAML11\XML\samlp\AbstractQueryAbstractType; -use SimpleSAML\SAML11\XML\samlp\AbstractSamlpElement; -use SimpleSAML\SAML11\XML\samlp\AbstractSubjectQueryAbstractType; -use SimpleSAML\SAML11\XML\samlp\AttributeQuery; -use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\SAML11\Type\{ + AnyURIValue as SAMLAnyURIValue, + StringValue as SAMLStringValue, +}; +use SimpleSAML\SAML11\XML\saml\{ + AttributeDesignator, + ConfirmationMethod, + NameIdentifier, + Subject, + SubjectConfirmation, + SubjectConfirmationData, +}; +use SimpleSAML\SAML11\XML\samlp\{ + AbstractAttributeQueryType, + AbstractQueryAbstractType, + AbstractSamlpElement, + AbstractSubjectQueryAbstractType, + AttributeQuery, +}; +use SimpleSAML\XML\{Chunk, DOMDocumentFactory}; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\{Base64BinaryValue, IDValue, StringValue}; use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; -use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; -use SimpleSAML\XMLSecurity\XML\ds\KeyName; -use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; -use SimpleSAML\XMLSecurity\XML\ds\X509Data; -use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\ds\{ + KeyInfo, + KeyName, + X509Certificate, + X509Data, + X509SubjectName, +}; use function dirname; use function strval; @@ -36,6 +45,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('samlp')] #[CoversClass(AttributeQuery::class)] #[CoversClass(AbstractAttributeQueryType::class)] #[CoversClass(AbstractSubjectQueryAbstractType::class)] @@ -56,8 +66,6 @@ final class AttributeQueryTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-protocol-1.1.xsd'; - self::$testedClass = AttributeQuery::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -98,43 +106,64 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $scd = new SubjectConfirmationData('phpunit'); + $scd = new SubjectConfirmationData( + SAMLStringValue::fromString('phpunit'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - 'fed654', + IDValue::fromString('fed654'), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + SAMLStringValue::fromString('TheNameIDValue'), + SAMLStringValue::fromString('TheNameQualifier'), + SAMLAnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); $attributeQuery = new AttributeQuery( $subject, - 'urn:some:resource', + SAMLAnyURIValue::fromString('urn:some:resource'), [ - new AttributeDesignator('TheName', 'https://example.org/'), - new AttributeDesignator('TheOtherName', 'https://example.org/'), + new AttributeDesignator( + SAMLStringValue::fromString('TheName'), + SAMLAnyURIValue::fromString('https://example.org/'), + ), + new AttributeDesignator( + SAMLStringValue::fromString('TheOtherName'), + SAMLAnyURIValue::fromString('https://example.org/'), + ), ], ); diff --git a/tests/src/SAML11/XML/samlp/AuthenticationQueryTest.php b/tests/src/SAML11/XML/samlp/AuthenticationQueryTest.php index 5db861f..580c8e0 100644 --- a/tests/src/SAML11/XML/samlp/AuthenticationQueryTest.php +++ b/tests/src/SAML11/XML/samlp/AuthenticationQueryTest.php @@ -4,29 +4,38 @@ namespace SimpleSAML\Test\SAML11\XML\samlp; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\ConfirmationMethod; -use SimpleSAML\SAML11\XML\saml\NameIdentifier; -use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmation; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmationData; -use SimpleSAML\SAML11\XML\samlp\AbstractAuthenticationQueryType; -use SimpleSAML\SAML11\XML\samlp\AbstractQueryAbstractType; -use SimpleSAML\SAML11\XML\samlp\AbstractSamlpElement; -use SimpleSAML\SAML11\XML\samlp\AbstractSubjectQueryAbstractType; -use SimpleSAML\SAML11\XML\samlp\AuthenticationQuery; -use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\SAML11\Type\{ + AnyURIValue as SAMLAnyURIValue, + StringValue as SAMLStringValue, +}; +use SimpleSAML\SAML11\XML\saml\{ + ConfirmationMethod, + NameIdentifier, + Subject, + SubjectConfirmation, + SubjectConfirmationData, +}; +use SimpleSAML\SAML11\XML\samlp\{ + AbstractAuthenticationQueryType, + AbstractQueryAbstractType, + AbstractSamlpElement, + AbstractSubjectQueryAbstractType, + AuthenticationQuery, +}; +use SimpleSAML\XML\{Chunk, DOMDocumentFactory}; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\{Base64BinaryValue, IDValue, StringValue}; use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; -use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; -use SimpleSAML\XMLSecurity\XML\ds\KeyName; -use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; -use SimpleSAML\XMLSecurity\XML\ds\X509Data; -use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\ds\{ + KeyInfo, + KeyName, + X509Certificate, + X509Data, + X509SubjectName, +}; use function dirname; use function strval; @@ -36,6 +45,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('samlp')] #[CoversClass(AuthenticationQuery::class)] #[CoversClass(AbstractAuthenticationQueryType::class)] #[CoversClass(AbstractSubjectQueryAbstractType::class)] @@ -56,8 +66,6 @@ final class AuthenticationQueryTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-protocol-1.1.xsd'; - self::$testedClass = AuthenticationQuery::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -98,40 +106,55 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $scd = new SubjectConfirmationData('phpunit'); + $scd = new SubjectConfirmationData( + SAMLStringValue::fromString('phpunit'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - 'fed654', + IDValue::fromString('fed654'), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + SAMLStringValue::fromString('TheNameIDValue'), + SAMLStringValue::fromString('TheNameQualifier'), + SAMLAnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); $authnQuery = new AuthenticationQuery( $subject, - C::AC_PASSWORD, + SAMLAnyURIValue::fromString(C::AC_PASSWORD), ); $this->assertEquals( diff --git a/tests/src/SAML11/XML/samlp/AuthorizationDecisionQueryTest.php b/tests/src/SAML11/XML/samlp/AuthorizationDecisionQueryTest.php index c573c42..936e7cb 100644 --- a/tests/src/SAML11/XML/samlp/AuthorizationDecisionQueryTest.php +++ b/tests/src/SAML11/XML/samlp/AuthorizationDecisionQueryTest.php @@ -4,40 +4,55 @@ namespace SimpleSAML\Test\SAML11\XML\samlp; -use DateTimeImmutable; use DOMDocument; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\saml\Action; -use SimpleSAML\SAML11\XML\saml\Assertion; -use SimpleSAML\SAML11\XML\saml\AssertionIDReference; -use SimpleSAML\SAML11\XML\saml\AttributeStatement; -use SimpleSAML\SAML11\XML\saml\Audience; -use SimpleSAML\SAML11\XML\saml\AudienceRestrictionCondition; -use SimpleSAML\SAML11\XML\saml\AuthenticationStatement; -use SimpleSAML\SAML11\XML\saml\Conditions; -use SimpleSAML\SAML11\XML\saml\ConfirmationMethod; -use SimpleSAML\SAML11\XML\saml\DoNotCacheCondition; -use SimpleSAML\SAML11\XML\saml\Evidence; -use SimpleSAML\SAML11\XML\saml\NameIdentifier; -use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmation; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmationData; -use SimpleSAML\SAML11\XML\samlp\AbstractAuthorizationDecisionQueryType; -use SimpleSAML\SAML11\XML\samlp\AbstractQueryAbstractType; -use SimpleSAML\SAML11\XML\samlp\AbstractSamlpElement; -use SimpleSAML\SAML11\XML\samlp\AbstractSubjectQueryAbstractType; -use SimpleSAML\SAML11\XML\samlp\AuthorizationDecisionQuery; -use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\SAML11\Type\{ + AnyURIValue as SAMLAnyURIValue, + DateTimeValue as SAMLDateTimeValue, + StringValue as SAMLStringValue, +}; +use SimpleSAML\SAML11\XML\saml\{ + Action, + Assertion, + AssertionIDReference, + AttributeStatement, + Audience, + AudienceRestrictionCondition, + AuthenticationStatement, + Conditions, + ConfirmationMethod, + DoNotCacheCondition, + Evidence, + NameIdentifier, + Subject, + SubjectConfirmation, + SubjectConfirmationData, +}; +use SimpleSAML\SAML11\XML\samlp\{ + AbstractAuthorizationDecisionQueryType, + AbstractQueryAbstractType, + AbstractSamlpElement, + AbstractSubjectQueryAbstractType, + AuthorizationDecisionQuery, +}; +use SimpleSAML\XML\{Chunk, DOMDocumentFactory}; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\{ + Base64BinaryValue, + IDValue, + NCNameValue, + NonNegativeIntegerValue, + StringValue, +}; use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; -use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; -use SimpleSAML\XMLSecurity\XML\ds\KeyName; -use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; -use SimpleSAML\XMLSecurity\XML\ds\X509Data; -use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\ds\{ + KeyInfo, + KeyName, + X509Certificate, + X509Data, + X509SubjectName, +}; use function dirname; use function strval; @@ -47,6 +62,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('samlp')] #[CoversClass(AuthorizationDecisionQuery::class)] #[CoversClass(AbstractAuthorizationDecisionQueryType::class)] #[CoversClass(AbstractSubjectQueryAbstractType::class)] @@ -85,8 +101,6 @@ final class AuthorizationDecisionQueryTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-protocol-1.1.xsd'; - self::$testedClass = AuthorizationDecisionQuery::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -151,41 +165,60 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $scd = new SubjectConfirmationData('phpunit'); + $scd = new SubjectConfirmationData( + SAMLStringValue::fromString('phpunit'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - 'fed654', + IDValue::fromString('fed654'), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + SAMLAnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + SAMLStringValue::fromString('TheNameIDValue'), + SAMLStringValue::fromString('TheNameQualifier'), + SAMLAnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); - $assertionIDReference = new AssertionIDReference('_Test'); + $assertionIDReference = new AssertionIDReference( + NCNameValue::fromString('_Test'), + ); - $audience = new Audience('urn:x-simplesamlphp:audience'); + $audience = new Audience( + SAMLAnyURIValue::fromString('urn:x-simplesamlphp:audience'), + ); $audienceRestrictionCondition = new AudienceRestrictionCondition([$audience]); $doNotCacheCondition = new DoNotCacheCondition(); @@ -194,14 +227,16 @@ public function testMarshalling(): void [$audienceRestrictionCondition], [$doNotCacheCondition], [], - new DateTimeImmutable('2023-01-24T09:42:26Z'), - new DateTimeImmutable('2023-01-24T09:47:26Z'), + SAMLDateTimeValue::fromString('2023-01-24T09:42:26Z'), + SAMLDateTimeValue::fromString('2023-01-24T09:47:26Z'), ); $assertion = new Assertion( - '_abc123', - 'urn:x-simplesamlphp:phpunit', - new DateTimeImmutable('2023-01-24T09:42:26Z'), + NonNegativeIntegerValue::fromString('1'), + NonNegativeIntegerValue::fromString('1'), + IDValue::fromString('_abc123'), + SAMLStringValue::fromString('urn:x-simplesamlphp:phpunit'), + SAMLDateTimeValue::fromString('2023-01-24T09:42:26Z'), $conditions, null, // advice [ @@ -214,10 +249,13 @@ public function testMarshalling(): void $authorizationDecisionQuery = new AuthorizationDecisionQuery( $subject, - 'urn:some:resource', + SAMLAnyURIValue::fromString('urn:some:resource'), $evidence, [ - new Action('urn:x-simplesamlphp:action', 'urn:x-simplesamlphp:namespace'), + new Action( + SAMLStringValue::fromString('urn:x-simplesamlphp:action'), + SAMLAnyURIValue::fromString('urn:x-simplesamlphp:namespace'), + ), ], ); diff --git a/tests/src/SAML11/XML/samlp/QueryTest.php b/tests/src/SAML11/XML/samlp/QueryTest.php index f46b7f1..7c2762d 100644 --- a/tests/src/SAML11/XML/samlp/QueryTest.php +++ b/tests/src/SAML11/XML/samlp/QueryTest.php @@ -4,21 +4,21 @@ namespace SimpleSAML\Test\SAML11\XML\samlp; -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\Compat\AbstractContainer; -use SimpleSAML\SAML11\Compat\ContainerSingleton; +use SimpleSAML\SAML11\Compat\{AbstractContainer, ContainerSingleton}; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\samlp\AbstractQuery; -use SimpleSAML\SAML11\XML\samlp\AbstractQueryAbstractType; -use SimpleSAML\SAML11\XML\samlp\AbstractSamlpElement; -use SimpleSAML\SAML11\XML\samlp\StatusMessage; -use SimpleSAML\SAML11\XML\samlp\UnknownQuery; +use SimpleSAML\SAML11\Type\StringValue; +use SimpleSAML\SAML11\XML\samlp\{ + AbstractQuery, + AbstractQueryAbstractType, + AbstractSamlpElement, + StatusMessage, + UnknownQuery, +}; use SimpleSAML\Test\SAML11\CustomQuery; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -79,7 +79,11 @@ public static function tearDownAfterClass(): void public function testMarshalling(): void { $query = new CustomQuery( - [new StatusMessage('urn:some:audience')], + [ + new StatusMessage( + StringValue::fromString('urn:some:audience'), + ), + ], ); $this->assertEquals( @@ -102,7 +106,10 @@ public function testUnmarshallingUnregistered(): void $query = AbstractQuery::fromXML($element); $this->assertInstanceOf(UnknownQuery::class, $query); - $this->assertEquals('urn:x-simplesamlphp:namespace:UnknownQueryType', $query->getXsiType()); + $this->assertEquals( + '{urn:x-simplesamlphp:namespace}ssp:UnknownQueryType', + $query->getXsiType()->getRawValue(), + ); $chunk = $query->getRawQuery(); $this->assertEquals('samlp', $chunk->getPrefix()); diff --git a/tests/src/SAML11/XML/samlp/RespondWithTest.php b/tests/src/SAML11/XML/samlp/RespondWithTest.php index f260731..64dd880 100644 --- a/tests/src/SAML11/XML/samlp/RespondWithTest.php +++ b/tests/src/SAML11/XML/samlp/RespondWithTest.php @@ -4,12 +4,13 @@ namespace SimpleSAML\Test\SAML11\XML\samlp; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\samlp\AbstractSamlpElement; -use SimpleSAML\SAML11\XML\samlp\RespondWith; +use SimpleSAML\SAML11\Type\AnyURIValue; +use SimpleSAML\SAML11\XML\samlp\{AbstractSamlpElement, RespondWith}; use SimpleSAML\XML\DOMDocumentFactory; use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\Type\{NCNameValue, QNameValue}; use function dirname; use function strval; @@ -19,6 +20,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('samlp')] #[CoversClass(RespondWith::class)] #[CoversClass(AbstractSamlpElement::class)] final class RespondWithTest extends TestCase @@ -42,7 +44,13 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $respondWith = new RespondWith(RespondWith::NS_PREFIX . ':RespondWith', RespondWith::NS); + $respondWith = new RespondWith( + QNameValue::fromParts( + NCNameValue::fromString('RespondWith'), + AnyURIValue::fromString(RespondWith::NS), + NCNameValue::fromString(RespondWith::NS_PREFIX), + ), + ); $this->assertEquals( self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), diff --git a/tests/src/SAML11/XML/samlp/ResponseTest.php b/tests/src/SAML11/XML/samlp/ResponseTest.php index 785659d..0689e7e 100644 --- a/tests/src/SAML11/XML/samlp/ResponseTest.php +++ b/tests/src/SAML11/XML/samlp/ResponseTest.php @@ -4,28 +4,32 @@ namespace SimpleSAML\Test\SAML11\XML\samlp; -use DateTimeImmutable; use DOMDocument; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\Assertion; -//use SimpleSAML\SAML11\XML\saml\AttributeStatement; -use SimpleSAML\SAML11\XML\saml\Audience; -use SimpleSAML\SAML11\XML\saml\AudienceRestrictionCondition; -use SimpleSAML\SAML11\XML\saml\AuthenticationStatement; -use SimpleSAML\SAML11\XML\saml\Conditions; -use SimpleSAML\SAML11\XML\saml\DoNotCacheCondition; -use SimpleSAML\SAML11\XML\samlp\AbstractResponseAbstractType; -use SimpleSAML\SAML11\XML\samlp\AbstractSamlpElement; -use SimpleSAML\SAML11\XML\samlp\Response; -use SimpleSAML\SAML11\XML\samlp\Status; -use SimpleSAML\SAML11\XML\samlp\StatusCode; -//use SimpleSAML\SAML11\XML\samlp\StatusDetail; -use SimpleSAML\SAML11\XML\samlp\StatusMessage; +use SimpleSAML\SAML11\Type\{AnyURIValue, DateTimeValue, StringValue}; +use SimpleSAML\SAML11\XML\saml\{ + Assertion, + //AttributeStatement, + Audience, + AudienceRestrictionCondition, + AuthenticationStatement, + Conditions, + DoNotCacheCondition, +}; +use SimpleSAML\SAML11\XML\samlp\{ + AbstractResponseAbstractType, + AbstractSamlpElement, + Response, + Status, + StatusCode, + //StatusDetail, + StatusMessage, +}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\{IDValue, NonNegativeIntegerValue, QNameValue}; use function dirname; use function strval; @@ -35,6 +39,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('samlp')] #[CoversClass(Response::class)] #[CoversClass(AbstractResponseAbstractType::class)] #[CoversClass(AbstractSamlpElement::class)] @@ -50,8 +55,6 @@ final class ResponseTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-protocol-1.1.xsd'; - self::$testedClass = Response::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -72,7 +75,9 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $audience = new Audience('urn:x-simplesamlphp:audience'); + $audience = new Audience( + AnyURIValue::fromString('urn:x-simplesamlphp:audience'), + ); $audienceRestrictionCondition = new AudienceRestrictionCondition([$audience]); $doNotCacheCondition = new DoNotCacheCondition(); @@ -81,14 +86,16 @@ public function testMarshalling(): void [$audienceRestrictionCondition], [$doNotCacheCondition], [], - new DateTimeImmutable('2023-01-24T09:42:26Z'), - new DateTimeImmutable('2023-01-24T09:47:26Z'), + DateTimeValue::fromString('2023-01-24T09:42:26Z'), + DateTimeValue::fromString('2023-01-24T09:47:26Z'), ); $assertion = new Assertion( - '_abc123', - 'urn:x-simplesamlphp:phpunit', - new DateTimeImmutable('2023-01-24T09:42:26Z'), + NonNegativeIntegerValue::fromString('1'), + NonNegativeIntegerValue::fromString('1'), + IDValue::fromString('_abc123'), + StringValue::fromString('urn:x-simplesamlphp:phpunit'), + DateTimeValue::fromString('2023-01-24T09:42:26Z'), $conditions, null, // advice [ @@ -98,23 +105,25 @@ public function testMarshalling(): void $status = new Status( new StatusCode( - C::STATUS_RESPONDER, + QNameValue::fromString('{' . C::NS_SAMLP . '}' . C::STATUS_RESPONDER), [ new StatusCode( - C::STATUS_REQUEST_DENIED, + QNameValue::fromString('{' . C::NS_SAMLP . '}' . C::STATUS_REQUEST_DENIED), ), ], ), - new StatusMessage('Something went wrong'), + new StatusMessage( + StringValue::fromString('Something went wrong'), + ), ); $response = new Response( - 'def456', + NonNegativeIntegerValue::fromString('1'), + NonNegativeIntegerValue::fromString('1'), + IDValue::fromString('def456'), $status, [$assertion], - 1, - 1, - new DateTimeImmutable('2023-01-24T09:42:26Z'), + DateTimeValue::fromString('2023-01-24T09:42:26Z'), ); $this->assertEquals( diff --git a/tests/src/SAML11/XML/samlp/StatusCodeTest.php b/tests/src/SAML11/XML/samlp/StatusCodeTest.php index 617e34a..a2cbd82 100644 --- a/tests/src/SAML11/XML/samlp/StatusCodeTest.php +++ b/tests/src/SAML11/XML/samlp/StatusCodeTest.php @@ -4,15 +4,13 @@ namespace SimpleSAML\Test\SAML11\XML\samlp; -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\samlp\AbstractSamlpElement; -use SimpleSAML\SAML11\XML\samlp\StatusCode; +use SimpleSAML\SAML11\XML\samlp\{AbstractSamlpElement, StatusCode}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\QNameValue; use function dirname; use function strval; @@ -35,8 +33,6 @@ final class StatusCodeTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-protocol-1.1.xsd'; - self::$testedClass = StatusCode::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -51,9 +47,11 @@ public function testMarshalling(): void { $statusCode = new StatusCode( - C::STATUS_RESPONDER, + QNameValue::fromString('{' . C::NS_SAMLP . '}' . C::STATUS_RESPONDER), [ - new StatusCode(C::STATUS_REQUEST_DENIED), + new StatusCode( + QNameValue::fromString('{' . C::NS_SAMLP . '}' . C::STATUS_REQUEST_DENIED), + ), ], ); diff --git a/tests/src/SAML11/XML/samlp/StatusDetailTest.php b/tests/src/SAML11/XML/samlp/StatusDetailTest.php index 8ca0523..69011fe 100644 --- a/tests/src/SAML11/XML/samlp/StatusDetailTest.php +++ b/tests/src/SAML11/XML/samlp/StatusDetailTest.php @@ -4,7 +4,7 @@ namespace SimpleSAML\Test\SAML11\XML\samlp; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; use SimpleSAML\SAML11\Constants as C; use SimpleSAML\SAML11\XML\samlp\AbstractSamlpElement; @@ -23,6 +23,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('samlp')] #[CoversClass(StatusDetail::class)] #[CoversClass(AbstractStatusDetailType::class)] #[CoversClass(AbstractSamlpElement::class)] @@ -35,8 +36,6 @@ final class StatusDetailTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-protocol-1.1.xsd'; - self::$testedClass = StatusDetail::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( diff --git a/tests/src/SAML11/XML/samlp/StatusMessageTest.php b/tests/src/SAML11/XML/samlp/StatusMessageTest.php index 7c88c9b..31f2ca8 100644 --- a/tests/src/SAML11/XML/samlp/StatusMessageTest.php +++ b/tests/src/SAML11/XML/samlp/StatusMessageTest.php @@ -4,14 +4,12 @@ namespace SimpleSAML\Test\SAML11\XML\samlp; -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\XML\samlp\AbstractSamlpElement; -use SimpleSAML\SAML11\XML\samlp\StatusMessage; +use SimpleSAML\SAML11\Type\StringValue; +use SimpleSAML\SAML11\XML\samlp\{AbstractSamlpElement, StatusMessage}; use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; use function dirname; use function strval; @@ -33,8 +31,6 @@ final class StatusMessageTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-protocol-1.1.xsd'; - self::$testedClass = StatusMessage::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -47,7 +43,9 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $statusMessage = new StatusMessage('Something went wrong'); + $statusMessage = new StatusMessage( + StringValue::fromString('Something went wrong'), + ); $this->assertEquals( self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement), diff --git a/tests/src/SAML11/XML/samlp/StatusTest.php b/tests/src/SAML11/XML/samlp/StatusTest.php index a649639..6becf49 100644 --- a/tests/src/SAML11/XML/samlp/StatusTest.php +++ b/tests/src/SAML11/XML/samlp/StatusTest.php @@ -5,20 +5,21 @@ namespace SimpleSAML\Test\SAML11\XML\samlp; use DOMDocument; -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; use SimpleSAML\SAML11\Constants as C; +use SimpleSAML\SAML11\Type\StringValue; use SimpleSAML\SAML11\Utils\XPath; -use SimpleSAML\SAML11\XML\samlp\AbstractSamlpElement; -use SimpleSAML\SAML11\XML\samlp\Status; -use SimpleSAML\SAML11\XML\samlp\StatusCode; -use SimpleSAML\SAML11\XML\samlp\StatusDetail; -use SimpleSAML\SAML11\XML\samlp\StatusMessage; -use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\SAML11\XML\samlp\{ + AbstractSamlpElement, + Status, + StatusCode, + StatusDetail, + StatusMessage, +}; +use SimpleSAML\XML\{Chunk, DOMDocumentFactory}; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\QNameValue; use function dirname; use function strval; @@ -44,8 +45,6 @@ final class StatusTest extends TestCase */ public static function setUpBeforeClass(): void { - self::$schemaFile = dirname(__FILE__, 6) . '/resources/schemas/oasis-sstc-saml-schema-protocol-1.1.xsd'; - self::$testedClass = Status::class; self::$xmlRepresentation = DOMDocumentFactory::fromFile( @@ -64,14 +63,16 @@ public function testMarshalling(): void { $status = new Status( new StatusCode( - C::STATUS_RESPONDER, + QNameValue::fromString('{' . C::NS_SAMLP . '}' . C::STATUS_RESPONDER), [ new StatusCode( - C::STATUS_REQUEST_DENIED, + QNameValue::fromString('{' . C::NS_SAMLP . '}' . C::STATUS_REQUEST_DENIED), ), ], ), - new StatusMessage('Something went wrong'), + new StatusMessage( + StringValue::fromString('Something went wrong'), + ), StatusDetail::fromXML( DOMDocumentFactory::fromFile( dirname(__FILE__, 5) . '/resources/xml/samlp_StatusDetail.xml', @@ -92,14 +93,16 @@ public function testMarshallingElementOrdering(): void { $status = new Status( new StatusCode( - C::STATUS_RESPONDER, + QNameValue::fromString('{' . C::NS_SAMLP . '}' . C::STATUS_RESPONDER), [ new StatusCode( - C::STATUS_REQUEST_DENIED, + QNameValue::fromString('{' . C::NS_SAMLP . '}' . C::STATUS_REQUEST_DENIED), ), ], ), - new StatusMessage('Something went wrong'), + new StatusMessage( + StringValue::fromString('Something went wrong'), + ), new StatusDetail([new Chunk(self::$detail->documentElement)]), ); diff --git a/tests/src/SAML11/XML/samlp/SubjectQueryTest.php b/tests/src/SAML11/XML/samlp/SubjectQueryTest.php index 230e4bf..3b8e5db 100644 --- a/tests/src/SAML11/XML/samlp/SubjectQueryTest.php +++ b/tests/src/SAML11/XML/samlp/SubjectQueryTest.php @@ -4,32 +4,37 @@ namespace SimpleSAML\Test\SAML11\XML\samlp; -use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\{CoversClass, Group}; use PHPUnit\Framework\TestCase; -use SimpleSAML\SAML11\Compat\AbstractContainer; -use SimpleSAML\SAML11\Compat\ContainerSingleton; +use SimpleSAML\SAML11\Compat\{AbstractContainer, ContainerSingleton}; use SimpleSAML\SAML11\Constants as C; -use SimpleSAML\SAML11\XML\saml\ConfirmationMethod; -use SimpleSAML\SAML11\XML\saml\NameIdentifier; -use SimpleSAML\SAML11\XML\saml\Subject; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmation; -use SimpleSAML\SAML11\XML\saml\SubjectConfirmationData; -use SimpleSAML\SAML11\XML\samlp\AbstractSamlpElement; -use SimpleSAML\SAML11\XML\samlp\AbstractSubjectQuery; -use SimpleSAML\SAML11\XML\samlp\AbstractSubjectQueryAbstractType; -use SimpleSAML\SAML11\XML\samlp\StatusMessage; -use SimpleSAML\SAML11\XML\samlp\UnknownSubjectQuery; +use SimpleSAML\SAML11\Type\{AnyURIValue, StringValue}; +use SimpleSAML\SAML11\XML\saml\{ + ConfirmationMethod, + NameIdentifier, + Subject, + SubjectConfirmation, + SubjectConfirmationData, +}; +use SimpleSAML\SAML11\XML\samlp\{ + AbstractSamlpElement, + AbstractSubjectQuery, + AbstractSubjectQueryAbstractType, + StatusMessage, + UnknownSubjectQuery, +}; use SimpleSAML\Test\SAML11\CustomSubjectQuery; -use SimpleSAML\XML\Chunk; -use SimpleSAML\XML\DOMDocumentFactory; -use SimpleSAML\XML\TestUtils\SchemaValidationTestTrait; -use SimpleSAML\XML\TestUtils\SerializableElementTestTrait; +use SimpleSAML\XML\{Chunk, DOMDocumentFactory}; +use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait}; +use SimpleSAML\XML\Type\{Base64BinaryValue, IDValue}; use SimpleSAML\XMLSecurity\TestUtils\PEMCertificatesMock; -use SimpleSAML\XMLSecurity\XML\ds\KeyInfo; -use SimpleSAML\XMLSecurity\XML\ds\KeyName; -use SimpleSAML\XMLSecurity\XML\ds\X509Certificate; -use SimpleSAML\XMLSecurity\XML\ds\X509Data; -use SimpleSAML\XMLSecurity\XML\ds\X509SubjectName; +use SimpleSAML\XMLSecurity\XML\ds\{ + KeyInfo, + KeyName, + X509Certificate, + X509Data, + X509SubjectName, +}; use function dirname; use function strval; @@ -39,6 +44,7 @@ * * @package simplesamlphp/saml11 */ +#[Group('samlp')] #[CoversClass(AbstractSubjectQuery::class)] #[CoversClass(AbstractSubjectQueryAbstractType::class)] #[CoversClass(AbstractSamlpElement::class)] @@ -116,40 +122,59 @@ public static function tearDownAfterClass(): void */ public function testMarshalling(): void { - $scd = new SubjectConfirmationData('phpunit'); + $scd = new SubjectConfirmationData( + StringValue::fromString('phpunit'), + ); $keyInfo = new KeyInfo( [ - new KeyName('testkey'), + new KeyName( + StringValue::fromString('testkey'), + ), new X509Data( [ - new X509Certificate(self::$certificate), - new X509SubjectName(self::$certData['name']), + new X509Certificate( + Base64BinaryValue::fromString(self::$certificate), + ), + new X509SubjectName( + StringValue::fromString(self::$certData['name']), + ), ], ), new Chunk(DOMDocumentFactory::fromString( 'some', )->documentElement), ], - 'fed654', + IDValue::fromString('fed654'), ); $sc = new SubjectConfirmation( - [new ConfirmationMethod('_Test1'), new ConfirmationMethod('_Test2')], + [ + new ConfirmationMethod( + AnyURIValue::fromString('_Test1'), + ), + new ConfirmationMethod( + AnyURIValue::fromString('_Test2'), + ), + ], $scd, $keyInfo, ); $nameIdentifier = new NameIdentifier( - 'TheNameIDValue', - 'TheNameQualifier', - 'urn:the:format', + StringValue::fromString('TheNameIDValue'), + StringValue::fromString('TheNameQualifier'), + AnyURIValue::fromString('urn:the:format'), ); $subject = new Subject($sc, $nameIdentifier); $subjectQuery = new CustomSubjectQuery( $subject, - [new StatusMessage('urn:some:audience')], + [ + new StatusMessage( + StringValue::fromString('urn:some:audience'), + ), + ], ); $this->assertEquals( @@ -168,6 +193,7 @@ public function testUnmarshallingUnregistered(): void { $element = clone self::$xmlRepresentation->documentElement; $element->setAttributeNS(C::NS_XSI, 'xsi:type', 'ssp:UnknownSubjectQueryType'); + $element->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:ssp', 'urn:x-simplesamlphp:namespace'); // Normalize the DOMElement by importing it into a clean empty document $newDoc = DOMDocumentFactory::create(); @@ -177,7 +203,10 @@ public function testUnmarshallingUnregistered(): void $subjectQuery = AbstractSubjectQuery::fromXML($element); $this->assertInstanceOf(UnknownSubjectQuery::class, $subjectQuery); - $this->assertEquals('urn:x-simplesamlphp:namespace:UnknownSubjectQueryType', $subjectQuery->getXsiType()); + $this->assertEquals( + '{urn:x-simplesamlphp:namespace}ssp:UnknownSubjectQueryType', + $subjectQuery->getXsiType()->getRawValue(), + ); $chunk = $subjectQuery->getRawSubjectQuery(); $this->assertEquals('samlp', $chunk->getPrefix());