Skip to content

Commit

Permalink
Simplified the login logic for the email fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
dtdesign committed Dec 17, 2024
1 parent 9af3a0a commit 720c312
Showing 1 changed file with 37 additions and 22 deletions.
59 changes: 37 additions & 22 deletions wcfsetup/install/files/lib/acp/form/LoginForm.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,55 +133,56 @@ protected function validatePassword(PasswordFormField $passwordFormField): void
{
$usernameFormField = $this->form->getNodeById('username');
\assert($usernameFormField instanceof TextFormField);
$handleException = null;
$validationError = null;

try {
$this->user = UserAuthenticationFactory::getInstance()
->getUserAuthentication()
->loginManually($usernameFormField->getValue(), $passwordFormField->getValue());
} catch (UserInputException $e) {
if (
\get_class(UserAuthenticationFactory::getInstance()->getUserAuthentication()) === DefaultUserAuthentication::class
&& $e->getField() == 'username'
) {
$validationError = $e;

if ($e->getField() === 'username') {
try {
$this->user = EmailUserAuthentication::getInstance()
->loginManually($usernameFormField->getValue(), $passwordFormField->getValue());
} catch (UserInputException $e2) {
if ($e2->getField() == 'username') {
$handleException = $e;
} else {
$handleException = $e2;
$user = $this->tryAuthenticationByEmail($usernameFormField->getValue(), $passwordFormField->getValue());
if ($user !== null) {
$this->user = $user;
$validationError = null;
}
} catch (UserInputException $emailException) {
// The attempt to use the email address as login username is
// only implicit, therefore we only use the inner exception
// if the error is about an incorrect password.
if ($emailException->getField() !== 'username') {
$validationError = $emailException;
}
}
} else {
$handleException = $e;
}
}

if ($handleException !== null) {
if ($handleException->getField() == 'username') {
if ($validationError !== null) {
if ($validationError->getField() == 'username') {
$usernameFormField->addValidationError(
new FormFieldValidationError(
$handleException->getType(),
'wcf.user.username.error.' . $handleException->getType(),
$validationError->getType(),
'wcf.user.username.error.' . $validationError->getType(),
[
'username' => $usernameFormField->getValue(),
]
)
);
} else if ($handleException->getField() == 'password') {
} else if ($validationError->getField() == 'password') {
$passwordFormField->addValidationError(
new FormFieldValidationError(
$handleException->getType(),
'wcf.user.password.error.' . $handleException->getType()
$validationError->getType(),
'wcf.user.password.error.' . $validationError->getType()
)
);
} else {
throw new \LogicException('unreachable');
}

$this->saveAuthenticationFailure($handleException->getField(), $usernameFormField->getValue());
$this->saveAuthenticationFailure($validationError->getField(), $usernameFormField->getValue());
}

if (RequestHandler::getInstance()->isACPRequest() && $this->user !== null) {
Expand All @@ -205,6 +206,20 @@ protected function validatePassword(PasswordFormField $passwordFormField): void
}
}

protected function tryAuthenticationByEmail(
string $username,
#[\SensitiveParameter] string $password
): ?User {
$defaultAuthentication = UserAuthenticationFactory::getInstance()->getUserAuthentication();
if (\get_class($defaultAuthentication) !== DefaultUserAuthentication::class) {
// The email fallback is only supported for the built-in
// authentication method.
return null;
}

return EmailUserAuthentication::getInstance()->loginManually($username, $password);
}

protected function saveAuthenticationFailure(string $errorField, string $username): void
{
if (!ENABLE_USER_AUTHENTICATION_FAILURE) {
Expand Down

0 comments on commit 720c312

Please sign in to comment.