use MediaWiki\MediaWikiServices;
use MediaWiki\Session\SessionManager;
use MediaWiki\Session\Token;
+use MediaWiki\Auth\AuthManager;
+use MediaWiki\Auth\AuthenticationResponse;
+use MediaWiki\Auth\AuthenticationRequest;
/**
* String Some punctuation to prevent editing from broken text-mangling proxies.
$data = $processCache->get( $key );
if ( !is_array( $data ) ) {
$data = $cache->get( $key );
- if ( !is_array( $data ) || $data['mVersion'] < self::VERSION ) {
+ if ( !is_array( $data )
+ || !isset( $data['mVersion'] )
+ || $data['mVersion'] < self::VERSION
+ ) {
// Object is expired
return false;
}
* This can optionally create the user if it doesn't exist, and "steal" the
* account if it does exist.
*
+ * "Stealing" an existing user is intended to make it impossible for normal
+ * authentication processes to use the account, effectively disabling the
+ * account for normal use:
+ * - Email is invalidated, to prevent account recovery by emailing a
+ * temporary password and to disassociate the account from the existing
+ * human.
+ * - The token is set to a magic invalid value, to kill existing sessions
+ * and to prevent $this->setToken() calls from resetting the token to a
+ * valid value.
+ * - SessionManager is instructed to prevent new sessions for the user, to
+ * do things like deauthorizing OAuth consumers.
+ * - AuthManager is instructed to revoke access, to invalidate or remove
+ * passwords and other credentials.
+ *
* @param string $name Username
* @param array $options Options are:
* - validate: As for User::getCanonicalName(), default 'valid'
* - create: Whether to create the user if it doesn't already exist, default true
- * - steal: Whether to reset the account's password and email if it
- * already exists, default false
+ * - steal: Whether to "disable" the account for normal use if it already
+ * exists, default false
* @return User|null
* @since 1.27
*/
public static function newSystemUser( $name, $options = [] ) {
+ global $wgDisableAuthManager;
+
$options += [
'validate' => 'valid',
'create' => true,
return null;
}
+ $fields = self::selectFields();
+ if ( $wgDisableAuthManager ) {
+ $fields = array_merge( $fields, [ 'user_password', 'user_newpassword' ] );
+ }
+
$dbw = wfGetDB( DB_MASTER );
$row = $dbw->selectRow(
'user',
- array_merge(
- self::selectFields(),
- [ 'user_password', 'user_newpassword' ]
- ),
+ $fields,
[ 'user_name' => $name ],
__METHOD__
);
}
$user = self::newFromRow( $row );
- // A user is considered to exist as a non-system user if it has a
- // password set, or a temporary password set, or an email set, or a
- // non-invalid token.
- $passwordFactory = new PasswordFactory();
- $passwordFactory->init( RequestContext::getMain()->getConfig() );
- try {
- $password = $passwordFactory->newFromCiphertext( $row->user_password );
- } catch ( PasswordError $e ) {
- wfDebug( 'Invalid password hash found in database.' );
- $password = PasswordFactory::newInvalidPassword();
- }
- try {
- $newpassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
- } catch ( PasswordError $e ) {
- wfDebug( 'Invalid password hash found in database.' );
- $newpassword = PasswordFactory::newInvalidPassword();
- }
- if ( !$password instanceof InvalidPassword || !$newpassword instanceof InvalidPassword
- || $user->mEmail || $user->mToken !== self::INVALID_TOKEN
- ) {
+ // A user is considered to exist as a non-system user if it can
+ // authenticate, or has an email set, or has a non-invalid token.
+ if ( !$user->mEmail && $user->mToken === self::INVALID_TOKEN ) {
+ if ( $wgDisableAuthManager ) {
+ $passwordFactory = new PasswordFactory();
+ $passwordFactory->init( RequestContext::getMain()->getConfig() );
+ try {
+ $password = $passwordFactory->newFromCiphertext( $row->user_password );
+ } catch ( PasswordError $e ) {
+ wfDebug( 'Invalid password hash found in database.' );
+ $password = PasswordFactory::newInvalidPassword();
+ }
+ try {
+ $newpassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
+ } catch ( PasswordError $e ) {
+ wfDebug( 'Invalid password hash found in database.' );
+ $newpassword = PasswordFactory::newInvalidPassword();
+ }
+ $canAuthenticate = !$password instanceof InvalidPassword ||
+ !$newpassword instanceof InvalidPassword;
+ } else {
+ $canAuthenticate = AuthManager::singleton()->userCanAuthenticate( $name );
+ }
+ }
+ if ( $user->mEmail || $user->mToken !== self::INVALID_TOKEN || $canAuthenticate ) {
// User exists. Steal it?
if ( !$options['steal'] ) {
return null;
}
- $nopass = PasswordFactory::newInvalidPassword()->toString();
+ if ( $wgDisableAuthManager ) {
+ $nopass = PasswordFactory::newInvalidPassword()->toString();
+ $dbw->update(
+ 'user',
+ [
+ 'user_password' => $nopass,
+ 'user_newpassword' => $nopass,
+ 'user_newpass_time' => null,
+ ],
+ [ 'user_id' => $user->getId() ],
+ __METHOD__
+ );
+ } else {
+ AuthManager::singleton()->revokeAccessForUser( $name );
+ }
- $dbw->update(
- 'user',
- [
- 'user_password' => $nopass,
- 'user_newpassword' => $nopass,
- 'user_newpass_time' => null,
- ],
- [ 'user_id' => $user->getId() ],
- __METHOD__
- );
$user->invalidateEmail();
$user->mToken = self::INVALID_TOKEN;
$user->saveSettings();
}
// Reject various classes of invalid names
- global $wgAuth;
- $name = $wgAuth->getCanonicalName( $t->getText() );
+ $name = AuthManager::callLegacyAuthPlugin(
+ 'getCanonicalName', [ $t->getText() ], $t->getText()
+ );
switch ( $validate ) {
case false:
* @see $wgAutopromoteOnce
*/
public function addAutopromoteOnceGroups( $event ) {
- global $wgAutopromoteOnceLogInRC, $wgAuth;
+ global $wgAutopromoteOnceLogInRC;
if ( wfReadOnly() || !$this->getId() ) {
return [];
}
// update groups in external authentication database
Hooks::run( 'UserGroupsChanged', [ $this, $toPromote, [], false, false ] );
- $wgAuth->updateExternalDBGroups( $this, $toPromote );
+ AuthManager::callLegacyAuthPlugin( 'updateExternalDBGroups', [ $this, $toPromote ] );
$newGroups = array_merge( $oldGroups, $toPromote ); // all groups
return $toPromote;
}
+ /**
+ * Builds update conditions. Additional conditions may be added to $conditions to
+ * protected against race conditions using a compare-and-set (CAS) mechanism
+ * based on comparing $this->mTouched with the user_touched field.
+ *
+ * @param DatabaseBase $db
+ * @param array $conditions WHERE conditions for use with DatabaseBase::update
+ * @return array WHERE conditions for use with DatabaseBase::update
+ */
+ protected function makeUpdateConditions( DatabaseBase $db, array $conditions ) {
+ if ( $this->mTouched ) {
+ // CAS check: only update if the row wasn't changed sicne it was loaded.
+ $conditions['user_touched'] = $db->timestamp( $this->mTouched );
+ }
+
+ return $conditions;
+ }
+
/**
* Bump user_touched if it didn't change since this object was loaded
*
}
// Get a new user_touched that is higher than the old one
- $oldTouched = $this->mTouched;
$newTouched = $this->newTouchedTimestamp();
$dbw = wfGetDB( DB_MASTER );
$dbw->update( 'user',
[ 'user_touched' => $dbw->timestamp( $newTouched ) ],
- [
+ $this->makeUpdateConditions( $dbw, [
'user_id' => $this->mId,
- 'user_touched' => $dbw->timestamp( $oldTouched ) // CAS check
- ],
+ ] ),
__METHOD__
);
$success = ( $dbw->affectedRows() > 0 );
if ( $this->mLocked !== null ) {
return $this->mLocked;
}
- global $wgAuth;
- $authUser = $wgAuth->getUserInstance( $this );
- $this->mLocked = (bool)$authUser->isLocked();
+ $authUser = AuthManager::callLegacyAuthPlugin( 'getUserInstance', [ &$this ], null );
+ $this->mLocked = $authUser && $authUser->isLocked();
Hooks::run( 'UserIsLocked', [ $this, &$this->mLocked ] );
return $this->mLocked;
}
}
$this->getBlockedStatus();
if ( !$this->mHideName ) {
- global $wgAuth;
- $authUser = $wgAuth->getUserInstance( $this );
- $this->mHideName = (bool)$authUser->isHidden();
+ $authUser = AuthManager::callLegacyAuthPlugin( 'getUserInstance', [ &$this ], null );
+ $this->mHideName = $authUser && $authUser->isHidden();
Hooks::run( 'UserIsHidden', [ $this, &$this->mHideName ] );
}
return $this->mHideName;
* wipes it, so the account cannot be logged in until
* a new password is set, for instance via e-mail.
*
- * @deprecated since 1.27. AuthManager is coming.
+ * @deprecated since 1.27, use AuthManager instead
* @param string $str New password to set
* @throws PasswordError On failure
* @return bool
*/
public function setPassword( $str ) {
- global $wgAuth;
+ global $wgAuth, $wgDisableAuthManager;
+
+ if ( !$wgDisableAuthManager ) {
+ return $this->setPasswordInternal( $str );
+ }
if ( $str !== null ) {
if ( !$wgAuth->allowPasswordChange() ) {
$this->setOption( 'watchlisttoken', false );
$this->setPasswordInternal( $str );
- SessionManager::singleton()->invalidateSessionsForUser( $this );
return true;
}
/**
* Set the password and reset the random token unconditionally.
*
- * @deprecated since 1.27. AuthManager is coming.
+ * @deprecated since 1.27, use AuthManager instead
* @param string|null $str New password to set or null to set an invalid
* password hash meaning that the user will not be able to log in
* through the web interface.
*/
public function setInternalPassword( $str ) {
- global $wgAuth;
+ global $wgAuth, $wgDisableAuthManager;
+
+ if ( !$wgDisableAuthManager ) {
+ $this->setPasswordInternal( $str );
+ }
if ( $wgAuth->allowSetLocalPassword() ) {
$this->setOption( 'watchlisttoken', false );
$this->setPasswordInternal( $str );
- SessionManager::singleton()->invalidateSessionsForUser( $this );
}
}
* @param string|null $str New password to set or null to set an invalid
* password hash meaning that the user will not be able to log in
* through the web interface.
+ * @return bool Success
*/
private function setPasswordInternal( $str ) {
- $id = self::idFromName( $this->getName(), self::READ_LATEST );
- if ( $id == 0 ) {
- throw new LogicException( 'Cannot set a password for a user that is not in the database.' );
+ global $wgDisableAuthManager;
+
+ if ( $wgDisableAuthManager ) {
+ $id = self::idFromName( $this->getName(), self::READ_LATEST );
+ if ( $id == 0 ) {
+ throw new LogicException( 'Cannot set a password for a user that is not in the database.' );
+ }
+
+ $passwordFactory = new PasswordFactory();
+ $passwordFactory->init( RequestContext::getMain()->getConfig() );
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->update(
+ 'user',
+ [
+ 'user_password' => $passwordFactory->newFromPlaintext( $str )->toString(),
+ 'user_newpassword' => PasswordFactory::newInvalidPassword()->toString(),
+ 'user_newpass_time' => $dbw->timestampOrNull( null ),
+ ],
+ [
+ 'user_id' => $id,
+ ],
+ __METHOD__
+ );
+
+ // When the main password is changed, invalidate all bot passwords too
+ BotPassword::invalidateAllPasswordsForUser( $this->getName() );
+ } else {
+ $manager = AuthManager::singleton();
+
+ // If the user doesn't exist yet, fail
+ if ( !$manager->userExists( $this->getName() ) ) {
+ throw new LogicException( 'Cannot set a password for a user that is not in the database.' );
+ }
+
+ $data = [
+ 'username' => $this->getName(),
+ 'password' => $str,
+ 'retype' => $str,
+ ];
+ $reqs = $manager->getAuthenticationRequests( AuthManager::ACTION_CHANGE, $this );
+ $reqs = AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data );
+ foreach ( $reqs as $req ) {
+ $status = $manager->allowsAuthenticationDataChange( $req );
+ if ( !$status->isOk() ) {
+ \MediaWiki\Logger\LoggerFactory::getInstance( 'authentication' )
+ ->info( __METHOD__ . ': Password change rejected: ' . $status->getWikiText() );
+ return false;
+ }
+ }
+ foreach ( $reqs as $req ) {
+ $manager->changeAuthenticationData( $req );
+ }
+
+ $this->setOption( 'watchlisttoken', false );
}
- $passwordFactory = new PasswordFactory();
- $passwordFactory->init( RequestContext::getMain()->getConfig() );
- $dbw = wfGetDB( DB_MASTER );
- $dbw->update(
- 'user',
- [
- 'user_password' => $passwordFactory->newFromPlaintext( $str )->toString(),
- 'user_newpassword' => PasswordFactory::newInvalidPassword()->toString(),
- 'user_newpass_time' => $dbw->timestampOrNull( null ),
- ],
- [
- 'user_id' => $id,
- ],
- __METHOD__
- );
+ SessionManager::singleton()->invalidateSessionsForUser( $this );
- // When the main password is changed, invalidate all bot passwords too
- BotPassword::invalidateAllPasswordsForUser( $this->getName() );
+ return true;
}
/**
/**
* Set the password for a password reminder or new account email
*
- * @deprecated since 1.27, AuthManager is coming
+ * @deprecated Removed in 1.27. Use PasswordReset instead.
* @param string $str New password to set or null to set an invalid
* password hash meaning that the user will not be able to use it
* @param bool $throttle If true, reset the throttle timestamp to the present
*/
public function setNewpassword( $str, $throttle = true ) {
- $id = $this->getId();
- if ( $id == 0 ) {
- throw new LogicException( 'Cannot set new password for a user that is not in the database.' );
- }
+ global $wgDisableAuthManager;
- $dbw = wfGetDB( DB_MASTER );
+ if ( $wgDisableAuthManager ) {
+ $id = $this->getId();
+ if ( $id == 0 ) {
+ throw new LogicException( 'Cannot set new password for a user that is not in the database.' );
+ }
- $passwordFactory = new PasswordFactory();
- $passwordFactory->init( RequestContext::getMain()->getConfig() );
- $update = [
- 'user_newpassword' => $passwordFactory->newFromPlaintext( $str )->toString(),
- ];
+ $dbw = wfGetDB( DB_MASTER );
- if ( $str === null ) {
- $update['user_newpass_time'] = null;
- } elseif ( $throttle ) {
- $update['user_newpass_time'] = $dbw->timestamp();
- }
+ $passwordFactory = new PasswordFactory();
+ $passwordFactory->init( RequestContext::getMain()->getConfig() );
+ $update = [
+ 'user_newpassword' => $passwordFactory->newFromPlaintext( $str )->toString(),
+ ];
- $dbw->update( 'user', $update, [ 'user_id' => $id ], __METHOD__ );
+ if ( $str === null ) {
+ $update['user_newpass_time'] = null;
+ } elseif ( $throttle ) {
+ $update['user_newpass_time'] = $dbw->timestamp();
+ }
+
+ $dbw->update( 'user', $update, [ 'user_id' => $id ], __METHOD__ );
+ } else {
+ throw new BadMethodCallException( __METHOD__ . ' has been removed in 1.27' );
+ }
}
/**
* Has password reminder email been sent within the last
* $wgPasswordReminderResendTime hours?
+ * @deprecated Removed in 1.27. See above.
* @return bool
*/
public function isPasswordReminderThrottled() {
- global $wgPasswordReminderResendTime;
+ global $wgPasswordReminderResendTime, $wgDisableAuthManager;
- if ( !$wgPasswordReminderResendTime ) {
- return false;
- }
+ if ( $wgDisableAuthManager ) {
+ if ( !$wgPasswordReminderResendTime ) {
+ return false;
+ }
- $this->load();
+ $this->load();
- $db = ( $this->queryFlagsUsed & self::READ_LATEST )
- ? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
- $newpassTime = $db->selectField(
- 'user',
- 'user_newpass_time',
- [ 'user_id' => $this->getId() ],
- __METHOD__
- );
+ $db = ( $this->queryFlagsUsed & self::READ_LATEST )
+ ? wfGetDB( DB_MASTER )
+ : wfGetDB( DB_SLAVE );
+ $newpassTime = $db->selectField(
+ 'user',
+ 'user_newpass_time',
+ [ 'user_id' => $this->getId() ],
+ __METHOD__
+ );
- if ( $newpassTime === null ) {
- return false;
+ if ( $newpassTime === null ) {
+ return false;
+ }
+ $expiry = wfTimestamp( TS_UNIX, $newpassTime ) + $wgPasswordReminderResendTime * 3600;
+ return time() < $expiry;
+ } else {
+ throw new BadMethodCallException( __METHOD__ . ' has been removed in 1.27' );
}
- $expiry = wfTimestamp( TS_UNIX, $newpassTime ) + $wgPasswordReminderResendTime * 3600;
- return time() < $expiry;
}
/**
if ( !$session->canSetUser() ) {
\MediaWiki\Logger\LoggerFactory::getInstance( 'session' )
->warning( __METHOD__ . ": Cannot log out of an immutable session" );
+ $error = 'immutable';
} elseif ( !$session->getUser()->equals( $this ) ) {
\MediaWiki\Logger\LoggerFactory::getInstance( 'session' )
->warning( __METHOD__ .
);
// But we still may as well make this user object anon
$this->clearInstanceCache( 'defaults' );
+ $error = 'wronguser';
} else {
$this->clearInstanceCache( 'defaults' );
$delay = $session->delaySave();
$session->setLoggedOutTimestamp( time() );
$session->setUser( new User );
$session->set( 'wsUserID', 0 ); // Other code expects this
+ $session->resetAllTokens();
ScopedCallback::consume( $delay );
+ $error = false;
}
+ \MediaWiki\Logger\LoggerFactory::getInstance( 'authmanager' )->info( 'Logout', [
+ 'event' => 'logout',
+ 'successful' => $error === false,
+ 'status' => $error ?: 'success',
+ ] );
}
/**
// Get a new user_touched that is higher than the old one.
// This will be used for a CAS check as a last-resort safety
// check against race conditions and slave lag.
- $oldTouched = $this->mTouched;
$newTouched = $this->newTouchedTimestamp();
$dbw = wfGetDB( DB_MASTER );
'user_token' => strval( $this->mToken ),
'user_email_token' => $this->mEmailToken,
'user_email_token_expires' => $dbw->timestampOrNull( $this->mEmailTokenExpires ),
- ], [ /* WHERE */
+ ], $this->makeUpdateConditions( $dbw, [ /* WHERE */
'user_id' => $this->mId,
- 'user_touched' => $dbw->timestamp( $oldTouched ) // CAS check
- ], __METHOD__
+ ] ), __METHOD__
);
if ( !$dbw->affectedRows() ) {
/**
* Check to see if the given clear-text password is one of the accepted passwords
- * @deprecated since 1.27. AuthManager is coming.
+ * @deprecated since 1.27, use AuthManager instead
* @param string $password User password
* @return bool True if the given password is correct, otherwise False
*/
public function checkPassword( $password ) {
- global $wgAuth, $wgLegacyEncoding;
+ global $wgAuth, $wgLegacyEncoding, $wgDisableAuthManager;
- $this->load();
+ if ( $wgDisableAuthManager ) {
+ $this->load();
- // Some passwords will give a fatal Status, which means there is
- // some sort of technical or security reason for this password to
- // be completely invalid and should never be checked (e.g., T64685)
- if ( !$this->checkPasswordValidity( $password )->isOK() ) {
- return false;
- }
+ // Some passwords will give a fatal Status, which means there is
+ // some sort of technical or security reason for this password to
+ // be completely invalid and should never be checked (e.g., T64685)
+ if ( !$this->checkPasswordValidity( $password )->isOK() ) {
+ return false;
+ }
- // Certain authentication plugins do NOT want to save
- // domain passwords in a mysql database, so we should
- // check this (in case $wgAuth->strict() is false).
- if ( $wgAuth->authenticate( $this->getName(), $password ) ) {
- return true;
- } elseif ( $wgAuth->strict() ) {
- // Auth plugin doesn't allow local authentication
- return false;
- } elseif ( $wgAuth->strictUserAuth( $this->getName() ) ) {
- // Auth plugin doesn't allow local authentication for this user name
- return false;
- }
+ // Certain authentication plugins do NOT want to save
+ // domain passwords in a mysql database, so we should
+ // check this (in case $wgAuth->strict() is false).
+ if ( $wgAuth->authenticate( $this->getName(), $password ) ) {
+ return true;
+ } elseif ( $wgAuth->strict() ) {
+ // Auth plugin doesn't allow local authentication
+ return false;
+ } elseif ( $wgAuth->strictUserAuth( $this->getName() ) ) {
+ // Auth plugin doesn't allow local authentication for this user name
+ return false;
+ }
- $passwordFactory = new PasswordFactory();
- $passwordFactory->init( RequestContext::getMain()->getConfig() );
- $db = ( $this->queryFlagsUsed & self::READ_LATEST )
- ? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
+ $passwordFactory = new PasswordFactory();
+ $passwordFactory->init( RequestContext::getMain()->getConfig() );
+ $db = ( $this->queryFlagsUsed & self::READ_LATEST )
+ ? wfGetDB( DB_MASTER )
+ : wfGetDB( DB_SLAVE );
- try {
- $mPassword = $passwordFactory->newFromCiphertext( $db->selectField(
- 'user', 'user_password', [ 'user_id' => $this->getId() ], __METHOD__
- ) );
- } catch ( PasswordError $e ) {
- wfDebug( 'Invalid password hash found in database.' );
- $mPassword = PasswordFactory::newInvalidPassword();
- }
+ try {
+ $mPassword = $passwordFactory->newFromCiphertext( $db->selectField(
+ 'user', 'user_password', [ 'user_id' => $this->getId() ], __METHOD__
+ ) );
+ } catch ( PasswordError $e ) {
+ wfDebug( 'Invalid password hash found in database.' );
+ $mPassword = PasswordFactory::newInvalidPassword();
+ }
- if ( !$mPassword->equals( $password ) ) {
- if ( $wgLegacyEncoding ) {
- // Some wikis were converted from ISO 8859-1 to UTF-8, the passwords can't be converted
- // Check for this with iconv
- $cp1252Password = iconv( 'UTF-8', 'WINDOWS-1252//TRANSLIT', $password );
- if ( $cp1252Password === $password || !$mPassword->equals( $cp1252Password ) ) {
+ if ( !$mPassword->equals( $password ) ) {
+ if ( $wgLegacyEncoding ) {
+ // Some wikis were converted from ISO 8859-1 to UTF-8, the passwords can't be converted
+ // Check for this with iconv
+ $cp1252Password = iconv( 'UTF-8', 'WINDOWS-1252//TRANSLIT', $password );
+ if ( $cp1252Password === $password || !$mPassword->equals( $cp1252Password ) ) {
+ return false;
+ }
+ } else {
return false;
}
- } else {
- return false;
}
- }
- if ( $passwordFactory->needsUpdate( $mPassword ) && !wfReadOnly() ) {
- $this->setPasswordInternal( $password );
- }
+ if ( $passwordFactory->needsUpdate( $mPassword ) && !wfReadOnly() ) {
+ $this->setPasswordInternal( $password );
+ }
- return true;
+ return true;
+ } else {
+ $manager = AuthManager::singleton();
+ $reqs = AuthenticationRequest::loadRequestsFromSubmission(
+ $manager->getAuthenticationRequests( AuthManager::ACTION_LOGIN ),
+ [
+ 'username' => $this->getName(),
+ 'password' => $password,
+ ]
+ );
+ $res = AuthManager::singleton()->beginAuthentication( $reqs, 'null:' );
+ switch ( $res->status ) {
+ case AuthenticationResponse::PASS:
+ return true;
+ case AuthenticationResponse::FAIL:
+ // Hope it's not a PreAuthenticationProvider that failed...
+ \MediaWiki\Logger\LoggerFactory::getInstance( 'authentication' )
+ ->info( __METHOD__ . ': Authentication failed: ' . $res->message->plain() );
+ return false;
+ default:
+ throw new BadMethodCallException(
+ 'AuthManager returned a response unsupported by ' . __METHOD__
+ );
+ }
+ }
}
/**
* Check if the given clear-text password matches the temporary password
* sent by e-mail for password reset operations.
*
- * @deprecated since 1.27. AuthManager is coming.
+ * @deprecated since 1.27, use AuthManager instead
* @param string $plaintext
* @return bool True if matches, false otherwise
*/
public function checkTemporaryPassword( $plaintext ) {
- global $wgNewPasswordExpiry;
+ global $wgNewPasswordExpiry, $wgDisableAuthManager;
- $this->load();
+ if ( $wgDisableAuthManager ) {
+ $this->load();
- $passwordFactory = new PasswordFactory();
- $passwordFactory->init( RequestContext::getMain()->getConfig() );
- $db = ( $this->queryFlagsUsed & self::READ_LATEST )
- ? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
+ $passwordFactory = new PasswordFactory();
+ $passwordFactory->init( RequestContext::getMain()->getConfig() );
+ $db = ( $this->queryFlagsUsed & self::READ_LATEST )
+ ? wfGetDB( DB_MASTER )
+ : wfGetDB( DB_SLAVE );
- $row = $db->selectRow(
- 'user',
- [ 'user_newpassword', 'user_newpass_time' ],
- [ 'user_id' => $this->getId() ],
- __METHOD__
- );
- try {
- $newPassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
- } catch ( PasswordError $e ) {
- wfDebug( 'Invalid password hash found in database.' );
- $newPassword = PasswordFactory::newInvalidPassword();
- }
+ $row = $db->selectRow(
+ 'user',
+ [ 'user_newpassword', 'user_newpass_time' ],
+ [ 'user_id' => $this->getId() ],
+ __METHOD__
+ );
+ try {
+ $newPassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
+ } catch ( PasswordError $e ) {
+ wfDebug( 'Invalid password hash found in database.' );
+ $newPassword = PasswordFactory::newInvalidPassword();
+ }
- if ( $newPassword->equals( $plaintext ) ) {
- if ( is_null( $row->user_newpass_time ) ) {
- return true;
+ if ( $newPassword->equals( $plaintext ) ) {
+ if ( is_null( $row->user_newpass_time ) ) {
+ return true;
+ }
+ $expiry = wfTimestamp( TS_UNIX, $row->user_newpass_time ) + $wgNewPasswordExpiry;
+ return ( time() < $expiry );
+ } else {
+ return false;
}
- $expiry = wfTimestamp( TS_UNIX, $row->user_newpass_time ) + $wgNewPasswordExpiry;
- return ( time() < $expiry );
} else {
- return false;
+ // Can't check the temporary password individually.
+ return $this->checkPassword( $plaintext );
}
}
* Add a newuser log entry for this user.
* Before 1.19 the return value was always true.
*
+ * @deprecated since 1.27, AuthManager handles logging
* @param string|bool $action Account creation type.
* - String, one of the following values:
* - 'create' for an anonymous user creating an account for himself.
* - true will be converted to 'byemail'
* - false will be converted to 'create' if this object is the same as
* $wgUser and to 'create2' otherwise
- *
* @param string $reason User supplied reason
- *
- * @return int|bool True if not $wgNewUserLog; otherwise ID of log item or 0 on failure
+ * @return int|bool True if not $wgNewUserLog or not $wgDisableAuthManager;
+ * otherwise ID of log item or 0 on failure
*/
public function addNewUserLogEntry( $action = false, $reason = '' ) {
- global $wgUser, $wgNewUserLog;
- if ( empty( $wgNewUserLog ) ) {
+ global $wgUser, $wgNewUserLog, $wgDisableAuthManager;
+ if ( !$wgDisableAuthManager || empty( $wgNewUserLog ) ) {
return true; // disabled
}
* Used by things like CentralAuth and perhaps other authplugins.
* Consider calling addNewUserLogEntry() directly instead.
*
+ * @deprecated since 1.27, AuthManager handles logging
* @return bool
*/
public function addNewUserLogEntryAutoCreate() {