8000 Merge branch '3.4' into 4.4 · symfony/symfony@3057c68 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3057c68

Browse files
committed
Merge branch '3.4' into 4.4
* 3.4: [Security] Allow switching to another user when already switched
2 parents 1b377a8 + 6f95125 commit 3057c68

File tree

4 files changed

+40
-6
lines changed

4 files changed

+40
-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
@@ -29,15 +29,15 @@ public function testSwitchUser($originalUser, $targetUser, $expectedUser, $expec
2929
$this->assertEquals($expectedUser, $client->getProfile()->getCollector('security')->getUser());
3030
}
3131

32-
public function testSwitchedUserCannotSwitchToOther()
32+
public function testSwitchedUserCanSwitchToOther()
3333
{
3434
$client = $this->createAuthenticatedClient('user_can_switch');
3535

3636
$client->request('GET', '/profile?_switch_user=user_cannot_switch_1');
3737
$client->request('GET', '/profile?_switch_user=user_cannot_switch_2');
3838

39-
$this->assertEquals(500, $client->getResponse()->getStatusCode());
40-
$this->assertEquals('user_cannot_switch_1', $client->getProfile()->getCollector('security')->getUser());
39+
$this->assertEquals(200, $client->getResponse()->getStatusCode());
40+
$this->assertEquals('user_cannot_switch_2', $client->getProfile()->getCollector('security')->getUser());
4141
}
4242

4343
public function testSwitchedUserExit()

src/Symfony/Bundle/SecurityBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"symfony/security-core": "^4.4",
2525
"symfony/security-csrf": "^4.2|^5.0",
2626
"symfony/security-guard": "^4.2|^5.0",
27-
"symfony/security-http": "^4.4.3"
27+
"symfony/security-http": "^4.4.5"
2828
},
2929
"require-dev": {
3030
"doctrine/doctrine-bundle": "^1.5|^2.0",

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ private function attemptSwitchUser(Request $request, string $username): ?TokenIn
154154
return $token;
155155
}
156156

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

160161
$currentUsername = $token->getUsername();
@@ -189,7 +190,7 @@ private function attemptSwitchUser(Request $request, string $username): ?TokenIn
189190
$this->userChecker->checkPostAuth($user);
190191

191192
$roles = $user->getRoles();
192-
$roles[] = new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $this->tokenStorage->getToken(), false);
193+
$roles[] = new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $token, false);
193194

194195
$token = new SwitchUserToken($user, $user->getPassword(), $this->providerKey, $roles, $token);
195196

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,39 @@ public function testSwitchUser()
240240
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $this->tokenStorage->getToken());
241241
}
242242

243+
public function testSwitchUserAlreadySwitched()
244+
{
245+
$originalToken = new UsernamePasswordToken('original', null, 'key', ['ROLE_FOO']);
246+
$alreadySwitchedToken = new SwitchUserToken('switched_1', null, 'key', ['ROLE_BAR'], $originalToken);
247+
248+
$tokenStorage = new TokenStorage();
249+
$tokenStorage->setToken($alreadySwitchedToken);
250+
251+
$targetUser = new User('kuba', 'password', ['ROLE_FOO', 'ROLE_BAR']);
252+
253+
$this->request->query->set('_switch_user', 'kuba');
254+
255+
$this->accessDecisionManager->expects($this->once())
256+
->method('decide')->with($originalToken, ['ROLE_ALLOWED_TO_SWITCH'], $targetUser)
257+
->willReturn(true);
258+
259+
$this->userProvider->expects($this->exactly(2))
260+
->method('loadUserByUsername')
261+
->withConsecutive(['kuba'])
262+
->will($this->onConsecutiveCalls($targetUser, $this->throwException(new UsernameNotFoundException())));
263+
$this->userChecker->expects($this->once())
264+
->method('checkPostAuth')->with($targetUser);
265+
266+
$listener = new SwitchUserListener($tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', null, false);
267+
$listener($this->event);
268+
269+
$this->assertSame([], $this->request->query->all());
270+
$this->assertSame('', $this->request->server->get('QUERY_STRING'));
271+
$this->assertInstanceOf(SwitchUserToken::class, $tokenStorage->getToken());
272+
$this->assertSame('kuba', $tokenStorage->getToken()->getUsername());
273+
$this->assertSame($originalToken, $tokenStorage->getToken()->getOriginalToken());
274+
}
275+
243276
public function testSwitchUserWorksWithFalsyUsernames()
244277
{
245278
$token = new UsernamePasswordToken('username', '', 'key', ['ROLE_FOO']);

0 commit comments

Comments
 (0)
0