From dee6a70a7983acc4570161b28dcb82376fa3d4eb Mon Sep 17 00:00:00 2001 From: Johan Kromhout Date: Thu, 22 Jan 2026 11:48:36 +0100 Subject: [PATCH 1/6] Composer Update & update phpstan + fix Also remove deprecated phpcpd --- ci/qa/phpcpd | 7 ---- ci/qa/phplint.yaml | 2 +- ci/qa/phpstan-baseline.neon | 41 +++++++++++-------- composer.json | 8 +--- src/Controller/SSOController.php | 2 +- src/Logger/StepupRequestIdSariLogger.php | 2 +- src/Monolog/Processor/RequestIdProcessor.php | 2 + src/Saml/ResponseContext.php | 2 +- .../DateTime/SystemDateTimeService.php | 3 -- src/Service/StateHandler.php | 9 +--- src/Service/ValueStore.php | 2 +- src/Service/ValueStore/InMemoryValueStore.php | 2 +- src/Service/ValueStore/SessionValueStore.php | 2 +- 13 files changed, 37 insertions(+), 47 deletions(-) delete mode 100755 ci/qa/phpcpd diff --git a/ci/qa/phpcpd b/ci/qa/phpcpd deleted file mode 100755 index e8d7f7c..0000000 --- a/ci/qa/phpcpd +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -cd $(dirname $0)/../../ - -# https://github.com/sebastianbergmann/phpcpd -./vendor/bin/phpcpd ./src $1 -./vendor/bin/phpcpd ./tests $1 diff --git a/ci/qa/phplint.yaml b/ci/qa/phplint.yaml index f07ad6c..1cc9bd1 100644 --- a/ci/qa/phplint.yaml +++ b/ci/qa/phplint.yaml @@ -1,6 +1,6 @@ path: [./src, ./tests] jobs: 10 -cache: /var/qa/phplint.cache +cache-dir: var/cache/qa/phplint.cache extensions: - php exclude: diff --git a/ci/qa/phpstan-baseline.neon b/ci/qa/phpstan-baseline.neon index 42c3be9..dd09b88 100644 --- a/ci/qa/phpstan-baseline.neon +++ b/ci/qa/phpstan-baseline.neon @@ -1,66 +1,73 @@ parameters: ignoreErrors: - - message: "#^Method Surfnet\\\\GsspBundle\\\\Logger\\\\StepupRequestIdSariLogger\\:\\:log\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\GsspBundle\\Logger\\StepupRequestIdSariLogger\:\:log\(\) has parameter \$context with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Logger/StepupRequestIdSariLogger.php - - message: "#^Cannot access offset 'request_id' on array\\|DateTimeImmutable\\|int\\|string\\|null\\.$#" - count: 1 - path: ../../src/Monolog/Processor/RequestIdProcessor.php - - - - message: "#^Method Surfnet\\\\GsspBundle\\\\Saml\\\\ResponseContext\\:\\:getErrorStatus\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\GsspBundle\\Saml\\ResponseContext\:\:getErrorStatus\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Saml/ResponseContext.php - - message: "#^Method Surfnet\\\\GsspBundle\\\\Saml\\\\ResponseContextInterface\\:\\:getErrorStatus\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\GsspBundle\\Saml\\ResponseContextInterface\:\:getErrorStatus\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Saml/ResponseContextInterface.php - - message: "#^Method Surfnet\\\\GsspBundle\\\\Service\\\\StateHandler\\:\\:getErrorStatus\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\GsspBundle\\Service\\StateHandler\:\:getErrorStatus\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Service/StateHandler.php - - message: "#^Method Surfnet\\\\GsspBundle\\\\Service\\\\StateHandler\\:\\:getScopingRequesterIds\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\GsspBundle\\Service\\StateHandler\:\:getScopingRequesterIds\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Service/StateHandler.php - - message: "#^Parameter \\#1 \\$serviceProvider of method Surfnet\\\\GsspBundle\\\\Service\\\\StateHandler\\:\\:setRequestServiceProvider\\(\\) expects string, string\\|null given\\.$#" + message: '#^Parameter \#1 \$serviceProvider of method Surfnet\\GsspBundle\\Service\\StateHandler\:\:setRequestServiceProvider\(\) expects string, string\|null given\.$#' + identifier: argument.type count: 2 path: ../../src/Service/StateHandler.php - - message: "#^Method Surfnet\\\\GsspBundle\\\\Service\\\\StateHandlerInterface\\:\\:getErrorStatus\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\GsspBundle\\Service\\StateHandlerInterface\:\:getErrorStatus\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Service/StateHandlerInterface.php - - message: "#^Method Surfnet\\\\GsspBundle\\\\Service\\\\StateHandlerInterface\\:\\:getScopingRequesterIds\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Surfnet\\GsspBundle\\Service\\StateHandlerInterface\:\:getScopingRequesterIds\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: ../../src/Service/StateHandlerInterface.php - - message: "#^Cannot call method clear\\(\\) on Symfony\\\\Component\\\\HttpFoundation\\\\Session\\\\SessionInterface\\|null\\.$#" + message: '#^Cannot call method clear\(\) on Symfony\\Component\\HttpFoundation\\Session\\SessionInterface\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/Service/ValueStore/SessionValueStore.php - - message: "#^Cannot call method get\\(\\) on Symfony\\\\Component\\\\HttpFoundation\\\\Session\\\\SessionInterface\\|null\\.$#" + message: '#^Cannot call method get\(\) on Symfony\\Component\\HttpFoundation\\Session\\SessionInterface\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/Service/ValueStore/SessionValueStore.php - - message: "#^Cannot call method has\\(\\) on Symfony\\\\Component\\\\HttpFoundation\\\\Session\\\\SessionInterface\\|null\\.$#" + message: '#^Cannot call method has\(\) on Symfony\\Component\\HttpFoundation\\Session\\SessionInterface\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/Service/ValueStore/SessionValueStore.php - - message: "#^Cannot call method set\\(\\) on Symfony\\\\Component\\\\HttpFoundation\\\\Session\\\\SessionInterface\\|null\\.$#" + message: '#^Cannot call method set\(\) on Symfony\\Component\\HttpFoundation\\Session\\SessionInterface\|null\.$#' + identifier: method.nonObject count: 1 path: ../../src/Service/ValueStore/SessionValueStore.php diff --git a/composer.json b/composer.json index e56494a..d9ce473 100644 --- a/composer.json +++ b/composer.json @@ -24,16 +24,14 @@ }, "require-dev": { "behat/behat": "^3.13", - "jakub-onderka/php-parallel-lint": "^1", "malukenho/docheader": "^0", "mockery/mockery": "^1.5", "overtrue/phplint": "*", "phpmd/phpmd": "^2.13", - "phpstan/phpstan": "^1.10", - "phpstan/phpstan-symfony": "^1.3", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-symfony": "^2.0", "phpunit/phpcov": "^8.2", "phpunit/phpunit": "^9.6", - "sebastian/phpcpd": "^6.0", "slevomat/coding-standard": "^8.13", "squizlabs/php_codesniffer": "^3.7.1", "symfony/phpunit-bridge": "^6.4" @@ -43,7 +41,6 @@ "@composer-validate", "@docheader", "@phplint", - "@phpcpd", "@phpcs", "@phpmd", "@phpstan", @@ -54,7 +51,6 @@ "composer-validate": "./ci/qa/validate", "phplint": "./ci/qa/phplint", "phpcs": "./ci/qa/phpcs", - "phpcpd": "./ci/qa/phpcpd", "phpmd": "./ci/qa/phpmd", "phpstan": "./ci/qa/phpstan", "phpstan-baseline": "./ci/qa/phpstan-update-baseline", diff --git a/src/Controller/SSOController.php b/src/Controller/SSOController.php index 385ccfd..3a3c328 100644 --- a/src/Controller/SSOController.php +++ b/src/Controller/SSOController.php @@ -38,7 +38,7 @@ /** * Handles the SAML AuthnRequest from the service provider. * - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings("PHPMD.CouplingBetweenObjects") */ final class SSOController extends AbstractController { diff --git a/src/Logger/StepupRequestIdSariLogger.php b/src/Logger/StepupRequestIdSariLogger.php index f3d6618..2cb4234 100644 --- a/src/Logger/StepupRequestIdSariLogger.php +++ b/src/Logger/StepupRequestIdSariLogger.php @@ -39,7 +39,7 @@ public function __construct( } /** - * @SuppressWarnings(PHPMD.ElseExpression) + * @SuppressWarnings("PHPMD.ElseExpression") */ public function log(mixed $level, string|Stringable $message, array $context = []): void { diff --git a/src/Monolog/Processor/RequestIdProcessor.php b/src/Monolog/Processor/RequestIdProcessor.php index afb5c75..1d14d90 100644 --- a/src/Monolog/Processor/RequestIdProcessor.php +++ b/src/Monolog/Processor/RequestIdProcessor.php @@ -37,6 +37,8 @@ public function __construct() */ public function __invoke(LogRecord $record): LogRecord { + /** @see LogRecord::__construct */ + assert(is_array($record['extra'])); $record['extra']['request_id'] = $this->requestId; return $record; diff --git a/src/Saml/ResponseContext.php b/src/Saml/ResponseContext.php index cbbcd5c..f177009 100644 --- a/src/Saml/ResponseContext.php +++ b/src/Saml/ResponseContext.php @@ -44,7 +44,7 @@ public function getIssuer(): ?string return $this->hostedIdentityProvider->getEntityId(); } - public function getInResponseTo(): ?string + public function getInResponseTo(): string { return $this->stateHandler->getRequestId(); } diff --git a/src/Service/DateTime/SystemDateTimeService.php b/src/Service/DateTime/SystemDateTimeService.php index 1df3d00..e94c93a 100644 --- a/src/Service/DateTime/SystemDateTimeService.php +++ b/src/Service/DateTime/SystemDateTimeService.php @@ -40,9 +40,6 @@ public function __construct(string $timezone = 'UTC') $this->timezone = new DateTimeZone($timezone); } - /** - * @throws Exception - */ public function getCurrent(): DateTimeImmutable { return new DateTimeImmutable('now', $this->timezone); diff --git a/src/Service/StateHandler.php b/src/Service/StateHandler.php index 5f3ca96..f648554 100644 --- a/src/Service/StateHandler.php +++ b/src/Service/StateHandler.php @@ -71,13 +71,8 @@ public function saveRegistrationRequest(ReceivedAuthnRequest $authnRequest, stri ->set(self::REQUEST_TYPE, self::REQUEST_TYPE_REGISTRATION) ; - if ($authnRequest->getExtensions()->getGsspUserAttributesChunk() instanceof GsspUserAttributesChunk) { - $chunk = $authnRequest->getExtensions()->getGsspUserAttributesChunk(); - if (!$chunk instanceof GsspUserAttributesChunk) { - throw new RuntimeException( - 'Unable to store GsspUserAttributes in state, as no GSSP chunk found in AuthNRequest' - ); - } + $chunk = $authnRequest->getExtensions()->getGsspUserAttributesChunk(); + if ($chunk instanceof GsspUserAttributesChunk) { $this->setGsspUserAttributes($chunk); } } diff --git a/src/Service/ValueStore.php b/src/Service/ValueStore.php index 149cec9..422cd81 100644 --- a/src/Service/ValueStore.php +++ b/src/Service/ValueStore.php @@ -27,7 +27,7 @@ interface ValueStore /** * Is the property the given value. * - * @SuppressWarnings(PHPMD.ShortMethodName) + * @SuppressWarnings("PHPMD.ShortMethodName") */ public function is(string $key, mixed $value): bool; diff --git a/src/Service/ValueStore/InMemoryValueStore.php b/src/Service/ValueStore/InMemoryValueStore.php index 30ce0a4..06ffca1 100644 --- a/src/Service/ValueStore/InMemoryValueStore.php +++ b/src/Service/ValueStore/InMemoryValueStore.php @@ -45,7 +45,7 @@ public function get(string $key): mixed } /** - * @SuppressWarnings(PHPMD.ShortMethodName) + * @SuppressWarnings("PHPMD.ShortMethodName") */ public function is(string $key, mixed $value): bool { diff --git a/src/Service/ValueStore/SessionValueStore.php b/src/Service/ValueStore/SessionValueStore.php index bd97b64..58dad17 100644 --- a/src/Service/ValueStore/SessionValueStore.php +++ b/src/Service/ValueStore/SessionValueStore.php @@ -68,7 +68,7 @@ public function get(string $key): mixed } /** - * @SuppressWarnings(PHPMD.ShortMethodName) + * @SuppressWarnings("PHPMD.ShortMethodName") */ public function is(string $key, mixed $value): bool { From cee19e0863be375cf30b3ccd72acdb9f8ae04cf8 Mon Sep 17 00:00:00 2001 From: Johan Kromhout Date: Thu, 22 Jan 2026 12:03:16 +0100 Subject: [PATCH 2/6] Install rector & apply rectors AttributeToAttributeRector ReadOnlyPropertyRector TypedPropertyRector MixedTypeRector --- .github/workflows/test-integration.yml | 8 +- ci/qa/phpunit.xml | 48 +++++---- ci/qa/rector.php | 17 ++++ ci/qa/rector.sh | 5 + composer.json | 7 ++ src/Controller/MetadataController.php | 4 +- src/DependencyInjection/Configuration.php | 2 +- src/Features/Context/GsspContext.php | 97 +++++++------------ src/Monolog/Processor/RequestIdProcessor.php | 2 +- src/Saml/AssertionSigningService.php | 10 +- src/Saml/AssertionSigningServiceInterface.php | 1 - src/Saml/ResponseContext.php | 8 +- src/Service/ConfigurationContainer.php | 10 +- src/Service/ResponseService.php | 10 +- .../StateBasedAuthenticationService.php | 11 +-- src/Service/StateBasedRegistrationService.php | 8 +- src/Service/StateHandler.php | 2 +- 17 files changed, 116 insertions(+), 134 deletions(-) create mode 100644 ci/qa/rector.php create mode 100755 ci/qa/rector.sh diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index 5f6670f..42ba99c 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -6,11 +6,7 @@ jobs: continue-on-error: ${{ matrix.experimental }} strategy: matrix: - php-versions: [ '8.2' ] - experimental: [ false ] - include: - - php-versions: '8.3' - experimental: true + php: ['8.2', '8.5'] timeout-minutes: 30 name: PHP ${{ matrix.php-versions }} on Ubuntu latest. Experimental == ${{ matrix.experimental }} steps: @@ -24,7 +20,7 @@ jobs: run: composer install continue-on-error: ${{ matrix.experimental }} - name: Run CI tests - run: composer check + run: composer check-ci continue-on-error: ${{ matrix.experimental }} - name: Output log files on failure if: failure() diff --git a/ci/qa/phpunit.xml b/ci/qa/phpunit.xml index 61d47e1..69b8eca 100644 --- a/ci/qa/phpunit.xml +++ b/ci/qa/phpunit.xml @@ -1,31 +1,29 @@ - - - - - - - - - ../../tests - - - - - ../../src - - ../../src/*Bundle/Resources - ../../src/*/*Bundle/Resources - ../../src/*/Bundle/*Bundle/Resources - - - + failOnRisky="true" + cacheDirectory="../../var/qa/phpunit.cache" +> + + + ../../src + + + ../../src/*Bundle/Resources + ../../src/*/*Bundle/Resources + ../../src/*/Bundle/*Bundle/Resources + + + + + + + + ../../tests + + diff --git a/ci/qa/rector.php b/ci/qa/rector.php new file mode 100644 index 0000000..55df933 --- /dev/null +++ b/ci/qa/rector.php @@ -0,0 +1,17 @@ +withPaths([ + __DIR__ . '/../../src', + __DIR__ . '/../../tests', + ]) + ->withPhpSets() + ->withAttributesSets(all: true) + ->withComposerBased(twig: true, phpunit: true, symfony: true) + ->withPHPStanConfigs([__DIR__.'/phpstan.neon']) + ->withPreparedSets(deadCode: true) +; diff --git a/ci/qa/rector.sh b/ci/qa/rector.sh new file mode 100755 index 0000000..b2b5857 --- /dev/null +++ b/ci/qa/rector.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +# Ensure we run from project root +cd "$(dirname "$0")/../../" || exit 1 +./vendor/bin/rector --config=ci/qa/rector.php "$@" diff --git a/composer.json b/composer.json index d9ce473..488341c 100644 --- a/composer.json +++ b/composer.json @@ -32,12 +32,17 @@ "phpstan/phpstan-symfony": "^2.0", "phpunit/phpcov": "^8.2", "phpunit/phpunit": "^9.6", + "rector/rector": "^2.3", "slevomat/coding-standard": "^8.13", "squizlabs/php_codesniffer": "^3.7.1", "symfony/phpunit-bridge": "^6.4" }, "scripts": { "check": [ + "@check-ci", + "@rector" + ], + "check-ci": [ "@composer-validate", "@docheader", "@phplint", @@ -49,6 +54,8 @@ ], "behat": "./ci/qa/behat", "composer-validate": "./ci/qa/validate", + "rector": "./ci/qa/rector.sh --dry-run", + "rector-fix": "./ci/qa/rector.sh", "phplint": "./ci/qa/phplint", "phpcs": "./ci/qa/phpcs", "phpmd": "./ci/qa/phpmd", diff --git a/src/Controller/MetadataController.php b/src/Controller/MetadataController.php index 503a7b4..e759cdd 100644 --- a/src/Controller/MetadataController.php +++ b/src/Controller/MetadataController.php @@ -24,9 +24,9 @@ use Surfnet\SamlBundle\Metadata\MetadataFactory; use Symfony\Component\Routing\Annotation\Route; -final class MetadataController +final readonly class MetadataController { - public function __construct(private readonly MetadataFactory $metadataFactory) + public function __construct(private MetadataFactory $metadataFactory) { } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 183e3d5..64b045c 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -28,7 +28,7 @@ class Configuration implements ConfigurationInterface /** * {@inheritdoc} */ - public function getConfigTreeBuilder() + public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder('surfnet_gssp'); $rootNode = $treeBuilder->getRootNode(); diff --git a/src/Features/Context/GsspContext.php b/src/Features/Context/GsspContext.php index 2da47d8..31ea92b 100644 --- a/src/Features/Context/GsspContext.php +++ b/src/Features/Context/GsspContext.php @@ -24,11 +24,15 @@ use Assert\AssertionFailedException; use Behat\Behat\Context\Context; use Behat\Gherkin\Node\TableNode; +use Behat\Hook\BeforeScenario; +use Behat\Step\Given; +use Behat\Step\Then; +use Behat\Step\When; use Exception; -use JakubOnderka\PhpParallelLint\RunTimeException; use Mockery; use Mockery\MockInterface; use RobRichards\XMLSecLibs\XMLSecurityKey; +use RuntimeException; use SAML2\AuthnRequest as SAMLAuthnRequest; use SAML2\Certificate\KeyLoader; use SAML2\Certificate\PrivateKeyLoader; @@ -65,6 +69,7 @@ use Symfony\Component\ErrorHandler\BufferingLogger; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\RouterInterface; use Twig\Environment; @@ -88,7 +93,7 @@ final class GsspContext implements Context /** * Last controller response. */ - private null|\Symfony\Component\HttpFoundation\Response|\Symfony\Component\HttpFoundation\RedirectResponse $response = null; + private null|Response|RedirectResponse $response = null; /** * Last controller twig render template */ @@ -111,10 +116,10 @@ final class GsspContext implements Context /** * Every scenario we start with a clean slate. * - * @BeforeScenario * @throws AssertionFailedException * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ + #[BeforeScenario] public function bootstrapDependencies(): void { // Empty state variables. @@ -256,10 +261,10 @@ function ( /** * Creates a normal AuthnRequest and set it to this context. * - * @Given a normal SAML 2.0 AuthnRequest * * @throws Exception */ + #[Given('a normal SAML 2.0 AuthnRequest')] public function createANormalAuthnRequest(): void { $request = new SAMLAuthnRequest(); @@ -275,15 +280,14 @@ public function createANormalAuthnRequest(): void /** * Creates a normal AuthnRequest from an random SP. * - * @Given a normal SAML 2.0 AuthnRequest form a unknown service provider entityId :entityId acu :acu * * @param string $entityId * The service provider entity id * @param string $acu * The assertion consumer service url - * * @throws Exception */ + #[Given('a normal SAML 2.0 AuthnRequest form a unknown service provider entityId :entityId acu :acu')] public function createANormalAuthnRequestFromServiceProvider(string $entityId, string $acu): void { $request = new SAMLAuthnRequest(); @@ -299,10 +303,10 @@ public function createANormalAuthnRequestFromServiceProvider(string $entityId, s /** * Sign the AuthnRequest on this context from the SP. * - * @Given AuthnRequest is signed with sha256 * * @throws Exception */ + #[Given('AuthnRequest is signed with sha256')] public function signAuthnRequest(): void { $this->authnRequest->setSignatureKey( @@ -312,9 +316,8 @@ public function signAuthnRequest(): void /** * Call the SSO IdP endpoint action with HTTP AuthnRequest request, set the response on this context. - * - * @When the service provider sends the AuthnRequest with HTTP-Redirect binding */ + #[When('the service provider sends the AuthnRequest with HTTP-Redirect binding')] public function callIdentityProviderSSOActionWithAuthnRequest(): void { $request = AuthnRequest::createNew($this->authnRequest); @@ -329,10 +332,10 @@ public function callIdentityProviderSSOActionWithAuthnRequest(): void * * Removes the signature from the request. * - * @When the service provider sends an unsigned AuthnRequest with HTTP-Redirect binding * * @throws Exception */ + #[When('the service provider sends an unsigned AuthnRequest with HTTP-Redirect binding')] public function callIdentityProviderSSOActionWithAuthnRequestWithoutSignature(): void { $request = AuthnRequest::createNew($this->authnRequest); @@ -350,10 +353,10 @@ public function callIdentityProviderSSOActionWithAuthnRequestWithoutSignature(): * * Set an invalid signature * - * @When the service provider sends an invalided signed AuthnRequest with HTTP-Redirect binding * * @throws Exception */ + #[When('the service provider sends an invalided signed AuthnRequest with HTTP-Redirect binding')] public function callIdentityProviderSSOActionWithAuthnRequestWithIncorrectSignature(): void { $request = AuthnRequest::createNew($this->authnRequest); @@ -367,17 +370,16 @@ public function callIdentityProviderSSOActionWithAuthnRequestWithIncorrectSignat } /** - * @Then the identity provider response should be an unrecoverable error :expected - * * This error should be handled by the application implementing this bundle. * * @throws AssertionFailedException */ + #[Then('the identity provider response should be an unrecoverable error :expected')] public function responseShouldBeAnUnrecoverableError($expected): void { $actual = ''; - if ($this->lastException instanceof \Exception) { + if ($this->lastException instanceof Exception) { $actual = $this->lastException->getMessage(); } @@ -387,9 +389,7 @@ public function responseShouldBeAnUnrecoverableError($expected): void ); } - /** - * @Then the identity provider register the user with an unique identifier token - */ + #[Then('the identity provider register the user with an unique identifier token')] public function assignAUniqueIdentifierToTheToken(): void { $this->registrationService->register('unique-identifier-token'); @@ -397,13 +397,13 @@ public function assignAUniqueIdentifierToTheToken(): void } /** - * @Then the user is redirected to the identity provider sso return endpoint - * @Then the user is redirected to the identity provider sso return endpoint without registration - * @Then the user is redirected to the identity provider sso return endpoint without authentication * * @throws AssertionFailedException * @throws Exception */ + #[Then('the user is redirected to the identity provider sso return endpoint')] + #[Then('the user is redirected to the identity provider sso return endpoint without registration')] + #[Then('the user is redirected to the identity provider sso return endpoint without authentication')] public function requestSSOreturnEndpoint(): void { try { @@ -414,11 +414,11 @@ public function requestSSOreturnEndpoint(): void } /** - * @Then Identity provider sso return endpoint should redirect client-side a saml response to the service provider * * @throws AssertionFailedException * @throws Exception */ + #[Then('Identity provider sso return endpoint should redirect client-side a saml response to the service provider')] public function shouldReturnSamlResponse(): void { $parameters = $this->twigParameters; @@ -431,9 +431,7 @@ public function shouldReturnSamlResponse(): void Assertion::eq('@SurfnetGssp/StepupGssp/ssoReturn.html.twig-response', $this->response->getContent()); } - /** - * @Then the saml response status code should be :code - */ + #[Then('the saml response status code should be :code')] public function theResponseStatusCodeShouldBe($code): void { $status = $this->ssoReturnResponse->getStatus(); @@ -441,11 +439,11 @@ public function theResponseStatusCodeShouldBe($code): void } /** - * @Then the saml response assertion should be signed * * @throws AssertionFailedException * @throws RunTimeException */ + #[Then('the saml response assertion should be signed')] public function theResponseAssertionShouldBeSigned(): void { $assertion = $this->getSsoAssertionResponse(); @@ -462,9 +460,7 @@ public function theResponseAssertionShouldBeSigned(): void } } - /** - * @Then the saml response should have an authenticating authority of the IdP EntityId with class ref :classRef - */ + #[Then('the saml response should have an authenticating authority of the IdP EntityId with class ref :classRef')] public function theResponseShouldHaveAnAuthenticatingAuthorityOfTheIdpWithClassRef($classRef): void { $assertion = $this->getSsoAssertionResponse(); @@ -472,9 +468,7 @@ public function theResponseShouldHaveAnAuthenticatingAuthorityOfTheIdpWithClassR Assertion::eq([$this->identityProvider->getEntityId()], $assertion->getAuthenticatingAuthority()); } - /** - * @Then the saml response should have the token identifier in the Subject NameID of the Assertion section - */ + #[Then('the saml response should have the token identifier in the Subject NameID of the Assertion section')] public function theResponseShouldHaveTheTokenIdentifierInTheSubjectNameIdOfTheAssertionSection(): void { $assertion = $this->getSsoAssertionResponse(); @@ -513,9 +507,6 @@ private function loadPublicKey($publicKey): XMLSecurityKey } - /** - * @return string - */ private function loadIdpPublicCertificate(): string { $keyLoader = new KeyLoader(); @@ -536,11 +527,8 @@ private function getSsoAssertionResponse(): \SAML2\Assertion|EncryptedAssertion| return reset($assertions); } - /** - * - * @When /^an user requests the identity provider sso endpoint$/ - * @When /^the user requests the identity provider sso endpoint$/ - */ + #[When('/^an user requests the identity provider sso endpoint$/')] + #[When('/^the user requests the identity provider sso endpoint$/')] public function callIdentityProviderSSOAction(array $parameters = []): void { $uri = 'https://identity_provider/saml/sso'; @@ -561,10 +549,9 @@ public function callIdentityProviderSSOAction(array $parameters = []): void } /** - * @Then /^the response should be an redirect the application registration endpoint$/ - * * @throws AssertionFailedException */ + #[Then('/^the response should be an redirect the application registration endpoint$/')] public function theResponseShouldBeAnRedirectTheApplicationRegistrationEndpoint(): void { Assertion::isInstanceOf($this->response, RedirectResponse::class); @@ -574,10 +561,9 @@ public function theResponseShouldBeAnRedirectTheApplicationRegistrationEndpoint( } /** - * @Then /^the response should be an redirect the application authentication endpoint$/ - * * @throws AssertionFailedException */ + #[Then('/^the response should be an redirect the application authentication endpoint$/')] public function theResponseShouldBeAnRedirectTheApplicationAuthenticationEndpoint(): void { Assertion::isInstanceOf($this->response, RedirectResponse::class); @@ -587,29 +573,26 @@ public function theResponseShouldBeAnRedirectTheApplicationAuthenticationEndpoin } /** - * @Then /^there should not be an unique identifier token assigned$/ - * * @throws AssertionFailedException */ + #[Then('/^there should not be an unique identifier token assigned$/')] public function thereShouldNotBeAnUniqueIdentifierTokenAssigned(): void { Assertion::false($this->responseContext->isRegistered()); } - /** - * @When /^I clear the logs$/ - */ + #[When('/^I clear the logs$/')] public function clearTheLogs(): void { $this->logger->cleanLogs(); } /** - * @Given /^the logs are:$/ * * @throws AssertionFailedException * @SuppressWarnings(PHPMD.ElseExpression) */ + #[Given('/^the logs are:$/')] public function theLogsAre(TableNode $table): void { $logs = $this->logger->cleanLogs(); @@ -635,18 +618,14 @@ public function theLogsAre(TableNode $table): void Assertion::noContent($logs, var_export($logs, true)); } - /** - * @Then the identity provider rejects the request with the error :message - */ + #[Then('the identity provider rejects the request with the error :message')] public function theIdentityProviderSetsAnError($message): void { $this->registrationService->reject($message); $this->registrationService->replyToServiceProvider(); } - /** - * @Given set the subject nameId to :nameId - */ + #[Given('set the subject nameId to :nameId')] public function setTheSubjectNameIdTo(string $nameId): void { $nameIdVo = new NameID(); @@ -655,17 +634,13 @@ public function setTheSubjectNameIdTo(string $nameId): void $this->authnRequest->setNameId($nameIdVo); } - /** - * @Then /^the identity provider authenticates the user$/ - */ + #[Then('/^the identity provider authenticates the user$/')] public function theIdentityProviderAuthenticatesTheUser(): void { $this->authenticationService->authenticate(); } - /** - * @Then /^the return endpoint should raise an exception with "([^"]*)"$/ - */ + #[Then('/^the return endpoint should raise an exception with "([^"]*)"$/')] public function theReturnEndpointShouldRaiseAnException($message): void { Assertion::eq($message, $this->lastException->getMessage()); diff --git a/src/Monolog/Processor/RequestIdProcessor.php b/src/Monolog/Processor/RequestIdProcessor.php index 1d14d90..fa89cf9 100644 --- a/src/Monolog/Processor/RequestIdProcessor.php +++ b/src/Monolog/Processor/RequestIdProcessor.php @@ -24,7 +24,7 @@ class RequestIdProcessor { - private string $requestId; + private readonly string $requestId; public function __construct() { diff --git a/src/Saml/AssertionSigningService.php b/src/Saml/AssertionSigningService.php index 0c8788f..0e09cb2 100644 --- a/src/Saml/AssertionSigningService.php +++ b/src/Saml/AssertionSigningService.php @@ -30,16 +30,12 @@ use Surfnet\GsspBundle\Exception\RuntimeException; use Surfnet\SamlBundle\Entity\IdentityProvider; -final class AssertionSigningService implements AssertionSigningServiceInterface +final readonly class AssertionSigningService implements AssertionSigningServiceInterface { public function __construct(private IdentityProvider $identityProvider) { } - /** - * @param Assertion $assertion - * @return Assertion - */ public function signAssertion(Assertion $assertion): Assertion { $assertion->setSignatureKey($this->loadPrivateKey()); @@ -49,7 +45,6 @@ public function signAssertion(Assertion $assertion): Assertion } /** - * @return XMLSecurityKey * @throws Exception * @throws Exception */ @@ -68,9 +63,6 @@ private function loadPrivateKey(): XMLSecurityKey return $xmlSecurityKey; } - /** - * @return string - */ private function getPublicCertificate(): string { $keyLoader = new KeyLoader(); diff --git a/src/Saml/AssertionSigningServiceInterface.php b/src/Saml/AssertionSigningServiceInterface.php index fd31443..fa361c8 100644 --- a/src/Saml/AssertionSigningServiceInterface.php +++ b/src/Saml/AssertionSigningServiceInterface.php @@ -25,7 +25,6 @@ interface AssertionSigningServiceInterface { /** - * @param Assertion $assertion * @return Assertion */ public function signAssertion(Assertion $assertion); diff --git a/src/Saml/ResponseContext.php b/src/Saml/ResponseContext.php index f177009..ce7e35a 100644 --- a/src/Saml/ResponseContext.php +++ b/src/Saml/ResponseContext.php @@ -25,12 +25,12 @@ use Surfnet\SamlBundle\Entity\ServiceProvider; use Surfnet\SamlBundle\Entity\ServiceProviderRepository; -final class ResponseContext implements ResponseContextInterface +final readonly class ResponseContext implements ResponseContextInterface { public function __construct( - private readonly IdentityProvider $hostedIdentityProvider, - private readonly ServiceProviderRepository $serviceProviderRepository, - private readonly StateHandlerInterface $stateHandler + private IdentityProvider $hostedIdentityProvider, + private ServiceProviderRepository $serviceProviderRepository, + private StateHandlerInterface $stateHandler ) { } diff --git a/src/Service/ConfigurationContainer.php b/src/Service/ConfigurationContainer.php index 217fdd3..eabc8ea 100644 --- a/src/Service/ConfigurationContainer.php +++ b/src/Service/ConfigurationContainer.php @@ -23,18 +23,18 @@ use Assert\Assertion; use Assert\AssertionFailedException; -final class ConfigurationContainer +final readonly class ConfigurationContainer { /** * The gssp middleware route that does the actual registration. */ - private readonly string $registrationRoute; + private string $registrationRoute; /** * The gssp middleware route that does the actual authentication. */ - private readonly string $authenticationRoute; + private string $authenticationRoute; /** * @param string[] $configuration @@ -54,8 +54,6 @@ public function __construct(array $configuration) /** * Getter. - * - * @return string */ public function getAuthenticationRoute(): string { @@ -64,8 +62,6 @@ public function getAuthenticationRoute(): string /** * Getter. - * - * @return string */ public function getRegistrationRoute(): string { diff --git a/src/Service/ResponseService.php b/src/Service/ResponseService.php index 9104cd8..ed74068 100644 --- a/src/Service/ResponseService.php +++ b/src/Service/ResponseService.php @@ -32,13 +32,13 @@ use Surfnet\GsspBundle\Saml\ResponseContextInterface; use Surfnet\SamlBundle\Entity\IdentityProvider; -final class ResponseService implements ResponseServiceInterface +final readonly class ResponseService implements ResponseServiceInterface { public function __construct( - private readonly IdentityProvider $hostedIdentityProvider, - private readonly ResponseContextInterface $responseContext, - private readonly AssertionSigningServiceInterface $assertionSigningService, - private readonly DateTimeService $dateTimeService + private IdentityProvider $hostedIdentityProvider, + private ResponseContextInterface $responseContext, + private AssertionSigningServiceInterface $assertionSigningService, + private DateTimeService $dateTimeService ) { } diff --git a/src/Service/StateBasedAuthenticationService.php b/src/Service/StateBasedAuthenticationService.php index d81c05b..bb78b5b 100644 --- a/src/Service/StateBasedAuthenticationService.php +++ b/src/Service/StateBasedAuthenticationService.php @@ -32,12 +32,12 @@ * * @see AuthenticationService for an example */ -final class StateBasedAuthenticationService implements AuthenticationService +final readonly class StateBasedAuthenticationService implements AuthenticationService { public function __construct( - private readonly StateHandlerInterface $stateHandler, - private readonly RouterInterface $router, - private readonly LoggerInterface $logger + private StateHandlerInterface $stateHandler, + private RouterInterface $router, + private LoggerInterface $logger ) { } @@ -102,9 +102,6 @@ private function generateSsoReturnUrl(): string return $this->router->generate('gssp_saml_sso_return'); } - /** - * @return string - */ public function getIssuer(): string { return $this->stateHandler->getRequestServiceProvider(); diff --git a/src/Service/StateBasedRegistrationService.php b/src/Service/StateBasedRegistrationService.php index cfa37fc..ad8337d 100644 --- a/src/Service/StateBasedRegistrationService.php +++ b/src/Service/StateBasedRegistrationService.php @@ -31,12 +31,12 @@ * * @see RegistrationService for an example */ -final class StateBasedRegistrationService implements RegistrationService +final readonly class StateBasedRegistrationService implements RegistrationService { public function __construct( - private readonly StateHandlerInterface $stateHandler, - private readonly RouterInterface $router, - private readonly LoggerInterface $logger + private StateHandlerInterface $stateHandler, + private RouterInterface $router, + private LoggerInterface $logger ) { } diff --git a/src/Service/StateHandler.php b/src/Service/StateHandler.php index f648554..e382d19 100644 --- a/src/Service/StateHandler.php +++ b/src/Service/StateHandler.php @@ -29,7 +29,7 @@ /** * Knows and preserves the integrity of the GSSP application state. */ -final class StateHandler implements StateHandlerInterface +final readonly class StateHandler implements StateHandlerInterface { public const REQUEST_ID = 'request_id'; public const REQUEST_SERVICE_PROVIDER = 'service_provider'; From 8e62503dfe8ad71351acc83d4d23add6993b1888 Mon Sep 17 00:00:00 2001 From: Johan Kromhout Date: Thu, 22 Jan 2026 12:11:13 +0100 Subject: [PATCH 3/6] Update PHPUnit 9 > 11 --- .gitignore | 1 + ci/qa/phplint | 1 - ci/qa/phpunit.xml | 4 ++-- composer.json | 6 +++--- tests/Service/ResponseServiceTest.php | 9 +++----- .../ValueStore/SessionValueStoreTest.php | 21 ++++++------------- 6 files changed, 15 insertions(+), 27 deletions(-) diff --git a/.gitignore b/.gitignore index 9089690..3ddc61d 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ composer.lock .phpunit.result.cache ci/qa/.phpunit.result.cache +var/cache \ No newline at end of file diff --git a/ci/qa/phplint b/ci/qa/phplint index c09b7ac..9b5b520 100755 --- a/ci/qa/phplint +++ b/ci/qa/phplint @@ -1,7 +1,6 @@ #!/usr/bin/env bash cd $(dirname $0)/../../ -mkdir -p var/qa # https://github.com/overtrue/phplint ./vendor/bin/phplint --configuration=ci/qa/phplint.yaml $1 diff --git a/ci/qa/phpunit.xml b/ci/qa/phpunit.xml index 69b8eca..8adb74f 100644 --- a/ci/qa/phpunit.xml +++ b/ci/qa/phpunit.xml @@ -1,12 +1,12 @@ diff --git a/composer.json b/composer.json index 488341c..62cae00 100644 --- a/composer.json +++ b/composer.json @@ -26,12 +26,12 @@ "behat/behat": "^3.13", "malukenho/docheader": "^0", "mockery/mockery": "^1.5", - "overtrue/phplint": "*", + "overtrue/phplint": "^9.0", "phpmd/phpmd": "^2.13", "phpstan/phpstan": "^2.1", "phpstan/phpstan-symfony": "^2.0", - "phpunit/phpcov": "^8.2", - "phpunit/phpunit": "^9.6", + "phpunit/phpcov": "^10.0", + "phpunit/phpunit": "^11", "rector/rector": "^2.3", "slevomat/coding-standard": "^8.13", "squizlabs/php_codesniffer": "^3.7.1", diff --git a/tests/Service/ResponseServiceTest.php b/tests/Service/ResponseServiceTest.php index abb4fb0..08ad5cd 100644 --- a/tests/Service/ResponseServiceTest.php +++ b/tests/Service/ResponseServiceTest.php @@ -21,6 +21,7 @@ namespace Tests\Surfnet\GsspBundle\Service; use Mockery\MockInterface; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Psr\Log\NullLogger; use SAML2\Compat\ContainerSingleton; @@ -63,9 +64,7 @@ protected function setUp(): void $this->assertionSigningService = \Mockery::spy(AssertionSigningServiceInterface::class); } - /** - * @test - */ + #[Test] public function canCreateResponse() { $datetimeService = new StaticDateTimeService( @@ -107,9 +106,7 @@ public function canCreateResponse() $this->assertionSigningService->shouldHaveReceived('signAssertion'); } - /** - * @test - */ + #[Test] public function canCreateErrorResponse() { $datetimeService = new StaticDateTimeService( diff --git a/tests/Service/ValueStore/SessionValueStoreTest.php b/tests/Service/ValueStore/SessionValueStoreTest.php index 0afc254..29831d6 100644 --- a/tests/Service/ValueStore/SessionValueStoreTest.php +++ b/tests/Service/ValueStore/SessionValueStoreTest.php @@ -21,6 +21,7 @@ namespace Tests\Surfnet\GsspBundle\Service\ValueStore; use Mockery; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Surfnet\GsspBundle\Exception\NotFound; use Surfnet\GsspBundle\Service\ValueStore\SessionValueStore; @@ -30,9 +31,7 @@ class SessionValueStoreTest extends TestCase { - /** - * @test - */ + #[Test] public function canSetProperties() { /** @var \Mockery\MockInterface $session */ @@ -50,9 +49,7 @@ public function canSetProperties() $this->assertNull(Mockery::close()); } - /** - * @test - */ + #[Test] public function canGetProperties() { /** @var \Mockery\MockInterface $session */ @@ -71,9 +68,7 @@ public function canGetProperties() $this->assertEquals(2, $valueStore->get('value2')); } - /** - * @test - */ + #[Test] public function shouldThrowExceptionWhenRequestingUnknownProperties() { $this->expectException(NotFound::class); @@ -89,9 +84,7 @@ public function shouldThrowExceptionWhenRequestingUnknownProperties() $valueStore->get('test'); } - /** - * @test - */ + #[Test] public function knowsIfValueIsSet() { /** @var \Mockery\MockInterface $session */ @@ -107,9 +100,7 @@ public function knowsIfValueIsSet() $this->assertFalse($valueStore->has('value2')); } - /** - * @test - */ + #[Test] public function knowsIfValueMatches() { /** @var \Mockery\MockInterface $session */ From 696a1f02758f755dfb36ba85f0beeff71d027033 Mon Sep 17 00:00:00 2001 From: Johan Kromhout Date: Thu, 22 Jan 2026 12:18:45 +0100 Subject: [PATCH 4/6] Make Symfony 7.4 compatible --- CHANGELOG.md | 4 ++++ ci/qa/phpstan-baseline.neon | 6 ------ composer.json | 16 ++++++++-------- src/Controller/MetadataController.php | 2 +- src/Controller/SSOController.php | 2 +- src/Controller/SSOReturnController.php | 2 +- 6 files changed, 15 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7e5c4c..7a39e79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 6.0.0 + +Make Symfony 7.4 compatible + # 5.0.1 .. 5.0.11 Make the bundle SF6 proof. And upgrade code to be PHP 8.2 compatible All homestead and vagrant references have been removed. diff --git a/ci/qa/phpstan-baseline.neon b/ci/qa/phpstan-baseline.neon index dd09b88..7c51709 100644 --- a/ci/qa/phpstan-baseline.neon +++ b/ci/qa/phpstan-baseline.neon @@ -1,11 +1,5 @@ parameters: ignoreErrors: - - - message: '#^Method Surfnet\\GsspBundle\\Logger\\StepupRequestIdSariLogger\:\:log\(\) has parameter \$context with no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: ../../src/Logger/StepupRequestIdSariLogger.php - - message: '#^Method Surfnet\\GsspBundle\\Saml\\ResponseContext\:\:getErrorStatus\(\) return type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue diff --git a/composer.json b/composer.json index 62cae00..d695cd9 100644 --- a/composer.json +++ b/composer.json @@ -17,14 +17,14 @@ "php": "^8.2", "ext-openssl": "*", "beberlei/assert": "^3", - "symfony/monolog-bundle": "^3.8", - "surfnet/stepup-saml-bundle": "^6.0", - "symfony/dependency-injection": "^6.4", - "symfony/framework-bundle": "^6.4" + "surfnet/stepup-saml-bundle": "^7.0.1", + "symfony/dependency-injection": "^7.4", + "symfony/framework-bundle": "^7.4", + "symfony/monolog-bundle": "^4.0" }, "require-dev": { "behat/behat": "^3.13", - "malukenho/docheader": "^0", + "malukenho/docheader": "^1.1.0", "mockery/mockery": "^1.5", "overtrue/phplint": "^9.0", "phpmd/phpmd": "^2.13", @@ -33,9 +33,9 @@ "phpunit/phpcov": "^10.0", "phpunit/phpunit": "^11", "rector/rector": "^2.3", - "slevomat/coding-standard": "^8.13", - "squizlabs/php_codesniffer": "^3.7.1", - "symfony/phpunit-bridge": "^6.4" + "slevomat/coding-standard": "^8.26", + "squizlabs/php_codesniffer": "^4.0", + "symfony/phpunit-bridge": "^7.4" }, "scripts": { "check": [ diff --git a/src/Controller/MetadataController.php b/src/Controller/MetadataController.php index e759cdd..d041779 100644 --- a/src/Controller/MetadataController.php +++ b/src/Controller/MetadataController.php @@ -22,7 +22,7 @@ use Surfnet\SamlBundle\Http\XMLResponse; use Surfnet\SamlBundle\Metadata\MetadataFactory; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; final readonly class MetadataController { diff --git a/src/Controller/SSOController.php b/src/Controller/SSOController.php index 3a3c328..ee875da 100644 --- a/src/Controller/SSOController.php +++ b/src/Controller/SSOController.php @@ -33,7 +33,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; /** * Handles the SAML AuthnRequest from the service provider. diff --git a/src/Controller/SSOReturnController.php b/src/Controller/SSOReturnController.php index 81d0dff..15c86c6 100644 --- a/src/Controller/SSOReturnController.php +++ b/src/Controller/SSOReturnController.php @@ -33,7 +33,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; /** * Sends back the SAML return response to the service provider. From b761af38a8ff17bf1e909a3938e0775eba72d675 Mon Sep 17 00:00:00 2001 From: Johan Kromhout Date: Thu, 22 Jan 2026 12:21:30 +0100 Subject: [PATCH 5/6] Fix pipeline --- .github/workflows/test-integration.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index 42ba99c..910bdae 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -1,14 +1,17 @@ name: test-integration -on: [ push ] +on: + pull_request: + push: + branches: + - main jobs: build: runs-on: ubuntu-latest - continue-on-error: ${{ matrix.experimental }} strategy: matrix: php: ['8.2', '8.5'] timeout-minutes: 30 - name: PHP ${{ matrix.php-versions }} on Ubuntu latest. Experimental == ${{ matrix.experimental }} + name: PHP ${{ matrix.php-versions }} on Ubuntu latest. steps: - name: Install PHP uses: shivammathur/setup-php@v2 @@ -18,10 +21,8 @@ jobs: uses: actions/checkout@master - name: Install dependencies run: composer install - continue-on-error: ${{ matrix.experimental }} - name: Run CI tests run: composer check-ci - continue-on-error: ${{ matrix.experimental }} - name: Output log files on failure if: failure() run: tail -2000 /var/log/syslog From 4053d883bea3146343674ed33da01ca60d1cd1ff Mon Sep 17 00:00:00 2001 From: Johan Kromhout Date: Thu, 22 Jan 2026 13:59:47 +0100 Subject: [PATCH 6/6] Include updated `stepup-saml-bundle` which allows SF 7.4 --- composer.json | 2 +- src/Monolog/Processor/RequestIdProcessor.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index d695cd9..5ad3b82 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "php": "^8.2", "ext-openssl": "*", "beberlei/assert": "^3", - "surfnet/stepup-saml-bundle": "^7.0.1", + "surfnet/stepup-saml-bundle": "^7.0", "symfony/dependency-injection": "^7.4", "symfony/framework-bundle": "^7.4", "symfony/monolog-bundle": "^4.0" diff --git a/src/Monolog/Processor/RequestIdProcessor.php b/src/Monolog/Processor/RequestIdProcessor.php index fa89cf9..e26de07 100644 --- a/src/Monolog/Processor/RequestIdProcessor.php +++ b/src/Monolog/Processor/RequestIdProcessor.php @@ -38,8 +38,7 @@ public function __construct() public function __invoke(LogRecord $record): LogRecord { /** @see LogRecord::__construct */ - assert(is_array($record['extra'])); - $record['extra']['request_id'] = $this->requestId; + $record->extra['requestId'] = $this->requestId; return $record; }