From a22261af6ddcc4d7b8a74c7a1c0b0aa831101de5 Mon Sep 17 00:00:00 2001 From: Robert Lemke Date: Fri, 11 Sep 2026 09:32:41 +0200 Subject: [PATCH 1/2] Require Flow 9 and PHP 8.3, upgrade to PHPUnit 12 The package now requires Flow 9 and PHP 8.3 or later. It is tested with PHPUnit 12 on PHP 8.3, 8.4 and 8.5. lcobucci/jwt is raised to version 5, which supports PHP 8.5. Previously, the package supported Flow 7.3 and PHP 8.1. Keeping these versions would have pinned lcobucci/jwt to the outdated 4.x line and PHPUnit to version 10 at most. Flow 9.2 itself requires PHP 8.4, so current Flow applications are not affected. Still, this is a breaking change and needs a new major release. The tests use attributes and test stubs, as PHPUnit 12 expects. They now fail on deprecations, so PHP 8.5 issues show up in CI. One test built an authentication token without a provider name and triggered such a deprecation. Flow always sets that name, so the test was corrected instead of the middleware. --- .github/workflows/ci.yaml | 3 +- .gitignore | 1 + Tests/Unit/IdentityTokenTest.php | 29 ++++------- Tests/Unit/OpenIdConnectClientTest.php | 42 +++++----------- Tests/Unit/SetJwtCookieMiddlewareTest.php | 61 ++++++++++------------- composer.json | 13 +++-- phpunit.xml.dist | 14 ++++-- 7 files changed, 66 insertions(+), 97 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 34cf5fb..5ddb3c0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -22,10 +22,9 @@ jobs: - ubuntu-latest php-version: - - "8.1" - - "8.2" - "8.3" - "8.4" + - "8.5" dependencies: - lowest diff --git a/.gitignore b/.gitignore index 1a28732..8521ca6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ vendor Packages composer.lock +.phpunit.cache diff --git a/Tests/Unit/IdentityTokenTest.php b/Tests/Unit/IdentityTokenTest.php index 4d7d28e..10320f8 100644 --- a/Tests/Unit/IdentityTokenTest.php +++ b/Tests/Unit/IdentityTokenTest.php @@ -11,6 +11,8 @@ * source code. */ +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; class IdentityTokenTest extends TestCase @@ -28,11 +30,8 @@ public static function invalidJsonStrings(): array ]; } - /** - * @test - * @dataProvider invalidJsonStrings - * @throws - */ + #[Test] + #[DataProvider('invalidJsonStrings')] public function fromJsonRejectsInvalidJsonStrings(string $json, int $expectedExceptionCode): void { $this->expectException(\InvalidArgumentException::class); @@ -44,10 +43,8 @@ public function fromJsonRejectsInvalidJsonStrings(string $json, int $expectedExc * {"kid":"dfebe5e7-4232-4464-8f2e-151681a0d173","typ":"JWT","alg":"RS256"} * {"iss":"https://id.example.com","aud":"@!DDD5.370D.8547.FFD9!0001!A1C9.92C1!0008!13DB.54D8.65DE.2761","exp":1559205560,"iat":1559201960,"auth_time":1559201959,"at_hash":"_SPGts59ISlWMHxs2a03sw","oxOpenIDConnectVersion":"openidconnect-1.0","sub":"UWAYfzzmcaNAZy_C8a8UoUxMmhT1IlcKlXG8TnWkyIM"} * … (binary data of signature) … - * - * @test - * @throws */ + #[Test] public function fromJsonSetsValuesCorrectly(): void { $json = 'eyJraWQiOiJkZmViZTVlNy00MjMyLTQ0NjQtOGYyZS0xNTE2ODFhMGQxNzMiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL2lkLmV4YW1wbGUuY29tIiwiYXVkIjoiQCFEREQ1LjM3MEQuODU0Ny5GRkQ5ITAwMDEhQTFDOS45MkMxITAwMDghMTNEQi41NEQ4LjY1REUuMjc2MSIsImV4cCI6MTU1OTIwNTU2MCwiaWF0IjoxNTU5MjAxOTYwLCJhdXRoX3RpbWUiOjE1NTkyMDE5NTksImF0X2hhc2giOiJfU1BHdHM1OUlTbFdNSHhzMmEwM3N3Iiwib3hPcGVuSURDb25uZWN0VmVyc2lvbiI6Im9wZW5pZGNvbm5lY3QtMS4wIiwic3ViIjoiVVdBWWZ6em1jYU5BWnlfQzhhOFVvVXhNbWhUMUlsY0tsWEc4VG5Xa3lJTSJ9.VsOdosHuRWVaoacWG1CNJl0IZrHH-HbFTCZDcQDtFPSma13sHO-C69tm_HTjHX5DnMX6B_lDCgu3A8AsSZIQEG71z_Mnd2uxHoUrKUtHr8iM9bhpPKMnaXx9jr0O1EtKAJDLkz4qdzNunyOU7Ud94Lc8YxIjf7FZH_-jJc0UqFyFKY2rdEiZQVATNG94F-SIWA4CK5FZtW47TCL8EPBUzP8gGG8g6eMBEIfv80uWQxpJ59_UB91D8U6zSOiA4JrFDBRLkIX2kGnUZ7eu1G-4O6TglL_Id0oMeJdNEsMARYKHGmYZjvHGFVoLyoxca1KDK5dlcnLsYyxfKsZWNrTaqA'; @@ -58,10 +55,7 @@ public function fromJsonSetsValuesCorrectly(): void static::assertSame('@!DDD5.370D.8547.FFD9!0001!A1C9.92C1!0008!13DB.54D8.65DE.2761', $identityToken->values['aud']); } - /** - * @test - * @throws - */ + #[Test] public function asJwtReturnsTokenAsString(): void { $json = 'eyJraWQiOiJkZmViZTVlNy00MjMyLTQ0NjQtOGYyZS0xNTE2ODFhMGQxNzMiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL2lkLmV4YW1wbGUuY29tIiwiYXVkIjoiQCFEREQ1LjM3MEQuODU0Ny5GRkQ5ITAwMDEhQTFDOS45MkMxITAwMDghMTNEQi41NEQ4LjY1REUuMjc2MSIsImV4cCI6MTU1OTIwNTU2MCwiaWF0IjoxNTU5MjAxOTYwLCJhdXRoX3RpbWUiOjE1NTkyMDE5NTksImF0X2hhc2giOiJfU1BHdHM1OUlTbFdNSHhzMmEwM3N3Iiwib3hPcGVuSURDb25uZWN0VmVyc2lvbiI6Im9wZW5pZGNvbm5lY3QtMS4wIiwic3ViIjoiVVdBWWZ6em1jYU5BWnlfQzhhOFVvVXhNbWhUMUlsY0tsWEc4VG5Xa3lJTSJ9.VsOdosHuRWVaoacWG1CNJl0IZrHH-HbFTCZDcQDtFPSma13sHO-C69tm_HTjHX5DnMX6B_lDCgu3A8AsSZIQEG71z_Mnd2uxHoUrKUtHr8iM9bhpPKMnaXx9jr0O1EtKAJDLkz4qdzNunyOU7Ud94Lc8YxIjf7FZH_-jJc0UqFyFKY2rdEiZQVATNG94F-SIWA4CK5FZtW47TCL8EPBUzP8gGG8g6eMBEIfv80uWQxpJ59_UB91D8U6zSOiA4JrFDBRLkIX2kGnUZ7eu1G-4O6TglL_Id0oMeJdNEsMARYKHGmYZjvHGFVoLyoxca1KDK5dlcnLsYyxfKsZWNrTaqA'; @@ -70,9 +64,7 @@ public function asJwtReturnsTokenAsString(): void static::assertSame((string)$identityToken, $json); } - /** - * @test - */ + #[Test] public function isExpiredAtReturnsCorrectResult(): void { $json = 'eyJraWQiOiJkZmViZTVlNy00MjMyLTQ0NjQtOGYyZS0xNTE2ODFhMGQxNzMiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL2lkLmV4YW1wbGUuY29tIiwiYXVkIjoiQCFEREQ1LjM3MEQuODU0Ny5GRkQ5ITAwMDEhQTFDOS45MkMxITAwMDghMTNEQi41NEQ4LjY1REUuMjc2MSIsImV4cCI6MTU1OTIwNTU2MCwiaWF0IjoxNTU5MjAxOTYwLCJhdXRoX3RpbWUiOjE1NTkyMDE5NTksImF0X2hhc2giOiJfU1BHdHM1OUlTbFdNSHhzMmEwM3N3Iiwib3hPcGVuSURDb25uZWN0VmVyc2lvbiI6Im9wZW5pZGNvbm5lY3QtMS4wIiwic3ViIjoiVVdBWWZ6em1jYU5BWnlfQzhhOFVvVXhNbWhUMUlsY0tsWEc4VG5Xa3lJTSJ9.VsOdosHuRWVaoacWG1CNJl0IZrHH-HbFTCZDcQDtFPSma13sHO-C69tm_HTjHX5DnMX6B_lDCgu3A8AsSZIQEG71z_Mnd2uxHoUrKUtHr8iM9bhpPKMnaXx9jr0O1EtKAJDLkz4qdzNunyOU7Ud94Lc8YxIjf7FZH_-jJc0UqFyFKY2rdEiZQVATNG94F-SIWA4CK5FZtW47TCL8EPBUzP8gGG8g6eMBEIfv80uWQxpJ59_UB91D8U6zSOiA4JrFDBRLkIX2kGnUZ7eu1G-4O6TglL_Id0oMeJdNEsMARYKHGmYZjvHGFVoLyoxca1KDK5dlcnLsYyxfKsZWNrTaqA'; @@ -96,11 +88,8 @@ public static function audiences(): array ]; } - /** - * @test - * @dataProvider audiences - * @throws - */ + #[Test] + #[DataProvider('audiences')] public function audienceContainsSupportsSingleAndMultipleAudiences(string|array|null $audienceClaim, string $audience, bool $expectedResult): void { $values = ['iss' => 'https://id.example.com', 'sub' => 'subject']; diff --git a/Tests/Unit/OpenIdConnectClientTest.php b/Tests/Unit/OpenIdConnectClientTest.php index 92abe70..67e7580 100644 --- a/Tests/Unit/OpenIdConnectClientTest.php +++ b/Tests/Unit/OpenIdConnectClientTest.php @@ -20,6 +20,8 @@ use Neos\Cache\Backend\TransientMemoryBackend; use Neos\Cache\Frontend\VariableFrontend; use Neos\Flow\Utility\Algorithms; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\StreamInterface; @@ -77,7 +79,7 @@ public function setUp(): void $this->jwksCache = new VariableFrontend('jwks', new TransientMemoryBackend()); $this->jwksCache->initializeObject(); - $this->oAuthClient = $this->createPartialMock(OAuthClient::class, ['getAuthorization']); + $this->oAuthClient = $this->createStub(OAuthClient::class); $logger = $this->createStub(LoggerInterface::class); @@ -88,10 +90,7 @@ public function setUp(): void $this->inject($this->oidcClient, 'logger', $logger); } - /** - * @test - * @throws - */ + #[Test] public function getJwksReturnsJwksAndStoresItInCache(): void { $mockHttpClient = $this->createMock(HttpClient::class); @@ -115,14 +114,11 @@ public function getJwksReturnsJwksAndStoresItInCache(): void static::assertSame($expectedJwks, $this->jwksCache->get($cacheEntryIdentifier)); } - /** - * @test - * @throws - */ + #[Test] public function getJwksThrowsExceptionOnFailedDiscoveryRequest(): void { $mockHttpClient = $this->createMock(HttpClient::class); - $mockHttpRequest = $this->createMock(Request::class); + $mockHttpRequest = $this->createStub(Request::class); $this->inject($this->oidcClient, 'settings', $this->settings); $this->inject($this->oidcClient, 'httpClient', $mockHttpClient); @@ -134,10 +130,7 @@ public function getJwksThrowsExceptionOnFailedDiscoveryRequest(): void $this->oidcClient->getJwks(); } - /** - * @test - * @throws - */ + #[Test] public function getJwksThrowsExceptionOnMalformedResponseFromDiscoveryService(): void { $mockHttpClient = $this->createMock(HttpClient::class); @@ -156,10 +149,7 @@ public function getJwksThrowsExceptionOnMalformedResponseFromDiscoveryService(): $this->oidcClient->getJwks(); } - /** - * @test - * @throws - */ + #[Test] public function getJwksReturnsJwksFromCacheIfItExists(): void { $this->inject($this->oidcClient, 'settings', $this->settings); @@ -172,10 +162,7 @@ public function getJwksReturnsJwksFromCacheIfItExists(): void static::assertSame($expectedJwks, $this->oidcClient->getJwks()); } - /** - * @test - * @throws - */ + #[Test] public function getAccessTokenReturnsAccessTokenFromAuthorization(): void { $serviceName = 'test'; @@ -192,7 +179,7 @@ public function getAccessTokenReturnsAccessTokenFromAuthorization(): void $authorization = new Authorization($authorizationId, $serviceName, $clientId, Authorization::GRANT_CLIENT_CREDENTIALS, $scope); $authorization->setSerializedAccessToken(json_encode($expectedAccessToken, JSON_THROW_ON_ERROR, 512)); - $this->oAuthClient->method('getAuthorization')->with($authorizationId)->willReturn($authorization); + $this->oAuthClient->method('getAuthorization')->willReturnMap([[$authorizationId, $authorization]]); $actualAccessToken = $this->oidcClient->getAccessToken($serviceName, $clientId, $clientSecret, $scope); @@ -212,15 +199,11 @@ public static function authorizationScopes(): array ]; } - /** - * @test - * @dataProvider authorizationScopes - * @throws - */ + #[Test] + #[DataProvider('authorizationScopes')] public function buildAuthorizationScopeAddsRequiredScopeIdentifiers(string $scope, bool $requestRefreshToken, string $expectedScope): void { $method = new \ReflectionMethod(OpenIdConnectClient::class, 'buildAuthorizationScope'); - $method->setAccessible(true); static::assertSame($expectedScope, $method->invoke($this->oidcClient, $scope, $requestRefreshToken)); } @@ -253,7 +236,6 @@ protected function inject($target, $name, $dependency): void $target->$methodName($dependency); } elseif ($objectReflection->hasProperty($name)) { $property = $objectReflection->getProperty($name); - $property->setAccessible(true); $property->setValue($target, $dependency); } else { throw new \RuntimeException('Could not inject ' . $name . ' into object of type ' . get_class($target)); diff --git a/Tests/Unit/SetJwtCookieMiddlewareTest.php b/Tests/Unit/SetJwtCookieMiddlewareTest.php index aab990e..22ddd9e 100644 --- a/Tests/Unit/SetJwtCookieMiddlewareTest.php +++ b/Tests/Unit/SetJwtCookieMiddlewareTest.php @@ -17,6 +17,8 @@ use GuzzleHttp\Psr7\Uri; use Neos\Flow\Security\Account; use Neos\Flow\Security\Context as SecurityContext; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; @@ -79,11 +81,11 @@ class SetJwtCookieMiddlewareTest extends TestCase public function setUp(): void { - $this->mockSecurityContext = $this->getMockBuilder(SecurityContext::class)->disableOriginalConstructor()->getMock(); - $this->mockLogger = $this->getMockBuilder(LoggerInterface::class)->getMock(); - $this->mockRequest = $this->getMockBuilder(ServerRequestInterface::class)->getMock(); + $this->mockSecurityContext = $this->createStub(SecurityContext::class); + $this->mockLogger = $this->createStub(LoggerInterface::class); + $this->mockRequest = $this->createStub(ServerRequestInterface::class); $this->mockRequest->method('getUri')->willReturn(new Uri('http://localhost')); - $this->mockOriginalResponse = $this->getMockBuilder(ResponseInterface::class)->getMock(); + $this->mockOriginalResponse = $this->createStub(ResponseInterface::class); $this->mockNextRequestHandler = new class implements RequestHandlerInterface { public $originalResponse; @@ -103,20 +105,17 @@ private function getMiddleware(array $options = [], array $authenticationProvide return $middleware; } - /** - * @test - */ + #[Test] public function processReturnsUnalteredResponseOfInnerMiddlewareChainIfSecurityContextIsNotInitialized(): void { - $middleware = $this->getMiddleware(); + $this->mockSecurityContext = $this->createMock(SecurityContext::class); $this->mockSecurityContext->expects($this->atLeastOnce())->method('isInitialized')->willReturn(false); + $middleware = $this->getMiddleware(); $response = $middleware->process($this->mockRequest, $this->mockNextRequestHandler); self::assertSame($response, $this->mockOriginalResponse); } - /** - * @test - */ + #[Test] public function processReturnsUnalteredResponseOfInnerMiddlewareChainIfNoOidcAuthenticationTokensAreActive(): void { $middleware = $this->getMiddleware(); @@ -151,10 +150,8 @@ public static function removeJwtCookieDataProvider(): array ]; } - /** - * @test - * @dataProvider removeJwtCookieDataProvider - */ + #[Test] + #[DataProvider('removeJwtCookieDataProvider')] public function removeJwtCookieTests(array $options, array $authenticationProviderConfiguration, array $authenticatedTokens, array $activeCookies, ?string $expectedCookieHeader = null): void { $middleware = $this->getMiddleware($options, $authenticationProviderConfiguration); @@ -203,10 +200,8 @@ public static function setJwtCookieDataProvider(): array ]; } - /** - * @test - * @dataProvider setJwtCookieDataProvider - */ + #[Test] + #[DataProvider('setJwtCookieDataProvider')] public function setJwtCookieTests(array $options, array $authenticationProviderConfiguration, array $authenticatedTokens, array $activeCookies, ?string $expectedCookieHeader = null): void { $middleware = $this->getMiddleware($options, $authenticationProviderConfiguration); @@ -214,11 +209,11 @@ public function setJwtCookieTests(array $options, array $authenticationProviderC $this->mockSecurityContext->method('getAccountByAuthenticationProviderName')->willReturnCallback(function(string $providerName) { switch ($providerName) { case 'SomeProvider': - $mockAccount = $this->getMockBuilder(Account::class)->disableOriginalConstructor()->getMock(); + $mockAccount = $this->createStub(Account::class); $mockAccount->method('getCredentialsSource')->willReturn(self::JWT_NODY); break; case 'SomeOtherProvider': - $mockAccount = $this->getMockBuilder(Account::class)->disableOriginalConstructor()->getMock(); + $mockAccount = $this->createStub(Account::class); $mockAccount->method('getCredentialsSource')->willReturn(self::JWT_JODY); break; } @@ -242,17 +237,17 @@ public function setJwtCookieTests(array $options, array $authenticationProviderC } } - /** - * @test - */ + #[Test] public function processDoesNotSetCookieHeaderIfAuthenticatedAccountDoesNotContainIdentityToken(): void { $middleware = $this->getMiddleware(); $this->mockSecurityContext->method('isInitialized')->willReturn(true); - $mockAccount = $this->getMockBuilder(Account::class)->disableOriginalConstructor()->getMock(); + $mockAccount = $this->createStub(Account::class); $mockAccount->method('getCredentialsSource')->willReturn('not-a-jwt-string'); $this->mockSecurityContext->method('getAccountByAuthenticationProviderName')->willReturn($mockAccount); - $this->mockSecurityContext->method('getAuthenticationTokensOfType')->willReturn([new OpenIdConnectToken()]); + $token = new OpenIdConnectToken(); + $token->setAuthenticationProviderName('SomeProvider'); + $this->mockSecurityContext->method('getAuthenticationTokensOfType')->willReturn([$token]); $this->mockNextRequestHandler->originalResponse = new Response(); $response = $middleware->process($this->mockRequest, $this->mockNextRequestHandler); @@ -273,16 +268,14 @@ public static function removeOidcQueryParametersDataProvider(): array ]; } - /** - * @test - * @dataProvider removeOidcQueryParametersDataProvider - */ + #[Test] + #[DataProvider('removeOidcQueryParametersDataProvider')] public function removeOidcQueryParametersTests(string $requestUri, ?string $expectedLocationHeader = null): void { $middleware = $this->getMiddleware(); $this->mockSecurityContext->method('isInitialized')->willReturn(true); $this->mockSecurityContext->method('getAuthenticationTokensOfType')->willReturn([]); - $mockRequest = $this->getMockBuilder(ServerRequestInterface::class)->getMock(); + $mockRequest = $this->createStub(ServerRequestInterface::class); $mockRequest->method('getUri')->willReturn(new Uri($requestUri)); $this->mockNextRequestHandler->originalResponse = new Response(); $response = $middleware->process($mockRequest, $this->mockNextRequestHandler); @@ -293,15 +286,13 @@ public function removeOidcQueryParametersTests(string $requestUri, ?string $expe } } - /** - * @test - */ + #[Test] public function removeOidcQueryParametersDoesNotAlterLocationHeaderIfOneIsPresentAlready(): void { $middleware = $this->getMiddleware(); $this->mockSecurityContext->method('isInitialized')->willReturn(true); $this->mockSecurityContext->method('getAuthenticationTokensOfType')->willReturn([]); - $mockRequest = $this->getMockBuilder(ServerRequestInterface::class)->getMock(); + $mockRequest = $this->createStub(ServerRequestInterface::class); $mockRequest->method('getUri')->willReturn(new Uri('http://localhost?flownative_oidc=foo&flownative_oauth2_authorization_id_oidc=bar')); $responseWithLocationHeader = new Response(200, ['Location' => 'http://original-redirect.tld']); $this->mockNextRequestHandler->originalResponse = $responseWithLocationHeader; diff --git a/composer.json b/composer.json index 9ac72bc..c1ac616 100644 --- a/composer.json +++ b/composer.json @@ -21,17 +21,16 @@ } ], "require": { - "php": "8.1.* || 8.2.* || 8.3.* || 8.4.* || 8.5.*", - "neos/flow": "^7.3 || ^8.0 || ^9.0", - "guzzlehttp/guzzle": "^6.0 || ^7.0", - "flownative/oauth2-client": "^4.1.1", + "php": "8.3.* || 8.4.* || 8.5.*", + "neos/flow": "^9.0", + "guzzlehttp/guzzle": "^7.9", + "flownative/oauth2-client": "^4.1.2", "phpseclib/phpseclib": "^3.0.52", - "lcobucci/jwt": "^4.1", + "lcobucci/jwt": "^5.6", "psr/http-server-middleware": "^1.0" }, "require-dev": { - "phpunit/phpunit": "^9.6.21", - "phpunit/php-code-coverage": "*" + "phpunit/phpunit": "^12.5" }, "autoload": { "psr-4": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 5d468ee..e1f18e5 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,10 +1,18 @@ - - + + ./Classes - + From 5007c6d7d83048a80d6c0c03965b5c1949a5e2b9 Mon Sep 17 00:00:00 2001 From: Robert Lemke Date: Fri, 11 Sep 2026 09:32:42 +0200 Subject: [PATCH 2/2] Use PHP attributes instead of annotations Dependency injection, configuration injection and the signal of the authentication provider are declared with PHP attributes. The discovery response is decoded with the native json_decode(), because the Guzzle helper function is deprecated. --- Classes/Authentication/OpenIdConnectEntryPoint.php | 2 +- Classes/Authentication/OpenIdConnectProvider.php | 13 ++++++------- Classes/Authentication/TokenArguments.php | 4 ++-- Classes/Command/OidcCommandController.php | 2 +- Classes/OAuthClient.php | 2 +- Classes/OpenIdConnectClient.php | 10 +++++++--- 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/Classes/Authentication/OpenIdConnectEntryPoint.php b/Classes/Authentication/OpenIdConnectEntryPoint.php index 743d3e4..efe7f08 100644 --- a/Classes/Authentication/OpenIdConnectEntryPoint.php +++ b/Classes/Authentication/OpenIdConnectEntryPoint.php @@ -17,9 +17,9 @@ final class OpenIdConnectEntryPoint extends AbstractEntryPoint { /** - * @Flow\Inject(name="Neos.Flow:SecurityLogger") * @var LoggerInterface */ + #[Flow\Inject(name: 'Neos.Flow:SecurityLogger')] protected $logger; /** diff --git a/Classes/Authentication/OpenIdConnectProvider.php b/Classes/Authentication/OpenIdConnectProvider.php index 9ee0189..86662eb 100644 --- a/Classes/Authentication/OpenIdConnectProvider.php +++ b/Classes/Authentication/OpenIdConnectProvider.php @@ -29,33 +29,33 @@ final class OpenIdConnectProvider extends AbstractProvider { /** - * @Flow\Inject(lazy = false) * @var Context */ + #[Flow\Inject(lazy: false)] protected $securityContext; /** - * @Flow\Inject(lazy = false) * @var PolicyService */ + #[Flow\Inject(lazy: false)] protected $policyService; /** - * @Flow\Inject(name="Neos.Flow:SecurityLogger") * @var LoggerInterface */ + #[Flow\Inject(name: 'Neos.Flow:SecurityLogger')] protected $logger; /** - * @Flow\Inject * @var AccountRepository */ + #[Flow\Inject] protected $accountRepository; /** - * @Flow\Inject * @var SessionInterface */ + #[Flow\Inject] protected $session; /** @@ -206,9 +206,8 @@ public function getServiceName(): string * @param TokenInterface $authenticationToken * @param IdentityToken $identityToken * @param Role[] $roles - * @return void - * @Flow\Signal() */ + #[Flow\Signal] public function emitAuthenticated(TokenInterface $authenticationToken, IdentityToken $identityToken, array $roles): void { } diff --git a/Classes/Authentication/TokenArguments.php b/Classes/Authentication/TokenArguments.php index 774397f..da8abb8 100644 --- a/Classes/Authentication/TokenArguments.php +++ b/Classes/Authentication/TokenArguments.php @@ -13,15 +13,15 @@ final class TokenArguments implements \ArrayAccess public const SERVICE_NAME = 'service'; /** - * @Flow\Inject * @var HashService */ + #[Flow\Inject] protected $hashService; /** - * @Flow\Inject * @var LoggerInterface */ + #[Flow\Inject] protected $logger; /** diff --git a/Classes/Command/OidcCommandController.php b/Classes/Command/OidcCommandController.php index 38435ac..4064313 100644 --- a/Classes/Command/OidcCommandController.php +++ b/Classes/Command/OidcCommandController.php @@ -17,9 +17,9 @@ final class OidcCommandController extends CommandController protected $entityManager; /** - * @Flow\InjectConfiguration * @var array */ + #[Flow\InjectConfiguration] protected $settings; /** diff --git a/Classes/OAuthClient.php b/Classes/OAuthClient.php index 0ca0655..4d92b43 100644 --- a/Classes/OAuthClient.php +++ b/Classes/OAuthClient.php @@ -25,9 +25,9 @@ class OAuthClient extends \Flownative\OAuth2\Client\OAuthClient public const SERVICE_TYPE= 'oidc'; /** - * @Flow\InjectConfiguration(path="http.baseUri", package="Neos.Flow") * @var string */ + #[Flow\InjectConfiguration(path: 'http.baseUri', package: 'Neos.Flow')] protected $flowBaseUriSetting; private array $options = []; diff --git a/Classes/OpenIdConnectClient.php b/Classes/OpenIdConnectClient.php index 11cb30f..3f44b82 100644 --- a/Classes/OpenIdConnectClient.php +++ b/Classes/OpenIdConnectClient.php @@ -44,9 +44,9 @@ final class OpenIdConnectClient private $oAuthClient; /** - * @Flow\InjectConfiguration * @var array */ + #[Flow\InjectConfiguration] protected $settings; /** @@ -55,9 +55,9 @@ final class OpenIdConnectClient protected $httpClient; /** - * @Flow\Inject(name="Neos.Flow:SecurityLogger") * @var LoggerInterface */ + #[Flow\Inject(name: 'Neos.Flow:SecurityLogger')] protected $logger; /** @@ -350,7 +350,11 @@ private function amendOptionsWithDiscovery(string $discoveryUri): void } catch (GuzzleException $e) { throw new ConnectionException(sprintf('OpenID Connect Client: Failed discovering options at %s: %s', $discoveryUri, $e->getMessage()), 1554902567); } - $discoveredOptions = \GuzzleHttp\json_decode($response->getBody()->getContents(), true); + try { + $discoveredOptions = json_decode($response->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR); + } catch (\JsonException) { + $discoveredOptions = null; + } if (!is_array($discoveredOptions)) { throw new ConnectionException('OpenID Connect Client: Discovery endpoint returned invalid response.', 1554903349); }