Merge "Introduce User::INVALID_TOKEN"
This commit is contained in:
commit
8ea3e9135d
3 changed files with 21 additions and 18 deletions
|
|
@ -520,13 +520,6 @@ final class SessionManager implements SessionManagerInterface {
|
|||
public function preventSessionsForUser( $username ) {
|
||||
$this->preventUsers[$username] = true;
|
||||
|
||||
// Reset the user's token to kill existing sessions
|
||||
$user = User::newFromName( $username );
|
||||
if ( $user && $user->getToken( false ) ) {
|
||||
$user->setToken();
|
||||
$user->saveSettings();
|
||||
}
|
||||
|
||||
// Instruct the session providers to kill any other sessions too.
|
||||
foreach ( $this->getProviders() as $provider ) {
|
||||
$provider->preventSessionsForUser( $username );
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ class User implements IDBAccessObject {
|
|||
*/
|
||||
const TOKEN_LENGTH = 32;
|
||||
|
||||
/**
|
||||
* @const string An invalid value for user_token
|
||||
*/
|
||||
const INVALID_TOKEN = '*** INVALID ***';
|
||||
|
||||
/**
|
||||
* Global constant made accessible as class constants so that autoloader
|
||||
* magic can be used.
|
||||
|
|
@ -657,7 +662,8 @@ class User implements IDBAccessObject {
|
|||
$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.
|
||||
// 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 {
|
||||
|
|
@ -673,7 +679,7 @@ class User implements IDBAccessObject {
|
|||
$newpassword = PasswordFactory::newInvalidPassword();
|
||||
}
|
||||
if ( !$password instanceof InvalidPassword || !$newpassword instanceof InvalidPassword
|
||||
|| $user->mEmail
|
||||
|| $user->mEmail || $user->mToken !== self::INVALID_TOKEN
|
||||
) {
|
||||
// User exists. Steal it?
|
||||
if ( !$options['steal'] ) {
|
||||
|
|
@ -693,11 +699,11 @@ class User implements IDBAccessObject {
|
|||
__METHOD__
|
||||
);
|
||||
$user->invalidateEmail();
|
||||
$user->mToken = self::INVALID_TOKEN;
|
||||
$user->saveSettings();
|
||||
SessionManager::singleton()->preventSessionsForUser( $user->getName() );
|
||||
}
|
||||
|
||||
SessionManager::singleton()->preventSessionsForUser( $user->getName() );
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
|
|
@ -2489,13 +2495,18 @@ class User implements IDBAccessObject {
|
|||
$this->setToken();
|
||||
}
|
||||
|
||||
// If the user doesn't have a token, return null to indicate that.
|
||||
// Otherwise, hmac the version with the secret if we have a version.
|
||||
if ( !$this->mToken ) {
|
||||
// The user doesn't have a token, return null to indicate that.
|
||||
return null;
|
||||
} elseif ( $this->mToken === self::INVALID_TOKEN ) {
|
||||
// We return a random value here so existing token checks are very
|
||||
// likely to fail.
|
||||
return MWCryptRand::generateHex( self::TOKEN_LENGTH );
|
||||
} elseif ( $wgAuthenticationTokenVersion === null ) {
|
||||
// $wgAuthenticationTokenVersion not in use, so return the raw secret
|
||||
return $this->mToken;
|
||||
} else {
|
||||
// $wgAuthenticationTokenVersion in use, so hmac it.
|
||||
$ret = MWCryptHash::hmac( $wgAuthenticationTokenVersion, $this->mToken, false );
|
||||
|
||||
// The raw hash can be overly long. Shorten it up.
|
||||
|
|
@ -2516,7 +2527,10 @@ class User implements IDBAccessObject {
|
|||
*/
|
||||
public function setToken( $token = false ) {
|
||||
$this->load();
|
||||
if ( !$token ) {
|
||||
if ( $this->mToken === self::INVALID_TOKEN ) {
|
||||
\MediaWiki\Logger\LoggerFactory::getInstance( 'session' )
|
||||
->debug( __METHOD__ . ": Ignoring attempt to set token for system user \"$this\"" );
|
||||
} elseif ( !$token ) {
|
||||
$this->mToken = MWCryptRand::generateHex( self::TOKEN_LENGTH );
|
||||
} else {
|
||||
$this->mToken = $token;
|
||||
|
|
|
|||
|
|
@ -1062,12 +1062,8 @@ class SessionManagerTest extends MediaWikiTestCase {
|
|||
$this->objectCacheDef( $provider1 ),
|
||||
) );
|
||||
|
||||
$user = User::newFromName( 'UTSysop' );
|
||||
$token = $user->getToken( true );
|
||||
|
||||
$this->assertFalse( $manager->isUserSessionPrevented( 'UTSysop' ) );
|
||||
$manager->preventSessionsForUser( 'UTSysop' );
|
||||
$this->assertNotEquals( $token, User::newFromName( 'UTSysop' )->getToken() );
|
||||
$this->assertTrue( $manager->isUserSessionPrevented( 'UTSysop' ) );
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue