Skip to content

Commit

Permalink
Use local versions of StringElementTrait and URIElementTrait to compl…
Browse files Browse the repository at this point in the history
…y with stricter SAML 2.0 specs
  • Loading branch information
tvdijen committed Jan 4, 2025
1 parent 92085db commit 93354ff
Show file tree
Hide file tree
Showing 34 changed files with 158 additions and 533 deletions.
3 changes: 1 addition & 2 deletions src/Assert/CustomAssertionTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ private static function validURI(string $value, string $message = ''): void
}

try {
BaseAssert::notWhitespaceOnly($value, $message ?: '%s is not a SAML2-compliant URI');

// If it doesn't have a scheme, it's not an absolute URI
BaseAssert::regex($value, self::$scheme_regex, $message ?: '%s is not a SAML2-compliant URI');
} catch (AssertionFailedException $e) {
Expand All @@ -82,6 +80,7 @@ private static function validEntityID(string $value, string $message = ''): void
static::validURI($value);

try {
BaseAssert::notWhitespaceOnly($value);
BaseAssert::maxLength(
$value,
C::ENTITYID_MAX_LENGTH,
Expand Down
39 changes: 39 additions & 0 deletions src/XML/StringElementTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\SAML2\XML;

use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
use SimpleSAML\XML\StringElementTrait as BaseStringElementTrait;

/**
* Trait extending the default StringElementTrait to comply with the restrictions added by the SAML 2.0 specifications.
*
* @package simplesamlphp/saml2
*/
trait StringElementTrait
{
use BaseStringElementTrait;

/**
* 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(/** @scrutinizer ignore-unused */ string $content): void
{
/**
* 1.3.1 String Values
*
* All SAML string values have the type xs:string, which is built in to the W3C XML Schema Datatypes
* specification [Schema2]. Unless otherwise noted in this specification or particular profiles, all strings in
* SAML messages MUST consist of at least one non-whitespace character (whitespace is defined in the
* XML Recommendation [XML] Section 2.3).
*/
Assert::notWhitespaceOnly($content, ProtocolViolationException::class);
}
}
41 changes: 41 additions & 0 deletions src/XML/URIElementTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\SAML2\XML;

use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML2\Assert\Assert as SAMLAssert;
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\URIElementTrait as BaseURIElementTrait;

/**
* Trait extending the default URIElementTrait to comply with the restrictions added by the SAML 2.0 specifications.
*
* @package simplesamlphp/saml2
*/
trait URIElementTrait
{
use BaseURIElementTrait;

/**
* 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
{
/**
* 1.3.2 URI Values
*
* Unless otherwise indicated in this specification, all URI reference values used within SAML-defined
* elements or attributes MUST consist of at least one non-whitespace character, and are REQUIRED to be
* absolute [RFC 2396].
*/
Assert::notWhitespaceOnly($content, ProtocolViolationException::class);
SAMLAssert::validURI($content, SchemaViolationException::class);
}
}
2 changes: 1 addition & 1 deletion src/XML/ecp/RelayState.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
use SimpleSAML\SAML2\XML\StringElementTrait;
use SimpleSAML\SOAP\Constants as C;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\MissingAttributeException;
use SimpleSAML\XML\SchemaValidatableElementInterface;
use SimpleSAML\XML\SchemaValidatableElementTrait;
use SimpleSAML\XML\StringElementTrait;

/**
* Class representing the ECP RelayState element.
Expand Down
9 changes: 5 additions & 4 deletions src/XML/emd/RepublishTarget.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
namespace SimpleSAML\SAML2\XML\emd;

use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML2\Assert\Assert as SAMLAssert;
use SimpleSAML\XML\StringElementTrait;
use SimpleSAML\SAML2\XML\URIElementTrait;

/**
* Class implementing RepublishTarget.
Expand All @@ -15,7 +14,9 @@
*/
final class RepublishTarget extends AbstractEmdElement
{
use StringElementTrait;
use URIElementTrait {
URIElementTrait::validateContent as baseValidateContent;
}


/**
Expand All @@ -36,7 +37,7 @@ public function __construct(string $content)
*/
protected function validateContent(string $content): void
{
SAMLAssert::validURI($content);
$this->baseValidateContent($content);
Assert::same($content, 'http://edugain.org/');
}
}
18 changes: 3 additions & 15 deletions src/XML/md/AbstractLocalizedName.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML2\Exception\ArrayValidationException;
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
use SimpleSAML\SAML2\XML\StringElementTrait;
use SimpleSAML\XML\ArrayizableElementInterface;
use SimpleSAML\XML\Constants as C;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\MissingAttributeException;
use SimpleSAML\XML\StringElementTrait;

use function array_key_first;

Expand All @@ -35,25 +36,12 @@ final public function __construct(
protected string $language,
string $value,
) {
Assert::notEmpty($language, 'xml:lang cannot be empty.');
Assert::notWhitespaceOnly($language, ProtocolViolationException::class);

$this->setContent($value);
}


/**
* 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::notEmpty($content);
}


/**
* Get the language this string is localized in.
*
Expand Down
17 changes: 2 additions & 15 deletions src/XML/md/AdditionalMetadataLocation.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML2\Assert\Assert as SAMLAssert;
use SimpleSAML\SAML2\XML\URIElementTrait;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\SchemaValidatableElementInterface;
use SimpleSAML\XML\SchemaValidatableElementTrait;
use SimpleSAML\XML\StringElementTrait;

use function trim;

Expand All @@ -23,7 +23,7 @@
final class AdditionalMetadataLocation extends AbstractMdElement implements SchemaValidatableElementInterface
{
use SchemaValidatableElementTrait;
use StringElementTrait;
use URIElementTrait;


/**
Expand Down Expand Up @@ -52,19 +52,6 @@ public function getNamespace(): string
}


/**
* 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
{
SAMLAssert::validURI($content, SchemaViolationException::class); // Covers the empty string
}


/**
* Initialize an AdditionalMetadataLocation element.
*
Expand Down
2 changes: 1 addition & 1 deletion src/XML/md/AffiliateMember.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace SimpleSAML\SAML2\XML\md;

use SimpleSAML\SAML2\Assert\Assert as SAMLAssert;
use SimpleSAML\SAML2\XML\StringElementTrait;
use SimpleSAML\XML\SchemaValidatableElementInterface;
use SimpleSAML\XML\SchemaValidatableElementTrait;
use SimpleSAML\XML\StringElementTrait;

/**
* Class implementing AffiliateMember.
Expand Down
33 changes: 1 addition & 32 deletions src/XML/md/AttributeProfile.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML2\Assert\Assert as SAMLAssert;
use SimpleSAML\SAML2\XML\StringElementTrait;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\SchemaValidatableElementInterface;
use SimpleSAML\XML\SchemaValidatableElementTrait;
use SimpleSAML\XML\StringElementTrait;

/**
* Class implementing AttributeProfile.
Expand All @@ -30,35 +30,4 @@ 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
{
SAMLAssert::validURI($content);
}


/**
* Convert XML into a AttributeProfile
*
* @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, 'AttributeProfile', InvalidDOMElementException::class);
Assert::same($xml->namespaceURI, AttributeProfile::NS, InvalidDOMElementException::class);

return new static($xml->textContent);
}
}
15 changes: 1 addition & 14 deletions src/XML/md/Company.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace SimpleSAML\SAML2\XML\md;

use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML2\XML\StringElementTrait;
use SimpleSAML\XML\SchemaValidatableElementInterface;
use SimpleSAML\XML\SchemaValidatableElementTrait;
use SimpleSAML\XML\StringElementTrait;

/**
* Class implementing Company.
Expand All @@ -27,17 +27,4 @@ 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::notEmpty($content, 'Company cannot be empty');
}
}
8 changes: 5 additions & 3 deletions src/XML/md/EmailAddress.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML2\Exception\ArrayValidationException;
use SimpleSAML\SAML2\XML\StringElementTrait;
use SimpleSAML\XML\ArrayizableElementInterface;
use SimpleSAML\XML\SchemaValidatableElementInterface;
use SimpleSAML\XML\SchemaValidatableElementTrait;
use SimpleSAML\XML\StringElementTrait;

use function array_key_first;
use function preg_filter;
Expand All @@ -26,7 +26,9 @@ final class EmailAddress extends AbstractMdElement implements
SchemaValidatableElementInterface
{
use SchemaValidatableElementTrait;
use StringElementTrait;
use StringElementTrait {
StringElementTrait::validateContent as baseValidateContent;
}


/**
Expand All @@ -47,7 +49,7 @@ public function __construct(string $content)
*/
protected function validateContent(string $content): void
{
Assert::notEmpty($content, 'EmailAddress cannot be empty');
$this->baseValidateContent($content);
Assert::email($content);
}

Expand Down
15 changes: 1 addition & 14 deletions src/XML/md/GivenName.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace SimpleSAML\SAML2\XML\md;

use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML2\XML\StringElementTrait;
use SimpleSAML\XML\SchemaValidatableElementInterface;
use SimpleSAML\XML\SchemaValidatableElementTrait;
use SimpleSAML\XML\StringElementTrait;

/**
* Class implementing GivenName.
Expand All @@ -27,17 +27,4 @@ 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::notEmpty($content, 'GivenName cannot be empty');
}
}
Loading

0 comments on commit 93354ff

Please sign in to comment.