Skip to content

Commit e170052

Browse files
committed
Add AuthnContextDecision-type
1 parent 6b9409c commit e170052

File tree

7 files changed

+161
-39
lines changed

7 files changed

+161
-39
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\SAML2\Type;
6+
7+
use SimpleSAML\Assert\Assert;
8+
use SimpleSAML\SAML2\XML\samlp\AuthnContextComparisonTypeEnum;
9+
use SimpleSAML\XML\Exception\SchemaViolationException;
10+
use SimpleSAML\XML\Type\StringValue;
11+
12+
use function array_column;
13+
14+
/**
15+
* @package simplesamlphp/saml2
16+
*/
17+
class AuthnContextComparisonTypeValue extends StringValue
18+
{
19+
/** @var string */
20+
public const SCHEMA_TYPE = 'authnContextComparisonType';
21+
22+
23+
/**
24+
* Validate the value.
25+
*
26+
* @param string $value The value
27+
* @throws \Exception on failure
28+
* @return void
29+
*/
30+
protected function validateValue(string $value): void
31+
{
32+
Assert::oneOf(
33+
$this->sanitizeValue($value),
34+
array_column(AuthnContextComparisonTypeEnum::cases(), 'value'),
35+
SchemaViolationException::class,
36+
);
37+
}
38+
39+
40+
/**
41+
* @param \SimpleSAML\SAML2\XML\samlp\AuthnContextComparisonTypeEnum $value
42+
* @return static
43+
*/
44+
public static function fromEnum(AuthnContextComparisonTypeEnum $value): static
45+
{
46+
return new static($value->value);
47+
}
48+
49+
50+
/**
51+
* @return \SimpleSAML\SAML2\XML\samlp\AuthnContextComparisonTypeEnum $value
52+
*/
53+
public function toEnum(): AuthnContextComparisonTypeEnum
54+
{
55+
return AuthnContextComparisonTypeEnum::from($this->getValue());
56+
}
57+
}

src/XML/Comparison.php renamed to src/XML/samlp/AuthnContextComparisonTypeEnum.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,34 @@
22

33
declare(strict_types=1);
44

5-
namespace SimpleSAML\SAML2\XML;
5+
namespace SimpleSAML\SAML2\XML\samlp;
66

7-
enum Comparison: string
7+
enum AuthnContextComparisonTypeEnum: string
88
{
99
/**
1010
* Request Authentication Context Comparison indicating that the resulting authentication context in the
1111
* authentication statement MUST be stronger (as deemed by the responder) than any one of the authentication
1212
* contexts specified
1313
*/
14-
case BETTER = 'better';
14+
case Better = 'better';
1515

1616
/**
1717
* Request Authentication Context Comparison indicating that the resulting authentication context in the
1818
* authentication statement MUST be the exact match of at least one of the authentication contexts specified
1919
*/
20-
case EXACT = 'exact';
20+
case Exact = 'exact';
2121

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

2929
/**
3030
* Request Authentication Context Comparison indicating that he resulting authentication context in the
3131
* authentication statement MUST be at least as strong (as deemed by the responder) as one of the authentication
3232
* contexts specified.
3333
*/
34-
case MINIMUM = 'minimum';
34+
case Minimum = 'minimum';
3535
}

src/XML/samlp/RequestedAuthnContext.php

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
use DOMElement;
88
use SimpleSAML\SAML2\Assert\Assert;
99
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
10-
use SimpleSAML\SAML2\Type\SAMLStringValue;
11-
use SimpleSAML\SAML2\XML\Comparison;
10+
use SimpleSAML\SAML2\Type\{AuthnContextComparisonTypeValue, SAMLStringValue};
1211
use SimpleSAML\SAML2\XML\saml\{AuthnContextClassRef, AuthnContextDeclRef};
1312
use SimpleSAML\XML\Constants as C;
1413
use SimpleSAML\XML\Exception\{InvalidDOMElementException, SchemaViolationException};
1514
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
1615

1716
use function array_merge;
17+
use function strval;
1818

