From 1ee52e899f97392dee74de85e5e0f52c67a3fb82 Mon Sep 17 00:00:00 2001 From: Rick Lambrechts Date: Fri, 27 Sep 2024 12:18:41 +0200 Subject: [PATCH 01/11] fix: remove overloaded properties of OpenIDConnectClient --- composer.json | 2 +- src/OpenIDConnectClient.php | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/composer.json b/composer.json index 09fed59..397a6f1 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ }, "require": { "php": ">=8.1", - "jumbojett/openid-connect-php": "^1.0.0", + "jumbojett/openid-connect-php": "^1.0.2", "guzzlehttp/guzzle": "^7.5", "web-token/jwt-library": "^3.4" }, diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index 856117a..d6924fd 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -20,15 +20,6 @@ class OpenIDConnectClient extends \Jumbojett\OpenIDConnectClient { protected ?JweDecryptInterface $jweDecrypter; protected ?OpenIDConfiguration $openIDConfiguration; - /** - * @var int|null Response code from the server - */ - protected ?int $responseCode; - - /** - * @var string|null Content type from the server - */ - private ?string $responseContentType; public function __construct( ?string $providerUrl = null, From 0ffd97790e546b1cbd26dbd1a58aa37e0141fc82 Mon Sep 17 00:00:00 2001 From: Rick Lambrechts Date: Mon, 30 Sep 2024 20:57:33 +0200 Subject: [PATCH 02/11] fix: remove unneeded excluded path of phpstan config --- phpstan.neon | 2 -- 1 file changed, 2 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 8baaf5e..5ba2d4f 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,7 +2,5 @@ parameters: paths: - src level: 8 - excludePaths: - - src/BaseOpenIDConnectClient.php includes: - phar://phpstan.phar/conf/bleedingEdge.neon From 5216e359ccda2103836dda50fa10967a0edf03d7 Mon Sep 17 00:00:00 2001 From: Rick Lambrechts Date: Mon, 30 Sep 2024 21:00:24 +0200 Subject: [PATCH 03/11] test: add test for state does not match exception and added needed sub claim --- .../LoginControllerResponseTest.php | 59 ++++++++++++++++--- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/tests/Feature/Http/Controllers/LoginControllerResponseTest.php b/tests/Feature/Http/Controllers/LoginControllerResponseTest.php index 790a004..b98a4a7 100644 --- a/tests/Feature/Http/Controllers/LoginControllerResponseTest.php +++ b/tests/Feature/Http/Controllers/LoginControllerResponseTest.php @@ -5,12 +5,15 @@ namespace MinVWS\OpenIDConnectLaravel\Tests\Feature\Http\Controllers; use Illuminate\Http\Client\Request; +use Illuminate\Http\Response; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Session; use Illuminate\Testing\TestResponse; +use Jumbojett\OpenIDConnectClientException; use MinVWS\OpenIDConnectLaravel\OpenIDConfiguration\OpenIDConfiguration; use MinVWS\OpenIDConnectLaravel\OpenIDConfiguration\OpenIDConfigurationLoader; +use MinVWS\OpenIDConnectLaravel\Services\ExceptionHandlerInterface; use MinVWS\OpenIDConnectLaravel\Tests\TestCase; use Mockery; @@ -129,11 +132,53 @@ public function codeChallengeMethodProvider(): array ]; } - public function testTokenSignedWithClientSecret(): void + public function testStateDoesNotMatch(): void + { + Http::fake([ + // Token requested by OpenIDConnectClient::authenticate() function. + // Currently needed because the package requests the token endpoint before checking the state. + // TODO: Remove if https://github.com/jumbojett/OpenID-Connect-PHP/pull/447 is merged. + 'https://provider.rdobeheer.nl/token' => Http::response([ + 'access_token' => 'access-token-from-token-endpoint', + 'id_token' => 'some-valid-token-not-needed-for-this-state-check', + 'token_type' => 'Bearer', + 'expires_in' => 3600, + ]), + ]); + + // Set OIDC config + $this->mockOpenIDConfigurationLoader(); + Config::set('oidc.issuer', 'https://provider.rdobeheer.nl'); + Config::set('oidc.client_id', 'test-client-id'); + Config::set('oidc.client_secret', 'the-secret-client-secret'); + + // Mock LoginResponseHandlerInterface to check handleExceptionWhileAuthenticate is called. + $mock = Mockery::mock(ExceptionHandlerInterface::class); + $mock + ->shouldReceive('handleExceptionWhileAuthenticate') + ->withArgs(function (OpenIDConnectClientException $e) { + return $e->getMessage() === 'Unable to determine state'; + }) + ->once() + ->andReturn(new Response('', 400)); + $this->app->instance(ExceptionHandlerInterface::class, $mock); + + // Set the current state, which is usually generated and saved in the session before login, + // and sent to the issuer during the login redirect. + Session::put('openid_connect_state', 'some-state'); + + // We simulate here that the state does not match with the state in the session. + // And that the repsonse of ExceptionHandlerInterface is returned. + $response = $this->getRoute('oidc.login', ['code' => 'some-code', 'state' => 'a-different-state']); + $response->assertStatus(400); + } + + public function testIdTokenSignedWithClientSecret(): void { $idToken = generateJwt([ "iss" => "https://provider.rdobeheer.nl", "aud" => 'test-client-id', + "sub" => 'test-subject', ], 'the-secret-client-secret'); Http::fake([ @@ -146,7 +191,7 @@ public function testTokenSignedWithClientSecret(): void ]), // User info requested by OpenIDConnectClient::requestUserInfo() function. 'https://provider.rdobeheer.nl/userinfo?schema=openid' => Http::response([ - 'email' => 'teste@rdobeheer.nl', + 'email' => 'tester@rdobeheer.nl', ]), ]); @@ -157,8 +202,8 @@ public function testTokenSignedWithClientSecret(): void Config::set('oidc.client_id', 'test-client-id'); Config::set('oidc.client_secret', 'the-secret-client-secret'); - // Set current state, normally this is generated before logging in and send - // to the issuer, when the user is redirected for login. + // Set the current state, which is usually generated and saved in the session before login, + // and sent to the issuer during the login redirect. Session::put('openid_connect_state', 'some-state'); // We simulate here that the user now comes back after successful login at issuer. @@ -166,7 +211,7 @@ public function testTokenSignedWithClientSecret(): void $response->assertStatus(200); $response->assertJson([ 'userInfo' => [ - 'email' => 'teste@rdobeheer.nl', + 'email' => 'tester@rdobeheer.nl', ] ]); @@ -234,8 +279,8 @@ public function testTokenSignedWithPrivateKey(): void [$key, $keyResource] = generateOpenSSLKey(); Config::set('oidc.client_authentication.signing_private_key_path', stream_get_meta_data($keyResource)['uri']); - // Set current state, normally this is generated before logging in and send - // to the issuer, when the user is redirected for login. + // Set the current state, which is usually generated and saved in the session before login, + // and sent to the issuer during the login redirect. Session::put('openid_connect_state', 'some-state'); // We simulate here that the user now comes back after successful login at issuer. From 42eb9dae349c75bbdcf59668ceb57a24aeb57e79 Mon Sep 17 00:00:00 2001 From: Rick Lambrechts Date: Mon, 30 Sep 2024 21:19:17 +0200 Subject: [PATCH 04/11] test: add test for state does not match exception and added needed sub claim --- .../Http/Controllers/LoginControllerResponseTest.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/Feature/Http/Controllers/LoginControllerResponseTest.php b/tests/Feature/Http/Controllers/LoginControllerResponseTest.php index b98a4a7..f380f5a 100644 --- a/tests/Feature/Http/Controllers/LoginControllerResponseTest.php +++ b/tests/Feature/Http/Controllers/LoginControllerResponseTest.php @@ -5,7 +5,6 @@ namespace MinVWS\OpenIDConnectLaravel\Tests\Feature\Http\Controllers; use Illuminate\Http\Client\Request; -use Illuminate\Http\Response; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Session; @@ -159,8 +158,7 @@ public function testStateDoesNotMatch(): void ->withArgs(function (OpenIDConnectClientException $e) { return $e->getMessage() === 'Unable to determine state'; }) - ->once() - ->andReturn(new Response('', 400)); + ->once(); $this->app->instance(ExceptionHandlerInterface::class, $mock); // Set the current state, which is usually generated and saved in the session before login, @@ -168,9 +166,7 @@ public function testStateDoesNotMatch(): void Session::put('openid_connect_state', 'some-state'); // We simulate here that the state does not match with the state in the session. - // And that the repsonse of ExceptionHandlerInterface is returned. - $response = $this->getRoute('oidc.login', ['code' => 'some-code', 'state' => 'a-different-state']); - $response->assertStatus(400); + $this->getRoute('oidc.login', ['code' => 'some-code', 'state' => 'a-different-state']); } public function testIdTokenSignedWithClientSecret(): void From c683a4ba1979922ba628a2e6554202c11f277067 Mon Sep 17 00:00:00 2001 From: Rick Lambrechts Date: Mon, 30 Sep 2024 21:24:37 +0200 Subject: [PATCH 05/11] test: add test for invalid signed id token --- .../LoginControllerResponseTest.php | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/tests/Feature/Http/Controllers/LoginControllerResponseTest.php b/tests/Feature/Http/Controllers/LoginControllerResponseTest.php index f380f5a..8ca1a62 100644 --- a/tests/Feature/Http/Controllers/LoginControllerResponseTest.php +++ b/tests/Feature/Http/Controllers/LoginControllerResponseTest.php @@ -253,6 +253,72 @@ public function testIdTokenSignedWithClientSecret(): void }); } + public function testIdTokenSignedWithIncorrectClientSecret(): void + { + $idToken = generateJwt([ + "iss" => "https://provider.rdobeheer.nl", + "aud" => 'test-client-id', + "sub" => 'test-subject', + ], 'not-the-secret-client-secret'); + + Http::fake([ + // Token requested by OpenIDConnectClient::authenticate() function. + 'https://provider.rdobeheer.nl/token' => Http::response([ + 'access_token' => 'access-token-from-token-endpoint', + 'id_token' => $idToken, + 'token_type' => 'Bearer', + 'expires_in' => 3600, + ]), + ]); + + // Set OIDC config + $this->mockOpenIDConfigurationLoader(); + Config::set('oidc.issuer', 'https://provider.rdobeheer.nl'); + Config::set('oidc.client_id', 'test-client-id'); + Config::set('oidc.client_secret', 'the-secret-client-secret'); + + // Mock LoginResponseHandlerInterface to check handleExceptionWhileAuthenticate is called. + $mock = Mockery::mock(ExceptionHandlerInterface::class); + $mock + ->shouldReceive('handleExceptionWhileAuthenticate') + ->withArgs(function (OpenIDConnectClientException $e) { + return $e->getMessage() === 'Unable to verify signature'; + }) + ->once(); + $this->app->instance(ExceptionHandlerInterface::class, $mock); + + // Set the current state, which is usually generated and saved in the session before login, + // and sent to the issuer during the login redirect. + Session::put('openid_connect_state', 'some-state'); + + // We simulate here that the user now comes back after successful login at issuer. + $this->getRoute('oidc.login', ['code' => 'some-code', 'state' => 'some-state']); + + Http::assertSentCount(1); + Http::assertSentInOrder([ + 'https://provider.rdobeheer.nl/token', + ]); + Http::assertSent(function (Request $request) { + if ($request->url() === 'https://provider.rdobeheer.nl/token') { + $this->assertSame( + expected: 'POST', + actual: $request->method(), + ); + $this->assertSame( + expected: 'grant_type=authorization_code' + . '&code=some-code' + . '&redirect_uri=http%3A%2F%2Flocalhost%2Foidc%2Flogin' + . '&client_id=test-client-id' + . '&client_secret=the-secret-client-secret', + actual: $request->body(), + ); + return true; + } + return true; + }); + } + + public function testTokenSignedWithPrivateKey(): void { Http::fake([ From 6d1efec2a874612b56e5b8ae342caac6411bdb37 Mon Sep 17 00:00:00 2001 From: Rick Lambrechts Date: Mon, 30 Sep 2024 21:26:56 +0200 Subject: [PATCH 06/11] test: add test for client secret signed user info --- .../LoginControllerResponseTest.php | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/tests/Feature/Http/Controllers/LoginControllerResponseTest.php b/tests/Feature/Http/Controllers/LoginControllerResponseTest.php index 8ca1a62..a49132b 100644 --- a/tests/Feature/Http/Controllers/LoginControllerResponseTest.php +++ b/tests/Feature/Http/Controllers/LoginControllerResponseTest.php @@ -318,6 +318,100 @@ public function testIdTokenSignedWithIncorrectClientSecret(): void }); } + public function testIdTokenAndUserinfoSignedWithClientSecret(): void + { + $idToken = generateJwt([ + "iss" => "https://provider.rdobeheer.nl", + "aud" => 'test-client-id', + "sub" => 'test-subject', + ], 'the-secret-client-secret'); + + $signedUserInfo = generateJwt([ + "iss" => "https://provider.rdobeheer.nl", + "aud" => 'test-client-id', + "sub" => 'test-subject', + "email" => 'tester@rdobeheer.nl', + ], 'the-secret-client-secret'); + + Http::fake([ + // Token requested by OpenIDConnectClient::authenticate() function. + 'https://provider.rdobeheer.nl/token' => Http::response([ + 'access_token' => 'access-token-from-token-endpoint', + 'id_token' => $idToken, + 'token_type' => 'Bearer', + 'expires_in' => 3600, + ]), + // User info requested by OpenIDConnectClient::requestUserInfo() function. + 'https://provider.rdobeheer.nl/userinfo?schema=openid' => Http::response( + body: $signedUserInfo, + status: 200, + headers: [ + 'Content-Type' => 'application/jwt', + ] + ), + ]); + + // Set OIDC config + $this->mockOpenIDConfigurationLoader(); + + Config::set('oidc.issuer', 'https://provider.rdobeheer.nl'); + Config::set('oidc.client_id', 'test-client-id'); + Config::set('oidc.client_secret', 'the-secret-client-secret'); + + // Set the current state, which is usually generated and saved in the session before login, + // and sent to the issuer during the login redirect. + Session::put('openid_connect_state', 'some-state'); + + // We simulate here that the user now comes back after successful login at issuer. + $response = $this->getRoute('oidc.login', ['code' => 'some-code', 'state' => 'some-state']); + $response->assertStatus(200); + $response->assertJson([ + 'userInfo' => [ + 'email' => 'tester@rdobeheer.nl', + ] + ]); + + $this->assertEmpty(session('openid_connect_state')); + $this->assertEmpty(session('openid_connect_nonce')); + + Http::assertSentCount(2); + Http::assertSentInOrder([ + 'https://provider.rdobeheer.nl/token', + 'https://provider.rdobeheer.nl/userinfo?schema=openid', + ]); + Http::assertSent(function (Request $request) { + if ($request->url() === 'https://provider.rdobeheer.nl/token') { + $this->assertSame( + expected: 'POST', + actual: $request->method(), + ); + $this->assertSame( + expected: 'grant_type=authorization_code' + . '&code=some-code' + . '&redirect_uri=http%3A%2F%2Flocalhost%2Foidc%2Flogin' + . '&client_id=test-client-id' + . '&client_secret=the-secret-client-secret', + actual: $request->body(), + ); + return true; + } + + if ($request->url() === 'https://provider.rdobeheer.nl/userinfo?schema=openid') { + $this->assertSame( + expected: 'GET', + actual: $request->method(), + ); + $this->assertSame( + expected: [ + 'Bearer access-token-from-token-endpoint' + ], + actual: $request->header('Authorization'), + ); + } + + return true; + }); + } public function testTokenSignedWithPrivateKey(): void { From 6ba58e55a1742339529807d6359df6318d0a3700 Mon Sep 17 00:00:00 2001 From: Rick Lambrechts Date: Mon, 30 Sep 2024 21:45:46 +0200 Subject: [PATCH 07/11] test: add test to test exception when sub claims differ. --- .../LoginControllerResponseTest.php | 111 +++++++++++++++++- 1 file changed, 105 insertions(+), 6 deletions(-) diff --git a/tests/Feature/Http/Controllers/LoginControllerResponseTest.php b/tests/Feature/Http/Controllers/LoginControllerResponseTest.php index a49132b..fe158d6 100644 --- a/tests/Feature/Http/Controllers/LoginControllerResponseTest.php +++ b/tests/Feature/Http/Controllers/LoginControllerResponseTest.php @@ -152,14 +152,14 @@ public function testStateDoesNotMatch(): void Config::set('oidc.client_secret', 'the-secret-client-secret'); // Mock LoginResponseHandlerInterface to check handleExceptionWhileAuthenticate is called. - $mock = Mockery::mock(ExceptionHandlerInterface::class); - $mock + $mockExceptionHandler = Mockery::mock(ExceptionHandlerInterface::class); + $mockExceptionHandler ->shouldReceive('handleExceptionWhileAuthenticate') ->withArgs(function (OpenIDConnectClientException $e) { return $e->getMessage() === 'Unable to determine state'; }) ->once(); - $this->app->instance(ExceptionHandlerInterface::class, $mock); + $this->app->instance(ExceptionHandlerInterface::class, $mockExceptionHandler); // Set the current state, which is usually generated and saved in the session before login, // and sent to the issuer during the login redirect. @@ -278,14 +278,14 @@ public function testIdTokenSignedWithIncorrectClientSecret(): void Config::set('oidc.client_secret', 'the-secret-client-secret'); // Mock LoginResponseHandlerInterface to check handleExceptionWhileAuthenticate is called. - $mock = Mockery::mock(ExceptionHandlerInterface::class); - $mock + $mockExceptionHandler = Mockery::mock(ExceptionHandlerInterface::class); + $mockExceptionHandler ->shouldReceive('handleExceptionWhileAuthenticate') ->withArgs(function (OpenIDConnectClientException $e) { return $e->getMessage() === 'Unable to verify signature'; }) ->once(); - $this->app->instance(ExceptionHandlerInterface::class, $mock); + $this->app->instance(ExceptionHandlerInterface::class, $mockExceptionHandler); // Set the current state, which is usually generated and saved in the session before login, // and sent to the issuer during the login redirect. @@ -413,6 +413,105 @@ public function testIdTokenAndUserinfoSignedWithClientSecret(): void }); } + public function testSubClaimIdTokenDoesNotEqualsSubClaimUserinfo(): void + { + $idToken = generateJwt([ + "iss" => "https://provider.rdobeheer.nl", + "aud" => 'test-client-id', + "sub" => 'test-subject', + ], 'the-secret-client-secret'); + + $signedUserInfo = generateJwt([ + "iss" => "https://provider.rdobeheer.nl", + "aud" => 'test-client-id', + "sub" => 'different-subject', + "email" => 'tester@rdobeheer.nl', + ], 'the-secret-client-secret'); + + Http::fake([ + // Token requested by OpenIDConnectClient::authenticate() function. + 'https://provider.rdobeheer.nl/token' => Http::response([ + 'access_token' => 'access-token-from-token-endpoint', + 'id_token' => $idToken, + 'token_type' => 'Bearer', + 'expires_in' => 3600, + ]), + // User info requested by OpenIDConnectClient::requestUserInfo() function. + 'https://provider.rdobeheer.nl/userinfo?schema=openid' => Http::response( + body: $signedUserInfo, + status: 200, + headers: [ + 'Content-Type' => 'application/jwt', + ] + ), + ]); + + // Set OIDC config + $this->mockOpenIDConfigurationLoader(); + + Config::set('oidc.issuer', 'https://provider.rdobeheer.nl'); + Config::set('oidc.client_id', 'test-client-id'); + Config::set('oidc.client_secret', 'the-secret-client-secret'); + + // Mock LoginResponseHandlerInterface to check handleExceptionWhileRequestUserInfo is called. + $mockExceptionHandler = Mockery::mock(ExceptionHandlerInterface::class); + $mockExceptionHandler + ->shouldReceive('handleExceptionWhileRequestUserInfo') + ->withArgs(function (OpenIDConnectClientException $e) { + return $e->getMessage() === 'Invalid JWT signature'; + }) + ->once(); + $this->app->instance(ExceptionHandlerInterface::class, $mockExceptionHandler); + + // Set the current state, which is usually generated and saved in the session before login, + // and sent to the issuer during the login redirect. + Session::put('openid_connect_state', 'some-state'); + + // We simulate here that the user now comes back after successful login at issuer. + $this->getRoute('oidc.login', ['code' => 'some-code', 'state' => 'some-state']); + + $this->assertEmpty(session('openid_connect_state')); + $this->assertEmpty(session('openid_connect_nonce')); + + Http::assertSentCount(2); + Http::assertSentInOrder([ + 'https://provider.rdobeheer.nl/token', + 'https://provider.rdobeheer.nl/userinfo?schema=openid', + ]); + Http::assertSent(function (Request $request) { + if ($request->url() === 'https://provider.rdobeheer.nl/token') { + $this->assertSame( + expected: 'POST', + actual: $request->method(), + ); + $this->assertSame( + expected: 'grant_type=authorization_code' + . '&code=some-code' + . '&redirect_uri=http%3A%2F%2Flocalhost%2Foidc%2Flogin' + . '&client_id=test-client-id' + . '&client_secret=the-secret-client-secret', + actual: $request->body(), + ); + return true; + } + + if ($request->url() === 'https://provider.rdobeheer.nl/userinfo?schema=openid') { + $this->assertSame( + expected: 'GET', + actual: $request->method(), + ); + $this->assertSame( + expected: [ + 'Bearer access-token-from-token-endpoint' + ], + actual: $request->header('Authorization'), + ); + } + + return true; + }); + } + public function testTokenSignedWithPrivateKey(): void { Http::fake([ From da2afedec58160ebc2ca3a188b4711645343c7d1 Mon Sep 17 00:00:00 2001 From: Rick Lambrechts Date: Mon, 10 Feb 2025 11:46:59 +0100 Subject: [PATCH 08/11] fix: rename overloaded responseContentType to internalResponseContentType --- src/OpenIDConnectClient.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/OpenIDConnectClient.php b/src/OpenIDConnectClient.php index d6924fd..286526b 100644 --- a/src/OpenIDConnectClient.php +++ b/src/OpenIDConnectClient.php @@ -21,6 +21,11 @@ class OpenIDConnectClient extends \Jumbojett\OpenIDConnectClient protected ?JweDecryptInterface $jweDecrypter; protected ?OpenIDConfiguration $openIDConfiguration; + /** + * @var string|null Content type from the server + */ + private ?string $internalResponseContentType = null; + public function __construct( ?string $providerUrl = null, ?string $clientId = null, @@ -190,7 +195,7 @@ protected function fetchURL(string $url, string $post_body = null, array $header } $this->responseCode = $request->status(); - $this->responseContentType = $request->header('Content-Type'); + $this->internalResponseContentType = $request->header('Content-Type'); if ($request->failed()) { throw new OpenIDConnectClientException( @@ -218,7 +223,7 @@ public function getResponseCode(): int */ public function getResponseContentType(): ?string { - return $this->responseContentType; + return $this->internalResponseContentType; } public function setTlsVerify(bool|string $tlsVerify): void From ea97d7366502fdaa9ca64e3e28e8ac4cd64cb8b6 Mon Sep 17 00:00:00 2001 From: Rick Lambrechts Date: Mon, 10 Feb 2025 12:01:25 +0100 Subject: [PATCH 09/11] fix: remove typescript for linter --- src/Services/ExceptionHandler.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Services/ExceptionHandler.php b/src/Services/ExceptionHandler.php index de5a378..b351f9d 100644 --- a/src/Services/ExceptionHandler.php +++ b/src/Services/ExceptionHandler.php @@ -103,11 +103,6 @@ protected function default400Response(OpenIDConnectClientException $exception): protected function getRequest(): ?Request { - $request = request(); - if (!($request instanceof Request)) { - return null; - } - - return $request; + return request(); } } From 5572f8dbbef0e7c4f97a0462b51eead17e1720a2 Mon Sep 17 00:00:00 2001 From: Rick Lambrechts Date: Mon, 10 Feb 2025 12:07:35 +0100 Subject: [PATCH 10/11] fix: set psalm var type for linter --- src/Services/ExceptionHandler.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Services/ExceptionHandler.php b/src/Services/ExceptionHandler.php index b351f9d..147f747 100644 --- a/src/Services/ExceptionHandler.php +++ b/src/Services/ExceptionHandler.php @@ -103,6 +103,8 @@ protected function default400Response(OpenIDConnectClientException $exception): protected function getRequest(): ?Request { - return request(); + /** @psalm-var Request $request */ + $request = request(); + return $request; } } From 04c504dae652e3b5c8e1224a29d2e874267a2a15 Mon Sep 17 00:00:00 2001 From: Rick Lambrechts Date: Mon, 10 Feb 2025 16:41:49 +0100 Subject: [PATCH 11/11] chore: use example.com as example domain name --- .../LoginControllerResponseTest.php | 100 +++++++++--------- .../Http/Controllers/LoginControllerTest.php | 16 +-- .../OpenIDConfigurationLoaderTest.php | 82 +++++++------- 3 files changed, 99 insertions(+), 99 deletions(-) diff --git a/tests/Feature/Http/Controllers/LoginControllerResponseTest.php b/tests/Feature/Http/Controllers/LoginControllerResponseTest.php index fe158d6..c8627ae 100644 --- a/tests/Feature/Http/Controllers/LoginControllerResponseTest.php +++ b/tests/Feature/Http/Controllers/LoginControllerResponseTest.php @@ -78,7 +78,7 @@ public function testNonceAndStateAreSetInCache(): void $response ->assertStatus(302) - ->assertRedirectContains("https://provider.rdobeheer.nl/authorize") + ->assertRedirectContains("https://provider.example.com/authorize") ->assertRedirectContains('response_type=code') ->assertRedirectContains('redirect_uri=http%3A%2F%2Flocalhost%2Foidc%2Flogin') ->assertRedirectContains('client_id=test-client-id') @@ -108,7 +108,7 @@ public function testCodeChallengeIsSetWhenSupported( $response ->assertStatus(302) - ->assertRedirectContains("https://provider.rdobeheer.nl/authorize"); + ->assertRedirectContains("https://provider.example.com/authorize"); if ($codeChallengeShouldBeSet) { $response @@ -137,7 +137,7 @@ public function testStateDoesNotMatch(): void // Token requested by OpenIDConnectClient::authenticate() function. // Currently needed because the package requests the token endpoint before checking the state. // TODO: Remove if https://github.com/jumbojett/OpenID-Connect-PHP/pull/447 is merged. - 'https://provider.rdobeheer.nl/token' => Http::response([ + 'https://provider.example.com/token' => Http::response([ 'access_token' => 'access-token-from-token-endpoint', 'id_token' => 'some-valid-token-not-needed-for-this-state-check', 'token_type' => 'Bearer', @@ -147,7 +147,7 @@ public function testStateDoesNotMatch(): void // Set OIDC config $this->mockOpenIDConfigurationLoader(); - Config::set('oidc.issuer', 'https://provider.rdobeheer.nl'); + Config::set('oidc.issuer', 'https://provider.example.com'); Config::set('oidc.client_id', 'test-client-id'); Config::set('oidc.client_secret', 'the-secret-client-secret'); @@ -172,29 +172,29 @@ public function testStateDoesNotMatch(): void public function testIdTokenSignedWithClientSecret(): void { $idToken = generateJwt([ - "iss" => "https://provider.rdobeheer.nl", + "iss" => "https://provider.example.com", "aud" => 'test-client-id', "sub" => 'test-subject', ], 'the-secret-client-secret'); Http::fake([ // Token requested by OpenIDConnectClient::authenticate() function. - 'https://provider.rdobeheer.nl/token' => Http::response([ + 'https://provider.example.com/token' => Http::response([ 'access_token' => 'access-token-from-token-endpoint', 'id_token' => $idToken, 'token_type' => 'Bearer', 'expires_in' => 3600, ]), // User info requested by OpenIDConnectClient::requestUserInfo() function. - 'https://provider.rdobeheer.nl/userinfo?schema=openid' => Http::response([ - 'email' => 'tester@rdobeheer.nl', + 'https://provider.example.com/userinfo?schema=openid' => Http::response([ + 'email' => 'tester@example.com', ]), ]); // Set OIDC config $this->mockOpenIDConfigurationLoader(); - Config::set('oidc.issuer', 'https://provider.rdobeheer.nl'); + Config::set('oidc.issuer', 'https://provider.example.com'); Config::set('oidc.client_id', 'test-client-id'); Config::set('oidc.client_secret', 'the-secret-client-secret'); @@ -207,7 +207,7 @@ public function testIdTokenSignedWithClientSecret(): void $response->assertStatus(200); $response->assertJson([ 'userInfo' => [ - 'email' => 'tester@rdobeheer.nl', + 'email' => 'tester@example.com', ] ]); @@ -216,11 +216,11 @@ public function testIdTokenSignedWithClientSecret(): void Http::assertSentCount(2); Http::assertSentInOrder([ - 'https://provider.rdobeheer.nl/token', - 'https://provider.rdobeheer.nl/userinfo?schema=openid', + 'https://provider.example.com/token', + 'https://provider.example.com/userinfo?schema=openid', ]); Http::assertSent(function (Request $request) { - if ($request->url() === 'https://provider.rdobeheer.nl/token') { + if ($request->url() === 'https://provider.example.com/token') { $this->assertSame( expected: 'POST', actual: $request->method(), @@ -236,7 +236,7 @@ public function testIdTokenSignedWithClientSecret(): void return true; } - if ($request->url() === 'https://provider.rdobeheer.nl/userinfo?schema=openid') { + if ($request->url() === 'https://provider.example.com/userinfo?schema=openid') { $this->assertSame( expected: 'GET', actual: $request->method(), @@ -256,14 +256,14 @@ public function testIdTokenSignedWithClientSecret(): void public function testIdTokenSignedWithIncorrectClientSecret(): void { $idToken = generateJwt([ - "iss" => "https://provider.rdobeheer.nl", + "iss" => "https://provider.example.com", "aud" => 'test-client-id', "sub" => 'test-subject', ], 'not-the-secret-client-secret'); Http::fake([ // Token requested by OpenIDConnectClient::authenticate() function. - 'https://provider.rdobeheer.nl/token' => Http::response([ + 'https://provider.example.com/token' => Http::response([ 'access_token' => 'access-token-from-token-endpoint', 'id_token' => $idToken, 'token_type' => 'Bearer', @@ -273,7 +273,7 @@ public function testIdTokenSignedWithIncorrectClientSecret(): void // Set OIDC config $this->mockOpenIDConfigurationLoader(); - Config::set('oidc.issuer', 'https://provider.rdobeheer.nl'); + Config::set('oidc.issuer', 'https://provider.example.com'); Config::set('oidc.client_id', 'test-client-id'); Config::set('oidc.client_secret', 'the-secret-client-secret'); @@ -296,10 +296,10 @@ public function testIdTokenSignedWithIncorrectClientSecret(): void Http::assertSentCount(1); Http::assertSentInOrder([ - 'https://provider.rdobeheer.nl/token', + 'https://provider.example.com/token', ]); Http::assertSent(function (Request $request) { - if ($request->url() === 'https://provider.rdobeheer.nl/token') { + if ($request->url() === 'https://provider.example.com/token') { $this->assertSame( expected: 'POST', actual: $request->method(), @@ -321,28 +321,28 @@ public function testIdTokenSignedWithIncorrectClientSecret(): void public function testIdTokenAndUserinfoSignedWithClientSecret(): void { $idToken = generateJwt([ - "iss" => "https://provider.rdobeheer.nl", + "iss" => "https://provider.example.com", "aud" => 'test-client-id', "sub" => 'test-subject', ], 'the-secret-client-secret'); $signedUserInfo = generateJwt([ - "iss" => "https://provider.rdobeheer.nl", + "iss" => "https://provider.example.com", "aud" => 'test-client-id', "sub" => 'test-subject', - "email" => 'tester@rdobeheer.nl', + "email" => 'tester@example.com', ], 'the-secret-client-secret'); Http::fake([ // Token requested by OpenIDConnectClient::authenticate() function. - 'https://provider.rdobeheer.nl/token' => Http::response([ + 'https://provider.example.com/token' => Http::response([ 'access_token' => 'access-token-from-token-endpoint', 'id_token' => $idToken, 'token_type' => 'Bearer', 'expires_in' => 3600, ]), // User info requested by OpenIDConnectClient::requestUserInfo() function. - 'https://provider.rdobeheer.nl/userinfo?schema=openid' => Http::response( + 'https://provider.example.com/userinfo?schema=openid' => Http::response( body: $signedUserInfo, status: 200, headers: [ @@ -354,7 +354,7 @@ public function testIdTokenAndUserinfoSignedWithClientSecret(): void // Set OIDC config $this->mockOpenIDConfigurationLoader(); - Config::set('oidc.issuer', 'https://provider.rdobeheer.nl'); + Config::set('oidc.issuer', 'https://provider.example.com'); Config::set('oidc.client_id', 'test-client-id'); Config::set('oidc.client_secret', 'the-secret-client-secret'); @@ -367,7 +367,7 @@ public function testIdTokenAndUserinfoSignedWithClientSecret(): void $response->assertStatus(200); $response->assertJson([ 'userInfo' => [ - 'email' => 'tester@rdobeheer.nl', + 'email' => 'tester@example.com', ] ]); @@ -376,11 +376,11 @@ public function testIdTokenAndUserinfoSignedWithClientSecret(): void Http::assertSentCount(2); Http::assertSentInOrder([ - 'https://provider.rdobeheer.nl/token', - 'https://provider.rdobeheer.nl/userinfo?schema=openid', + 'https://provider.example.com/token', + 'https://provider.example.com/userinfo?schema=openid', ]); Http::assertSent(function (Request $request) { - if ($request->url() === 'https://provider.rdobeheer.nl/token') { + if ($request->url() === 'https://provider.example.com/token') { $this->assertSame( expected: 'POST', actual: $request->method(), @@ -396,7 +396,7 @@ public function testIdTokenAndUserinfoSignedWithClientSecret(): void return true; } - if ($request->url() === 'https://provider.rdobeheer.nl/userinfo?schema=openid') { + if ($request->url() === 'https://provider.example.com/userinfo?schema=openid') { $this->assertSame( expected: 'GET', actual: $request->method(), @@ -416,28 +416,28 @@ public function testIdTokenAndUserinfoSignedWithClientSecret(): void public function testSubClaimIdTokenDoesNotEqualsSubClaimUserinfo(): void { $idToken = generateJwt([ - "iss" => "https://provider.rdobeheer.nl", + "iss" => "https://provider.example.com", "aud" => 'test-client-id', "sub" => 'test-subject', ], 'the-secret-client-secret'); $signedUserInfo = generateJwt([ - "iss" => "https://provider.rdobeheer.nl", + "iss" => "https://provider.example.com", "aud" => 'test-client-id', "sub" => 'different-subject', - "email" => 'tester@rdobeheer.nl', + "email" => 'tester@example.com', ], 'the-secret-client-secret'); Http::fake([ // Token requested by OpenIDConnectClient::authenticate() function. - 'https://provider.rdobeheer.nl/token' => Http::response([ + 'https://provider.example.com/token' => Http::response([ 'access_token' => 'access-token-from-token-endpoint', 'id_token' => $idToken, 'token_type' => 'Bearer', 'expires_in' => 3600, ]), // User info requested by OpenIDConnectClient::requestUserInfo() function. - 'https://provider.rdobeheer.nl/userinfo?schema=openid' => Http::response( + 'https://provider.example.com/userinfo?schema=openid' => Http::response( body: $signedUserInfo, status: 200, headers: [ @@ -449,7 +449,7 @@ public function testSubClaimIdTokenDoesNotEqualsSubClaimUserinfo(): void // Set OIDC config $this->mockOpenIDConfigurationLoader(); - Config::set('oidc.issuer', 'https://provider.rdobeheer.nl'); + Config::set('oidc.issuer', 'https://provider.example.com'); Config::set('oidc.client_id', 'test-client-id'); Config::set('oidc.client_secret', 'the-secret-client-secret'); @@ -475,11 +475,11 @@ public function testSubClaimIdTokenDoesNotEqualsSubClaimUserinfo(): void Http::assertSentCount(2); Http::assertSentInOrder([ - 'https://provider.rdobeheer.nl/token', - 'https://provider.rdobeheer.nl/userinfo?schema=openid', + 'https://provider.example.com/token', + 'https://provider.example.com/userinfo?schema=openid', ]); Http::assertSent(function (Request $request) { - if ($request->url() === 'https://provider.rdobeheer.nl/token') { + if ($request->url() === 'https://provider.example.com/token') { $this->assertSame( expected: 'POST', actual: $request->method(), @@ -495,7 +495,7 @@ public function testSubClaimIdTokenDoesNotEqualsSubClaimUserinfo(): void return true; } - if ($request->url() === 'https://provider.rdobeheer.nl/userinfo?schema=openid') { + if ($request->url() === 'https://provider.example.com/userinfo?schema=openid') { $this->assertSame( expected: 'GET', actual: $request->method(), @@ -516,7 +516,7 @@ public function testTokenSignedWithPrivateKey(): void { Http::fake([ // Token requested by OpenIDConnectClient::authenticate() function. - 'https://provider.rdobeheer.nl/token' => Http::response([ + 'https://provider.example.com/token' => Http::response([ 'access_token' => 'access-token-from-token-endpoint', 'id_token' => 'does-not-matter-not-testing-id-token', 'token_type' => 'Bearer', @@ -527,7 +527,7 @@ public function testTokenSignedWithPrivateKey(): void // Set OIDC provider configuration $this->mockOpenIDConfigurationLoader(tokenEndpointAuthMethodsSupported: ['private_key_jwt']); - Config::set('oidc.issuer', 'https://provider.rdobeheer.nl'); + Config::set('oidc.issuer', 'https://provider.example.com'); Config::set('oidc.client_id', 'test-client-id'); // Set client private key @@ -547,14 +547,14 @@ public function testTokenSignedWithPrivateKey(): void Http::assertSentCount(1); Http::assertSentInOrder([ - 'https://provider.rdobeheer.nl/token', + 'https://provider.example.com/token', ]); Http::assertSent(function (Request $request) { - if (!in_array($request->url(), ['https://provider.rdobeheer.nl/token'], true)) { + if (!in_array($request->url(), ['https://provider.example.com/token'], true)) { return false; } - if ($request->url() === 'https://provider.rdobeheer.nl/token') { + if ($request->url() === 'https://provider.example.com/token') { $this->assertSame( expected: 'POST', actual: $request->method(), @@ -610,16 +610,16 @@ protected function exampleOpenIDConfiguration( frontchannelLogoutSessionSupported: false, backchannelLogoutSupported: false, backchannelLogoutSessionSupported: false, - issuer: "https://provider.rdobeheer.nl", - authorizationEndpoint: "https://provider.rdobeheer.nl/authorize", - jwksUri: "https://provider.rdobeheer.nl/jwks", - tokenEndpoint: "https://provider.rdobeheer.nl/token", + issuer: "https://provider.example.com", + authorizationEndpoint: "https://provider.example.com/authorize", + jwksUri: "https://provider.example.com/jwks", + tokenEndpoint: "https://provider.example.com/token", scopesSupported: ["openid"], responseTypesSupported: ["code"], responseModesSupported: ["query"], subjectTypesSupported: ["pairwise"], idTokenSigningAlgValuesSupported: ["RS256"], - userinfoEndpoint: "https://provider.rdobeheer.nl/userinfo", + userinfoEndpoint: "https://provider.example.com/userinfo", codeChallengeMethodsSupported: $codeChallengeMethodsSupported, ); } diff --git a/tests/Feature/Http/Controllers/LoginControllerTest.php b/tests/Feature/Http/Controllers/LoginControllerTest.php index 133f054..c9d85bd 100644 --- a/tests/Feature/Http/Controllers/LoginControllerTest.php +++ b/tests/Feature/Http/Controllers/LoginControllerTest.php @@ -32,7 +32,7 @@ public function testLoginRouteRedirectsToAuthorizeUrlOfProvider(): void $response = $this->get(route('oidc.login')); $response ->assertStatus(302) - ->assertRedirectContains("https://provider.rdobeheer.nl/authorize") + ->assertRedirectContains("https://provider.example.com/authorize") ->assertRedirectContains('response_type=code') ->assertRedirectContains('redirect_uri=http%3A%2F%2Flocalhost%2Foidc%2Flogin') ->assertRedirectContains('client_id=test-client-id') @@ -55,7 +55,7 @@ public function testLoginRouteRedirectsToAuthorizeUrlOfProviderWithScopes( $response = $this->get(route('oidc.login', ['login_hint' => 'test-login-hint'])); $response ->assertStatus(302) - ->assertRedirectContains("https://provider.rdobeheer.nl/authorize") + ->assertRedirectContains("https://provider.example.com/authorize") ->assertRedirectContains('test-client-id') ->assertRedirectContains('login_hint=test-login-hint') ->assertRedirectContains($scopeInUrl); @@ -79,7 +79,7 @@ public function testLoginRouteRedirectsToAuthorizeUrlOfProviderWithLoginHint(): $response = $this->get(route('oidc.login', ['login_hint' => 'test-login-hint'])); $response ->assertStatus(302) - ->assertRedirectContains("https://provider.rdobeheer.nl/authorize") + ->assertRedirectContains("https://provider.example.com/authorize") ->assertRedirectContains('test-client-id') ->assertRedirectContains('login_hint=test-login-hint'); } @@ -139,16 +139,16 @@ protected function exampleOpenIDConfiguration(): OpenIDConfiguration frontchannelLogoutSessionSupported: false, backchannelLogoutSupported: false, backchannelLogoutSessionSupported: false, - issuer: "https://provider.rdobeheer.nl", - authorizationEndpoint: "https://provider.rdobeheer.nl/authorize", - jwksUri: "https://provider.rdobeheer.nl/jwks", - tokenEndpoint: "https://provider.rdobeheer.nl/token", + issuer: "https://provider.example.com", + authorizationEndpoint: "https://provider.example.com/authorize", + jwksUri: "https://provider.example.com/jwks", + tokenEndpoint: "https://provider.example.com/token", scopesSupported: ["openid"], responseTypesSupported: ["code"], responseModesSupported: ["query"], subjectTypesSupported: ["pairwise"], idTokenSigningAlgValuesSupported: ["RS256"], - userinfoEndpoint: "https://provider.rdobeheer.nl/userinfo", + userinfoEndpoint: "https://provider.example.com/userinfo", codeChallengeMethodsSupported: ["S256"], ); } diff --git a/tests/Feature/OpenIDConfiguration/OpenIDConfigurationLoaderTest.php b/tests/Feature/OpenIDConfiguration/OpenIDConfigurationLoaderTest.php index 8e58d75..251d3dc 100644 --- a/tests/Feature/OpenIDConfiguration/OpenIDConfigurationLoaderTest.php +++ b/tests/Feature/OpenIDConfiguration/OpenIDConfigurationLoaderTest.php @@ -27,17 +27,17 @@ public function testConfigurationIsLoaded(): void $this->fakeSuccessfulResponse(); $loader = new OpenIDConfigurationLoader( - 'https://provider.rdobeheer.nl', + 'https://provider.example.com', ); $configuration = $loader->getConfiguration(); $this->assertSame("3.0", $configuration->version); - $this->assertSame("https://provider.rdobeheer.nl", $configuration->issuer); - $this->assertSame("https://provider.rdobeheer.nl/authorize", $configuration->authorizationEndpoint); - $this->assertSame("https://provider.rdobeheer.nl/jwks", $configuration->jwksUri); - $this->assertSame("https://provider.rdobeheer.nl/token", $configuration->tokenEndpoint); - $this->assertSame("https://provider.rdobeheer.nl/userinfo", $configuration->userinfoEndpoint); + $this->assertSame("https://provider.example.com", $configuration->issuer); + $this->assertSame("https://provider.example.com/authorize", $configuration->authorizationEndpoint); + $this->assertSame("https://provider.example.com/jwks", $configuration->jwksUri); + $this->assertSame("https://provider.example.com/token", $configuration->tokenEndpoint); + $this->assertSame("https://provider.example.com/userinfo", $configuration->userinfoEndpoint); } public function testConfigurationIsLoadedMultipleTimesWhenNotCached(): void @@ -45,7 +45,7 @@ public function testConfigurationIsLoadedMultipleTimesWhenNotCached(): void $this->fakeSuccessfulResponse(); $loader = new OpenIDConfigurationLoader( - 'https://provider.rdobeheer.nl', + 'https://provider.example.com', ); // Load 2 times @@ -55,11 +55,11 @@ public function testConfigurationIsLoadedMultipleTimesWhenNotCached(): void Http::assertSentCount(2); $this->assertSame("3.0", $configuration->version); - $this->assertSame("https://provider.rdobeheer.nl", $configuration->issuer); - $this->assertSame("https://provider.rdobeheer.nl/authorize", $configuration->authorizationEndpoint); - $this->assertSame("https://provider.rdobeheer.nl/jwks", $configuration->jwksUri); - $this->assertSame("https://provider.rdobeheer.nl/token", $configuration->tokenEndpoint); - $this->assertSame("https://provider.rdobeheer.nl/userinfo", $configuration->userinfoEndpoint); + $this->assertSame("https://provider.example.com", $configuration->issuer); + $this->assertSame("https://provider.example.com/authorize", $configuration->authorizationEndpoint); + $this->assertSame("https://provider.example.com/jwks", $configuration->jwksUri); + $this->assertSame("https://provider.example.com/token", $configuration->tokenEndpoint); + $this->assertSame("https://provider.example.com/userinfo", $configuration->userinfoEndpoint); } public function testConfigurationIsCached(): void @@ -67,7 +67,7 @@ public function testConfigurationIsCached(): void $this->fakeSuccessfulResponse(); $loader = new OpenIDConfigurationLoader( - issuer: 'https://provider.rdobeheer.nl', + issuer: 'https://provider.example.com', cacheStore: Cache::store('array'), cacheTtl: 86400, ); @@ -82,11 +82,11 @@ public function testConfigurationIsCached(): void Http::assertSentCount(1); $this->assertSame("3.0", $configuration->version); - $this->assertSame("https://provider.rdobeheer.nl", $configuration->issuer); - $this->assertSame("https://provider.rdobeheer.nl/authorize", $configuration->authorizationEndpoint); - $this->assertSame("https://provider.rdobeheer.nl/jwks", $configuration->jwksUri); - $this->assertSame("https://provider.rdobeheer.nl/token", $configuration->tokenEndpoint); - $this->assertSame("https://provider.rdobeheer.nl/userinfo", $configuration->userinfoEndpoint); + $this->assertSame("https://provider.example.com", $configuration->issuer); + $this->assertSame("https://provider.example.com/authorize", $configuration->authorizationEndpoint); + $this->assertSame("https://provider.example.com/jwks", $configuration->jwksUri); + $this->assertSame("https://provider.example.com/token", $configuration->tokenEndpoint); + $this->assertSame("https://provider.example.com/userinfo", $configuration->userinfoEndpoint); } public function testLoaderThrowsExceptionWhenProviderReturns400ResponseCode(): void @@ -97,7 +97,7 @@ public function testLoaderThrowsExceptionWhenProviderReturns400ResponseCode(): v $this->expectExceptionMessage("Could not load OpenID configuration from issuer"); $loader = new OpenIDConfigurationLoader( - 'https://provider.rdobeheer.nl', + 'https://provider.example.com', ); $configuration = $loader->getConfiguration(); @@ -110,14 +110,14 @@ public function testLoaderThrowsExceptionWhenProviderReturns400ResponseCodeAsser try { $loader = new OpenIDConfigurationLoader( - 'https://provider.rdobeheer.nl', + 'https://provider.example.com', ); $configuration = $loader->getConfiguration(); } catch (OpenIDConfigurationLoaderException $exception) { $this->assertSame("Could not load OpenID configuration from issuer", $exception->getMessage()); $context = $exception->context(); - $this->assertSame("https://provider.rdobeheer.nl", $context['issuer']); + $this->assertSame("https://provider.example.com", $context['issuer']); $this->assertSame("/.well-known/openid-configuration", $context['url']); $this->assertSame(400, $context['response_status_code']); } @@ -129,14 +129,14 @@ public function testLoaderThrowsExceptionWhenProviderReturns500ResponseCodeAsser try { $loader = new OpenIDConfigurationLoader( - 'https://provider.rdobeheer.nl', + 'https://provider.example.com', ); $configuration = $loader->getConfiguration(); } catch (OpenIDConfigurationLoaderException $exception) { $this->assertSame("Could not load OpenID configuration from issuer", $exception->getMessage()); $context = $exception->context(); - $this->assertSame("https://provider.rdobeheer.nl", $context['issuer']); + $this->assertSame("https://provider.example.com", $context['issuer']); $this->assertSame("/.well-known/openid-configuration", $context['url']); $this->assertSame(500, $context['response_status_code']); } @@ -148,14 +148,14 @@ public function testLoaderThrowsExceptionWhenProviderReturns200ButNullResponse() try { $loader = new OpenIDConfigurationLoader( - 'https://provider.rdobeheer.nl', + 'https://provider.example.com', ); $configuration = $loader->getConfiguration(); } catch (OpenIDConfigurationLoaderException $exception) { $this->assertSame("Response body of OpenID configuration is not JSON", $exception->getMessage()); $context = $exception->context(); - $this->assertSame("https://provider.rdobeheer.nl", $context['issuer']); + $this->assertSame("https://provider.example.com", $context['issuer']); $this->assertSame("/.well-known/openid-configuration", $context['url']); $this->assertSame(200, $context['response_status_code']); $this->assertSame('', $context['response_body']); @@ -168,14 +168,14 @@ public function testLoaderThrowsExceptionWhenProviderReturns200ButStringResponse try { $loader = new OpenIDConfigurationLoader( - 'https://provider.rdobeheer.nl', + 'https://provider.example.com', ); $configuration = $loader->getConfiguration(); } catch (OpenIDConfigurationLoaderException $exception) { $this->assertSame("Response body of OpenID configuration is not JSON", $exception->getMessage()); $context = $exception->context(); - $this->assertSame("https://provider.rdobeheer.nl", $context['issuer']); + $this->assertSame("https://provider.example.com", $context['issuer']); $this->assertSame("/.well-known/openid-configuration", $context['url']); $this->assertSame(200, $context['response_status_code']); $this->assertSame('some invalid response', $context['response_body']); @@ -189,7 +189,7 @@ public function testLoaderReturnsEmptyConfigurationOnEmptyJsonResponse(): void $loader = new OpenIDConfigurationLoader( - 'https://provider.rdobeheer.nl', + 'https://provider.example.com', ); $configuration = $loader->getConfiguration(); @@ -205,7 +205,7 @@ public function testConfigurationIsLoadedMultipleTimesWhenCacheStoreIsNull(): vo $this->fakeSuccessfulResponse(); $loader = new OpenIDConfigurationLoader( - issuer: 'https://provider.rdobeheer.nl', + issuer: 'https://provider.example.com', cacheStore: Cache::store('null'), ); @@ -216,17 +216,17 @@ public function testConfigurationIsLoadedMultipleTimesWhenCacheStoreIsNull(): vo Http::assertSentCount(2); $this->assertSame("3.0", $configuration->version); - $this->assertSame("https://provider.rdobeheer.nl", $configuration->issuer); - $this->assertSame("https://provider.rdobeheer.nl/authorize", $configuration->authorizationEndpoint); - $this->assertSame("https://provider.rdobeheer.nl/jwks", $configuration->jwksUri); - $this->assertSame("https://provider.rdobeheer.nl/token", $configuration->tokenEndpoint); - $this->assertSame("https://provider.rdobeheer.nl/userinfo", $configuration->userinfoEndpoint); + $this->assertSame("https://provider.example.com", $configuration->issuer); + $this->assertSame("https://provider.example.com/authorize", $configuration->authorizationEndpoint); + $this->assertSame("https://provider.example.com/jwks", $configuration->jwksUri); + $this->assertSame("https://provider.example.com/token", $configuration->tokenEndpoint); + $this->assertSame("https://provider.example.com/userinfo", $configuration->userinfoEndpoint); } protected function fakeSuccessfulResponse(): void { Http::fake([ - 'https://provider.rdobeheer.nl/.well-known/openid-configuration' => Http::response([ + 'https://provider.example.com/.well-known/openid-configuration' => Http::response([ "version" => "3.0", "token_endpoint_auth_methods_supported" => [ "none" @@ -242,10 +242,10 @@ protected function fakeSuccessfulResponse(): void "frontchannel_logout_session_supported" => false, "backchannel_logout_supported" => false, "backchannel_logout_session_supported" => false, - "issuer" => "https://provider.rdobeheer.nl", - "authorization_endpoint" => "https://provider.rdobeheer.nl/authorize", - "jwks_uri" => "https://provider.rdobeheer.nl/jwks", - "token_endpoint" => "https://provider.rdobeheer.nl/token", + "issuer" => "https://provider.example.com", + "authorization_endpoint" => "https://provider.example.com/authorize", + "jwks_uri" => "https://provider.example.com/jwks", + "token_endpoint" => "https://provider.example.com/token", "scopes_supported" => [ "openid" ], @@ -258,7 +258,7 @@ protected function fakeSuccessfulResponse(): void "subject_types_supported" => [ "pairwise" ], - "userinfo_endpoint" => "https://provider.rdobeheer.nl/userinfo", + "userinfo_endpoint" => "https://provider.example.com/userinfo", "id_token_signing_alg_values_supported" => [ "RS256" ], @@ -272,7 +272,7 @@ protected function fakeSuccessfulResponse(): void protected function fakeInvalidResponse(int $statusCode, array|null|string $body): void { Http::fake([ - 'https://provider.rdobeheer.nl/*' => Http::response($body, $statusCode), + 'https://provider.example.com/*' => Http::response($body, $statusCode), ]); } }