From 46a8f07c78502240857c3f8f02678da1c1670787 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sun, 23 Jun 2024 16:32:31 +0200 Subject: [PATCH 1/7] Introduce isStateless method --- .../Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php | 2 +- src/Symfony/Component/HttpFoundation/Request.php | 5 +++++ .../HttpKernel/DataCollector/RequestDataCollector.php | 2 +- .../HttpKernel/EventListener/AbstractSessionListener.php | 4 ++-- .../HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php | 4 ++-- .../Authentication/DefaultAuthenticationFailureHandler.php | 2 +- .../Authentication/DefaultAuthenticationSuccessHandler.php | 2 +- .../DefaultAuthenticationFailureHandlerTest.php | 3 +-- 8 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php index fdf9c3d53a3c7..b100d5a707db8 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php @@ -88,7 +88,7 @@ public function testGetListeners(Request $request, bool $expectedState) $this->assertEquals([[$listener], $exceptionListener, $logoutListener], $firewallMap->getListeners($request)); $this->assertEquals($firewallConfig, $firewallMap->getFirewallConfig($request)); $this->assertEquals('security.firewall.map.context.foo', $request->attributes->get(self::ATTRIBUTE_FIREWALL_CONTEXT)); - $this->assertEquals($expectedState, $request->attributes->get('_stateless')); + $this->assertEquals($expectedState, $request->isStateless()); } public static function providesStatefulStatelessRequests(): \Generator diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index c17d1d10c39fe..f54a53d12317e 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -651,6 +651,11 @@ public function get(string $key, mixed $default = null): mixed return $default; } + public function isStateless(): bool + { + return $this->attributes->getBoolean('_stateless'); + } + /** * Gets the Session. * diff --git a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php index 235bd4c74f2d3..8b5511d8a4f60 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php @@ -106,7 +106,7 @@ public function collect(Request $request, Response $response, ?\Throwable $excep 'session_metadata' => $sessionMetadata, 'session_attributes' => $sessionAttributes, 'session_usages' => array_values($this->sessionUsages), - 'stateless_check' => $this->requestStack?->getMainRequest()?->attributes->get('_stateless') ?? false, + 'stateless_check' => $this->requestStack?->getMainRequest()?->isStateless() ?? false, 'flashes' => $flashes, 'path_info' => $request->getPathInfo(), 'controller' => 'n/a', diff --git a/src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php b/src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php index 5c9517be6557e..2d84f525088c8 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php @@ -206,7 +206,7 @@ public function onKernelResponse(ResponseEvent $event): void ->headers->addCacheControlDirective('must-revalidate'); } - if (!$event->getRequest()->attributes->get('_stateless', false)) { + if (!$event->getRequest()->isStateless()) { return; } @@ -239,7 +239,7 @@ public function onSessionUsage(): void $stateless = false; $clonedRequestStack = clone $requestStack; while (null !== ($request = $clonedRequestStack->pop()) && !$stateless) { - $stateless = $request->attributes->get('_stateless'); + $stateless = $request->isStateless(); } if (!$stateless) { diff --git a/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php b/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php index 2d492c5359289..cab4c55db4d70 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php @@ -281,7 +281,7 @@ public function testStatelessAttributeIsForwardedByDefault() $kernel ->expects($this->once()) ->method('handle') - ->with($this->callback(static fn (Request $subRequest) => $subRequest->attributes->get('_stateless'))) + ->with($this->callback(static fn (Request $subRequest) => $subRequest->isStateless())) ; $strategy = new InlineFragmentRenderer($kernel); $strategy->render('/', $request); @@ -296,7 +296,7 @@ public function testStatelessAttributeCanBeDisabled() $kernel ->expects($this->once()) ->method('handle') - ->with($this->callback(static fn (Request $subRequest) => !$subRequest->attributes->get('_stateless'))) + ->with($this->callback(static fn (Request $subRequest) => !$subRequest->isStateless())) ; $strategy = new InlineFragmentRenderer($kernel); $strategy->render(new ControllerReference('main_controller', ['_stateless' => false]), $request); diff --git a/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationFailureHandler.php b/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationFailureHandler.php index 4003b7d1b1789..b13b29a33b500 100644 --- a/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationFailureHandler.php +++ b/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationFailureHandler.php @@ -86,7 +86,7 @@ public function onAuthenticationFailure(Request $request, AuthenticationExceptio $this->logger?->debug('Authentication failure, redirect triggered.', ['failure_path' => $options['failure_path']]); - if (!$request->attributes->getBoolean('_stateless')) { + if (!$request->isStateless()) { $request->getSession()->set(SecurityRequestAttributes::AUTHENTICATION_ERROR, $exception); } diff --git a/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php b/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php index 5f69def453971..ff9cf7d53da16 100644 --- a/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php +++ b/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php @@ -99,7 +99,7 @@ protected function determineTargetUrl(Request $request): string } $firewallName = $this->getFirewallName(); - if (null !== $firewallName && !$request->attributes->getBoolean('_stateless') && $targetUrl = $this->getTargetPath($request->getSession(), $firewallName)) { + if (null !== $firewallName && !$request->isStateless() && $targetUrl = $this->getTargetPath($request->getSession(), $firewallName)) { $this->removeTargetPath($request->getSession(), $firewallName); return $targetUrl; diff --git a/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php b/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php index e29d62dc2ed24..65888f3fbc3da 100644 --- a/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php @@ -47,7 +47,6 @@ protected function setUp(): void $this->session = $this->createMock(SessionInterface::class); $this->request = $this->createMock(Request::class); - $this->request->attributes = new ParameterBag(['_stateless' => false]); $this->request->expects($this->any())->method('getSession')->willReturn($this->session); $this->exception = $this->getMockBuilder(AuthenticationException::class)->onlyMethods(['getMessage'])->getMock(); } @@ -93,7 +92,7 @@ public function testExceptionIsPersistedInSession() public function testExceptionIsNotPersistedInSessionOnStatelessRequest() { - $this->request->attributes = new ParameterBag(['_stateless' => true]); + $this->request->method('isStateless')->willReturn(true); $this->session->expects($this->never()) ->method('set')->with(SecurityRequestAttributes::AUTHENTICATION_ERROR, $this->exception); From 7e9fef09cc977e3e42695400dc372f2fc7cdcdc8 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sat, 27 Jul 2024 21:04:47 +0200 Subject: [PATCH 2/7] Bump version --- src/Symfony/Component/HttpKernel/composer.json | 2 +- src/Symfony/Component/Security/Http/composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index 8e54c82c9ae02..52c3abd2873ff 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -20,7 +20,7 @@ "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^6.4|^7.0", "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-foundation": "^7.2", "symfony/polyfill-ctype": "^1.8", "psr/log": "^1|^2|^3" }, diff --git a/src/Symfony/Component/Security/Http/composer.json b/src/Symfony/Component/Security/Http/composer.json index 9a443fe8ce621..74154829b557e 100644 --- a/src/Symfony/Component/Security/Http/composer.json +++ b/src/Symfony/Component/Security/Http/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-foundation": "^7.2", "symfony/http-kernel": "^6.4|^7.0", "symfony/polyfill-mbstring": "~1.0", "symfony/property-access": "^6.4|^7.0", From 032d16da27e206f223e4ae82b7de745d0edfbbe8 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sat, 27 Jul 2024 23:21:40 +0200 Subject: [PATCH 3/7] Prefer function --- .../Component/HttpKernel/DataCollector/RequestDataCollector.php | 2 +- .../Component/HttpKernel/EventListener/ProfilerListener.php | 2 +- .../Component/Security/Http/Firewall/ContextListener.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php index 8b5511d8a4f60..b49ca5c76cbb5 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php @@ -62,7 +62,7 @@ public function collect(Request $request, Response $response, ?\Throwable $excep $sessionMetadata = []; $sessionAttributes = []; $flashes = []; - if (!$request->attributes->getBoolean('_stateless') && $request->hasSession()) { + if (!$request->isStateless() && $request->hasSession()) { $session = $request->getSession(); if ($session->isStarted()) { $sessionMetadata['Created'] = date(\DATE_RFC822, $session->getMetadataBag()->getCreated()); diff --git a/src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php b/src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php index ecaaceb9488b8..545bb86e8277c 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php @@ -91,7 +91,7 @@ public function onKernelResponse(ResponseEvent $event): void return; } - $session = !$request->attributes->getBoolean('_stateless') && $request->hasPreviousSession() ? $request->getSession() : null; + $session = !$request->isStateless() && $request->hasPreviousSession() ? $request->getSession() : null; if ($session instanceof Session) { $usageIndexValue = $usageIndexReference = &$session->getUsageIndex(); diff --git a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php index 47bd62afb242a..2ebd72eaf13f9 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php @@ -85,7 +85,7 @@ public function authenticate(RequestEvent $event): void } $request = $event->getRequest(); - $session = !$request->attributes->getBoolean('_stateless') && $request->hasPreviousSession() ? $request->getSession() : null; + $session = !$request->isStateless() && $request->hasPreviousSession() ? $request->getSession() : null; $request->attributes->set('_security_firewall_run', $this->sessionKey); From 0bcaf2d38cb0d07a54d97e3e441e60fed749992f Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Mon, 29 Jul 2024 09:08:51 +0200 Subject: [PATCH 4/7] Rework --- src/Symfony/Bundle/SecurityBundle/composer.json | 2 +- src/Symfony/Component/HttpFoundation/CHANGELOG.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 7267fa759094c..8e1ee62a53e27 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -24,7 +24,7 @@ "symfony/dependency-injection": "^6.4|^7.0", "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-foundation": "^7.2", "symfony/password-hasher": "^6.4|^7.0", "symfony/security-core": "^7.2", "symfony/security-csrf": "^6.4|^7.0", diff --git a/src/Symfony/Component/HttpFoundation/CHANGELOG.md b/src/Symfony/Component/HttpFoundation/CHANGELOG.md index 64c2d38f2de2f..98f59fbf5664f 100644 --- a/src/Symfony/Component/HttpFoundation/CHANGELOG.md +++ b/src/Symfony/Component/HttpFoundation/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG --- * Add optional `$requests` argument to `RequestStack::__construct()` + * Add `Request::isStateless()` 7.1 --- From 54fa27a8de7a80fe2ed0c3846ecf5da455e25528 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Mon, 29 Jul 2024 09:24:20 +0200 Subject: [PATCH 5/7] Revert --- .../Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php | 2 +- src/Symfony/Bundle/SecurityBundle/composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php index b100d5a707db8..7eef76c2c59bf 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php @@ -88,7 +88,7 @@ public function testGetListeners(Request $request, bool $expectedState) $this->assertEquals([[$listener], $exceptionListener, $logoutListener], $firewallMap->getListeners($request)); $this->assertEquals($firewallConfig, $firewallMap->getFirewallConfig($request)); $this->assertEquals('security.firewall.map.context.foo', $request->attributes->get(self::ATTRIBUTE_FIREWALL_CONTEXT)); - $this->assertEquals($expectedState, $request->isStateless()); + $this->assertEquals($expectedState, method_exists($request, 'isStateless') ? $request->isStateless() : $request->attributes->get('_stateless')); } public static function providesStatefulStatelessRequests(): \Generator diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 8e1ee62a53e27..7267fa759094c 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -24,7 +24,7 @@ "symfony/dependency-injection": "^6.4|^7.0", "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", - "symfony/http-foundation": "^7.2", + "symfony/http-foundation": "^6.4|^7.0", "symfony/password-hasher": "^6.4|^7.0", "symfony/security-core": "^7.2", "symfony/security-csrf": "^6.4|^7.0", From d4b0937cf93771fbcd982f126ba1b29818da8b52 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Mon, 29 Jul 2024 10:33:08 +0200 Subject: [PATCH 6/7] Try introducing setStateless --- .../Bundle/SecurityBundle/Security/FirewallMap.php | 4 ++-- .../SecurityBundle/Tests/Security/FirewallMapTest.php | 4 ++-- src/Symfony/Bundle/SecurityBundle/composer.json | 2 +- .../Controller/ProfilerController.php | 6 +++--- src/Symfony/Bundle/WebProfilerBundle/composer.json | 1 + src/Symfony/Component/HttpFoundation/CHANGELOG.md | 2 +- src/Symfony/Component/HttpFoundation/Request.php | 11 ++++++++++- .../HttpKernel/Fragment/InlineFragmentRenderer.php | 4 ++-- .../Tests/DataCollector/RequestDataCollectorTest.php | 2 +- .../Tests/EventListener/SessionListenerTest.php | 10 +++++----- .../Tests/Fragment/InlineFragmentRendererTest.php | 4 ++-- .../DefaultAuthenticationSuccessHandlerTest.php | 2 +- 12 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php b/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php index f02b4c2d45106..9f749cb792f2d 100644 --- a/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php +++ b/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php @@ -66,8 +66,8 @@ private function getFirewallContext(Request $request): ?FirewallContext /** @var FirewallContext $context */ $context = $this->container->get($contextId); - if ($context->getConfig()?->isStateless() && !$request->attributes->has('_stateless')) { - $request->attributes->set('_stateless', true); + if ($context->getConfig()?->isStateless() && null === $request->isStateless()) { + $request->setStateless(); } return $context; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php index 7eef76c2c59bf..faf09e356743c 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php @@ -54,7 +54,7 @@ public function testGetListenersWithInvalidParameter() $this->assertEquals([[], null, null], $firewallMap->getListeners($request)); $this->assertNull($firewallMap->getFirewallConfig($request)); $this->assertFalse($request->attributes->has(self::ATTRIBUTE_FIREWALL_CONTEXT)); - $this->assertFalse($request->attributes->has('_stateless')); + $this->assertNull($request->isStateless()); } /** @dataProvider providesStatefulStatelessRequests */ @@ -88,7 +88,7 @@ public function testGetListeners(Request $request, bool $expectedState) $this->assertEquals([[$listener], $exceptionListener, $logoutListener], $firewallMap->getListeners($request)); $this->assertEquals($firewallConfig, $firewallMap->getFirewallConfig($request)); $this->assertEquals('security.firewall.map.context.foo', $request->attributes->get(self::ATTRIBUTE_FIREWALL_CONTEXT)); - $this->assertEquals($expectedState, method_exists($request, 'isStateless') ? $request->isStateless() : $request->attributes->get('_stateless')); + $this->assertEquals($expectedState, $request->isStateless()); } public static function providesStatefulStatelessRequests(): \Generator diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 7267fa759094c..8e1ee62a53e27 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -24,7 +24,7 @@ "symfony/dependency-injection": "^6.4|^7.0", "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-foundation": "^7.2", "symfony/password-hasher": "^6.4|^7.0", "symfony/security-core": "^7.2", "symfony/security-csrf": "^6.4|^7.0", diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php index 79db452019ab0..50372c20540d1 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php @@ -127,7 +127,7 @@ public function toolbarAction(Request $request, ?string $token = null): Response throw new NotFoundHttpException('The profiler must be enabled.'); } - if (!$request->attributes->getBoolean('_stateless') && $request->hasSession() + if (!$request->isStateless() && $request->hasSession() && ($session = $request->getSession())->isStarted() && $session->getFlashBag() instanceof AutoExpireFlashBag ) { // keep current flashes for one more request if using AutoExpireFlashBag @@ -174,7 +174,7 @@ public function searchBarAction(Request $request): Response $this->cspHandler?->disableCsp(); $session = null; - if (!$request->attributes->getBoolean('_stateless') && $request->hasSession()) { + if (!$request->isStateless() && $request->hasSession()) { $session = $request->getSession(); } @@ -254,7 +254,7 @@ public function searchAction(Request $request): Response $token = $request->query->get('token'); $profileType = $request->query->get('type', 'request'); - if (!$request->attributes->getBoolean('_stateless') && $request->hasSession()) { + if (!$request->isStateless() && $request->hasSession()) { $session = $request->getSession(); $session->set('_profiler_search_ip', $ip); diff --git a/src/Symfony/Bundle/WebProfilerBundle/composer.json b/src/Symfony/Bundle/WebProfilerBundle/composer.json index a6a1cf2df0976..fd73e35b1d44a 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/composer.json +++ b/src/Symfony/Bundle/WebProfilerBundle/composer.json @@ -20,6 +20,7 @@ "symfony/config": "^6.4|^7.0", "symfony/framework-bundle": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", + "symfony/http-foundation": "^7.2", "symfony/routing": "^6.4|^7.0", "symfony/twig-bundle": "^6.4|^7.0", "twig/twig": "^3.10" diff --git a/src/Symfony/Component/HttpFoundation/CHANGELOG.md b/src/Symfony/Component/HttpFoundation/CHANGELOG.md index 98f59fbf5664f..7f6ad36eafce9 100644 --- a/src/Symfony/Component/HttpFoundation/CHANGELOG.md +++ b/src/Symfony/Component/HttpFoundation/CHANGELOG.md @@ -5,7 +5,7 @@ CHANGELOG --- * Add optional `$requests` argument to `RequestStack::__construct()` - * Add `Request::isStateless()` + * Add `Request::isStateless()` and `Request::setStateless()` 7.1 --- diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index f54a53d12317e..bf25dd0f8bea6 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -651,8 +651,17 @@ public function get(string $key, mixed $default = null): mixed return $default; } - public function isStateless(): bool + public function setStateless(bool $stateless = true): void { + $this->attributes->set('_stateless', $stateless); + } + + public function isStateless(): ?bool + { + if (!$this->attributes->has('_stateless')) { + return null; + } + return $this->attributes->getBoolean('_stateless'); } diff --git a/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php b/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php index 2dbe7be602b60..ff1b5b67bbf85 100644 --- a/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php +++ b/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php @@ -124,8 +124,8 @@ protected function createSubRequest(string $uri, Request $request): Request if ($request->getDefaultLocale() !== $request->getLocale()) { $subRequest->setLocale($request->getLocale()); } - if ($request->attributes->has('_stateless')) { - $subRequest->attributes->set('_stateless', $request->attributes->get('_stateless')); + if (null !== $request->isStateless()) { + $subRequest->setStateless($request->isStateless()); } if ($request->attributes->has('_check_controller_is_allowed')) { $subRequest->attributes->set('_check_controller_is_allowed', $request->attributes->get('_check_controller_is_allowed')); diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php index 65608851de8e4..d313638aee3b1 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php @@ -318,7 +318,7 @@ public function testStatelessCheck() $requestStack = new RequestStack(); $request = $this->createRequest(); - $request->attributes->set('_stateless', true); + $request->setStateless(); $requestStack->push($request); $collector = new RequestDataCollector($requestStack); diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php index 2aa5d622e27bd..a72206ce2c391 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php @@ -753,7 +753,7 @@ public function testSessionUsageExceptionIfStatelessAndSessionUsed() $kernel = $this->createMock(HttpKernelInterface::class); $request = new Request(); - $request->attributes->set('_stateless', true); + $request->setStateless(); $listener->onKernelRequest(new RequestEvent($kernel, $request, HttpKernelInterface::MAIN_REQUEST)); $request->getSession(); @@ -780,7 +780,7 @@ public function testSessionUsageLogIfStatelessAndSessionUsed() $kernel = $this->createMock(HttpKernelInterface::class); $request = new Request(); - $request->attributes->set('_stateless', true); + $request->setStateless(); $listener->onKernelRequest(new RequestEvent($kernel, $request, HttpKernelInterface::MAIN_REQUEST)); $request->getSession(); @@ -805,7 +805,7 @@ public function testSessionIsSavedWhenUnexpectedSessionExceptionThrown() $kernel = $this->createMock(HttpKernelInterface::class); $request = new Request(); - $request->attributes->set('_stateless', true); + $request->setStateless(); $listener->onKernelRequest(new RequestEvent($kernel, $request, HttpKernelInterface::MAIN_REQUEST)); $request->getSession(); @@ -824,7 +824,7 @@ public function testSessionUsageCallbackWhenDebugAndStateless() $requestStack = new RequestStack(); $request = new Request(); - $request->attributes->set('_stateless', true); + $request->setStateless(); $requestStack->push(new Request()); $requestStack->push($request); @@ -849,7 +849,7 @@ public function testSessionUsageCallbackWhenNoDebug() $session->expects($this->exactly(0))->method('save'); $request = new Request(); - $request->attributes->set('_stateless', true); + $request->setStateless(); $requestStack = new RequestStack(); $requestStack->push($request); diff --git a/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php b/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php index cab4c55db4d70..da98139cc3785 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php @@ -275,7 +275,7 @@ public function testIpAddressOfRangedTrustedProxyIsSetAsRemote() public function testStatelessAttributeIsForwardedByDefault() { $request = Request::create('/'); - $request->attributes->set('_stateless', true); + $request->setStateless(); $kernel = $this->createMock(HttpKernelInterface::class); $kernel @@ -290,7 +290,7 @@ public function testStatelessAttributeIsForwardedByDefault() public function testStatelessAttributeCanBeDisabled() { $request = Request::create('/'); - $request->attributes->set('_stateless', true); + $request->setStateless(); $kernel = $this->createMock(HttpKernelInterface::class); $kernel diff --git a/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php b/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php index a9750223f0891..ab06105895ad6 100644 --- a/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php @@ -63,7 +63,7 @@ public function testStatelessRequestRedirections() $session->expects($this->never())->method('remove')->with('_security.admin.target_path'); $statelessRequest = Request::create('/'); $statelessRequest->setSession($session); - $statelessRequest->attributes->set('_stateless', true); + $statelessRequest->setStateless(); $urlGenerator = $this->createMock(UrlGeneratorInterface::class); $urlGenerator->expects($this->any())->method('generate')->willReturn('http://localhost/login'); From 9685160f2a48e634ef77ffb47b0ba8b6a77b6a51 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Mon, 29 Jul 2024 11:38:45 +0200 Subject: [PATCH 7/7] Keep has check --- src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php | 2 +- .../SecurityBundle/Tests/Security/FirewallMapTest.php | 2 +- src/Symfony/Component/HttpFoundation/Request.php | 6 +----- .../HttpKernel/Fragment/InlineFragmentRenderer.php | 2 +- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php b/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php index 9f749cb792f2d..64ceb2313ed00 100644 --- a/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php +++ b/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php @@ -66,7 +66,7 @@ private function getFirewallContext(Request $request): ?FirewallContext /** @var FirewallContext $context */ $context = $this->container->get($contextId); - if ($context->getConfig()?->isStateless() && null === $request->isStateless()) { + if ($context->getConfig()?->isStateless() && !$request->attributes->has('_stateless')) { $request->setStateless(); } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php index faf09e356743c..b100d5a707db8 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallMapTest.php @@ -54,7 +54,7 @@ public function testGetListenersWithInvalidParameter() $this->assertEquals([[], null, null], $firewallMap->getListeners($request)); $this->assertNull($firewallMap->getFirewallConfig($request)); $this->assertFalse($request->attributes->has(self::ATTRIBUTE_FIREWALL_CONTEXT)); - $this->assertNull($request->isStateless()); + $this->assertFalse($request->attributes->has('_stateless')); } /** @dataProvider providesStatefulStatelessRequests */ diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index bf25dd0f8bea6..af2e84617021c 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -656,12 +656,8 @@ public function setStateless(bool $stateless = true): void $this->attributes->set('_stateless', $stateless); } - public function isStateless(): ?bool + public function isStateless(): bool { - if (!$this->attributes->has('_stateless')) { - return null; - } - return $this->attributes->getBoolean('_stateless'); } diff --git a/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php b/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php index ff1b5b67bbf85..98f60eb3235cb 100644 --- a/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php +++ b/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php @@ -124,7 +124,7 @@ protected function createSubRequest(string $uri, Request $request): Request if ($request->getDefaultLocale() !== $request->getLocale()) { $subRequest->setLocale($request->getLocale()); } - if (null !== $request->isStateless()) { + if ($request->attributes->has('_stateless')) { $subRequest->setStateless($request->isStateless()); } if ($request->attributes->has('_check_controller_is_allowed')) {