Skip to content

Commit

Permalink
Start using PHP 8.1 features
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Dec 17, 2023
1 parent a9d4609 commit ca1f79e
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 60 deletions.
40 changes: 0 additions & 40 deletions src/SAML2/Constants.php
Expand Up @@ -96,33 +96,6 @@ class Constants extends \SimpleSAML\XMLSecurity\Constants
*/
public const CM_VOUCHES = 'urn:oasis:names:tc:SAML:2.0:cm:sender-vouches';

/**
* Request Authentication Context Comparison indicating that the resulting authentication context in the
* authentication statement MUST be stronger (as deemed by the responder) than any one of the authentication
* contexts specified
*/
public const COMPARISON_BETTER = 'better';

/**
* Request Authentication Context Comparison indicating that the resulting authentication context in the
* authentication statement MUST be the exact match of at least one of the authentication contexts specified
*/
public const COMPARISON_EXACT = 'exact';

/**
* Request Authentication Context Comparison indicating that the resulting authentication context in the
* authentication statement MUST be as strong as possible (as deemed by the responder) without exceeding the
* strength of at least one of the authentication contexts specified.
*/
public const COMPARISON_MAXIMUM = 'maximum';

/**
* Request Authentication Context Comparison indicating that he resulting authentication context in the
* authentication statement MUST be at least as strong (as deemed by the responder) as one of the authentication
* contexts specified.
*/
public const COMPARISON_MINIMUM = 'minimum';

/**
* Indicates that a principal’s consent has been explicitly obtained by the issuer of the message during the
* action that initiated the message.
Expand Down Expand Up @@ -498,17 +471,4 @@ class Constants extends \SimpleSAML\XMLSecurity\Constants
* The format to express a timestamp in SAML2
*/
public const DATETIME_FORMAT = 'Y-m-d\\TH:i:sp';

/**
* Valid values for saml:DecisionType
*/
public const AUTHZ_DECISION_PERMIT = 'Permit';
public const AUTHZ_DECISION_DENY = 'Deny';
public const AUTHZ_DECISION_INDETERMINATE = 'Indeterminate';

public const AUTHZ_DECISIONS = [
self::AUTHZ_DECISION_PERMIT,
self::AUTHZ_DECISION_DENY,
self::AUTHZ_DECISION_INDETERMINATE,
];
}
35 changes: 35 additions & 0 deletions src/SAML2/XML/Comparison.php
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\SAML2\XML;

enum Comparison: string
{
/**
* Request Authentication Context Comparison indicating that the resulting authentication context in the
* authentication statement MUST be stronger (as deemed by the responder) than any one of the authentication
* contexts specified
*/
case BETTER = 'better';

/**
* Request Authentication Context Comparison indicating that the resulting authentication context in the
* authentication statement MUST be the exact match of at least one of the authentication contexts specified
*/
case EXACT = 'exact';

/**
* Request Authentication Context Comparison indicating that the resulting authentication context in the
* authentication statement MUST be as strong as possible (as deemed by the responder) without exceeding the
* strength of at least one of the authentication contexts specified.
*/
case MAXIMUM = 'maximum';

/**
* Request Authentication Context Comparison indicating that he resulting authentication context in the
* authentication statement MUST be at least as strong (as deemed by the responder) as one of the authentication
* contexts specified.
*/
case MINIMUM = 'minimum';
}
15 changes: 15 additions & 0 deletions src/SAML2/XML/Decision.php
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace SimpleSAML\SAML2\XML;

/**
* Valid values for saml:DecisionType
*/
enum Decision: string
{
case PERMIT = 'Permit';
case DENY = 'Deny';
case INDETERMINATE = 'Indeterminate';
}
22 changes: 15 additions & 7 deletions src/SAML2/XML/saml/AuthzDecisionStatement.php
Expand Up @@ -8,14 +8,17 @@
use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML2\Constants as C;
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
use SimpleSAML\SAML2\XML\Decision;
use SimpleSAML\XML\Exception\InvalidDOMElementException;
use SimpleSAML\XML\Exception\MissingElementException;
use SimpleSAML\XML\Exception\SchemaViolationException;
use SimpleSAML\XML\Exception\TooManyElementsException;
use SimpleSAML\XML\Utils as XMLUtils;
use ValueError;

use function array_pop;
use function gmdate;
use function sprintf;

