X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2Fsession%2FSessionManager.php;h=b8e480f71168da562d1e0414415d024bc29fe156;hb=5111bd2def4e63ecc8a2acbf468e5c39029f9efd;hp=c3481e80ed57d5f0b5db3e5f8c03aa44d05d8bcb;hpb=aff17edd95620bff595dfa88013b422b38b1db2a;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/session/SessionManager.php b/includes/session/SessionManager.php index c3481e80ed..b8e480f711 100644 --- a/includes/session/SessionManager.php +++ b/includes/session/SessionManager.php @@ -35,8 +35,15 @@ use WebRequest; /** * This serves as the entry point to the MediaWiki session handling system. * + * Most methods here are for internal use by session handling code. Other callers + * should only use getGlobalSession and the methods of SessionManagerInterface; + * the rest of the functionality is exposed via MediaWiki\Session\Session methods. + * + * To provide custom session handling, implement a MediaWiki\Session\SessionProvider. + * * @ingroup Session * @since 1.27 + * @see https://www.mediawiki.org/wiki/Manual:SessionManager_and_AuthManager */ final class SessionManager implements SessionManagerInterface { /** @var SessionManager|null */ @@ -374,202 +381,15 @@ final class SessionManager implements SessionManagerInterface { * @deprecated since 1.27, use MediaWiki\Auth\AuthManager::autoCreateUser instead * @param User $user User to auto-create * @return bool Success + * @codeCoverageIgnore */ public static function autoCreateUser( User $user ) { - global $wgAuth, $wgDisableAuthManager; - - // @codeCoverageIgnoreStart - if ( !$wgDisableAuthManager ) { - wfDeprecated( __METHOD__, '1.27' ); - return \MediaWiki\Auth\AuthManager::singleton()->autoCreateUser( - $user, - \MediaWiki\Auth\AuthManager::AUTOCREATE_SOURCE_SESSSION, - false - )->isGood(); - } - // @codeCoverageIgnoreEnd - - $logger = self::singleton()->logger; - - // Much of this code is based on that in CentralAuth - - // Try the local user from the slave DB - $localId = User::idFromName( $user->getName() ); - $flags = 0; - - // Fetch the user ID from the master, so that we don't try to create the user - // when they already exist, due to replication lag - // @codeCoverageIgnoreStart - if ( !$localId && wfGetLB()->getReaderIndex() != 0 ) { - $localId = User::idFromName( $user->getName(), User::READ_LATEST ); - $flags = User::READ_LATEST; - } - // @codeCoverageIgnoreEnd - - if ( $localId ) { - // User exists after all. - $user->setId( $localId ); - $user->loadFromId( $flags ); - return false; - } - - // Denied by AuthPlugin? But ignore AuthPlugin itself. - if ( get_class( $wgAuth ) !== 'AuthPlugin' && !$wgAuth->autoCreate() ) { - $logger->debug( __METHOD__ . ': denied by AuthPlugin' ); - $user->setId( 0 ); - $user->loadFromId(); - return false; - } - - // Wiki is read-only? - if ( wfReadOnly() ) { - $logger->debug( __METHOD__ . ': denied by wfReadOnly()' ); - $user->setId( 0 ); - $user->loadFromId(); - return false; - } - - $userName = $user->getName(); - - // Check the session, if we tried to create this user already there's - // no point in retrying. - $session = self::getGlobalSession(); - $reason = $session->get( 'MWSession::AutoCreateBlacklist' ); - if ( $reason ) { - $logger->debug( __METHOD__ . ": blacklisted in session ($reason)" ); - $user->setId( 0 ); - $user->loadFromId(); - return false; - } - - // Is the IP user able to create accounts? - $anon = new User; - if ( !$anon->isAllowedAny( 'createaccount', 'autocreateaccount' ) - || $anon->isBlockedFromCreateAccount() - ) { - // Blacklist the user to avoid repeated DB queries subsequently - $logger->debug( __METHOD__ . ': user is blocked from this wiki, blacklisting' ); - $session->set( 'MWSession::AutoCreateBlacklist', 'blocked', 600 ); - $session->persist(); - $user->setId( 0 ); - $user->loadFromId(); - return false; - } - - // Check for validity of username - if ( !User::isCreatableName( $userName ) ) { - $logger->debug( __METHOD__ . ': Invalid username, blacklisting' ); - $session->set( 'MWSession::AutoCreateBlacklist', 'invalid username', 600 ); - $session->persist(); - $user->setId( 0 ); - $user->loadFromId(); - return false; - } - - // Give other extensions a chance to stop auto creation. - $user->loadDefaults( $userName ); - $abortMessage = ''; - if ( !\Hooks::run( 'AbortAutoAccount', [ $user, &$abortMessage ] ) ) { - // In this case we have no way to return the message to the user, - // but we can log it. - $logger->debug( __METHOD__ . ": denied by hook: $abortMessage" ); - $session->set( 'MWSession::AutoCreateBlacklist', "hook aborted: $abortMessage", 600 ); - $session->persist(); - $user->setId( 0 ); - $user->loadFromId(); - return false; - } - - // Make sure the name has not been changed - if ( $user->getName() !== $userName ) { - $user->setId( 0 ); - $user->loadFromId(); - throw new \UnexpectedValueException( - 'AbortAutoAccount hook tried to change the user name' - ); - } - - // Ignore warnings about master connections/writes...hard to avoid here - \Profiler::instance()->getTransactionProfiler()->resetExpectations(); - - $cache = \ObjectCache::getLocalClusterInstance(); - $backoffKey = wfMemcKey( 'MWSession', 'autocreate-failed', md5( $userName ) ); - if ( $cache->get( $backoffKey ) ) { - $logger->debug( __METHOD__ . ': denied by prior creation attempt failures' ); - $user->setId( 0 ); - $user->loadFromId(); - return false; - } - - // Checks passed, create the user... - $from = isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : 'CLI'; - $logger->info( __METHOD__ . ': creating new user ({username}) - from: {url}', - [ - 'username' => $userName, - 'url' => $from, - ] ); - - try { - // Insert the user into the local DB master - $status = $user->addToDatabase(); - if ( !$status->isOK() ) { - // @codeCoverageIgnoreStart - // 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( false, false, 'en' ), - [ - 'username' => $userName, - ] - ); - } - $user->setId( $id ); - $user->loadFromId( User::READ_LATEST ); - return false; - // @codeCoverageIgnoreEnd - } - } catch ( \Exception $ex ) { - // @codeCoverageIgnoreStart - $logger->error( __METHOD__ . ': failed with exception {exception}', [ - 'exception' => $ex, - 'username' => $userName, - ] ); - // Do not keep throwing errors for a while - $cache->set( $backoffKey, 1, 600 ); - // Bubble up error; which should normally trigger DB rollbacks - throw $ex; - // @codeCoverageIgnoreEnd - } - - # Notify AuthPlugin - // @codeCoverageIgnoreStart - $tmpUser = $user; - $wgAuth->initUser( $tmpUser, true ); - if ( $tmpUser !== $user ) { - $logger->warning( __METHOD__ . ': ' . - get_class( $wgAuth ) . '::initUser() replaced the user object' ); - } - // @codeCoverageIgnoreEnd - - # Notify hooks (e.g. Newuserlog) - \Hooks::run( 'AuthPluginAutoCreate', [ $user ] ); - \Hooks::run( 'LocalUserCreated', [ $user, true ] ); - - $user->saveSettings(); - - # Update user count - \DeferredUpdates::addUpdate( new \SiteStatsUpdate( 0, 0, 0, 0, 1 ) ); - - # Watch user's userpage and talk page - $user->addWatch( $user->getUserPage(), User::IGNORE_USER_RIGHTS ); - - return true; + wfDeprecated( __METHOD__, '1.27' ); + return \MediaWiki\Auth\AuthManager::singleton()->autoCreateUser( + $user, + \MediaWiki\Auth\AuthManager::AUTOCREATE_SOURCE_SESSION, + false + )->isGood(); } /** @@ -1006,9 +826,9 @@ final class SessionManager implements SessionManagerInterface { } /** - * Create a session corresponding to the passed SessionInfo + * Create a Session corresponding to the passed SessionInfo * @private For use by a SessionProvider that needs to specially create its - * own session. + * own Session. Most session providers won't need this. * @param SessionInfo $info * @param WebRequest $request * @return Session @@ -1060,7 +880,7 @@ final class SessionManager implements SessionManagerInterface { $session->resetId(); } - \ScopedCallback::consume( $delay ); + \Wikimedia\ScopedCallback::consume( $delay ); return $session; } @@ -1128,6 +948,7 @@ final class SessionManager implements SessionManagerInterface { /** * Reset the internal caching for unit testing + * @protected Unit tests only */ public static function resetCache() { if ( !defined( 'MW_PHPUNIT_TEST' ) ) {