From 843d003d11254b7680e53690365f7b102f76876a Mon Sep 17 00:00:00 2001 From: turegjorup Date: Thu, 11 Jun 2026 11:20:35 +0200 Subject: [PATCH] test: use RFC 2606 reserved domains in fixtures and README example provider.example.org for IdP-side URLs (metadata), app.example.org for application-side URLs (redirect URI); some.url and redirect.url are not reserved names. The post-logout URL already uses the reserved .test TLD and the Azure B2C fixture endpoints are left as realistic shape examples. Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 4 ++ README.md | 2 +- .../OpenIdConfigurationProviderTest.php | 56 +++++++++---------- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20368aa..41c5b32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Test fixtures and README examples use RFC 2606 reserved domains + (`provider.example.org` for IdP-side URLs, `app.example.org` for + application-side URLs) instead of invented registrable domains + - Strengthened constructor tests guided by mutation testing: the `jwt` collaborator is asserted to become the request factory, and `0` is asserted to be an accepted boundary value for `cacheDuration` and diff --git a/README.md b/README.md index 361b75b..ad446ee 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ require_once __DIR__.'/vendor/autoload.php'; use ItkDev\OpenIdConnect\Security\OpenIdConfigurationProvider; $provider = new OpenIdConfigurationProvider([ - 'redirectUri' => 'https://some.url', // Absolute url to where the user is redirected after a successful login + 'redirectUri' => 'https://app.example.org', // Absolute url to where the user is redirected after a successful login 'openIDConnectMetadataUrl' => 'https:/.../openid-configuration', // url to OpenId Discovery document 'cacheItemPool' => 'Psr6/CacheItemPoolInterface', // Implementation of CacheItemPoolInterface for caching above discovery document 'clientId' => 'client_id', // Client id assigned by authorizer diff --git a/tests/Security/OpenIdConfigurationProviderTest.php b/tests/Security/OpenIdConfigurationProviderTest.php index fe7fbcd..5f9d754 100644 --- a/tests/Security/OpenIdConfigurationProviderTest.php +++ b/tests/Security/OpenIdConfigurationProviderTest.php @@ -35,7 +35,7 @@ class OpenIdConfigurationProviderTest extends TestCase private const CLIENT_ID = 'test_client_id'; private const CLIENT_SECRET = 'test_client_secret'; - private const REDIRECT_URI = 'https://redirect.url'; + private const REDIRECT_URI = 'https://app.example.org'; private const NONCE = '12345678'; private OpenIdConfigurationProvider $provider; @@ -44,7 +44,7 @@ public function setUp(): void { parent::setUp(); - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $jwks_uri = 'https://azure_b2c_test.b2clogin.com/azure_b2c_test.onmicrosoft.com/discovery/v2.0/keys?p=test-policy'; $mockConfigResponse = $this->getMockHttpSuccessResponse('/../MockData/mockOpenIDConfiguration.json'); @@ -106,7 +106,7 @@ public function testConstructCacheDuration(): void $provider = new OpenIdConfigurationProvider([ 'cacheItemPool' => $mockCacheItemPool, - 'openIDConnectMetadataUrl' => 'https://some.url/openid-configuration', + 'openIDConnectMetadataUrl' => 'https://provider.example.org/openid-configuration', 'cacheDuration' => -10, ], []); } @@ -120,7 +120,7 @@ public function testConstructLeeway(): void $provider = new OpenIdConfigurationProvider([ 'cacheItemPool' => $mockCacheItemPool, - 'openIDConnectMetadataUrl' => 'https://some.url/openid-configuration', + 'openIDConnectMetadataUrl' => 'https://provider.example.org/openid-configuration', 'leeway' => -10, ], []); } @@ -133,7 +133,7 @@ public function testConstructZeroCacheDurationAndLeewayAccepted(): void // tolerate no clock skew. Only negative values are rejected. $provider = new OpenIdConfigurationProvider([ 'cacheItemPool' => $mockCacheItemPool, - 'openIDConnectMetadataUrl' => 'https://some.url/openid-configuration', + 'openIDConnectMetadataUrl' => 'https://provider.example.org/openid-configuration', 'cacheDuration' => 0, 'leeway' => 0, ], []); @@ -148,7 +148,7 @@ public function testConstructWiresJwtCollaboratorAsRequestFactory(): void $provider = new OpenIdConfigurationProvider([ 'cacheItemPool' => $mockCacheItemPool, - 'openIDConnectMetadataUrl' => 'https://some.url/openid-configuration', + 'openIDConnectMetadataUrl' => 'https://provider.example.org/openid-configuration', ], [ 'jwt' => $requestFactory, ]); @@ -364,11 +364,11 @@ public function testConstructHttpUrlNotAllowed(): void $mockCacheItemPool = $this->createStub(CacheItemPoolInterface::class); $this->expectException(IllegalSchemeException::class); - $this->expectExceptionMessage('OpenIDConnectMetadataUrl must use https: http://some.url/openid-configuration'); + $this->expectExceptionMessage('OpenIDConnectMetadataUrl must use https: http://provider.example.org/openid-configuration'); new OpenIdConfigurationProvider([ 'cacheItemPool' => $mockCacheItemPool, - 'openIDConnectMetadataUrl' => 'http://some.url/openid-configuration', + 'openIDConnectMetadataUrl' => 'http://provider.example.org/openid-configuration', ], []); } @@ -383,7 +383,7 @@ public function testConstructHttpUrlAllowed(): void $provider = new OpenIdConfigurationProvider([ 'cacheItemPool' => $mockCacheItemPool, - 'openIDConnectMetadataUrl' => 'http://some.url/openid-configuration', + 'openIDConnectMetadataUrl' => 'http://provider.example.org/openid-configuration', 'allowHttp' => true, 'clientId' => self::CLIENT_ID, 'clientSecret' => self::CLIENT_SECRET, @@ -518,7 +518,7 @@ public function testValidateIdTokenArrayAudienceInvalid(): void public function testGetIdTokenSuccess(): void { $tokenEndpoint = 'https://azure_b2c_test.b2clogin.com/azure_b2c_test.onmicrosoft.com/oauth2/v2.0/token?p=test-policy'; - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $jwks_uri = 'https://azure_b2c_test.b2clogin.com/azure_b2c_test.onmicrosoft.com/discovery/v2.0/keys?p=test-policy'; $mockConfigResponse = $this->getMockHttpSuccessResponse('/../MockData/mockOpenIDConfiguration.json'); @@ -568,7 +568,7 @@ public function testGetIdTokenSuccess(): void public function testGetIdTokenFailure(): void { - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $mockHttpClient = $this->createStub(ClientInterface::class); // PSR-18 transport stub — Guzzle's real exceptions need a RequestInterface @@ -608,7 +608,7 @@ public function testGetIdTokenFailure(): void public function testGetIdTokenRejectsInvalidJsonResponse(): void { $tokenEndpoint = 'https://azure_b2c_test.b2clogin.com/azure_b2c_test.onmicrosoft.com/oauth2/v2.0/token?p=test-policy'; - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $mockConfigResponse = $this->getMockHttpSuccessResponse('/../MockData/mockOpenIDConfiguration.json'); @@ -663,7 +663,7 @@ public function testGetIdTokenRejectsInvalidJsonResponse(): void public function testGetIdTokenRejectsResponseWithoutStringIdToken(): void { $tokenEndpoint = 'https://azure_b2c_test.b2clogin.com/azure_b2c_test.onmicrosoft.com/oauth2/v2.0/token?p=test-policy'; - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $mockConfigResponse = $this->getMockHttpSuccessResponse('/../MockData/mockOpenIDConfiguration.json'); @@ -726,7 +726,7 @@ public function testGetConfigurationCacheHit(): void $mockHttpClient = $this->createStub(ClientInterface::class); $provider = new OpenIdConfigurationProvider([ - 'openIDConnectMetadataUrl' => 'https://some.url/openid-configuration', + 'openIDConnectMetadataUrl' => 'https://provider.example.org/openid-configuration', 'cacheItemPool' => $mockCacheItemPool, 'clientId' => self::CLIENT_ID, 'clientSecret' => self::CLIENT_SECRET, @@ -758,7 +758,7 @@ public function testGetConfigurationNonStringValue(): void $mockCacheItemPool->method('getItem')->willReturn($mockCacheItem); $provider = new OpenIdConfigurationProvider([ - 'openIDConnectMetadataUrl' => 'https://some.url/openid-configuration', + 'openIDConnectMetadataUrl' => 'https://provider.example.org/openid-configuration', 'cacheItemPool' => $mockCacheItemPool, 'clientId' => self::CLIENT_ID, 'clientSecret' => self::CLIENT_SECRET, @@ -776,7 +776,7 @@ public function testGetConfigurationNonStringValue(): void public function testFetchJsonResourceNon200(): void { - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $mockStream = $this->createStub(StreamInterface::class); $mockStream->method('getContents')->willReturn(''); @@ -805,14 +805,14 @@ public function testFetchJsonResourceNon200(): void ]); $this->expectException(HttpException::class); - $this->expectExceptionMessage('Cannot access json resource: https://some.url/openid-configuration'); + $this->expectExceptionMessage('Cannot access json resource: https://provider.example.org/openid-configuration'); $provider->getBaseAuthorizationUrl(); } public function testFetchJsonResourceClientException(): void { - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $mockHttpClient = $this->createStub(ClientInterface::class); $exception = new class('Connection refused') extends \RuntimeException implements ClientExceptionInterface { @@ -849,7 +849,7 @@ public function testFetchJsonResourceClientException(): void public function testFetchJsonResourceInvalidJson(): void { - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $mockStream = $this->createStub(StreamInterface::class); $mockStream->method('getContents')->willReturn('not valid json{{{'); @@ -938,7 +938,7 @@ public function testGetJwtVerificationKeysRejectsRsaWithoutStringExpOrModulus(): public function testGetJwtVerificationKeysRejectsNonStringKid(): void { - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $jwks_uri = 'https://azure_b2c_test.b2clogin.com/azure_b2c_test.onmicrosoft.com/discovery/v2.0/keys?p=test-policy'; $mockConfigResponse = $this->getMockHttpSuccessResponse('/../MockData/mockOpenIDConfiguration.json'); @@ -985,7 +985,7 @@ public function testGetJwtVerificationKeysRejectsNonStringKid(): void public function testGetJwtVerificationKeysUnsupportedKeyType(): void { - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $jwks_uri = 'https://azure_b2c_test.b2clogin.com/azure_b2c_test.onmicrosoft.com/discovery/v2.0/keys?p=test-policy'; $mockConfigResponse = $this->getMockHttpSuccessResponse('/../MockData/mockOpenIDConfiguration.json'); @@ -1031,7 +1031,7 @@ public function testGetJwtVerificationKeysUnsupportedKeyType(): void public function testGetJwtVerificationKeysCacheHit(): void { - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $configuration = $this->loadMockFixture('mockOpenIDConfiguration.json'); @@ -1078,7 +1078,7 @@ public function testGetJwtVerificationKeysCacheHit(): void public function testGetConfigurationCachesFetchedDocument(): void { - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $configuration = $this->loadMockFixture('mockOpenIDConfiguration.json'); $mockConfigResponse = $this->getMockHttpSuccessResponse('/../MockData/mockOpenIDConfiguration.json'); @@ -1115,7 +1115,7 @@ public function testGetConfigurationCachesFetchedDocument(): void public function testGetJwtVerificationKeysCachesFetchedKeys(): void { - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $configuration = $this->loadMockFixture('mockOpenIDConfiguration.json'); $mockKeysResponse = $this->getMockHttpSuccessResponse('/../MockData/mockOpenIDValidationKeys.json'); @@ -1194,7 +1194,7 @@ public function testGetJwtVerificationKeysBuildsAllJwksKeys(): void public function testGetConfigurationCacheInvalidArgument(): void { - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $exception = new class('Invalid cache key') extends \InvalidArgumentException implements \Psr\Cache\InvalidArgumentException { }; @@ -1227,7 +1227,7 @@ public function testGetConfigurationCacheInvalidArgument(): void public function testGetJwtVerificationKeysCacheInvalidArgument(): void { - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $configuration = $this->loadMockFixture('mockOpenIDConfiguration.json'); $configCacheItem = $this->createStub(CacheItemInterface::class); @@ -1272,7 +1272,7 @@ public function testGetJwtVerificationKeysCacheInvalidArgument(): void public function testBase64urlDecodeFailure(): void { - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $jwks_uri = 'https://azure_b2c_test.b2clogin.com/azure_b2c_test.onmicrosoft.com/discovery/v2.0/keys?p=test-policy'; $mockConfigResponse = $this->getMockHttpSuccessResponse('/../MockData/mockOpenIDConfiguration.json'); @@ -1348,7 +1348,7 @@ private function loadMockFixture(string $filename): array */ private function createProviderWithCustomJwks(string $jwksJson): OpenIdConfigurationProvider { - $openIDConnectMetadataUrl = 'https://some.url/openid-configuration'; + $openIDConnectMetadataUrl = 'https://provider.example.org/openid-configuration'; $jwks_uri = 'https://azure_b2c_test.b2clogin.com/azure_b2c_test.onmicrosoft.com/discovery/v2.0/keys?p=test-policy'; $mockConfigResponse = $this->getMockHttpSuccessResponse('/../MockData/mockOpenIDConfiguration.json');