diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-05-01 15:32:59 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-05-01 15:32:59 -0400 |
commit | 6dc1997577fab2c366781fd7048144935afa0012 (patch) | |
tree | 8918d28c7ab4342f0738985e37af1dfc42d0e93a /includes/specials/SpecialUserlogin.php | |
parent | 150f94f051128f367bc89f6b7e5f57eb2a69fc62 (diff) | |
parent | fa89acd685cb09cdbe1c64cbb721ec64975bbbc1 (diff) |
Merge commit 'fa89acd'
# Conflicts:
# .gitignore
# extensions/ArchInterWiki.sql
Diffstat (limited to 'includes/specials/SpecialUserlogin.php')
-rw-r--r-- | includes/specials/SpecialUserlogin.php | 115 |
1 files changed, 84 insertions, 31 deletions
diff --git a/includes/specials/SpecialUserlogin.php b/includes/specials/SpecialUserlogin.php index 10edbcfb..21f1194f 100644 --- a/includes/specials/SpecialUserlogin.php +++ b/includes/specials/SpecialUserlogin.php @@ -20,6 +20,7 @@ * @file * @ingroup SpecialPage */ +use MediaWiki\Logger\LoggerFactory; /** * Implements Special:UserLogin @@ -43,6 +44,24 @@ class LoginForm extends SpecialPage { const WRONG_TOKEN = 13; const USER_MIGRATED = 14; + public static $statusCodes = array( + self::SUCCESS => 'success', + self::NO_NAME => 'no_name', + self::ILLEGAL => 'illegal', + self::WRONG_PLUGIN_PASS => 'wrong_plugin_pass', + self::NOT_EXISTS => 'not_exists', + self::WRONG_PASS => 'wrong_pass', + self::EMPTY_PASS => 'empty_pass', + self::RESET_PASS => 'reset_pass', + self::ABORTED => 'aborted', + self::CREATE_BLOCKED => 'create_blocked', + self::THROTTLED => 'throttled', + self::USER_BLOCKED => 'user_blocked', + self::NEED_TOKEN => 'need_token', + self::WRONG_TOKEN => 'wrong_token', + self::USER_MIGRATED => 'user_migrated', + ); + /** * Valid error and warning messages * @@ -194,13 +213,13 @@ class LoginForm extends SpecialPage { && in_array( $entryError->getKey(), self::getValidErrorMessages() ) ) { $this->mEntryErrorType = 'error'; - $this->mEntryError = $entryError->rawParams( $loginreqlink )->escaped(); + $this->mEntryError = $entryError->rawParams( $loginreqlink )->parse(); } elseif ( $entryWarning->exists() && in_array( $entryWarning->getKey(), self::getValidErrorMessages() ) ) { $this->mEntryErrorType = 'warning'; - $this->mEntryError = $entryWarning->rawParams( $loginreqlink )->escaped(); + $this->mEntryError = $entryWarning->rawParams( $loginreqlink )->parse(); } if ( $wgEnableEmail ) { @@ -338,6 +357,10 @@ class LoginForm extends SpecialPage { } $status = $this->addNewAccountInternal(); + LoggerFactory::getInstance( 'authmanager' )->info( 'Account creation attempt with mailed password', array( + 'event' => 'accountcreation', + 'status' => $status, + ) ); if ( !$status->isGood() ) { $error = $status->getMessage(); $this->mainLoginForm( $error->toString() ); @@ -375,6 +398,11 @@ class LoginForm extends SpecialPage { # Create the account and abort if there's a problem doing so $status = $this->addNewAccountInternal(); + LoggerFactory::getInstance( 'authmanager' )->info( 'Account creation attempt', array( + 'event' => 'accountcreation', + 'status' => $status, + ) ); + if ( !$status->isGood() ) { $error = $status->getMessage(); $this->mainLoginForm( $error->toString() ); @@ -453,8 +481,7 @@ class LoginForm extends SpecialPage { * @return Status */ public function addNewAccountInternal() { - global $wgAuth, $wgMemc, $wgAccountCreationThrottle, - $wgMinimalPasswordLength, $wgEmailConfirmToEdit; + global $wgAuth, $wgMemc, $wgAccountCreationThrottle, $wgEmailConfirmToEdit; // If the user passes an invalid domain, something is fishy if ( !$wgAuth->validDomain( $this->mDomain ) ) { @@ -530,9 +557,15 @@ class LoginForm extends SpecialPage { # Now create a dummy user ($u) and check if it is valid $u = User::newFromName( $this->mUsername, 'creatable' ); - if ( !is_object( $u ) ) { + if ( !$u ) { return Status::newFatal( 'noname' ); - } elseif ( 0 != $u->idForName() ) { + } + + # Make sure the user does not exist already + $lock = $wgMemc->getScopedLock( wfGlobalCacheKey( 'account', md5( $this->mUsername ) ) ); + if ( !$lock ) { + return Status::newFatal( 'usernameinprogress' ); + } elseif ( $u->idForName( User::READ_LOCKING ) ) { return Status::newFatal( 'userexists' ); } @@ -546,7 +579,7 @@ class LoginForm extends SpecialPage { } # check for password validity, return a fatal Status if invalid - $validity = $u->checkPasswordValidity( $this->mPassword ); + $validity = $u->checkPasswordValidity( $this->mPassword, 'create' ); if ( !$validity->isGood() ) { $validity->ok = false; // make sure this Status is fatal return $validity; @@ -641,7 +674,12 @@ class LoginForm extends SpecialPage { $u->setRealName( $this->mRealName ); $u->setToken(); + Hooks::run( 'LocalUserCreated', array( $u, $autocreate ) ); + $oldUser = $u; $wgAuth->initUser( $u, $autocreate ); + if ( $oldUser !== $u ) { + wfWarn( get_class( $wgAuth ) . '::initUser() replaced the user object' ); + } $u->saveSettings(); @@ -710,7 +748,11 @@ class LoginForm extends SpecialPage { } $u = User::newFromName( $this->mUsername ); + if ( $u === false ) { + return self::ILLEGAL; + } + $msg = null; // Give extensions a way to indicate the username has been updated, // rather than telling the user the account doesn't exist. if ( !Hooks::run( 'LoginUserMigrated', array( $u, &$msg ) ) ) { @@ -718,7 +760,7 @@ class LoginForm extends SpecialPage { return self::USER_MIGRATED; } - if ( !( $u instanceof User ) || !User::isUsableName( $u->getName() ) ) { + if ( !User::isUsableName( $u->getName() ) ) { return self::ILLEGAL; } @@ -736,7 +778,6 @@ class LoginForm extends SpecialPage { // Give general extensions, such as a captcha, a chance to abort logins $abort = self::ABORTED; - $msg = null; if ( !Hooks::run( 'AbortLogin', array( $u, $this->mPassword, &$abort, &$msg ) ) ) { $this->mAbortLoginErrorMsg = $msg; @@ -784,7 +825,12 @@ class LoginForm extends SpecialPage { $retval = self::RESET_PASS; $this->mAbortLoginErrorMsg = 'resetpass-expired'; } else { + Hooks::run( 'UserLoggedIn', array( $u ) ); + $oldUser = $u; $wgAuth->updateUser( $u ); + if ( $oldUser !== $u ) { + wfWarn( get_class( $wgAuth ) . '::updateUser() replaced the user object' ); + } $wgUser = $u; // This should set it for OutputPage and the Skin // which is needed or the personal links will be @@ -909,7 +955,8 @@ class LoginForm extends SpecialPage { global $wgMemc, $wgLang, $wgSecureLogin, $wgPasswordAttemptThrottle, $wgInvalidPasswordReset; - switch ( $this->authenticateUserData() ) { + $authRes = $this->authenticateUserData(); + switch ( $authRes ) { case self::SUCCESS: # We've verified now, update the real record $user = $this->getUser(); @@ -946,7 +993,10 @@ class LoginForm extends SpecialPage { } elseif ( $wgInvalidPasswordReset && !$user->isValidPassword( $this->mPassword ) ) { - $status = $user->checkPasswordValidity( $this->mPassword ); + $status = $user->checkPasswordValidity( + $this->mPassword, + 'login' + ); $this->resetLoginForm( $status->getMessage( 'resetpass-validity-soft' ) ); @@ -1029,6 +1079,12 @@ class LoginForm extends SpecialPage { default: throw new MWException( 'Unhandled case value' ); } + + LoggerFactory::getInstance( 'authmanager' )->info( 'Login attempt', array( + 'event' => 'login', + 'successful' => $authRes === self::SUCCESS, + 'status' => LoginForm::$statusCodes[$authRes], + ) ); } /** @@ -1280,8 +1336,9 @@ class LoginForm extends SpecialPage { function mainLoginForm( $msg, $msgtype = 'error' ) { global $wgEnableEmail, $wgEnableUserEmail; global $wgHiddenPrefs, $wgLoginLanguageSelector; - global $wgAuth, $wgEmailConfirmToEdit, $wgCookieExpiration; + global $wgAuth, $wgEmailConfirmToEdit; global $wgSecureLogin, $wgPasswordResetRoutes; + global $wgExtendedLoginCookieExpiration, $wgCookieExpiration; $titleObj = $this->getPageTitle(); $user = $this->getUser(); @@ -1320,9 +1377,6 @@ class LoginForm extends SpecialPage { 'mediawiki.ui.input', 'mediawiki.special.userlogin.common.styles' ) ); - $out->addModules( array( - 'mediawiki.special.userlogin.common.js' - ) ); if ( $this->mType == 'signup' ) { // XXX hack pending RL or JS parse() support for complex content messages @@ -1384,6 +1438,7 @@ class LoginForm extends SpecialPage { : is_array( $wgPasswordResetRoutes ) && in_array( true, array_values( $wgPasswordResetRoutes ) ); $template->set( 'header', '' ); + $template->set( 'formheader', '' ); $template->set( 'skin', $this->getSkin() ); $template->set( 'name', $this->mUsername ); $template->set( 'password', $this->mPassword ); @@ -1404,7 +1459,7 @@ class LoginForm extends SpecialPage { $template->set( 'emailothers', $wgEnableUserEmail ); $template->set( 'canreset', $wgAuth->allowPasswordChange() ); $template->set( 'resetlink', $resetLink ); - $template->set( 'canremember', ( $wgCookieExpiration > 0 ) ); + $template->set( 'canremember', $wgExtendedLoginCookieExpiration === null ? ( $wgCookieExpiration > 0 ) : ( $wgExtendedLoginCookieExpiration > 0 ) ); $template->set( 'usereason', $user->isLoggedIn() ); $template->set( 'remember', $this->mRemember ); $template->set( 'cansecurelogin', ( $wgSecureLogin === true ) ); @@ -1526,7 +1581,6 @@ class LoginForm extends SpecialPage { */ public static function getCreateaccountToken() { global $wgRequest; - return $wgRequest->getSessionData( 'wsCreateaccountToken' ); } @@ -1601,22 +1655,21 @@ class LoginForm extends SpecialPage { */ function makeLanguageSelector() { $msg = $this->msg( 'loginlanguagelinks' )->inContentLanguage(); - if ( !$msg->isBlank() ) { - $langs = explode( "\n", $msg->text() ); - $links = array(); - foreach ( $langs as $lang ) { - $lang = trim( $lang, '* ' ); - $parts = explode( '|', $lang ); - if ( count( $parts ) >= 2 ) { - $links[] = $this->makeLanguageSelectorLink( $parts[0], trim( $parts[1] ) ); - } - } - - return count( $links ) > 0 ? $this->msg( 'loginlanguagelabel' )->rawParams( - $this->getLanguage()->pipeList( $links ) )->escaped() : ''; - } else { + if ( $msg->isBlank() ) { return ''; } + $langs = explode( "\n", $msg->text() ); + $links = array(); + foreach ( $langs as $lang ) { + $lang = trim( $lang, '* ' ); + $parts = explode( '|', $lang ); + if ( count( $parts ) >= 2 ) { + $links[] = $this->makeLanguageSelectorLink( $parts[0], trim( $parts[1] ) ); + } + } + + return count( $links ) > 0 ? $this->msg( 'loginlanguagelabel' )->rawParams( + $this->getLanguage()->pipeList( $links ) )->escaped() : ''; } /** |