From 37c591516a47d470759528edec0fc9cf166cca8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Sun, 31 Jan 2021 20:45:01 +0100 Subject: [PATCH] Deprecate session.storage --- UPGRADE-5.3.md | 2 + UPGRADE-6.0.md | 2 + .../Bundle/FrameworkBundle/CHANGELOG.md | 2 + .../Compiler/SessionPass.php | 2 +- .../DependencyInjection/Configuration.php | 7 +++ .../FrameworkExtension.php | 41 +++++++++++--- .../Bundle/FrameworkBundle/KernelBrowser.php | 3 +- .../Resources/config/schema/symfony-1.0.xsd | 1 + .../Resources/config/session.php | 56 ++++++++++++++++++- .../Compiler/SessionPassTest.php | 6 +- .../DependencyInjection/ConfigurationTest.php | 1 + .../DependencyInjection/Fixtures/php/csrf.php | 1 + .../DependencyInjection/Fixtures/php/full.php | 2 +- .../Fixtures/php/session.php | 1 + .../php/session_cookie_secure_auto.php | 1 + .../php/session_cookie_secure_auto_legacy.php | 9 +++ .../Fixtures/php/session_legacy.php | 8 +++ .../DependencyInjection/Fixtures/xml/csrf.xml | 2 +- .../xml/form_csrf_sets_field_name.xml | 2 +- .../form_csrf_under_form_sets_field_name.xml | 2 +- .../DependencyInjection/Fixtures/xml/full.xml | 2 +- .../Fixtures/xml/session.xml | 2 +- .../xml/session_cookie_secure_auto.xml | 2 +- .../xml/session_cookie_secure_auto_legacy.xml | 12 ++++ .../Fixtures/xml/session_legacy.xml | 12 ++++ .../DependencyInjection/Fixtures/yml/csrf.yml | 3 +- .../DependencyInjection/Fixtures/yml/full.yml | 2 +- .../Fixtures/yml/session.yml | 1 + .../yml/session_cookie_secure_auto.yml | 1 + .../yml/session_cookie_secure_auto_legacy.yml | 5 ++ .../Fixtures/yml/session_legacy.yml | 4 ++ .../FrameworkExtensionTest.php | 38 ++++++++++++- .../Functional/app/ConfigDump/config.yml | 1 + .../Functional/app/ContainerDump/config.yml | 3 +- .../Tests/Functional/app/config/framework.yml | 2 +- .../RegisterTokenUsageTrackingPass.php | 2 +- .../RegisterTokenUsageTrackingPassTest.php | 4 +- .../SecurityExtensionTest.php | 1 + .../Tests/Functional/app/Anonymous/config.yml | 2 +- .../Functional/app/Authenticator/config.yml | 2 +- .../app/FirewallEntryPoint/config.yml | 2 +- .../Tests/Functional/app/Guarded/config.yml | 2 +- .../app/RememberMeLogout/config.yml | 1 + .../Tests/Functional/app/config/framework.yml | 2 +- .../Bundle/SecurityBundle/composer.json | 2 +- .../Functional/WebProfilerBundleKernel.php | 2 +- .../Bundle/WebProfilerBundle/composer.json | 2 +- .../Component/HttpFoundation/CHANGELOG.md | 1 + .../HttpFoundation/Session/SessionFactory.php | 40 +++++++++++++ .../Storage/MockFileSessionStorageFactory.php | 42 ++++++++++++++ .../Storage/NativeSessionStorageFactory.php | 49 ++++++++++++++++ .../PhpBridgeSessionStorageFactory.php | 47 ++++++++++++++++ .../Session/Storage/ServiceSessionFactory.php | 38 +++++++++++++ .../SessionStorageFactoryInterface.php | 25 +++++++++ 54 files changed, 468 insertions(+), 39 deletions(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_cookie_secure_auto_legacy.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_legacy.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_cookie_secure_auto_legacy.xml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_legacy.xml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_cookie_secure_auto_legacy.yml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_legacy.yml create mode 100644 src/Symfony/Component/HttpFoundation/Session/SessionFactory.php create mode 100644 src/Symfony/Component/HttpFoundation/Session/Storage/MockFileSessionStorageFactory.php create mode 100644 src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorageFactory.php create mode 100644 src/Symfony/Component/HttpFoundation/Session/Storage/PhpBridgeSessionStorageFactory.php create mode 100644 src/Symfony/Component/HttpFoundation/Session/Storage/ServiceSessionFactory.php create mode 100644 src/Symfony/Component/HttpFoundation/Session/Storage/SessionStorageFactoryInterface.php diff --git a/UPGRADE-5.3.md b/UPGRADE-5.3.md index d4b8bebe17..9ede8f6e81 100644 --- a/UPGRADE-5.3.md +++ b/UPGRADE-5.3.md @@ -31,6 +31,8 @@ Form FrameworkBundle --------------- + * Deprecate the `session.storage` alias and `session.storage.*` services, use the `session.storage.factory` alias and `session.storage.factory.*` services instead + * Deprecate the `framework.session.storage_id` configuration option, use the `framework.session.storage_factory_id` configuration option instead * Deprecate the `session` service and the `SessionInterface` alias, use the `\Symfony\Component\HttpFoundation\Request::getSession()` or the new `\Symfony\Component\HttpFoundation\RequestStack::getSession()` methods instead HttpFoundation diff --git a/UPGRADE-6.0.md b/UPGRADE-6.0.md index a6ee83505c..85209e010e 100644 --- a/UPGRADE-6.0.md +++ b/UPGRADE-6.0.md @@ -69,6 +69,8 @@ Form FrameworkBundle --------------- + * Remove the `session.storage` alias and `session.storage.*` services, use the `session.storage.factory` alias and `session.storage.factory.*` services instead + * Remove `framework.session.storage_id` configuration option, use the `framework.session.storage_factory_id` configuration option instead * Remove the `session` service and the `SessionInterface` alias, use the `\Symfony\Component\HttpFoundation\Request::getSession()` or the new `\Symfony\Component\HttpFoundation\RequestStack::getSession()` methods instead * `MicroKernelTrait::configureRoutes()` is now always called with a `RoutingConfigurator` * The "framework.router.utf8" configuration option defaults to `true` diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index 61edb7de0e..fd572dc16c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -4,6 +4,8 @@ CHANGELOG 5.3 --- + * Deprecate the `session.storage` alias and `session.storage.*` services, use the `session.storage.factory` alias and `session.storage.factory.*` services instead + * Deprecate the `framework.session.storage_id` configuration option, use the `framework.session.storage_factory_id` configuration option instead * Deprecate the `session` service and the `SessionInterface` alias, use the `Request::getSession()` or the new `RequestStack::getSession()` methods instead * Added `AbstractController::renderForm()` to render a form and set the appropriate HTTP status code * Added support for configuring PHP error level to log levels diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/SessionPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/SessionPass.php index df82076702..c0c9dd6758 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/SessionPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/SessionPass.php @@ -22,7 +22,7 @@ class SessionPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { - if (!$container->has('session.storage')) { + if (!$container->has('session.factory')) { return; } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index f5e2678e40..5c34fd696f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -600,8 +600,15 @@ class Configuration implements ConfigurationInterface ->arrayNode('session') ->info('session configuration') ->canBeEnabled() + ->beforeNormalization() + ->ifTrue(function ($v) { + return \is_array($v) && isset($v['storage_id']) && isset($v['storage_factory_id']); + }) + ->thenInvalid('You cannot use both "storage_id" and "storage_factory_id" at the same time under "framework.session"') + ->end() ->children() ->scalarNode('storage_id')->defaultValue('session.storage.native')->end() + ->scalarNode('storage_factory_id')->defaultNull()->end() ->scalarNode('handler_id')->defaultValue('session.handler.native_file')->end() ->scalarNode('name') ->validate() diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index ac528cbc3c..d69e566871 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -70,6 +70,7 @@ use Symfony\Component\HttpClient\Retry\GenericRetryStrategy; use Symfony\Component\HttpClient\RetryableHttpClient; use Symfony\Component\HttpClient\ScopingHttpClient; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface; use Symfony\Component\HttpKernel\CacheClearer\CacheClearerInterface; use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface; use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; @@ -1028,7 +1029,20 @@ class FrameworkExtension extends Extension $loader->load('session.php'); // session storage - $container->setAlias('session.storage', $config['storage_id']); + if (null === $config['storage_factory_id']) { + trigger_deprecation('symfony/framework-bundle', '5.3', 'Not setting the "framework.session.storage_factory_id" configuration option is deprecated, it will default to "session.storage.factory.native" and will replace the "framework.session.storage_id" configuration option in version 6.0.'); + $container->setAlias('session.storage', $config['storage_id']); + $container->setAlias('session.storage.factory', 'session.storage.factory.service'); + } else { + $container->setAlias('session.storage.factory', $config['storage_factory_id']); + + $container->removeAlias(SessionStorageInterface::class); + $container->removeDefinition('session.storage.metadata_bag'); + $container->removeDefinition('session.storage.native'); + $container->removeDefinition('session.storage.php_bridge'); + $container->removeAlias('session.storage.filesystem'); + } + $options = ['cache_limiter' => '0']; foreach (['name', 'cookie_lifetime', 'cookie_path', 'cookie_domain', 'cookie_secure', 'cookie_httponly', 'cookie_samesite', 'use_cookies', 'gc_maxlifetime', 'gc_probability', 'gc_divisor', 'sid_length', 'sid_bits_per_character'] as $key) { if (isset($config[$key])) { @@ -1037,11 +1051,16 @@ class FrameworkExtension extends Extension } if ('auto' === ($options['cookie_secure'] ?? null)) { - $locator = $container->getDefinition('session_listener')->getArgument(0); - $locator->setValues($locator->getValues() + [ - 'session_storage' => new Reference('session.storage', ContainerInterface::IGNORE_ON_INVALID_REFERENCE), - 'request_stack' => new Reference('request_stack'), - ]); + if (null === $config['storage_factory_id']) { + $locator = $container->getDefinition('session_listener')->getArgument(0); + $locator->setValues($locator->getValues() + [ + 'session_storage' => new Reference('session.storage', ContainerInterface::IGNORE_ON_INVALID_REFERENCE), + 'request_stack' => new Reference('request_stack'), + ]); + } else { + $container->getDefinition('session.storage.factory.native')->replaceArgument(3, true); + $container->getDefinition('session.storage.factory.php_bridge')->replaceArgument(2, true); + } } $container->setParameter('session.storage.options', $options); @@ -1049,8 +1068,14 @@ class FrameworkExtension extends Extension // session handler (the internal callback registered with PHP session management) if (null === $config['handler_id']) { // Set the handler class to be null - $container->getDefinition('session.storage.native')->replaceArgument(1, null); - $container->getDefinition('session.storage.php_bridge')->replaceArgument(0, null); + if ($container->hasDefinition('session.storage.native')) { + $container->getDefinition('session.storage.native')->replaceArgument(1, null); + $container->getDefinition('session.storage.php_bridge')->replaceArgument(0, null); + } else { + $container->getDefinition('session.storage.factory.native')->replaceArgument(1, null); + $container->getDefinition('session.storage.factory.php_bridge')->replaceArgument(0, null); + } + $container->setAlias('session.handler', 'session.handler.native_file'); } else { $container->resolveEnvPlaceholders($config['handler_id'], null, $usedEnvs); diff --git a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php index 19a5005157..cba7b829bb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php +++ b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php @@ -18,7 +18,6 @@ use Symfony\Component\BrowserKit\History; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpKernel\HttpKernelBrowser; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\HttpKernel\Profiler\Profile as HttpProfile; @@ -123,7 +122,7 @@ class KernelBrowser extends HttpKernelBrowser $token = new TestBrowserToken($user->getRoles(), $user); $token->setAuthenticated(true); - $session = new Session($this->getContainer()->get('test.service_container')->get('session.storage')); + $session = $this->getContainer()->get('test.service_container')->get('session.factory')->createSession(); $session->set('_security_'.$firewallContext, serialize($token)); $session->save(); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd index 05675e19b3..061647649a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd @@ -107,6 +107,7 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.php index fcaca3ffc4..bef83c3c01 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/session.php @@ -16,6 +16,7 @@ use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag; use Symfony\Component\HttpFoundation\Session\Flash\FlashBag; use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpFoundation\Session\SessionFactory; use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\Storage\Handler\AbstractSessionHandler; use Symfony\Component\HttpFoundation\Session\Storage\Handler\IdentityMarshaller; @@ -25,8 +26,12 @@ use Symfony\Component\HttpFoundation\Session\Storage\Handler\SessionHandlerFacto use Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandler; use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag; use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage; +use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorageFactory; use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; +use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorageFactory; use Symfony\Component\HttpFoundation\Session\Storage\PhpBridgeSessionStorage; +use Symfony\Component\HttpFoundation\Session\Storage\PhpBridgeSessionStorageFactory; +use Symfony\Component\HttpFoundation\Session\Storage\ServiceSessionFactory; use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface; use Symfony\Component\HttpKernel\EventListener\SessionListener; @@ -35,17 +40,57 @@ return static function (ContainerConfigurator $container) { $container->services() ->set('.session.do-not-use', Session::class) // to be removed in 6.0 + ->factory([service('session.factory'), 'createSession']) + ->set('session.factory', SessionFactory::class) ->args([ - service('session.storage'), - null, // AttributeBagInterface - null, // FlashBagInterface + service('request_stack'), + service('session.storage.factory'), [service('session_listener'), 'onSessionUsage'], ]) + + ->set('session.storage.factory.native', NativeSessionStorageFactory::class) + ->args([ + param('session.storage.options'), + service('session.handler'), + inline_service(MetadataBag::class) + ->args([ + param('session.metadata.storage_key'), + param('session.metadata.update_threshold'), + ]), + false, + ]) + ->set('session.storage.factory.php_bridge', PhpBridgeSessionStorageFactory::class) + ->args([ + service('session.handler'), + inline_service(MetadataBag::class) + ->args([ + param('session.metadata.storage_key'), + param('session.metadata.update_threshold'), + ]), + false, + ]) + ->set('session.storage.factory.mock_file', MockFileSessionStorageFactory::class) + ->args([ + param('kernel.cache_dir').'/sessions', + 'MOCKSESSID', + inline_service(MetadataBag::class) + ->args([ + param('session.metadata.storage_key'), + param('session.metadata.update_threshold'), + ]), + ]) + ->set('session.storage.factory.service', ServiceSessionFactory::class) + ->args([ + service('session.storage'), + ]) + ->deprecate('symfony/framework-bundle', '5.3', 'The "%service_id%" service is deprecated, use "session.storage.factory.native", "session.storage.factory.php_bridge" or "session.storage.factory.mock_file" instead.') + ->set('.session.deprecated', SessionInterface::class) // to be removed in 6.0 ->factory([inline_service(DeprecatedSessionFactory::class)->args([service('request_stack')]), 'getSession']) ->alias(SessionInterface::class, '.session.do-not-use') ->deprecate('symfony/framework-bundle', '5.3', 'The "%alias_id%" alias is deprecated, use "$requestStack->getSession()" instead.') ->alias(SessionStorageInterface::class, 'session.storage') + ->deprecate('symfony/framework-bundle', '5.3', 'The "%alias_id%" alias is deprecated, use "session.storage.factory" instead.') ->alias(\SessionHandlerInterface::class, 'session.handler') ->set('session.storage.metadata_bag', MetadataBag::class) @@ -53,6 +98,7 @@ return static function (ContainerConfigurator $container) { param('session.metadata.storage_key'), param('session.metadata.update_threshold'), ]) + ->deprecate('symfony/framework-bundle', '5.3', 'The "%service_id%" service is deprecated, create your own "session.storage.factory" instead.') ->set('session.storage.native', NativeSessionStorage::class) ->args([ @@ -60,12 +106,14 @@ return static function (ContainerConfigurator $container) { service('session.handler'), service('session.storage.metadata_bag'), ]) + ->deprecate('symfony/framework-bundle', '5.3', 'The "%service_id%" service is deprecated, use "session.storage.factory.native" instead.') ->set('session.storage.php_bridge', PhpBridgeSessionStorage::class) ->args([ service('session.handler'), service('session.storage.metadata_bag'), ]) + ->deprecate('symfony/framework-bundle', '5.3', 'The "%service_id%" service is deprecated, use "session.storage.factory.php_bridge" instead.') ->set('session.flash_bag', FlashBag::class) ->factory([service('.session.do-not-use'), 'getFlashBag']) @@ -83,6 +131,7 @@ return static function (ContainerConfigurator $container) { 'MOCKSESSID', service('session.storage.metadata_bag'), ]) + ->deprecate('symfony/framework-bundle', '5.3', 'The "%service_id%" service is deprecated, use "session.storage.factory.mock_file" instead.') ->set('session.handler.native_file', StrictSessionHandler::class) ->args([ @@ -108,6 +157,7 @@ return static function (ContainerConfigurator $container) { // for BC ->alias('session.storage.filesystem', 'session.storage.mock_file') + ->deprecate('symfony/framework-bundle', '5.3', 'The "%alias_id%" alias is deprecated, use "session.storage.factory.mock_file" instead.') ->set('session.marshaller', IdentityMarshaller::class) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SessionPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SessionPassTest.php index 4b3601969d..7cbb3262f1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SessionPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SessionPassTest.php @@ -22,7 +22,7 @@ class SessionPassTest extends TestCase { $container = new ContainerBuilder(); $container - ->register('session.storage'); // marker service + ->register('session.factory'); // marker service $container ->register('.session.do-not-use'); @@ -41,7 +41,7 @@ class SessionPassTest extends TestCase ]; $container = new ContainerBuilder(); $container - ->register('session.storage'); // marker service + ->register('session.factory'); // marker service $container ->register('session') ->setArguments($arguments); @@ -70,7 +70,7 @@ class SessionPassTest extends TestCase ]; $container = new ContainerBuilder(); $container - ->register('session.storage'); // marker service + ->register('session.factory'); // marker service $container ->register('trueSession') ->setArguments($arguments); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index 73dcb2c4ba..bab22e1d23 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -463,6 +463,7 @@ class ConfigurationTest extends TestCase 'session' => [ 'enabled' => false, 'storage_id' => 'session.storage.native', + 'storage_factory_id' => null, 'handler_id' => 'session.handler.native_file', 'cookie_httponly' => true, 'cookie_samesite' => null, diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/csrf.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/csrf.php index e3f3577c1b..41a3e2ee84 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/csrf.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/csrf.php @@ -6,6 +6,7 @@ $container->loadFromExtension('framework', [ 'legacy_error_messages' => false, ], 'session' => [ + 'storage_factory_id' => 'session.storage.factory.native', 'handler_id' => null, ], ]); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php index 32f174118c..7aa6c50135 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php @@ -27,7 +27,7 @@ $container->loadFromExtension('framework', [ 'utf8' => true, ], 'session' => [ - 'storage_id' => 'session.storage.native', + 'storage_factory_id' => 'session.storage.factory.native', 'handler_id' => 'session.handler.native_file', 'name' => '_SYMFONY', 'cookie_lifetime' => 86400, diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session.php index 375008c7db..8b4c6e6e4c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session.php @@ -2,6 +2,7 @@ $container->loadFromExtension('framework', [ 'session' => [ + 'storage_factory_id' => 'session.storage.factory.native', 'handler_id' => null, ], ]); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_cookie_secure_auto.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_cookie_secure_auto.php index 7259b07f92..b52935c726 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_cookie_secure_auto.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_cookie_secure_auto.php @@ -2,6 +2,7 @@ $container->loadFromExtension('framework', [ 'session' => [ + 'storage_factory_id' => 'session.storage.factory.native', 'handler_id' => null, 'cookie_secure' => 'auto', ], diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_cookie_secure_auto_legacy.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_cookie_secure_auto_legacy.php new file mode 100644 index 0000000000..23cd73767b --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_cookie_secure_auto_legacy.php @@ -0,0 +1,9 @@ +loadFromExtension('framework', [ + 'session' => [ + 'handler_id' => null, + 'cookie_secure' => 'auto', + ], +]); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_legacy.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_legacy.php new file mode 100644 index 0000000000..e453305799 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/session_legacy.php @@ -0,0 +1,8 @@ +loadFromExtension('framework', [ + 'session' => [ + 'handler_id' => null, + ], +]); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/csrf.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/csrf.xml index 4686d9ffc0..24acb3e327 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/csrf.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/csrf.xml @@ -9,6 +9,6 @@ - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/form_csrf_sets_field_name.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/form_csrf_sets_field_name.xml index 1552a3ceb6..30fcf6b7f3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/form_csrf_sets_field_name.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/form_csrf_sets_field_name.xml @@ -8,7 +8,7 @@ - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/form_csrf_under_form_sets_field_name.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/form_csrf_under_form_sets_field_name.xml index dda2e724cc..1e89bca965 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/form_csrf_under_form_sets_field_name.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/form_csrf_under_form_sets_field_name.xml @@ -9,6 +9,6 @@ - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml index 9207066f1c..4641e70267 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml @@ -15,7 +15,7 @@ - + text/csv diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session.xml index 599cbdee1c..e91d51955e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session.xml @@ -7,6 +7,6 @@ http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"> - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_cookie_secure_auto.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_cookie_secure_auto.xml index 1fff3e090e..3023c43fc1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_cookie_secure_auto.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_cookie_secure_auto.xml @@ -7,6 +7,6 @@ http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"> - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_cookie_secure_auto_legacy.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_cookie_secure_auto_legacy.xml new file mode 100644 index 0000000000..6893400865 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_cookie_secure_auto_legacy.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_legacy.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_legacy.xml new file mode 100644 index 0000000000..326cf268d9 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/session_legacy.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/csrf.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/csrf.yml index d29019cf48..26d1d832fc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/csrf.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/csrf.yml @@ -3,4 +3,5 @@ framework: csrf_protection: ~ form: legacy_error_messages: false - session: ~ + session: + storage_factory_id: session.storage.factory.native diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml index 2206585863..67a3f1db00 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml @@ -19,7 +19,7 @@ framework: type: xml utf8: true session: - storage_id: session.storage.native + storage_factory_id: session.storage.factory.native handler_id: session.handler.native_file name: _SYMFONY cookie_lifetime: 86400 diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session.yml index d91b0c3147..eb0df8d01c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session.yml @@ -1,3 +1,4 @@ framework: session: + storage_factory_id: session.storage.factory.native handler_id: null diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_cookie_secure_auto.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_cookie_secure_auto.yml index 17fe2f5a02..739b49b1e6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_cookie_secure_auto.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_cookie_secure_auto.yml @@ -1,4 +1,5 @@ framework: session: + storage_factory_id: session.storage.factory.native handler_id: ~ cookie_secure: auto diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_cookie_secure_auto_legacy.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_cookie_secure_auto_legacy.yml new file mode 100644 index 0000000000..bac546c371 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_cookie_secure_auto_legacy.yml @@ -0,0 +1,5 @@ +# to be removed in Symfony 6.0 +framework: + session: + handler_id: ~ + cookie_secure: auto diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_legacy.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_legacy.yml new file mode 100644 index 0000000000..171fadd076 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/session_legacy.yml @@ -0,0 +1,4 @@ +# to be removed in Symfony 6.0 +framework: + session: + handler_id: null diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 7cd3f08368..fd0521f98b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -544,7 +544,10 @@ abstract class FrameworkExtensionTest extends TestCase $this->assertTrue($container->hasAlias(SessionInterface::class), '->registerSessionConfiguration() loads session.xml'); $this->assertEquals('fr', $container->getParameter('kernel.default_locale')); - $this->assertEquals('session.storage.native', (string) $container->getAlias('session.storage')); + $this->assertEquals('session.storage.factory.native', (string) $container->getAlias('session.storage.factory')); + $this->assertFalse($container->has('session.storage')); + $this->assertFalse($container->has('session.storage.native')); + $this->assertFalse($container->has('session.storage.php_bridge')); $this->assertEquals('session.handler.native_file', (string) $container->getAlias('session.handler')); $options = $container->getParameter('session.storage.options'); @@ -568,6 +571,25 @@ abstract class FrameworkExtensionTest extends TestCase { $container = $this->createContainerFromFile('session'); + $this->assertTrue($container->hasAlias(SessionInterface::class), '->registerSessionConfiguration() loads session.xml'); + $this->assertNull($container->getDefinition('session.storage.factory.native')->getArgument(1)); + $this->assertNull($container->getDefinition('session.storage.factory.php_bridge')->getArgument(0)); + $this->assertSame('session.handler.native_file', (string) $container->getAlias('session.handler')); + + $expected = ['session', 'initialized_session', 'logger', 'session_collector']; + $this->assertEquals($expected, array_keys($container->getDefinition('session_listener')->getArgument(0)->getValues())); + $this->assertSame(false, $container->getDefinition('session.storage.factory.native')->getArgument(3)); + } + + /** + * @group legacy + */ + public function testNullSessionHandlerLegacy() + { + $this->expectDeprecation('Since symfony/framework-bundle 5.3: Not setting the "framework.session.storage_factory_id" configuration option is deprecated, it will default to "session.storage.factory.native" and will replace the "framework.session.storage_id" configuration option in version 6.0.'); + + $container = $this->createContainerFromFile('session_legacy'); + $this->assertTrue($container->hasAlias(SessionInterface::class), '->registerSessionConfiguration() loads session.xml'); $this->assertNull($container->getDefinition('session.storage.native')->getArgument(1)); $this->assertNull($container->getDefinition('session.storage.php_bridge')->getArgument(0)); @@ -575,6 +597,7 @@ abstract class FrameworkExtensionTest extends TestCase $expected = ['session', 'initialized_session', 'logger', 'session_collector']; $this->assertEquals($expected, array_keys($container->getDefinition('session_listener')->getArgument(0)->getValues())); + $this->assertSame(false, $container->getDefinition('session.storage.factory.native')->getArgument(3)); } public function testRequest() @@ -1479,6 +1502,19 @@ abstract class FrameworkExtensionTest extends TestCase { $container = $this->createContainerFromFile('session_cookie_secure_auto'); + $expected = ['session', 'initialized_session', 'logger', 'session_collector']; + $this->assertEquals($expected, array_keys($container->getDefinition('session_listener')->getArgument(0)->getValues())); + } + + /** + * @group legacy + */ + public function testSessionCookieSecureAutoLegacy() + { + $this->expectDeprecation('Since symfony/framework-bundle 5.3: Not setting the "framework.session.storage_factory_id" configuration option is deprecated, it will default to "session.storage.factory.native" and will replace the "framework.session.storage_id" configuration option in version 6.0.'); + + $container = $this->createContainerFromFile('session_cookie_secure_auto_legacy'); + $expected = ['session', 'initialized_session', 'logger', 'session_collector', 'session_storage', 'request_stack']; $this->assertEquals($expected, array_keys($container->getDefinition('session_listener')->getArgument(0)->getValues())); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/ConfigDump/config.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/ConfigDump/config.yml index 432e35bd2f..1ec484a7f5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/ConfigDump/config.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/ConfigDump/config.yml @@ -5,6 +5,7 @@ framework: secret: '%secret%' default_locale: '%env(LOCALE)%' session: + storage_factory_id: session.storage.factory.native cookie_httponly: '%env(bool:COOKIE_HTTPONLY)%' parameters: diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/ContainerDump/config.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/ContainerDump/config.yml index 5754ba9693..be0eab4d56 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/ContainerDump/config.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/ContainerDump/config.yml @@ -7,7 +7,8 @@ framework: fragments: true profiler: true router: true - session: true + session: + storage_factory_id: session.storage.factory.native request: true assets: true translator: true diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/config/framework.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/config/framework.yml index 50078d4fd5..bfe7e24b33 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/config/framework.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/config/framework.yml @@ -9,7 +9,7 @@ framework: test: true default_locale: en session: - storage_id: session.storage.mock_file + storage_factory_id: session.storage.factory.mock_file services: logger: { class: Psr\Log\NullLogger } diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterTokenUsageTrackingPass.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterTokenUsageTrackingPass.php index cedfe3a8d7..5ba017f51e 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterTokenUsageTrackingPass.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterTokenUsageTrackingPass.php @@ -41,7 +41,7 @@ class RegisterTokenUsageTrackingPass implements CompilerPassInterface TokenStorageInterface::class => new BoundArgument(new Reference('security.untracked_token_storage'), false), ]); - if (!$container->has('session.storage')) { + if (!$container->has('session.factory') && !$container->has('session.storage')) { $container->setAlias('security.token_storage', 'security.untracked_token_storage')->setPublic(true); $container->getDefinition('security.untracked_token_storage')->addTag('kernel.reset', ['method' => 'reset']); } elseif ($container->hasDefinition('security.context_listener')) { diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/RegisterTokenUsageTrackingPassTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/RegisterTokenUsageTrackingPassTest.php index f997a62cd5..993601ee8e 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/RegisterTokenUsageTrackingPassTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/RegisterTokenUsageTrackingPassTest.php @@ -18,7 +18,9 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpFoundation\Session\SessionFactory; use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; +use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorageFactory; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage; use Symfony\Component\Security\Http\Firewall\ContextListener; @@ -66,7 +68,7 @@ class RegisterTokenUsageTrackingPassTest extends TestCase $container = new ContainerBuilder(); $container->setParameter('security.token_storage.class', UsageTrackingTokenStorage::class); - $container->register('session.storage', NativeSessionStorage::class); + $container->register('session.factory', SessionFactory::class); $container->register('security.context_listener', ContextListener::class) ->setArguments([ new Reference('security.untracked_token_storage'), diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php index 3ffa6cb015..03db66cc98 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php @@ -398,6 +398,7 @@ class SecurityExtensionTest extends TestCase ], [ [ + 'storage_factory_id' => 'session.storage.factory.native', 'cookie_secure' => true, 'cookie_samesite' => 'lax', 'save_path' => null, diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Anonymous/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Anonymous/config.yml index c0f9a7c191..9d804818d8 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Anonymous/config.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Anonymous/config.yml @@ -7,7 +7,7 @@ framework: test: ~ default_locale: en session: - storage_id: session.storage.mock_file + storage_factory_id: session.storage.factory.mock_file profiler: { only_exceptions: false } services: diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/config.yml index 45bde5bda3..1beade7dbe 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/config.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/config.yml @@ -5,7 +5,7 @@ framework: default_locale: en profiler: false session: - storage_id: session.storage.mock_file + storage_factory_id: session.storage.factory.mock_file services: logger: { class: Psr\Log\NullLogger } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/config.yml index bcb5d374b0..b862b04a63 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/config.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/config.yml @@ -9,7 +9,7 @@ framework: test: ~ default_locale: en session: - storage_id: session.storage.mock_file + storage_factory_id: session.storage.factory.mock_file profiler: { only_exceptions: false } services: diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/config.yml index 75fa554462..81ef3399a9 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/config.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/config.yml @@ -5,7 +5,7 @@ framework: default_locale: en profiler: false session: - storage_id: session.storage.mock_file + storage_factory_id: session.storage.factory.mock_file services: logger: { class: Psr\Log\NullLogger } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/config.yml index 298574d2b1..caadeeb7a8 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/config.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/config.yml @@ -3,6 +3,7 @@ imports: framework: session: + storage_factory_id: session.storage.factory.mock_file cookie_secure: auto cookie_samesite: lax diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/config/framework.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/config/framework.yml index e145253080..94a00c01fc 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/config/framework.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/config/framework.yml @@ -10,7 +10,7 @@ framework: test: ~ default_locale: en session: - storage_id: session.storage.mock_file + storage_factory_id: session.storage.factory.mock_file profiler: { only_exceptions: false } services: diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index f2a710e1ce..82b2399602 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -39,7 +39,7 @@ "symfony/dom-crawler": "^4.4|^5.0", "symfony/expression-language": "^4.4|^5.0", "symfony/form": "^4.4|^5.0", - "symfony/framework-bundle": "^5.2", + "symfony/framework-bundle": "^5.3", "symfony/process": "^4.4|^5.0", "symfony/rate-limiter": "^5.2", "symfony/serializer": "^4.4|^5.0", diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Functional/WebProfilerBundleKernel.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Functional/WebProfilerBundleKernel.php index 1d3bcf33cd..32e9d936fb 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/Functional/WebProfilerBundleKernel.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Functional/WebProfilerBundleKernel.php @@ -43,7 +43,7 @@ class WebProfilerBundleKernel extends Kernel $containerBuilder->loadFromExtension('framework', [ 'secret' => 'foo-secret', 'profiler' => ['only_exceptions' => false], - 'session' => ['storage_id' => 'session.storage.mock_file'], + 'session' => ['storage_factory_id' => 'session.storage.factory.mock_file'], 'router' => ['utf8' => true], ]); diff --git a/src/Symfony/Bundle/WebProfilerBundle/composer.json b/src/Symfony/Bundle/WebProfilerBundle/composer.json index 46b7e78567..277f8095c0 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/composer.json +++ b/src/Symfony/Bundle/WebProfilerBundle/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=7.2.5", "symfony/config": "^4.4|^5.0", - "symfony/framework-bundle": "^5.1", + "symfony/framework-bundle": "^5.3", "symfony/http-kernel": "^5.2", "symfony/routing": "^4.4|^5.0", "symfony/twig-bundle": "^4.4|^5.0", diff --git a/src/Symfony/Component/HttpFoundation/CHANGELOG.md b/src/Symfony/Component/HttpFoundation/CHANGELOG.md index b71cc54d5e..d6a57aae14 100644 --- a/src/Symfony/Component/HttpFoundation/CHANGELOG.md +++ b/src/Symfony/Component/HttpFoundation/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 5.3 --- + * Add the `SessionFactory`, `NativeSessionStorageFactory`, `PhpBridgeSessionStorageFactory` and `MockFileSessionStorageFactory` classes * Calling `Request::getSession()` when there is no available session throws a `SessionNotFoundException` * Add the `RequestStack::getSession` method * Deprecate the `NamespacedAttributeBag` class diff --git a/src/Symfony/Component/HttpFoundation/Session/SessionFactory.php b/src/Symfony/Component/HttpFoundation/Session/SessionFactory.php new file mode 100644 index 0000000000..a9982ed0c3 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Session/SessionFactory.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session; + +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageFactoryInterface; + +// Help opcache.preload discover always-needed symbols +class_exists(Session::class); + +/** + * @author Jérémy Derussé + */ +class SessionFactory +{ + private $requestStack; + private $storageFactory; + private $usageReporter; + + public function __construct(RequestStack $requestStack, SessionStorageFactoryInterface $storageFactory, callable $usageReporter = null) + { + $this->requestStack = $requestStack; + $this->storageFactory = $storageFactory; + $this->usageReporter = $usageReporter; + } + + public function createSession(): SessionInterface + { + return new Session($this->storageFactory->createStorage($this->requestStack->getMasterRequest()), null, null, $this->usageReporter); + } +} diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/MockFileSessionStorageFactory.php b/src/Symfony/Component/HttpFoundation/Session/Storage/MockFileSessionStorageFactory.php new file mode 100644 index 0000000000..d0da1e1692 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/MockFileSessionStorageFactory.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage; + +use Symfony\Component\HttpFoundation\Request; + +// Help opcache.preload discover always-needed symbols +class_exists(MockFileSessionStorage::class); + +/** + * @author Jérémy Derussé + */ +class MockFileSessionStorageFactory implements SessionStorageFactoryInterface +{ + private $savePath; + private $name; + private $metaBag; + + /** + * @see MockFileSessionStorage constructor. + */ + public function __construct(string $savePath = null, string $name = 'MOCKSESSID', MetadataBag $metaBag = null) + { + $this->savePath = $savePath; + $this->name = $name; + $this->metaBag = $metaBag; + } + + public function createStorage(?Request $request): SessionStorageInterface + { + return new MockFileSessionStorage($this->savePath, $this->name, $this->metaBag); + } +} diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorageFactory.php b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorageFactory.php new file mode 100644 index 0000000000..a7d7411ff3 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorageFactory.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage; + +use Symfony\Component\HttpFoundation\Request; + +// Help opcache.preload discover always-needed symbols +class_exists(NativeSessionStorage::class); + +/** + * @author Jérémy Derussé + */ +class NativeSessionStorageFactory implements SessionStorageFactoryInterface +{ + private $options; + private $handler; + private $metaBag; + private $secure; + + /** + * @see NativeSessionStorage constructor. + */ + public function __construct(array $options = [], $handler = null, MetadataBag $metaBag = null, bool $secure = false) + { + $this->options = $options; + $this->handler = $handler; + $this->metaBag = $metaBag; + $this->secure = $secure; + } + + public function createStorage(?Request $request): SessionStorageInterface + { + $storage = new NativeSessionStorage($this->options, $this->handler, $this->metaBag); + if ($this->secure && $request && $request->isSecure()) { + $storage->setOptions(['cookie_secure' => true]); + } + + return $storage; + } +} diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/PhpBridgeSessionStorageFactory.php b/src/Symfony/Component/HttpFoundation/Session/Storage/PhpBridgeSessionStorageFactory.php new file mode 100644 index 0000000000..173ef71dea --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/PhpBridgeSessionStorageFactory.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage; + +use Symfony\Component\HttpFoundation\Request; + +// Help opcache.preload discover always-needed symbols +class_exists(PhpBridgeSessionStorage::class); + +/** + * @author Jérémy Derussé + */ +class PhpBridgeSessionStorageFactory implements SessionStorageFactoryInterface +{ + private $handler; + private $metaBag; + private $secure; + + /** + * @see PhpBridgeSessionStorage constructor. + */ + public function __construct($handler = null, MetadataBag $metaBag = null, bool $secure = false) + { + $this->handler = $handler; + $this->metaBag = $metaBag; + $this->secure = $secure; + } + + public function createStorage(?Request $request): SessionStorageInterface + { + $storage = new PhpBridgeSessionStorage($this->handler, $this->metaBag); + if ($this->secure && $request && $request->isSecure()) { + $storage->setOptions(['cookie_secure' => true]); + } + + return $storage; + } +} diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/ServiceSessionFactory.php b/src/Symfony/Component/HttpFoundation/Session/Storage/ServiceSessionFactory.php new file mode 100644 index 0000000000..d17c60aeba --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/ServiceSessionFactory.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage; + +use Symfony\Component\HttpFoundation\Request; + +/** + * @author Jérémy Derussé + * + * @internal to be removed in Symfony 6 + */ +final class ServiceSessionFactory implements SessionStorageFactoryInterface +{ + private $storage; + + public function __construct(SessionStorageInterface $storage) + { + $this->storage = $storage; + } + + public function createStorage(?Request $request): SessionStorageInterface + { + if ($this->storage instanceof NativeSessionStorage && $request && $request->isSecure()) { + $this->storage->setOptions(['cookie_secure' => true]); + } + + return $this->storage; + } +} diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/SessionStorageFactoryInterface.php b/src/Symfony/Component/HttpFoundation/Session/Storage/SessionStorageFactoryInterface.php new file mode 100644 index 0000000000..f0387b5e12 --- /dev/null +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/SessionStorageFactoryInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage; + +use Symfony\Component\HttpFoundation\Request; + +/** + * @author Jérémy Derussé + */ +interface SessionStorageFactoryInterface +{ + /** + * Creates a new instance of SessionStorageInterface + */ + public function createStorage(?Request $request): SessionStorageInterface; +}