Skip to content

Commit 77f2c23

Browse files
authored
Merge pull request #36208 from nextcloud/backport/35419/stable25
[stable25] Fix login loop if login CSRF fails and user is not logged in
2 parents 8c25285 + 197a2ea commit 77f2c23

2 files changed

Lines changed: 27 additions & 14 deletions

File tree

core/Controller/LoginController.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,23 @@ public function tryLogin(string $user,
300300
string $redirect_url = null,
301301
string $timezone = '',
302302
string $timezone_offset = ''): RedirectResponse {
303-
// If the user is already logged in and the CSRF check does not pass then
304-
// simply redirect the user to the correct page as required. This is the
305-
// case when an user has already logged-in, in another tab.
306303
if (!$this->request->passesCSRFCheck()) {
307-
return $this->generateRedirect($redirect_url);
304+
if ($this->userSession->isLoggedIn()) {
305+
// If the user is already logged in and the CSRF check does not pass then
306+
// simply redirect the user to the correct page as required. This is the
307+
// case when a user has already logged-in, in another tab.
308+
return $this->generateRedirect($redirect_url);
309+
}
310+
311+
// Clear any auth remnants like cookies to ensure a clean login
312+
// For the next attempt
313+
$this->userSession->logout();
314+
return $this->createLoginFailedResponse(
315+
$user,
316+
$user,
317+
$redirect_url,
318+
$this->l10n->t('Please try again')
319+
);
308320
}
309321

310322
$data = new LoginData(

tests/Core/Controller/LoginControllerTest.php

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ public function testLoginWithValidCredentials() {
498498
$this->assertEquals($expected, $this->loginController->tryLogin($user, $password));
499499
}
500500

501-
public function testLoginWithoutPassedCsrfCheckAndNotLoggedIn() {
501+
public function testLoginWithoutPassedCsrfCheckAndNotLoggedIn(): void {
502502
/** @var IUser|MockObject $user */
503503
$user = $this->createMock(IUser::class);
504504
$user->expects($this->any())
@@ -511,21 +511,20 @@ public function testLoginWithoutPassedCsrfCheckAndNotLoggedIn() {
511511
->expects($this->once())
512512
->method('passesCSRFCheck')
513513
->willReturn(false);
514-
$this->userSession->expects($this->once())
514+
$this->userSession
515515
->method('isLoggedIn')
516516
->with()
517517
->willReturn(false);
518518
$this->config->expects($this->never())
519519
->method('deleteUserValue');
520520
$this->userSession->expects($this->never())
521521
->method('createRememberMeToken');
522-
$this->urlGenerator
523-
->expects($this->once())
524-
->method('linkToDefaultPageUrl')
525-
->willReturn('/default/foo');
526522

527-
$expected = new RedirectResponse('/default/foo');
528-
$this->assertEquals($expected, $this->loginController->tryLogin('Jane', $password, $originalUrl));
523+
$response = $this->loginController->tryLogin('Jane', $password, $originalUrl);
524+
525+
$expected = new RedirectResponse('');
526+
$expected->throttle(['user' => 'Jane']);
527+
$this->assertEquals($expected, $response);
529528
}
530529

531530
public function testLoginWithoutPassedCsrfCheckAndLoggedIn() {
@@ -542,7 +541,7 @@ public function testLoginWithoutPassedCsrfCheckAndLoggedIn() {
542541
->expects($this->once())
543542
->method('passesCSRFCheck')
544543
->willReturn(false);
545-
$this->userSession->expects($this->once())
544+
$this->userSession
546545
->method('isLoggedIn')
547546
->with()
548547
->willReturn(true);
@@ -559,8 +558,10 @@ public function testLoginWithoutPassedCsrfCheckAndLoggedIn() {
559558
->with('remember_login_cookie_lifetime')
560559
->willReturn(1234);
561560

561+
$response = $this->loginController->tryLogin('Jane', $password, $originalUrl);
562+
562563
$expected = new RedirectResponse($redirectUrl);
563-
$this->assertEquals($expected, $this->loginController->tryLogin('Jane', $password, $originalUrl));
564+
$this->assertEquals($expected, $response);
564565
}
565566

566567
public function testLoginWithValidCredentialsAndRedirectUrl() {

0 commit comments

Comments
 (0)