1919
/**
2020
* Class representing SAML2 RequestedAuthnContext
@@ -32,11 +32,11 @@ final class RequestedAuthnContext extends AbstractSamlpElement implements Schema
3232
* \SimpleSAML\SAML2\XML\saml\AuthnContextClassRef|
3333
* \SimpleSAML\SAML2\XML\saml\AuthnContextDeclRef
3434
* )[] $requestedAuthnContexts
35-
* @param \SimpleSAML\SAML2\XML\Comparison $Comparison
35+
* @param \SimpleSAML\SAML2\Type\AuthnContextComparisonTypeValue $Comparison
3636
*/
3737
public function __construct(
3838
protected array $requestedAuthnContexts = [],
39-
protected ?Comparison $Comparison = null,
39+
protected ?AuthnContextComparisonTypeValue $Comparison = null,
4040
) {
4141
Assert::maxCount($requestedAuthnContexts, C::UNBOUNDED_LIMIT);
4242
Assert::minCount($requestedAuthnContexts, 1, SchemaViolationException::class);
@@ -78,9 +78,9 @@ public function getRequestedAuthnContexts(): array
7878
/**
7979
* Collect the value of the Comparison-property
8080
*
81-
* @return \SimpleSAML\SAML2\XML\Comparison|null
81+
* @return \SimpleSAML\SAML2\Type\AuthnContextComparisonTypeValue|null
8282
*/
83-
public function getComparison(): ?Comparison
83+
public function getComparison(): ?AuthnContextComparisonTypeValue
8484
{
8585
return $this->Comparison;
8686
}
@@ -100,19 +100,12 @@ public static function fromXML(DOMElement $xml): static
100100
Assert::same($xml->localName, 'RequestedAuthnContext', InvalidDOMElementException::class);
101101
Assert::same($xml->namespaceURI, RequestedAuthnContext::NS, InvalidDOMElementException::class);
102102

103-
$Comparison = self::getOptionalAttribute(
104-
$xml,
105-
'Comparison',
106-
SAMLStringValue::class,
107-
SAMLStringValue::fromString('unknown'),
108-
);
109-
110103
return new static(
111104
array_merge(
112105
AuthnContextClassRef::getChildrenOfClass($xml),
113106
AuthnContextDeclRef::getChildrenOfClass($xml),
114107
),
115-
Comparison::tryFrom($Comparison->getValue()),
108+
self::getOptionalAttribute($xml, 'Comparison', AuthnContextComparisonTypeValue::class, null),
116109
);
117110
}
118111

@@ -132,7 +125,7 @@ public function toXML(?DOMElement $parent = null): DOMElement
132125
}
133126

134127
if ($this->getComparison() !== null) {
135-
$e->setAttribute('Comparison', $this->getComparison()->value);
128+
$e->setAttribute('Comparison', strval($this->getComparison()));
136129
}
137130

138131
return $e;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\Test\SAML2\Type;
6+
7+
use PHPUnit\Framework\Attributes\{CoversClass, DataProvider, DependsOnClass};
8+
use PHPUnit\Framework\TestCase;
9+
use SimpleSAML\SAML2\Type\AuthnContextComparisonValue;
10+
use SimpleSAML\SAML2\XML\saml\AuthnContextComparisonEnum;
11+
use SimpleSAML\XML\Exception\SchemaViolationException;
12+
13+
/**
14+
* Class \SimpleSAML\Test\SAML2\Type\AuthnContextComparisonValueTest
15+
*
16+
* @package simplesamlphp/saml2
17+
*/
18+
#[CoversClass(AuthnContextComparisonValue::class)]
19+
final class AuthnContextComparisonValueTest extends TestCase
20+
{
21+
/**
22+
* @param string $AuthnContextComparison
23+
* @param bool $shouldPass
24+
*/
25+
#[DataProvider('provideAuthnContextComparison')]
26+
public function testAuthnContextComparisonValue(string $authnContextComparison, bool $shouldPass): void
27+
{
28+
try {
29+
AuthnContextComparisonValue::fromString($authnContextComparison);
30+
$this->assertTrue($shouldPass);
31+
} catch (SchemaViolationException $e) {
32+
$this->assertFalse($shouldPass);
33+
}
34+
}
35+
36+
37+
/**
38+
* Test helpers
39+
*/
40+
public function testHelpers(): void
41+
{
42+
$x = AuthnContextComparisonValue::fromEnum(AuthnContextComparisonEnum::Exact);
43+
$this->assertEquals(AuthnContextComparisonEnum::Exact, $x->toEnum());
44+
45+
$y = AuthnContextComparisonValue::fromString('exact');
46+
$this->assertEquals(AuthnContextComparisonEnum::Exact, $y->toEnum());
47+
}
48+
49+
50+
/**
51+
* @return array<string, array{0: string, 1: bool}>
52+
*/
53+
public static function provideAuthnContextComparison(): array
54+
{
55+
return [
56+
'better' => ['better', true],
57+
'exact' => ['exact', true],
58+
'maximum' => ['maximum', true],
59+
'minimum' => ['minimum', true],
60+
'undefined' => ['undefined', false],
61+
'empty' => ['', false],
62+
];
63+
}
64+
}

tests/SAML2/XML/samlp/AuthnQueryTest.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
use PHPUnit\Framework\Attributes\{CoversClass, Group};
88
use PHPUnit\Framework\TestCase;
99
use SimpleSAML\SAML2\Constants as C;
10-
use SimpleSAML\SAML2\Type\{SAMLAnyURIValue, SAMLDateTimeValue, SAMLStringValue};
11-
use SimpleSAML\SAML2\XML\Comparison;
10+
use SimpleSAML\SAML2\Type\{AuthnContextComparisonTypeValue, SAMLAnyURIValue, SAMLDateTimeValue, SAMLStringValue};
1211
use SimpleSAML\SAML2\XML\saml\{AuthnContextDeclRef, Issuer, NameID, Subject};
1312
use SimpleSAML\SAML2\XML\samlp\{
1413
AbstractMessage,
1514
AbstractRequest,
1615
AbstractSamlpElement,
1716
AbstractSubjectQuery,
17+
AuthnContextComparisonTypeEnum,
1818
AuthnQuery,
1919
RequestedAuthnContext,
2020
};
@@ -67,7 +67,10 @@ public function testMarshalling(): void
6767
$authnContextDeclRef = new AuthnContextDeclRef(
6868
SAMLAnyURIValue::fromString('https://example.org/relative/path/to/document.xml'),
6969
);
70-
$requestedAuthnContext = new RequestedAuthnContext([$authnContextDeclRef], Comparison::EXACT);
70+
$requestedAuthnContext = new RequestedAuthnContext(
71+
[$authnContextDeclRef],
72+
AuthnContextComparisonTypeValue::fromEnum(AuthnContextComparisonTypeEnum::Exact),
73+
);
7174

