summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Wurst <ChristophWurst@users.noreply.github.com>2023-01-18 11:55:24 +0100
committerGitHub <noreply@github.com>2023-01-18 11:55:24 +0100
commit9e08e4999821a0cf7c6b08fd9ab05f8d057c8362 (patch)
tree7b167435616aa75e6a37273029e7f727007ead84
parentdfa1a7b33b17ed69efef3d89db555d06363788f2 (diff)
parentf22101d4213768066d3dcbde81898dd64ce46445 (diff)
downloadnextcloud-server-9e08e4999821a0cf7c6b08fd9ab05f8d057c8362.tar.gz
nextcloud-server-9e08e4999821a0cf7c6b08fd9ab05f8d057c8362.zip
Merge pull request #35419 from nextcloud/fix/login-csrf-not-logged-in-clear-cookies
Fix login loop if login CSRF fails and user is not logged in
-rw-r--r--core/Controller/LoginController.php20
-rw-r--r--tests/Core/Controller/LoginControllerTest.php21
2 files changed, 27 insertions, 14 deletions
diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php
index 386987842c2..ef1c1fbd94f 100644
--- a/core/Controller/LoginController.php
+++ b/core/Controller/LoginController.php
@@ -303,11 +303,23 @@ class LoginController extends Controller {
string $redirect_url = null,
string $timezone = '',
string $timezone_offset = ''): RedirectResponse {
- // If the user is already logged in and the CSRF check does not pass then
- // simply redirect the user to the correct page as required. This is the
- // case when an user has already logged-in, in another tab.
if (!$this->request->passesCSRFCheck()) {
- return $this->generateRedirect($redirect_url);
+ if ($this->userSession->isLoggedIn()) {
+ // If the user is already logged in and the CSRF check does not pass then
+ // simply redirect the user to the correct page as required. This is the
+ // case when a user has already logged-in, in another tab.
+ return $this->generateRedirect($redirect_url);
+ }
+
+ // Clear any auth remnants like cookies to ensure a clean login
+ // For the next attempt
+ $this->userSession->logout();
+ return $this->createLoginFailedResponse(
+ $user,
+ $user,
+ $redirect_url,
+ $this->l10n->t('Please try again')
+ );
}
$data = new LoginData(
diff --git a/tests/Core/Controller/LoginControllerTest.php b/tests/Core/Controller/LoginControllerTest.php
index fae20ae6b74..8a206a429bd 100644
--- a/tests/Core/Controller/LoginControllerTest.php
+++ b/tests/Core/Controller/LoginControllerTest.php
@@ -511,7 +511,7 @@ class LoginControllerTest extends TestCase {
$this->assertEquals($expected, $this->loginController->tryLogin($user, $password));
}
- public function testLoginWithoutPassedCsrfCheckAndNotLoggedIn() {
+ public function testLoginWithoutPassedCsrfCheckAndNotLoggedIn(): void {
/** @var IUser|MockObject $user */
$user = $this->createMock(IUser::class);
$user->expects($this->any())
@@ -524,7 +524,7 @@ class LoginControllerTest extends TestCase {
->expects($this->once())
->method('passesCSRFCheck')
->willReturn(false);
- $this->userSession->expects($this->once())
+ $this->userSession
->method('isLoggedIn')
->with()
->willReturn(false);
@@ -532,13 +532,12 @@ class LoginControllerTest extends TestCase {
->method('deleteUserValue');
$this->userSession->expects($this->never())
->method('createRememberMeToken');
- $this->urlGenerator
- ->expects($this->once())
- ->method('linkToDefaultPageUrl')
- ->willReturn('/default/foo');
- $expected = new RedirectResponse('/default/foo');
- $this->assertEquals($expected, $this->loginController->tryLogin('Jane', $password, $originalUrl));
+ $response = $this->loginController->tryLogin('Jane', $password, $originalUrl);
+
+ $expected = new RedirectResponse('');
+ $expected->throttle(['user' => 'Jane']);
+ $this->assertEquals($expected, $response);
}
public function testLoginWithoutPassedCsrfCheckAndLoggedIn() {
@@ -555,7 +554,7 @@ class LoginControllerTest extends TestCase {
->expects($this->once())
->method('passesCSRFCheck')
->willReturn(false);
- $this->userSession->expects($this->once())
+ $this->userSession
->method('isLoggedIn')
->with()
->willReturn(true);
@@ -572,8 +571,10 @@ class LoginControllerTest extends TestCase {
->with('remember_login_cookie_lifetime')
->willReturn(1234);
+ $response = $this->loginController->tryLogin('Jane', $password, $originalUrl);
+
$expected = new RedirectResponse($redirectUrl);
- $this->assertEquals($expected, $this->loginController->tryLogin('Jane', $password, $originalUrl));
+ $this->assertEquals($expected, $response);
}
public function testLoginWithValidCredentialsAndRedirectUrl() {