8000 [Security] Handle non-callable implementations of `FirewallListenerIn… · symfony/symfony@59712ba · GitHub
[go: up one dir, main page]

Skip to content

Commit 59712ba

Browse files
committed
[Security] Handle non-callable implementations of FirewallListenerInterface
1 parent 9a7f7a3 commit 59712ba

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,11 @@ public static function getSubscribedEvents()
125125
protected function callListeners(RequestEvent $event, iterable $listeners)
126126
{
127127
foreach ($listeners as $listener) {
128-
$listener($event);
128+
if (!$listener instanceof FirewallListenerInterface) {
129+
$listener($event);
130+
} elseif (false !== $listener->supports($event->getRequest())) {
131+
$listener->authenticate($event);
132+
}
129133

130134
if ($event->hasResponse()) {
131135
break;

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
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;
23+
use Symfony\Component\Security\Http\Firewall\FirewallListenerInterface;
2224
use Symfony\Component\Security\Http\FirewallMapInterface;
2325

2426
class FirewallTest extends TestCase
@@ -97,4 +99,59 @@ public function testOnKernelRequestWithSubRequest()
9799

98100
$this->assertFalse($event->hasResponse());
99101
}
102+
103+
public function testListenersAreCalled()
104+
{
105+
$calledListeners = [];
106+
107+
$callableListener = static function() use(&$calledListeners) { $calledListeners[] = 'callableListener'; };
108+
$firewallListener = new class($calledListeners) implements FirewallListenerInterface {
109+
public function __construct(private array &$calledListeners) {}
110+
111+
public function supports(Request $request): ?bool
112+
{
113+
return true;
114+
}
115+
116+
public function authenticate(RequestEvent $event)
117+
{
118+
$this->calledListeners[] = 'firewallListener' 8000 ;;
119+
}
120+
121+
public static function getPriority(): int
122+
{
123+
return 0;
124+
}
125+
};
126+
$callableFirewallListener = new class($calledListeners) extends AbstractListener {
127+
public function __construct(private array &$calledListeners) {}
128+
129+
public function supports(Request $request): ?bool
130+
{
131+
return true;
132+
}
133+
134+
public function authenticate(RequestEvent $event)
135+
{
136+
$this->calledListeners[] = 'callableFirewallListener';
137+
}
138+
};
139+
140+
$request = $this->createMock(Request::class);
141+
142+
$map = $this->createMock(FirewallMapInterface::class);
143+
$map
144+
->expects($this->once())
145+
->method('getListeners')
146+
->with($this->equalTo($request))
147+
->willReturn([[$callableListener, $firewallListener, $callableFirewallListener], null, null])
148+
;
149+
150+
$event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST);
151+
152+
$firewall = new Firewall($map, $this->createMock(EventDispatcherInterface::class));
153+
$firewall->onKernelRequest($event);
154+
155+
$this->assertSame(['callableListener', 'firewallListener', 'callableFirewallListener'], $calledListeners);
156+
}
100157
}

0 commit comments

Comments
 (0)
0