7275
$authnQuery = new AuthnQuery(
7376
id: IDValue::fromString('aaf23196-1773-2113-474a-fe114412ab72'),

tests/SAML2/XML/samlp/AuthnRequestTest.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@
99
use Psr\Clock\ClockInterface;
1010
use SimpleSAML\SAML2\Compat\ContainerSingleton;
1111
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
12-
use SimpleSAML\SAML2\Type\{SAMLAnyURIValue, SAMLDateTimeValue, EntityIDValue, SAMLStringValue};
12+
use SimpleSAML\SAML2\Type\{
13+
AuthnContextComparisonTypeValue,
14+
SAMLAnyURIValue,
15+
SAMLDateTimeValue,
16+
EntityIDValue,
17+
SAMLStringValue,
18+
};
1319
use SimpleSAML\SAML2\Utils;
1420
use SimpleSAML\SAML2\Utils\XPath;
15-
use SimpleSAML\SAML2\XML\Comparison;
1621
use SimpleSAML\SAML2\XML\saml\{
1722
Audience,
1823
AudienceRestriction,
@@ -28,6 +33,7 @@
2833
use SimpleSAML\SAML2\XML\samlp\{
2934
AbstractMessage,
3035
AbstractSamlpElement,
36+
AuthnContextComparisonTypeEnum,
3137
AuthnRequest,
3238
GetComplete,
3339
IDPEntry,
@@ -122,7 +128,7 @@ public function testMarshallingElementOrdering(): void
122128
SAMLAnyURIValue::fromString('urn:test:accr2'),
123129
),
124130
],
125-
Comparison::BETTER,
131+
AuthnContextComparisonTypeValue::fromEnum(AuthnContextComparisonTypeEnum::Better),
126132
);
127133

128134
// Create Subject

tests/SAML2/XML/samlp/RequestedAuthnContextTest.php

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88
use PHPUnit\Framework\TestCase;
99
use SimpleSAML\SAML2\Constants as C;
1010
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
11-
use SimpleSAML\SAML2\Type\SAMLAnyURIValue;
12-
use SimpleSAML\SAML2\XML\Comparison;
11+
use SimpleSAML\SAML2\Type\{AuthnContextComparisonTypeValue, SAMLAnyURIValue};
1312
use SimpleSAML\SAML2\XML\saml\{AuthnContextClassRef, AuthnContextDeclRef};
14-
use SimpleSAML\SAML2\XML\samlp\{AbstractSamlpElement, RequestedAuthnContext};
13+
use SimpleSAML\SAML2\XML\samlp\{AbstractSamlpElement, AuthnContextComparisonTypeEnum, RequestedAuthnContext};
1514
use SimpleSAML\XML\DOMDocumentFactory;
1615
use SimpleSAML\XML\Exception\SchemaViolationException;
1716
use SimpleSAML\XML\TestUtils\{SchemaValidationTestTrait, SerializableElementTestTrait};
@@ -55,7 +54,7 @@ public function testMarshalling(): void
5554

5655
$requestedAuthnContext = new RequestedAuthnContext(
5756
[$authnContextDeclRef],
58-
Comparison::EXACT,
57+
AuthnContextComparisonTypeValue::fromEnum(AuthnContextComparisonTypeEnum::Exact),
5958
);
6059

6160
$this->assertEquals(
@@ -81,7 +80,7 @@ public function testMarshallingWithMixedContextsFails(): void
8180

8281
new RequestedAuthnContext(
8382
[$authnContextClassRef, $authnContextDeclRef],
84-
Comparison::EXACT,
83+
AuthnContextComparisonTypeValue::fromEnum(AuthnContextComparisonTypeEnum::Exact),
8584
);
8685
}
8786

@@ -101,13 +100,13 @@ public function testMarshallingWithInvalidContentFails(): void
101100
);
102101

103102
/** @psalm-suppress InvalidArgument */
104-
new RequestedAuthnContext(
105-
[
106-
DOMDocumentFactory::fromString('<root />'),
107-
$authnContextDeclRef,
108-
],
109-
Comparison::EXACT,
110-
);
103+
new RequestedAuthnContext(
104+
[
105+
DOMDocumentFactory::fromString('<root />'),
106+
$authnContextDeclRef,
107+
],
108+
AuthnContextComparisonTypeValue::fromEnum(AuthnContextComparisonTypeEnum::Exact),
109+
);
111110
}
112111

113112

0 commit comments

Comments
 (0)