Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0353077

Browse files
committed
[Security] Allow switching to another user when already switched
1 parent 159ef1b commit 0353077

File tree

4 files changed

+37
-6
lines changed

4 files changed

+37
-6
lines changed

src/Symfony/Bundle/SecurityBundle/Tests/Functional/SwitchUserTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ public function testSwitchUser($originalUser, $targetUser, $expectedUser, $expec
3333
$this->assertEquals($expectedUser, $client->getProfile()->getCollector('security')->getUser());
3434
}
3535

36-
public function testSwitchedUserCannotSwitchToOther()
36+
public function testSwitchedUserCanSwitchToOther()
3737
{
3838
$client = $this->createAuthenticatedClient('user_can_switch');
3939

4040
$client->request('GET', '/profile?_switch_user=user_cannot_switch_1');
4141
$client->request('GET', '/profile?_switch_user=user_cannot_switch_2');
4242

43-
$this->assertEquals(500, $client->getResponse()->getStatusCode());
44-
$this->assertEquals('user_cannot_switch_1', $client->getProfile()->getCollector('security')->getUser());
43+
$this->assertEquals(200, $client->getResponse()->getStatusCode());
44+
$this->assertEquals('user_cannot_switch_2', $client->getProfile()->getCollector('security')->getUser());
4545
}
4646

4747
public function testSwitchedUserExit()

src/Symfony/Bundle/SecurityBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"php": "^5.5.9|>=7.0.8",
2020
"ext-xml": "*",
2121
"symfony/config": "~3.4|~4.0",
22-
"symfony/security": "~3.4.37|~4.3.10|^4.4.3",
22+
"symfony/security": "~3.4.38|~4.3.10|^4.4.5",
2323
"symfony/dependency-injection": "^3.4.3|^4.0.3",
2424
"symfony/http-kernel": "~3.4|~4.0",
2525
"symfony/polyfill-php70": "~1.0"

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ private function attemptSwitchUser(Request $request, $username)
134134
return $token;
135135
}
136136

137-
throw new \LogicException(sprintf('You are already switched to "%s" user.', $token->getUsername()));
137+
// User already switched, exit before seamlessly switching to another user
138+
$token = $this->attemptExitUser($request);
138139
}
139140

140141
if (false === $this->accessDecisionManager->decide($token, [$this->role])) {
@@ -152,7 +153,7 @@ private function attemptSwitchUser(Request $request, $username)
152153
$this->userChecker->checkPostAuth($user);
153154

154155
$roles = $user->getRoles();
155-
$roles[] = new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $this->tokenStorage->getToken());
156+
$roles[] = new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $token);
156157

157158
$token = new UsernamePasswordToken($user, $user->getPassword(), $this->providerKey, $roles);
158159

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,36 @@ public function testSwitchUser()
191191
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $this->tokenStorage->getToken());
192192
}
193193

194+
public function testSwitchUserAlreadySwitched()
195+
{
196+
$originalToken = new UsernamePasswordToken('original', null, 'key', ['ROLE_FOO']);
197+
$alreadySwitchedToken = new UsernamePasswordToken('switched_1', null, 'key', [new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $originalToken)]);
198+
199+
$tokenStorage = new TokenStorage();
200+
$tokenStorage->setToken($alreadySwitchedToken);
201+
202+
$targetUser = new User('kuba', 'password', ['ROLE_FOO', 'ROLE_BAR']);
203+
$this->request->query->set('_switch_user', 'kuba');
204+
205+
$this->accessDecisionManager->expects($this->once())
206+
->method('decide')->with($originalToken, ['ROLE_ALLOWED_TO_SWITCH'])
207+
->willReturn(true);
208+
$this->userProvider->expects($this->once())
209+
->method('loadUserByUsername')
210+
->with('kuba')
211+
->willReturn($targetUser);
212+
$this->userChecker->expects($this->once())
213+
->method('checkPostAuth')->with($targetUser);
214+
215+
$listener = new SwitchUserListener($tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', null, false);
216+
$listener->handle($this->event);
217+
218+
$this->assertSame([], $this->request->query->all());
219+
$this->assertSame('', $this->request->server->get('QUERY_STRING'));
220+
$this->assertSame('kuba', $tokenStorage->getToken()->getUsername());
221+
$this->assertSame($originalToken, $tokenStorage->getToken()->getRoles()[2]->getSource());
222+
}
223+
194224
public function testSwitchUserWorksWithFalsyUsernames()
195225
{
196226
$token = new UsernamePasswordToken('username', '', 'key', ['ROLE_FOO']);

0 commit comments

Comments
 (0)