14
14
use Symfony \Bundle \SecurityBundle \Security \FirewallConfig ;
15
15
use Symfony \Bundle \SecurityBundle \Security \Security ;
16
16
use Symfony \Bundle \SecurityBundle \Tests \Functional \Bundle \SecuredPageBundle \Security \Core \User \ArrayUserProvider ;
17
+ use Symfony \Component \EventDispatcher \EventDispatcherInterface ;
17
18
use Symfony \Component \HttpFoundation \JsonResponse ;
18
19
use Symfony \Component \HttpFoundation \Request ;
20
+ use Symfony \Component \HttpFoundation \Response ;
21
+ use Symfony \Component \HttpKernel \Event \RequestEvent ;
22
+ use Symfony \Component \HttpKernel \KernelEvents ;
19
23
use Symfony \Component \Security \Core \Authentication \Token \UsernamePasswordToken ;
20
24
use Symfony \Component \Security \Core \User \InMemoryUser ;
21
25
use Symfony \Component \Security \Core \User \PasswordAuthenticatedUserInterface ;
22
26
use Symfony \Component \Security \Core \User \UserInterface ;
23
- use Symfony \Component \Security \Csrf \CsrfTokenManagerInterface ;
24
27
25
28
class SecurityTest extends AbstractWebTestCase
26
29
{
@@ -38,8 +41,10 @@ public function testServiceIsFunctional()
38
41
$ security = $ container ->get ('functional_test.security.helper ' );
39
42
$ this ->assertTrue ($ security ->isGranted ('ROLE_USER ' ));
40
43
$ this ->assertSame ($ token , $ security ->getToken ());
41
- $ this ->assertInstanceOf (FirewallConfig::class, $ firewallConfig = $ security ->getFirewallConfig (new Request ()));
42
- $ this ->assertSame ('default ' , $ firewallConfig ->getName ());
44
+ $ request = new Request ();
45
+ $ request ->server ->set ('REQUEST_URI ' , '/main/foo ' );
46
+ $ this ->assertInstanceOf (FirewallConfig::class, $ firewallConfig = $ security ->getFirewallConfig ($ request ));
47
+ $ this ->assertSame ('main ' , $ firewallConfig ->getName ());
43
48
}
44
49
45
50
/**
@@ -86,14 +91,14 @@ public function userWillBeMarkedAsChangedIfRolesHasChangedProvider()
86
91
}
87
92
88
93
/**
89
- * @testWith ["json_login "]
94
+ * @testWith ["form_login "]
90
95
* ["Symfony\\Bundle\\SecurityBundle\\Tests\\Functional\\Bundle\\AuthenticatorBundle\\ApiAuthenticator"]
91
96
*/
92
97
public function testLogin (string $ authenticator )
93
98
{
94
- $ client = $ this ->createClient (['test_case ' => 'SecurityHelper ' , 'root_config ' => 'config.yml ' ]);
95
- static ::getContainer ()->get (WelcomeController ::class)->authenticator = $ authenticator ;
96
- $ client ->request ('GET ' , '/welcome ' );
99
+ $ client = $ this ->createClient (['test_case ' => 'SecurityHelper ' , 'root_config ' => 'config.yml ' , ' debug ' > true ]);
100
+ static ::getContainer ()->get (ForceLoginController ::class)->authenticator = $ authenticator ;
101
+ $ client ->request ('GET ' , '/main/force-login ' );
97
102
$ response = $ client ->getResponse ();
98
103
99
104
$ this ->assertInstanceOf (JsonResponse::class, $ response );
@@ -104,8 +109,10 @@ public function testLogin(string $authenticator)
104
109
105
110
public function testLogout ()
106
111
{
107
- $ client = $ this ->createClient (['test_case ' => 'SecurityHelper ' , 'root_config ' => 'config.yml ' ]);
108
- $ client ->request ('GET ' , '/force-logout ' );
112
+ $ client = $ this ->createClient (['test_case ' => 'SecurityHelper ' , 'root_config ' => 'config.yml ' , 'debug ' => true ]);
113
+ $ client ->loginUser (new InMemoryUser ('chalasr ' , 'the-password ' , ['ROLE_FOO ' ]), 'main ' );
114
+
115
+ $ client ->request ('GET ' , '/main/force-logout ' );
109
116
$ response = $ client ->getResponse ();
110
117
111
118
$ this ->assertSame (200 , $ response ->getStatusCode ());
@@ -114,9 +121,38 @@ public function testLogout()
114
121
}
115
122
116
123
public function testLogoutWithCsrf ()
124
+ {
125
+ $ client = $ this ->createClient (['test_case ' => 'SecurityHelper ' , 'root_config ' => 'config_logout_csrf.yml ' , 'debug ' => true ]);
126
+ $ client ->loginUser (new InMemoryUser ('chalasr ' , 'the-password ' , ['ROLE_FOO ' ]), 'main ' );
127
+
128
+ /** @var EventDispatcherInterface $eventDispatcher */
129
+ $ eventDispatcher = static ::getContainer ()->get (EventDispatcherInterface::class);
130
+ $ setCsrfToken = function (RequestEvent $ event ) {
131
+ static ::getContainer ()->get ('security.csrf.token_storage ' )->setToken ('logout ' , 'bar ' );
132
+ $ event ->setResponse (new Response ('' ));
133
+ };
134
+ $ eventDispatcher ->addListener (KernelEvents::REQUEST , $ setCsrfToken );
135
+ try {
136
+ $ client ->request ('GET ' , '/ ' .uniqid ('' , true ));
137
+ } finally {
138
+ $ eventDispatcher ->removeListener (KernelEvents::REQUEST , $ setCsrfToken );
139
+ }
140
+
141
+ static ::getContainer ()->get (LogoutController::class)->checkCsrf = true ;
142
+ $ client ->request ('GET ' , '/main/force-logout ' , ['_csrf_token ' => 'bar ' ]);
143
+ $ response = $ client ->getResponse ();
144
+
145
+ $ this ->assertSame (200 , $ response ->getStatusCode ());
146
+ $ this ->assertNull (static ::getContainer ()->get ('security.helper ' )->getUser ());
147
+ $ this ->assertSame (['message ' => 'Logout successful ' ], json_decode ($ response ->getContent (), true ));
148
+ }
149
+
150
+ public function testLogoutBypassCsrf ()
117
151
{
118
152
$ client = $ this ->createClient (['test_case ' => 'SecurityHelper ' , 'root_config ' => 'config_logout_csrf.yml ' ]);
119
- $ client ->request ('GET ' , '/force-logout ' );
153
+ $ client ->loginUser (new InMemoryUser ('chalasr ' , 'the-password ' , ['ROLE_FOO ' ]), 'main ' );
154
+
155
+ $ client ->request ('GET ' , '/main/force-logout ' );
120
156
$ response = $ client ->getResponse ();
121
157
122
158
$ this ->assertSame (200 , $ response ->getStatusCode ());
@@ -232,17 +268,17 @@ public function eraseCredentials(): void
232
268
}
233
269
}
234
270
235
- class WelcomeController
271
+ class ForceLoginController
236
272
{
237
- public $ authenticator = 'json_login ' ;
273
+ public $ authenticator = 'form_login ' ;
238
274
239
275
public function __construct (private Security $ security )
240
276
{
241
277
}
242
278
243
279
public function welcome ()
244
280
{
245
- $ user = new InMemoryUser ('chalasr ' , '' , ['ROLE_USER ' ]);
281
+ $ user = new InMemoryUser ('chalasr ' , 'the-password ' , ['ROLE_FOO ' ]);
246
282
$ this ->security ->login ($ user , $ this ->authenticator );
247
283
248
284
return new JsonResponse (['message ' => sprintf ('Welcome @%s! ' , $ this ->security ->getUser ()->getUserIdentifier ())]);
@@ -251,18 +287,24 @@ public function welcome()
251
287
252
288
class LogoutController
253
289
{
254
- public function __construct (private Security $ security , private ?CsrfTokenManagerInterface $ csrfTokenManager = null )
290
+ public $ checkCsrf = false ;
291
+
292
+ public function __construct (private Security $ security )
255
293
{
256
294
}
257
295
258
- public function logout (Request $ request )
296
+ public function logout (UserInterface $ user )
259
297
{
260
- $ this ->security ->login (new InMemoryUser ('chalasr ' , '' , ['ROLE_USER ' ]), 'json_login ' , 'default ' );
261
- if ($ this ->csrfTokenManager ) {
262
- $ request ->query ->set ('_csrf_token ' , (string ) $ this ->csrfTokenManager ->getToken ('logout ' ));
263
- }
264
- $ this ->security ->logout ();
298
+ $ this ->security ->logout ($ this ->checkCsrf );
265
299
266
300
return new JsonResponse (['message ' => 'Logout successful ' ]);
267
301
}
268
302
}
303
+
304
+ class LoggedInController
305
+ {
306
+ public function __invoke (UserInterface $ user )
307
+ {
308
+ return new JsonResponse (['message ' => sprintf ('Welcome back @%s ' , $ user ->getUserIdentifier ())]);
309
+ }
310
+ }
0 commit comments