SessionBackend: skip isUserSessionPrevented check for anons
[lhc/web/wiklou.git] / includes / session / SessionManager.php
index f1ace2c..1aab12a 100644 (file)
@@ -24,7 +24,6 @@
 namespace MediaWiki\Session;
 
 use Psr\Log\LoggerInterface;
-use Psr\Log\LogLevel;
 use BagOStuff;
 use CachedBagOStuff;
 use Config;
@@ -168,7 +167,6 @@ final class SessionManager implements SessionManagerInterface {
                        $store = $options['store'];
                } else {
                        $store = \ObjectCache::getInstance( $this->config->get( 'SessionCacheType' ) );
-                       $store->setLogger( $this->logger );
                }
                $this->store = $store instanceof CachedBagOStuff ? $store : new CachedBagOStuff( $store );
 
@@ -477,12 +475,21 @@ final class SessionManager implements SessionManagerInterface {
                        $status = $user->addToDatabase();
                        if ( !$status->isOK() ) {
                                // @codeCoverageIgnoreStart
-                               $logger->error( __METHOD__ . ': failed with message ' . $status->getWikiText(),
-                                       [
-                                               'username' => $userName,
-                               ] );
-                               $user->setId( 0 );
-                               $user->loadFromId();
+                               // double-check for a race condition (T70012)
+                               $id = User::idFromName( $user->getName(), User::READ_LATEST );
+                               if ( $id ) {
+                                       $logger->info( __METHOD__ . ': tried to autocreate existing user',
+                                               [
+                                                       'username' => $userName,
+                                               ] );
+                               } else {
+                                       $logger->error( __METHOD__ . ': failed with message ' . $status->getWikiText(),
+                                               [
+                                                       'username' => $userName,
+                                               ] );
+                               }
+                               $user->setId( $id );
+                               $user->loadFromId( User::READ_LATEST );
                                return false;
                                // @codeCoverageIgnoreEnd
                        }
@@ -944,6 +951,15 @@ final class SessionManager implements SessionManagerInterface {
         * @return Session
         */
        public function getSessionFromInfo( SessionInfo $info, WebRequest $request ) {
+               if ( defined( 'MW_NO_SESSION' ) ) {
+                       if ( MW_NO_SESSION === 'warn' ) {
+                               // Undocumented safety case for converting existing entry points
+                               $this->logger->error( 'Sessions are supposed to be disabled for this entry point' );
+                       } else {
+                               throw new \BadMethodCallException( 'Sessions are disabled for this entry point' );
+                       }
+               }
+
                $id = $info->getId();
 
                if ( !isset( $this->allSessionBackends[$id] ) ) {
@@ -1057,96 +1073,6 @@ final class SessionManager implements SessionManagerInterface {
                self::$globalSessionRequest = null;
        }
 
-       /**
-        * Do a sanity check to make sure the session is not used from many different IP addresses
-        * and store some data for later sanity checks.
-        * FIXME remove this once SessionManager is considered stable
-        * @private For use in Setup.php only
-        * @param Session $session Defaults to the global session.
-        */
-       public function checkIpLimits( Session $session = null ) {
-               $session = $session ?: self::getGlobalSession();
-
-               try {
-                       $ip = $session->getRequest()->getIP();
-               } catch ( \MWException $e ) {
-                       return;
-               }
-               if ( $ip === '127.0.0.1' || \IP::isConfiguredProxy( $ip ) ) {
-                       return;
-               }
-               $now = time();
-
-               // Record (and possibly log) that the IP is using the current session.
-               // Don't touch the stored data unless we are adding a new IP or re-adding an expired one.
-               // This is slightly inaccurate (when an existing IP is seen again, the expiry is not
-               // extended) but that shouldn't make much difference and limits the session write frequency
-               // to # of IPs / $wgSuspiciousIpExpiry.
-               $data = $session->get( 'SessionManager-ip', [] );
-               if (
-                       !isset( $data[$ip] )
-                       || $data[$ip] < $now
-               ) {
-                       $data[$ip] = time() + $this->config->get( 'SuspiciousIpExpiry' );
-                       foreach ( $data as $key => $expires ) {
-                               if ( $expires < $now ) {
-                                       unset( $data[$key] );
-                               }
-                       }
-                       $session->set( 'SessionManager-ip', $data );
-
-                       $logger = \MediaWiki\Logger\LoggerFactory::getInstance( 'session-ip' );
-                       $logLevel = count( $data ) >= $this->config->get( 'SuspiciousIpPerSessionLimit' )
-                               ? LogLevel::WARNING : ( count( $data ) === 1 ? LogLevel::DEBUG : LogLevel::INFO );
-                       $logger->log(
-                               $logLevel,
-                               'Same session used from {count} IPs',
-                               [
-                                       'count' => count( $data ),
-                                       'ips' => $data,
-                                       'session' => $session->getId(),
-                                       'user' => $session->getUser()->getName(),
-                                       'persistent' => $session->isPersistent(),
-                               ]
-                       );
-               }
-
-               // Now do the same thing globally for the current user.
-               // We are using the object cache and assume it is shared between all wikis of a farm,
-               // and further assume that the same name belongs to the same user on all wikis. (It's either
-               // that or a central ID lookup which would mean an extra SQL query on every request.)
-               if ( $session->getUser()->isLoggedIn() ) {
-                       $userKey = 'SessionManager-ip:' . md5( $session->getUser()->getName() );
-                       $data = $this->store->get( $userKey ) ?: [];
-                       if (
-                               !isset( $data[$ip] )
-                               || $data[$ip] < $now
-                       ) {
-                               $data[$ip] = time() + $this->config->get( 'SuspiciousIpExpiry' );
-                               foreach ( $data as $key => $expires ) {
-                                       if ( $expires < $now ) {
-                                               unset( $data[$key] );
-                                       }
-                               }
-                               $this->store->set( $userKey, $data, $this->config->get( 'SuspiciousIpExpiry' ) );
-                               $logger = \MediaWiki\Logger\LoggerFactory::getInstance( 'session-ip' );
-                               $logLevel = count( $data ) >= $this->config->get( 'SuspiciousIpPerUserLimit' )
-                                       ? LogLevel::WARNING : ( count( $data ) === 1 ? LogLevel::DEBUG : LogLevel::INFO );
-                               $logger->log(
-                                       $logLevel,
-                                       'Same user had sessions from {count} IPs',
-                                       [
-                                               'count' => count( $data ),
-                                               'ips' => $data,
-                                               'session' => $session->getId(),
-                                               'user' => $session->getUser()->getName(),
-                                               'persistent' => $session->isPersistent(),
-                                       ]
-                               );
-                       }
-               }
-       }
-
        /**@}*/
 
 }