/**
* Class representing a SAML2 AuthzDecisionStatement
Expand All @@ -28,18 +31,17 @@ final class AuthzDecisionStatement extends AbstractStatementType
* Initialize an AuthzDecisionStatement.
*
* @param string $resource
* @param string $decision
* @param \SimpleSAML\SAML2\XML\Decision $decision
* @param \SimpleSAML\SAML2\XML\saml\Action[] $action
* @param \SimpleSAML\SAML2\XML\saml\Evidence|null $evidence
*/
public function __construct(
protected string $resource,
protected string $decision,
protected Decision $decision,
protected array $action,
protected ?Evidence $evidence = null,
) {
Assert::validURI($resource);
Assert::oneOf($decision, C::AUTHZ_DECISIONS, ProtocolViolationException::class);
Assert::maxCount($action, C::UNBOUNDED_LIMIT);
Assert::allIsInstanceOf($action, Action::class, SchemaViolationException::class);
}
Expand All @@ -59,9 +61,9 @@ public function getResource(): string
/**
* Collect the value of the decision-property
*
* @return string
* @return \SimpleSAML\SAML2\XML\Decision
*/
public function getDecision(): string
public function getDecision(): Decision
{
return $this->decision;
}
Expand Down Expand Up @@ -122,9 +124,15 @@ public static function fromXML(DOMElement $xml): static
TooManyElementsException::class,
);

try {
$decision = Decision::from(self::getAttribute($xml, 'Decision'));
} catch (ValueError) {
throw ProtocolViolationException(sprintf('Unknown value \'%s\' for Decision attribute.', $decision));
}

return new static(
self::getAttribute($xml, 'Resource'),
self::getAttribute($xml, 'Decision'),
$decision,
$action,
array_pop($evidence),
);
Expand All @@ -142,7 +150,7 @@ public function toXML(DOMElement $parent = null): DOMElement
$e = $this->instantiateParentElement($parent);

$e->setAttribute('Resource', $this->getResource());
$e->setAttribute('Decision', $this->getDecision());
$e->setAttribute('Decision', $this->getDecision()->value);

foreach ($this->getAction() as $action) {
$action->toXML($e);
Expand Down
15 changes: 8 additions & 7 deletions src/SAML2/XML/samlp/RequestedAuthnContext.php
Expand Up @@ -7,6 +7,7 @@
use DOMElement;
use SimpleSAML\Assert\Assert;
use SimpleSAML\SAML2\Utils;
use SimpleSAML\SAML2\XML\Comparison;
use SimpleSAML\SAML2\XML\saml\AuthnContextClassRef;
use SimpleSAML\SAML2\XML\saml\AuthnContextDeclRef;
use SimpleSAML\XML\Constants as C;
Expand All @@ -29,11 +30,11 @@ final class RequestedAuthnContext extends AbstractSamlpElement
* \SimpleSAML\SAML2\XML\saml\AuthnContextClassRef|
* \SimpleSAML\SAML2\XML\saml\AuthnContextDeclRef
* )[] $requestedAuthnContexts
* @param string $Comparison
* @param \SimpleSAML\SAML2\XML\Comparison $Comparison
*/
public function __construct(
protected array $requestedAuthnContexts = [],
protected ?string $Comparison = null,
protected ?Comparison $Comparison = null,
) {
Assert::maxCount($requestedAuthnContexts, C::UNBOUNDED_LIMIT);
Assert::minCount($requestedAuthnContexts, 1, SchemaViolationException::class);
Expand All @@ -56,7 +57,6 @@ public function __construct(
'You need either AuthnContextClassRef or AuthnContextDeclRef, not both.',
);
}
Assert::nullOrOneOf($Comparison, ['exact', 'minimum', 'maximum', 'better']);
}


Expand All @@ -74,9 +74,9 @@ public function getRequestedAuthnContexts(): array
/**
* Collect the value of the Comparison-property
*
* @return string|null
* @return SimpleSAML\SAML2\XML\Comparison|null
*/
public function getComparison(): ?string
public function getComparison(): ?Comparison
{
return $this->Comparison;
}
Expand All @@ -96,12 +96,13 @@ public static function fromXML(DOMElement $xml): static
Assert::same($xml->localName, 'RequestedAuthnContext', InvalidDOMElementException::class);
Assert::same($xml->namespaceURI, RequestedAuthnContext::NS, InvalidDOMElementException::class);

$Comparison = self::getOptionalAttribute($xml, 'Comparison', 'unknown');
return new static(
array_merge(
AuthnContextClassRef::getChildrenOfClass($xml),
AuthnContextDeclRef::getChildrenOfClass($xml),
),
self::getOptionalAttribute($xml, 'Comparison', null),
Comparison::tryFrom($Comparison),
);
}

Expand All @@ -122,7 +123,7 @@ public function toXML(DOMElement $parent = null): DOMElement
}

if ($this->getComparison() !== null) {
$e->setAttribute('Comparison', $this->getComparison());
$e->setAttribute('Comparison', $this->getComparison()->value);
}

return $e;
Expand Down
3 changes: 2 additions & 1 deletion tests/SAML2/XML/saml/AuthzDecisionStatementTest.php
Expand Up @@ -6,6 +6,7 @@

