Skip to content

Commit c3ee787

Browse files
Merge branch '7.3' into 7.4
* 7.3: [SecurityBundle] Add tests for `debug:firewall` command
2 parents 786b573 + 9d3b7c6 commit c3ee787

File tree

5 files changed

+352
-0
lines changed

5 files changed

+352
-0
lines changed
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\SecurityBundle\Tests\Command;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bundle\SecurityBundle\Command\DebugFirewallCommand;
16+
use Symfony\Bundle\SecurityBundle\Security\FirewallConfig;
17+
use Symfony\Bundle\SecurityBundle\Security\FirewallContext;
18+
use Symfony\Bundle\SecurityBundle\Tests\Fixtures\DummyAuthenticator;
19+
use Symfony\Component\Console\Tester\CommandTester;
20+
use Symfony\Component\DependencyInjection\ContainerInterface;
21+
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
22+
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
23+
24+
class DebugFirewallCommandTest extends TestCase
25+
{
26+
public function testFirewallListOutputMatchesFixture()
27+
{
28+
$firewallNames = ['main', 'api'];
29+
$contexts = $this->createMock(ContainerInterface::class);
30+
$eventDispatchers = $this->createMock(ContainerInterface::class);
31+
32+
$command = new DebugFirewallCommand($firewallNames, $contexts, $eventDispatchers, []);
33+
$tester = new CommandTester($command);
34+
35+
$this->assertSame(0, $tester->execute([]));
36+
$this->assertStringContainsString('Firewalls', $tester->getDisplay());
37+
$this->assertStringContainsString('The following firewalls are defined:', $tester->getDisplay());
38+
$this->assertStringContainsString('* main', $tester->getDisplay());
39+
$this->assertStringContainsString('* api', $tester->getDisplay());
40+
$this->assertStringContainsString('To view details of a specific firewall', $tester->getDisplay());
41+
}
42+
43+
public function testFirewallNotFoundDisplaysError()
44+
{
45+
$firewallNames = ['main', 'api'];
46+
47+
$contexts = $this->createMock(ContainerInterface::class);
48+
$contexts->method('has')->willReturn(false);
49+
50+
$eventDispatchers = $this->createMock(ContainerInterface::class);
51+
$authenticators = [];
52+
53+
$command = new DebugFirewallCommand(
54+
$firewallNames,
55+
$contexts,
56+
$eventDispatchers,
57+
$authenticators
58+
);
59+
60+
$tester = new CommandTester($command);
61+
62+
$this->assertSame(1, $tester->execute(['name' => 'admin']));
63+
$this->assertStringContainsString('Firewall admin was not found.', $tester->getDisplay());
64+
$this->assertStringContainsString('Available firewalls are: main, api', $tester->getDisplay());
65+
}
66+
67+
public function testFirewallMainOutputMatchesFixture()
68+
{
69+
$firewallNames = ['main'];
70+
71+
$config = new FirewallConfig(
72+
name: 'main',
73+
userChecker: 'user_checker_service',
74+
requestMatcher: null,
75+
securityEnabled: true,
76+
stateless: false,
77+
provider: 'user_provider_service',
78+
context: 'main',
79+
entryPoint: 'entry_point_service',
80+
accessDeniedHandler: 'access_denied_handler_service',
81+
accessDeniedUrl: '/access-denied',
82+
authenticators: [],
83+
switchUser: null
84+
);
85+
86+
$context = new FirewallContext([], config: $config);
87+
88+
$contexts = $this->createMock(ContainerInterface::class);
89+
$contexts->method('has')->willReturn(true);
90+
$contexts->method('get')->willReturn($context);
91+
92+
$eventDispatchers = $this->createMock(ContainerInterface::class);
93+
$authenticator = new DummyAuthenticator();
94+
$authenticators = ['main' => [$authenticator]];
95+
96+
$command = new DebugFirewallCommand($firewallNames, $contexts, $eventDispatchers, $authenticators);
97+
$tester = new CommandTester($command);
98+
99+
$this->assertSame(0, $tester->execute(['name' => 'main', '--events' => true]));
100+
$this->assertEquals($this->getFixtureOutput('firewall_main_output.txt'), trim(str_replace(\PHP_EOL, "\n", $tester->getDisplay())));
101+
}
102+
103+
public function testFirewallWithEventsOutputMatchesFixture()
104+
{
105+
$firewallNames = ['main'];
106+
107+
$config = new FirewallConfig(
108+
name: 'main',
109+
userChecker: 'user_checker_service',
110+
context: 'main',
111+
stateless: false,
112+
provider: 'user_provider_service',
113+
entryPoint: 'entry_point_service',
114+
accessDeniedHandler: 'access_denied_handler_service',
115+
accessDeniedUrl: '/access-denied',
116+
);
117+
118+
$context = new FirewallContext([], config: $config);
119+
120+
$contexts = $this->createMock(ContainerInterface::class);
121+
$contexts->method('has')->willReturn(true);
122+
$contexts->method('get')->willReturn($context);
123+
124+
$dispatcher = $this->createMock(EventDispatcherInterface::class);
125+
$listener = fn () => null;
126+
$listenerTwo = fn (int $number) => $number * 2;
127+
$dispatcher->method('getListeners')->willReturn([
128+
'security.event' => [$listener, $listenerTwo],
129+
]);
130+
$dispatcher->method('getListenerPriority')->willReturn(42);
131+
132+
$eventDispatchers = $this->createMock(ContainerInterface::class);
133+
$eventDispatchers->method('has')->willReturn(true);
134+
$eventDispatchers->method('get')->willReturn($dispatcher);
135+
136+
$authenticator = new DummyAuthenticator();
137+
$authenticatorTwo = new DummyAuthenticator();
138+
$authenticatorThree = new DummyAuthenticator();
139+
$authenticators = ['main' => [$authenticator, $authenticatorTwo], 'api' => [$authenticatorThree]];
140+
141+
$command = new DebugFirewallCommand($firewallNames, $contexts, $eventDispatchers, $authenticators);
142+
$tester = new CommandTester($command);
143+
144+
$this->assertSame(0, $tester->execute(['name' => 'main', '--events' => true]));
145+
$this->assertEquals($this->getFixtureOutput('firewall_main_with_events_output.txt'), trim(str_replace(\PHP_EOL, "\n", $tester->getDisplay())));
146+
}
147+
148+
public function testFirewallWithSwitchUserDisplaysSection()
149+
{
150+
$firewallNames = ['main'];
151+
152+
$switchUserConfig = [
153+
'parameter' => '_switch_user_test',
154+
'provider' => 'custom_provider_test',
155+
'role' => 'ROLE_ALLOWED_TO_SWITCH',
156+
];
157+
158+
$config = new FirewallConfig(
159+
name: 'main',
160+
userChecker: 'user_checker_service_test',
161+
context: 'main',
162+
stateless: false,
163+
provider: 'user_provider_service_test',
164+
entryPoint: 'entry_point_service_test',
165+
accessDeniedHandler: 'access_denied_handler_service_test',
166+
accessDeniedUrl: '/access-denied-test',
167+
switchUser: $switchUserConfig,
168+
);
169+
170+
$context = new FirewallContext([], config: $config);
171+
172+
$contexts = $this->createMock(ContainerInterface::class);
173+
$contexts->method('has')->willReturn(true);
174+
$contexts->method('get')->willReturn($context);
175+
176+
$eventDispatchers = $this->createMock(ContainerInterface::class);
177+
$authenticator = new DummyAuthenticator();
178+
$authenticatorTwo = $this->createMock(AuthenticatorInterface::class);
179+
$authenticators = ['main' => [$authenticator], 'api' => [$authenticatorTwo]];
180+
181+
$command = new DebugFirewallCommand(
182+
$firewallNames,
183+
$contexts,
184+
$eventDispatchers,
185+
$authenticators
186+
);
187+
$tester = new CommandTester($command);
188+
189+
$this->assertSame(0, $tester->execute(['name' => 'main']));
190+
$this->assertEquals($this->getFixtureOutput('firewall_main_with_switch_user.txt'), trim(str_replace(\PHP_EOL, "\n", $tester->getDisplay())));
191+
}
192+
193+
private function getFixtureOutput(string $file): string
194+
{
195+
return trim(file_get_contents(__DIR__.'/../Fixtures/Descriptor/'.$file));
196+
}
197+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Firewall "main"
2+
===============
3+
4+
----------------------- -------------------------------
5+
Option Value
6+
----------------------- -------------------------------
7+
Name main
8+
Context main
9+
Lazy No
10+
Stateless No
11+
User Checker user_checker_service
12+
Provider user_provider_service
13+
Entry Point entry_point_service
14+
Access Denied URL /access-denied
15+
Access Denied Handler access_denied_handler_service
16+
----------------------- -------------------------------
17+
18+
Event listeners for firewall "main"
19+
===================================
20+
21+
No event dispatcher has been registered for this firewall.
22+
23+
Authenticators for firewall "main"
24+
==================================
25+
26+
-----------------------------------------------------------------
27+
Classname
28+
-----------------------------------------------------------------
29+
Symfony\Bundle\SecurityBundle\Tests\Fixtures\DummyAuthenticator
30+
-----------------------------------------------------------------
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
Firewall "main"
2+
===============
3+
4+
----------------------- -------------------------------
5+
Option Value
6+
----------------------- -------------------------------
7+
Name main
8+
Context main
9+
Lazy No
10+
Stateless No
11+
User Checker user_checker_service
12+
Provider user_provider_service
13+
Entry Point entry_point_service
14+
Access Denied URL /access-denied
15+
Access Denied Handler access_denied_handler_service
16+
----------------------- -------------------------------
17+
18+
Event listeners for firewall "main"
19+
===================================
20+
21+
"security.event" event
22+
----------------------
23+
24+
------- ----------- ----------
25+
Order Callable Priority
26+
------- ----------- ----------
27+
#1 Closure() 42
28+
#2 Closure() 42
29+
------- ----------- ----------
30+
31+
Authenticators for firewall "main"
32+
==================================
33+
34+
-----------------------------------------------------------------
35+
Classname
36+
-----------------------------------------------------------------
37+
Symfony\Bundle\SecurityBundle\Tests\Fixtures\DummyAuthenticator
38+
Symfony\Bundle\SecurityBundle\Tests\Fixtures\DummyAuthenticator
39+
-----------------------------------------------------------------
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
Firewall "main"
2+
===============
3+
4+
----------------------- ------------------------------------
5+
Option Value
6+
----------------------- ------------------------------------
7+
Name main
8+
Context main
9+
Lazy No
10+
Stateless No
11+
User Checker user_checker_service_test
12+
Provider user_provider_service_test
13+
Entry Point entry_point_service_test
14+
Access Denied URL /access-denied-test
15+
Access Denied Handler access_denied_handler_service_test
16+
----------------------- ------------------------------------
17+
18+
User switching
19+
--------------
20+
21+
----------- ------------------------
22+
Option Value
23+
----------- ------------------------
24+
Parameter _switch_user_test
25+
Provider custom_provider_test
26+
User Role ROLE_ALLOWED_TO_SWITCH
27+
----------- ------------------------
28+
29+
Authenticators for firewall "main"
30+
==================================
31+
32+
-----------------------------------------------------------------
33+
Classname
34+
-----------------------------------------------------------------
35+
Symfony\Bundle\SecurityBundle\Tests\Fixtures\DummyAuthenticator
36+
-----------------------------------------------------------------
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\SecurityBundle\Tests\Fixtures;
13+
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\HttpFoundation\Response;
16+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
17+
use Symfony\Component\Security\Core\Exception\AuthenticationException;
18+
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
19+
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
20+
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
21+
22+
class DummyAuthenticator implements AuthenticatorInterface
23+
{
24+
public function supports(Request $request): ?bool
25+
{
26+
return null;
27+
}
28+
29+
public function authenticate(Request $request): Passport
30+
{
31+
}
32+
33+
public function createToken(Passport $passport, string $firewallName): TokenInterface
34+
{
35+
}
36+
37+
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
38+
{
39+
return null;
40+
}
41+
42+
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
43+
{
44+
return null;
45+
}
46+
47+
public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface
48+
{
49+
}
50+
}

0 commit comments

Comments
 (0)