8000 [Security] Deprecate callable firewall listeners · symfony/symfony@55c3cfb · GitHub
[go: up one dir, main page]

Skip to content

Commit 55c3cfb

Browse files
committed
[Security] Deprecate callable firewall listeners
1 parent 5aea219 commit 55c3cfb

File tree

7 files changed

+116
-21
lines changed

7 files changed

+116
-21
lines changed

UPGRADE-7.4.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
UPGRADE FROM 7.3 to 7.4
2+
=======================
3+
4+
Symfony 7.4 is a minor release. According to the Symfony release process, there should be no significant
5+
backward compatibility breaks. Minor backward compatibility breaks are prefixed in this document with
6+
`[BC BREAK]`, make sure your code is compatible with these entries before upgrading.
7+
Read more about this in the [Symfony documentation](https://symfony.com/doc/7.4/setup/upgrade_minor.html).
8+
9+
If you're upgrading from a version below 7.3, follow the [7.3 upgrade guide](UPGRADE-7.3.md) first.
10+
11+
Security
12+
--------
13+
14+
* Deprecate callable firewall listeners, extend `AbstractListener` instead

src/Symfony/Bundle/SecurityBundle/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
7.4
5+
---
6+
7+
* Deprecate callable firewall listeners, extend `AbstractListener` instead
8+
49
7.3
510
---
611

src/Symfony/Bundle/SecurityBundle/Security/LazyFirewallContext.php

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\SecurityBundle\Security;
1313

14+
use Symfony\Component\HttpFoundation\Request;
1415
use Symfony\Component\HttpKernel\Event\RequestEvent;
1516
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
1617
use Symfony\Component\Security\Http\Event\LazyResponseEvent;
@@ -23,7 +24,7 @@
2324
*
2425
* @author Nicolas Grekas <p@tchwork.com>
2526
*/
26-
class LazyFirewallContext extends FirewallContext
27+
class LazyFirewallContext extends FirewallContext implements FirewallListenerInterface
2728
{
2829
public function __construct(
2930
iterable $listeners,
@@ -40,7 +41,22 @@ public function getListeners(): iterable
4041
return [$this];
4142
}
4243

43-
public function __invoke(RequestEvent $event): void
44+
public function supports(Request $request): ?bool
45+
{
46+
foreach (parent::getListeners() as $listener) {
47+
if (!$listener instanceof FirewallListenerInterface) {
48+
return true;
49+
}
50+
51+
if (false !== $listener->supports($request)) {
52+
return true;
53+
}
54+
}
55+
56+
return false;
57+
}
58+
59+
public function authenticate(RequestEvent $event): void
4460
{
4561
$listeners = [];
4662
$request = $event->getRequest();
@@ -75,4 +91,14 @@ public function __invoke(RequestEvent $event): void
7591
}
7692
});
7793
}
94+
95+
public static function getPriority(): int
96+
{
97+
return 0;
98+
}
99+
100+
public function __invoke(RequestEvent $event): void
101+
{
102+
$this->authenticate($event);
103+
}
78104
}

src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
3333
use Symfony\Component\Security\Core\Role\RoleHierarchy;
3434
use Symfony\Component\Security\Core\User\InMemoryUser;
35+
use Symfony\Component\Security\Http\Firewall\FirewallListenerInterface;
3536
use Symfony\Component\Security\Http\FirewallMapInterface;
3637
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
3738
use Symfony\Component\VarDumper\Caster\ClassStub;
@@ -193,8 +194,24 @@ public function testGetListeners()
193194
$request = new Request();
194195
$event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST);
195196
$event->setResponse($response = new Response());
196-
$listener = function ($e) use ($event, &$listenerCalled) {
197-
$listenerCalled += $e === $event;
197+
$listener = new class implements FirewallListenerInterface
198+
{
199+
public int $callCount = 0;
200+
201+
public function supports(Request $request): ?bool
202+
{
203+
return true;
204+
}
205+
206+
public function authenticate(RequestEvent $event): void
207+
{
208+
++$this->callCount;
209+
}
210+
211+
public static function getPriority(): int
212+
{
213+
return 0;
214+
}
198215
};
199216
$firewallMap = $this
200217
->getMockBuilder(FirewallMap::class)
@@ -217,9 +234,9 @@ public function testGetListeners()
217234
$collector = new SecurityDataCollector(null, null, null, null, $firewallMap, $firewall, true);
218235
$collector->collect($request, $response);
219236

220-
$this->assertNotEmpty($collected = $collector->getListeners()[0]);
237+
$this->assertCount(1, $collector->getListeners());
221238
$collector->lateCollect();
222-
$this->assertSame(1, $listenerCalled);
239+
$this->assertSame(1, $listener->callCount);
223240
}
224241

225242
public function testCollectCollectsDecisionLogWhenStrategyIsAffirmative()