use DOMDocument;
use PHPUnit\Framework\TestCase;
use SimpleSAML\SAML2\XML\Decision;
use SimpleSAML\SAML2\XML\saml\Action;
use SimpleSAML\SAML2\XML\saml\AuthzDecisionStatement;
use SimpleSAML\SAML2\XML\saml\Evidence;
Expand Down Expand Up @@ -58,7 +59,7 @@ public function testMarshalling(): void
{
$authzDecisionStatement = new AuthzDecisionStatement(
'urn:x-simplesamlphp:resource',
'Permit',
Decision::PERMIT,
[
new Action('urn:x-simplesamlphp:namespace', 'SomeAction'),
new Action('urn:x-simplesamlphp:namespace', 'OtherAction'),
Expand Down
3 changes: 2 additions & 1 deletion tests/SAML2/XML/samlp/AuthnQueryTest.php
Expand Up @@ -9,6 +9,7 @@
use PHPUnit\Framework\TestCase;
use SimpleSAML\SAML2\Constants as C;
use SimpleSAML\SAML2\Utils\XPath;
use SimpleSAML\SAML2\XML\Comparison;
use SimpleSAML\SAML2\XML\saml\AuthnContextDeclRef;
use SimpleSAML\SAML2\XML\saml\Issuer;
use SimpleSAML\SAML2\XML\saml\NameID;
Expand Down Expand Up @@ -63,7 +64,7 @@ public function testMarshalling(): void
{
$nameId = new NameID('urn:example:subject', null, null, C::NAMEID_UNSPECIFIED);
$authnContextDeclRef = new AuthnContextDeclRef('https://example.org/relative/path/to/document.xml');
$requestedAuthnContext = new RequestedAuthnContext([$authnContextDeclRef], 'exact');
$requestedAuthnContext = new RequestedAuthnContext([$authnContextDeclRef], Comparison::EXACT);

$authnQuery = new AuthnQuery(
subject: new Subject($nameId),
Expand Down
3 changes: 2 additions & 1 deletion tests/SAML2/XML/samlp/AuthnRequestTest.php
Expand Up @@ -14,6 +14,7 @@
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
use SimpleSAML\SAML2\Utils;
use SimpleSAML\SAML2\Utils\XPath;
use SimpleSAML\SAML2\XML\Comparison;
use SimpleSAML\SAML2\XML\saml\Audience;
use SimpleSAML\SAML2\XML\saml\AudienceRestriction;
use SimpleSAML\SAML2\XML\saml\AuthnContextClassRef;
Expand Down Expand Up @@ -119,7 +120,7 @@ public function testMarshallingElementOrdering(): void
new AuthnContextClassRef('urn:test:accr1'),
new AuthnContextClassRef('urn:test:accr2'),
],
'better',
Comparison::BETTER,
);

// Create Subject
Expand Down
7 changes: 4 additions & 3 deletions tests/SAML2/XML/samlp/RequestedAuthnContextTest.php
Expand Up @@ -8,6 +8,7 @@
use PHPUnit\Framework\TestCase;
use SimpleSAML\Assert\AssertionFailedException;
use SimpleSAML\SAML2\Constants as C;
use SimpleSAML\SAML2\XML\Comparison;
use SimpleSAML\SAML2\XML\saml\AuthnContextClassRef;
use SimpleSAML\SAML2\XML\saml\AuthnContextDeclRef;
use SimpleSAML\SAML2\XML\samlp\RequestedAuthnContext;
Expand Down Expand Up @@ -51,7 +52,7 @@ public function testMarshalling(): void
{
$authnContextDeclRef = new AuthnContextDeclRef('https://example.org/relative/path/to/document.xml');

$requestedAuthnContext = new RequestedAuthnContext([$authnContextDeclRef], 'exact');
$requestedAuthnContext = new RequestedAuthnContext([$authnContextDeclRef], Comparison::EXACT);

$this->assertEquals(
self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
Expand All @@ -70,7 +71,7 @@ public function testMarshallingWithMixedContextsFails(): void
$this->expectException(AssertionFailedException::class);
$this->expectExceptionMessage('You need either AuthnContextClassRef or AuthnContextDeclRef, not both.');

new RequestedAuthnContext([$authnContextClassRef, $authnContextDeclRef], 'exact');
new RequestedAuthnContext([$authnContextClassRef, $authnContextDeclRef], Comparison::EXACT);
}


Expand All @@ -92,7 +93,7 @@ public function testMarshallingWithInvalidContentFails(): void
DOMDocumentFactory::fromString('<root />'),
$authnContextDeclRef,
],
'exact',
Comparison::EXACT,
);
}

Expand Down

0 comments on commit ca1f79e

Please sign in to comment.