Skip to content

Tag the per-firewall resettable services with kernel.reset - #330

Open
norkunas wants to merge 1 commit into
scheb:8.xfrom
norkunas:fix/329-propagate-kernel-reset
Open

norkunas wants to merge 1 commit into
scheb:8.xfrom
norkunas:fix/329-propagate-kernel-reset

Conversation

@norkunas

Copy link
Copy Markdown
Contributor

Fixes #329.

A ChildDefinition does not inherit its parent's tags, so the per-firewall services that implement ResetInterface were never reset and kept their state across requests under a persistent worker (FrankenPHP, RoadRunner, Swoole). Under PHP-FPM every request builds a new container, which is why this has gone unnoticed.

Three tags, not two — the authenticator needed both halves:

security.php kernel.reset added to the scheb_two_factor.security.authenticator parent, which had no such tag at all
TwoFactorFactory::createAuthenticator() tag re-added to the per-firewall authenticator child
TwoFactorServicesFactory::createProviderPreparationListener() tag re-added to the per-firewall listener child

TrustedDeviceTokenStorage is the only other ResetInterface implementation in the bundle; it is registered with a plain set() rather than a ChildDefinition and is already tagged, so it is unaffected.

On testing this reliably

You asked whether this could be covered without a compiler pass for the runtime execution. tests/DependencyInjection/ResettableServicesAreTaggedTest.php asserts the property rather than a list of ids: it loads the extension, creates one firewall's services through TwoFactorFactory, runs ResolveChildDefinitionsPass so the children get their parents' classes, then requires kernel.reset on every resolved definition whose class implements ResetInterface, found by reflection.

A resettable service added later without the tag fails this test without anyone remembering to extend it. A second arm asserts at least one resettable definition was found, so the first cannot pass vacuously against an empty container.

Red control — reverting the three tag additions, with the test left in place:

These services implement Symfony\Contracts\Service\ResetInterface but carry no "kernel.reset" tag,
so their state survives into the next request under a persistent worker:
  scheb_two_factor.security.authenticator
  security.authentication.provider_preparation_listener.two_factor.firewallName
  security.authenticator.two_factor.firewallName

Tests: 2, Assertions: 2, Failures: 1.

The vacuity arm stayed green. With the fix restored: OK (2 tests, 2 assertions).

Checks

vendor/bin/phpunit Tests: 480, Assertions: 1513 — OK
vendor/bin/phpcs 74/74 clean
vendor/bin/psalm No errors found!
php-cs-fixer fix --dry-run Found 0 of 257 files that can be fixed

…eb#329

A ChildDefinition does not inherit its parent's tags, so the per-firewall
authenticator and provider preparation listener were never reset. The
authenticator's parent definition carried no kernel.reset tag at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant