Merge "Introduce User::INVALID_TOKEN"
[lhc/web/wiklou.git] / includes / session / SessionManager.php
index 6b221fd..f03260f 100644 (file)
@@ -25,6 +25,7 @@ namespace MediaWiki\Session;
 
 use Psr\Log\LoggerInterface;
 use BagOStuff;
+use CachedBagOStuff;
 use Config;
 use FauxRequest;
 use Language;
@@ -54,11 +55,8 @@ final class SessionManager implements SessionManagerInterface {
        /** @var Config */
        private $config;
 
-       /** @var BagOStuff|null */
-       private $tempStore;
-
-       /** @var BagOStuff|null */
-       private $permStore;
+       /** @var CachedBagOStuff|null */
+       private $store;
 
        /** @var SessionProvider[] */
        private $sessionProviders = null;
@@ -162,18 +160,18 @@ final class SessionManager implements SessionManagerInterface {
                        $this->setLogger( \MediaWiki\Logger\LoggerFactory::getInstance( 'session' ) );
                }
 
-               $this->tempStore = new \HashBagOStuff;
                if ( isset( $options['store'] ) ) {
                        if ( !$options['store'] instanceof BagOStuff ) {
                                throw new \InvalidArgumentException(
                                        '$options[\'store\'] must be an instance of BagOStuff'
                                );
                        }
-                       $this->permStore = $options['store'];
+                       $store = $options['store'];
                } else {
-                       $this->permStore = \ObjectCache::getInstance( $this->config->get( 'SessionCacheType' ) );
-                       $this->permStore->setLogger( $this->logger );
+                       $store = \ObjectCache::getInstance( $this->config->get( 'SessionCacheType' ) );
+                       $store->setLogger( $this->logger );
                }
+               $this->store = $store instanceof CachedBagOStuff ? $store : new CachedBagOStuff( $store );
 
                register_shutdown_function( array( $this, 'shutdown' ) );
        }
@@ -206,14 +204,7 @@ final class SessionManager implements SessionManagerInterface {
                // Test this here to provide a better log message for the common case
                // of "no such ID"
                $key = wfMemcKey( 'MWSession', $id );
-               $existing = $this->tempStore->get( $key );
-               if ( $existing === false ) {
-                       $existing = $this->permStore->get( $key );
-                       if ( $existing !== false ) {
-                               $this->tempStore->set( $key, $existing );
-                       }
-               }
-               if ( is_array( $existing ) ) {
+               if ( is_array( $this->store->get( $key ) ) ) {
                        $info = new SessionInfo( SessionInfo::MIN_PRIORITY, array( 'id' => $id, 'idIsSafe' => true ) );
                        if ( $this->loadSessionInfoFromStore( $info, $request ) ) {
                                $session = $this->getSessionFromInfo( $info, $request );
@@ -251,14 +242,7 @@ final class SessionManager implements SessionManagerInterface {
                        }
 
                        $key = wfMemcKey( 'MWSession', $id );
-                       $existing = $this->tempStore->get( $key );
-                       if ( $existing === false ) {
-                               $existing = $this->permStore->get( $key );
-                               if ( $existing !== false ) {
-                                       $this->tempStore->set( $key, $existing );
-                               }
-                       }
-                       if ( is_array( $existing ) ) {
+                       if ( is_array( $this->store->get( $key ) ) ) {
                                throw new \InvalidArgumentException( 'Session ID already exists' );
                        }
                }
@@ -501,11 +485,7 @@ final class SessionManager implements SessionManagerInterface {
                        // @codeCoverageIgnoreEnd
                }
 
-               # Notify hooks (e.g. Newuserlog)
-               \Hooks::run( 'AuthPluginAutoCreate', array( $user ) );
-               \Hooks::run( 'LocalUserCreated', array( $user, true ) );
-
-               # Notify AuthPlugin too
+               # Notify AuthPlugin
                $tmpUser = $user;
                $wgAuth->initUser( $tmpUser, true );
                if ( $tmpUser !== $user ) {
@@ -513,6 +493,10 @@ final class SessionManager implements SessionManagerInterface {
                                get_class( $wgAuth ) . '::initUser() replaced the user object' );
                }
 
+               # Notify hooks (e.g. Newuserlog)
+               \Hooks::run( 'AuthPluginAutoCreate', array( $user ) );
+               \Hooks::run( 'LocalUserCreated', array( $user, true ) );
+
                $user->saveSettings();
 
                # Update user count
@@ -536,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 );
@@ -678,13 +655,7 @@ final class SessionManager implements SessionManagerInterface {
         */
        private function loadSessionInfoFromStore( SessionInfo &$info, WebRequest $request ) {
                $key = wfMemcKey( 'MWSession', $info->getId() );
-               $blob = $this->tempStore->get( $key );
-               if ( $blob === false ) {
-                       $blob = $this->permStore->get( $key );
-                       if ( $blob !== false ) {
-                               $this->tempStore->set( $key, $blob );
-                       }
-               }
+               $blob = $this->store->get( $key );
 
                $newParams = array();
 
@@ -692,8 +663,7 @@ final class SessionManager implements SessionManagerInterface {
                        // Sanity check: blob must be an array, if it's saved at all
                        if ( !is_array( $blob ) ) {
                                $this->logger->warning( "Session $info: Bad data" );
-                               $this->tempStore->delete( $key );
-                               $this->permStore->delete( $key );
+                               $this->store->delete( $key );
                                return false;
                        }
 
@@ -702,8 +672,7 @@ final class SessionManager implements SessionManagerInterface {
                                !isset( $blob['metadata'] ) || !is_array( $blob['metadata'] )
                        ) {
                                $this->logger->warning( "Session $info: Bad data structure" );
-                               $this->tempStore->delete( $key );
-                               $this->permStore->delete( $key );
+                               $this->store->delete( $key );
                                return false;
                        }
 
@@ -718,8 +687,7 @@ final class SessionManager implements SessionManagerInterface {
                                !array_key_exists( 'provider', $metadata )
                        ) {
                                $this->logger->warning( "Session $info: Bad metadata" );
-                               $this->tempStore->delete( $key );
-                               $this->permStore->delete( $key );
+                               $this->store->delete( $key );
                                return false;
                        }
 
@@ -729,8 +697,7 @@ final class SessionManager implements SessionManagerInterface {
                                $newParams['provider'] = $provider = $this->getProvider( $metadata['provider'] );
                                if ( !$provider ) {
                                        $this->logger->warning( "Session $info: Unknown provider, " . $metadata['provider'] );
-                                       $this->tempStore->delete( $key );
-                                       $this->permStore->delete( $key );
+                                       $this->store->delete( $key );
                                        return false;
                                }
                        } elseif ( $metadata['provider'] !== (string)$provider ) {
@@ -921,8 +888,7 @@ final class SessionManager implements SessionManagerInterface {
                        $backend = new SessionBackend(
                                $this->allSessionIds[$id],
                                $info,
-                               $this->tempStore,
-                               $this->permStore,
+                               $this->store,
                                $this->logger,
                                $this->config->get( 'ObjectCacheSessionExpiry' )
                        );
@@ -999,9 +965,7 @@ final class SessionManager implements SessionManagerInterface {
                do {
                        $id = wfBaseConvert( \MWCryptRand::generateHex( 40 ), 16, 32, 32 );
                        $key = wfMemcKey( 'MWSession', $id );
-               } while ( isset( $this->allSessionIds[$id] ) ||
-                       is_array( $this->tempStore->get( $key ) ) || is_array( $this->permStore->get( $key ) )
-               );
+               } while ( isset( $this->allSessionIds[$id] ) || is_array( $this->store->get( $key ) ) );
                return $id;
        }
 
@@ -1011,7 +975,7 @@ final class SessionManager implements SessionManagerInterface {
         * @param PHPSessionHandler $handler
         */
        public function setupPHPSessionHandler( PHPSessionHandler $handler ) {
-               $handler->setManager( $this, $this->permStore, $this->logger );
+               $handler->setManager( $this, $this->store, $this->logger );
        }
 
        /**