src/Symfony/Bundle/SecurityBundle/Tests/Debug/TraceableFirewallListenerTest.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
3131
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
3232
use Symfony\Component\Security\Http\Firewall\AuthenticatorManagerListener;
33+
use Symfony\Component\Security\Http\Firewall\FirewallListenerInterface;
3334
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
3435

3536
/**
@@ -41,9 +42,25 @@ public function testOnKernelRequestRecordsListeners()
4142
{
4243
$request = new Request();
4344
$event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST);
44-
$event->setResponse($response = new Response());
45-
$listener = function ($e) use ($event, &$listenerCalled) {
46-
$listenerCalled += $e === $event;
45+
$event->setResponse(new Response());
46+
$listener = new class implements FirewallListenerInterface
47+
{
48+
public int $callCount = 0;
49+
50+
public function supports(Request $request): ?bool
51+
{
52+
return true;
53+
}
54+
55+
public function authenticate(RequestEvent $event): void
56+
{
57+
++$this->callCount;
58+
}
59+
60+
public static function getPriority(): int
61+
{
62+
return 0;
63+
}
4764
};
4865
$firewallMap = $this->createMock(FirewallMap::class);
4966
$firewallMap

src/Symfony/Component/Security/Http/Firewall.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
1717
use Symfony\Component\HttpKernel\Event\RequestEvent;
1818
use Symfony\Component\HttpKernel\KernelEvents;
19+
use Symfony\Component\Security\Http\Firewall\AbstractListener;
1920
use Symfony\Component\Security\Http\Firewall\ExceptionListener;
2021
use Symfony\Component\Security\Http\Firewall\FirewallListenerInterface;
2122
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
@@ -122,6 +123,10 @@ public static function getSubscribedEvents()
122123
protected function callListeners(RequestEvent $event, iterable $listeners)
123124
{
124125
foreach ($listeners as $listener) {
126+
if (!$listener instanceof FirewallListenerInterface) {
127+
trigger_deprecation('symfony/security-http', '7.4', 'Using a callable as firewall listener is deprecated, extend "%s" instead.', AbstractListener::class);
128+
}
129+
125130
$listener($event);
126131

127132
if ($event->hasResponse()) {
@@ -130,8 +135,8 @@ protected function callListeners(RequestEvent $event, iterable $listeners)
130135
}
131136
}
132137

133-
private function getListenerPriority(object $logoutListener): int
138+
private function getListenerPriority(object $listener): int
134139
{
135-
return $logoutListener instanceof FirewallListenerInterface ? $logoutListener->getPriority() : 0;
140+
return $listener instanceof FirewallListenerInterface ? $listener->getPriority() : 0;
136141
}
137142
}

src/Symfony/Component/Security/Http/Tests/FirewallTest.php

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\HttpKernel\Event\RequestEvent;
1919
use Symfony\Component\HttpKernel\HttpKernelInterface;
2020
use Symfony\Component\Security\Http\Firewall;
21+
use Symfony\Component\Security\Http\Firewall\AbstractListener;
2122
use Symfony\Component\Security\Http\Firewall\ExceptionListener;
2223
use Symfony\Component\Security\Http\FirewallMapInterface;
2324

@@ -52,21 +53,31 @@ public function testOnKernelRequestRegistersExceptionListener()
5253

5354
public function testOnKernelRequestStopsWhenThereIsAResponse()
5455
{
55-
$called = [];
56-
57-
$first = function () use (&$called) {
58-
$called[] = 1;
59-
};
60-
61-
$second = function () use (&$called) {
62-
$called[] = 2;
56+
$listener = new class extends AbstractListener
57+
{
58+
public int $callCount = 0;
59+
60+
public function supports(Request $request): ?bool
61+
{
62+
return true;
63+
}
64+
65+
public function authenticate(RequestEvent $event): void
66+
{
67+
++$this->callCount;
68+
}
69+
70+
public static function getPriority(): int
71+
{
72+
return 0;
73+
}
6374
};
6475

6576
$map = $this->createMock(FirewallMapInterface::class);
6677
$map
6778
->expects($this->once())
6879
->method('getListeners')
69-
->willReturn([[$first, $second], null, null])
80+
->willReturn([[$listener, $listener], null, null])
7081
;
7182

7283
$event = new RequestEvent($this->createMock(HttpKernelInterface::class), new Request(), HttpKernelInterface::MAIN_REQUEST);
@@ -75,7 +86,7 @@ public function testOnKernelRequestStopsWhenThereIsAResponse()
7586
$firewall = new Firewall($map, $this->createMock(EventDispatcherInterface::class));
7687
$firewall->onKernelRequest($event);
7788

78-
$this->assertSame([1], $called);
89+
$this->assertSame(1, $listener->callCount);
7990
}
8091

8192
public function testOnKernelRequestWithSubRequest()

0 commit comments

Comments
 (0)
0