Changeset View
Changeset View
Standalone View
Standalone View
src/applications/auth/provider/PhabricatorPasswordAuthProvider.php
Show First 20 Lines • Show All 249 Lines • ▼ Show 20 Lines | final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider { | ||||
public function processLoginRequest( | public function processLoginRequest( | ||||
PhabricatorAuthLoginController $controller) { | PhabricatorAuthLoginController $controller) { | ||||
$request = $controller->getRequest(); | $request = $controller->getRequest(); | ||||
$viewer = $request->getUser(); | $viewer = $request->getUser(); | ||||
$content_source = PhabricatorContentSource::newFromRequest($request); | $content_source = PhabricatorContentSource::newFromRequest($request); | ||||
$captcha_limit = 5; | |||||
$hard_limit = 32; | |||||
$limit_window = phutil_units('15 minutes in seconds'); | |||||
$failed_attempts = PhabricatorUserLog::loadRecentEventsFromThisIP( | |||||
PhabricatorUserLog::ACTION_LOGIN_FAILURE, | |||||
$limit_window); | |||||
// If the same remote address has submitted several failed login attempts | |||||
// recently, require they provide a CAPTCHA response for new attempts. | |||||
amckinley: "require a they" | |||||
$require_captcha = false; | $require_captcha = false; | ||||
$captcha_valid = false; | $captcha_valid = false; | ||||
if (AphrontFormRecaptchaControl::isRecaptchaEnabled()) { | if (AphrontFormRecaptchaControl::isRecaptchaEnabled()) { | ||||
$failed_attempts = PhabricatorUserLog::loadRecentEventsFromThisIP( | if (count($failed_attempts) > $captcha_limit) { | ||||
PhabricatorUserLog::ACTION_LOGIN_FAILURE, | |||||
60 * 15); | |||||
if (count($failed_attempts) > 5) { | |||||
$require_captcha = true; | $require_captcha = true; | ||||
$captcha_valid = AphrontFormRecaptchaControl::processCaptcha($request); | $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; | $response = null; | ||||
$account = null; | $account = null; | ||||
$log_user = null; | $log_user = null; | ||||
if ($request->isFormPost()) { | if ($request->isFormPost()) { | ||||
if (!$require_captcha || $captcha_valid) { | if (!$require_captcha || $captcha_valid) { | ||||
$username_or_email = $request->getStr('username'); | $username_or_email = $request->getStr('username'); | ||||
if (strlen($username_or_email)) { | if (strlen($username_or_email)) { | ||||
▲ Show 20 Lines • Show All 98 Lines • Show Last 20 Lines |
"require a they"