Skip to content

Commit d3ceacd

Browse files
Merge branch '7.2' into 7.3
* 7.2: Fix-type-error-when-revealing-broken-secret fix compatibility with Relay 0.11 [Security] Handle non-callable implementations of `FirewallListenerInterface` [DomCrawler] Allow selecting `button`s by their `value` flip excluded properties with keys with Doctrine-style constraint config
2 parents 8658634 + c993975 commit d3ceacd

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

Firewall.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,11 @@ public static function getSubscribedEvents()
122122
protected function callListeners(RequestEvent $event, iterable $listeners)
123123
{
124124
foreach ($listeners as $listener) {
125-
$listener($event);
125+
if (!$listener instanceof FirewallListenerInterface) {
126+
$listener($event);
127+
} elseif (false !== $listener->supports($event->getRequest())) {
128+
$listener->authenticate($event);
129+
}
126130

127131
if ($event->hasResponse()) {
128132
break;

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): void
117+
{
118+
$this->calledListeners[] = 'firewallListener';
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): void
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)