Merge pull request #47686 from nextcloud/fix/move-email-logic-local-user-backend
fix: Move login via email logic to local backendpull/50702/head^2
commit
2ef04bfb5d
@ -1,53 +0,0 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/** |
||||
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
namespace OC\Authentication\Login; |
||||
|
||||
use OCP\IUserManager; |
||||
|
||||
class EmailLoginCommand extends ALoginCommand { |
||||
/** @var IUserManager */ |
||||
private $userManager; |
||||
|
||||
public function __construct(IUserManager $userManager) { |
||||
$this->userManager = $userManager; |
||||
} |
||||
|
||||
public function process(LoginData $loginData): LoginResult { |
||||
if ($loginData->getUser() === false) { |
||||
if (!filter_var($loginData->getUsername(), FILTER_VALIDATE_EMAIL)) { |
||||
return $this->processNextOrFinishSuccessfully($loginData); |
||||
} |
||||
|
||||
$users = $this->userManager->getByEmail($loginData->getUsername()); |
||||
// we only allow login by email if unique |
||||
if (count($users) === 1) { |
||||
// FIXME: This is a workaround to still stick to configured LDAP login filters |
||||
// this can be removed once the email login is properly implemented in the local user backend |
||||
// as described in https://github.com/nextcloud/server/issues/5221 |
||||
if ($users[0]->getBackendClassName() === 'LDAP') { |
||||
return $this->processNextOrFinishSuccessfully($loginData); |
||||
} |
||||
|
||||
$username = $users[0]->getUID(); |
||||
if ($username !== $loginData->getUsername()) { |
||||
$user = $this->userManager->checkPassword( |
||||
$username, |
||||
$loginData->getPassword() |
||||
); |
||||
if ($user !== false) { |
||||
$loginData->setUser($user); |
||||
$loginData->setUsername($username); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
return $this->processNextOrFinishSuccessfully($loginData); |
||||
} |
||||
} |
@ -1,148 +0,0 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Test\Authentication\Login; |
||||
|
||||
use OC\Authentication\Login\EmailLoginCommand; |
||||
use OCP\IUser; |
||||
use OCP\IUserManager; |
||||
use PHPUnit\Framework\MockObject\MockObject; |
||||
|
||||
class EmailLoginCommandTest extends ALoginCommandTest { |
||||
/** @var IUserManager|MockObject */ |
||||
private $userManager; |
||||
|
||||
protected function setUp(): void { |
||||
parent::setUp(); |
||||
|
||||
$this->userManager = $this->createMock(IUserManager::class); |
||||
|
||||
$this->cmd = new EmailLoginCommand( |
||||
$this->userManager |
||||
); |
||||
} |
||||
|
||||
public function testProcessAlreadyLoggedIn(): void { |
||||
$data = $this->getLoggedInLoginData(); |
||||
|
||||
$result = $this->cmd->process($data); |
||||
|
||||
$this->assertTrue($result->isSuccess()); |
||||
} |
||||
|
||||
public function testProcessNotAnEmailLogin(): void { |
||||
$data = $this->getFailedLoginData(); |
||||
$this->userManager->expects($this->never()) |
||||
->method('getByEmail') |
||||
->with($this->username) |
||||
->willReturn([]); |
||||
|
||||
$result = $this->cmd->process($data); |
||||
|
||||
$this->assertTrue($result->isSuccess()); |
||||
} |
||||
|
||||
public function testProcessDuplicateEmailLogin(): void { |
||||
$data = $this->getFailedLoginData(); |
||||
$data->setUsername('user@example.com'); |
||||
$this->userManager->expects($this->once()) |
||||
->method('getByEmail') |
||||
->with('user@example.com') |
||||
->willReturn([ |
||||
$this->createMock(IUser::class), |
||||
$this->createMock(IUser::class), |
||||
]); |
||||
|
||||
$result = $this->cmd->process($data); |
||||
|
||||
$this->assertTrue($result->isSuccess()); |
||||
} |
||||
|
||||
public function testProcessUidIsEmail(): void { |
||||
$email = 'user@domain.com'; |
||||
$data = $this->getFailedLoginData(); |
||||
$data->setUsername($email); |
||||
$emailUser = $this->createMock(IUser::class); |
||||
$emailUser->expects($this->any()) |
||||
->method('getUID') |
||||
->willReturn($email); |
||||
$this->userManager->expects($this->once()) |
||||
->method('getByEmail') |
||||
->with($email) |
||||
->willReturn([ |
||||
$emailUser, |
||||
]); |
||||
$this->userManager->expects($this->never()) |
||||
->method('checkPassword'); |
||||
|
||||
$result = $this->cmd->process($data); |
||||
|
||||
$this->assertTrue($result->isSuccess()); |
||||
$this->assertFalse($data->getUser()); |
||||
$this->assertEquals($email, $data->getUsername()); |
||||
} |
||||
|
||||
public function testProcessWrongPassword(): void { |
||||
$email = 'user@domain.com'; |
||||
$data = $this->getFailedLoginData(); |
||||
$data->setUsername($email); |
||||
$emailUser = $this->createMock(IUser::class); |
||||
$emailUser->expects($this->any()) |
||||
->method('getUID') |
||||
->willReturn('user2'); |
||||
$this->userManager->expects($this->once()) |
||||
->method('getByEmail') |
||||
->with($email) |
||||
->willReturn([ |
||||
$emailUser, |
||||
]); |
||||
$this->userManager->expects($this->once()) |
||||
->method('checkPassword') |
||||
->with( |
||||
'user2', |
||||
$this->password |
||||
) |
||||
->willReturn(false); |
||||
|
||||
$result = $this->cmd->process($data); |
||||
|
||||
$this->assertTrue($result->isSuccess()); |
||||
$this->assertFalse($data->getUser()); |
||||
$this->assertEquals($email, $data->getUsername()); |
||||
} |
||||
|
||||
public function testProcess(): void { |
||||
$email = 'user@domain.com'; |
||||
$data = $this->getFailedLoginData(); |
||||
$data->setUsername($email); |
||||
$emailUser = $this->createMock(IUser::class); |
||||
$emailUser->expects($this->any()) |
||||
->method('getUID') |
||||
->willReturn('user2'); |
||||
$this->userManager->expects($this->once()) |
||||
->method('getByEmail') |
||||
->with($email) |
||||
->willReturn([ |
||||
$emailUser, |
||||
]); |
||||
$this->userManager->expects($this->once()) |
||||
->method('checkPassword') |
||||
->with( |
||||
'user2', |
||||
$this->password |
||||
) |
||||
->willReturn($emailUser); |
||||
|
||||
$result = $this->cmd->process($data); |
||||
|
||||
$this->assertTrue($result->isSuccess()); |
||||
$this->assertEquals($emailUser, $data->getUser()); |
||||
$this->assertEquals('user2', $data->getUsername()); |
||||
} |
||||
} |
Loading…
Reference in new issue