diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2431,6 +2431,8 @@ 'PhabricatorAuthTestSMSAction' => 'applications/auth/action/PhabricatorAuthTestSMSAction.php', 'PhabricatorAuthTryEmailLoginAction' => 'applications/auth/action/PhabricatorAuthTryEmailLoginAction.php', 'PhabricatorAuthTryFactorAction' => 'applications/auth/action/PhabricatorAuthTryFactorAction.php', + 'PhabricatorAuthTryPasswordAction' => 'applications/auth/action/PhabricatorAuthTryPasswordAction.php', + 'PhabricatorAuthTryPasswordWithoutCAPTCHAAction' => 'applications/auth/action/PhabricatorAuthTryPasswordWithoutCAPTCHAAction.php', 'PhabricatorAuthUnlinkController' => 'applications/auth/controller/PhabricatorAuthUnlinkController.php', 'PhabricatorAuthValidateController' => 'applications/auth/controller/PhabricatorAuthValidateController.php', 'PhabricatorAuthWaitForApprovalMessageType' => 'applications/auth/message/PhabricatorAuthWaitForApprovalMessageType.php', @@ -8427,6 +8429,8 @@ 'PhabricatorAuthTestSMSAction' => 'PhabricatorSystemAction', 'PhabricatorAuthTryEmailLoginAction' => 'PhabricatorSystemAction', 'PhabricatorAuthTryFactorAction' => 'PhabricatorSystemAction', + 'PhabricatorAuthTryPasswordAction' => 'PhabricatorSystemAction', + 'PhabricatorAuthTryPasswordWithoutCAPTCHAAction' => 'PhabricatorSystemAction', 'PhabricatorAuthUnlinkController' => 'PhabricatorAuthController', 'PhabricatorAuthValidateController' => 'PhabricatorAuthController', 'PhabricatorAuthWaitForApprovalMessageType' => 'PhabricatorAuthMessageType', diff --git a/src/applications/auth/action/PhabricatorAuthTryPasswordAction.php b/src/applications/auth/action/PhabricatorAuthTryPasswordAction.php new file mode 100644 --- /dev/null +++ b/src/applications/auth/action/PhabricatorAuthTryPasswordAction.php @@ -0,0 +1,22 @@ +getUser(); $content_source = PhabricatorContentSource::newFromRequest($request); - $captcha_limit = 5; - $hard_limit = 32; - $limit_window = phutil_units('15 minutes in seconds'); + $rate_actor = PhabricatorSystemActionEngine::newActorFromRequest($request); - $failed_attempts = PhabricatorUserLog::loadRecentEventsFromThisIP( - PhabricatorUserLog::ACTION_LOGIN_FAILURE, - $limit_window); + PhabricatorSystemActionEngine::willTakeAction( + array($rate_actor), + new PhabricatorAuthTryPasswordAction(), + 1); // If the same remote address has submitted several failed login attempts // recently, require they provide a CAPTCHA response for new attempts. $require_captcha = false; $captcha_valid = false; if (AphrontFormRecaptchaControl::isRecaptchaEnabled()) { - if (count($failed_attempts) > $captcha_limit) { + try { + PhabricatorSystemActionEngine::willTakeAction( + array($rate_actor), + new PhabricatorAuthTryPasswordWithoutCAPTCHAAction(), + 1); + } catch (PhabricatorSystemActionRateLimitException $ex) { $require_captcha = true; $captcha_valid = AphrontFormRecaptchaControl::processCaptcha($request); } } - // If the user has submitted quite a few failed login attempts recently, - // give them a hard limit. - if (count($failed_attempts) > $hard_limit) { - $guidance = array(); - - $guidance[] = pht( - 'Your remote address has failed too many login attempts recently. '. - 'Wait a few minutes before trying again.'); - - $guidance[] = pht( - 'If you are unable to log in to your account, you can '. - '[[ /login/email | send a reset link to your email address ]].'); - - $guidance = implode("\n\n", $guidance); - - $dialog = $controller->newDialog() - ->setTitle(pht('Too Many Login Attempts')) - ->appendChild(new PHUIRemarkupView($viewer, $guidance)) - ->addCancelButton('/auth/start/', pht('Wait Patiently')); - - return array(null, $dialog); - } - $response = null; $account = null; $log_user = null;