From: Aaron Schulz Date: Mon, 29 Sep 2014 23:53:26 +0000 (-0700) Subject: Loosened the CLI restriction in RequestContext::importScopedSession() X-Git-Tag: 1.31.0-rc.0~13726 X-Git-Url: https://git.cyclocoop.org/%27.WWW_URL.%27admin/?a=commitdiff_plain;ds=sidebyside;h=f9ee99b2fa558eadf323fd89b8f9579e56aa9d7c;p=lhc%2Fweb%2Fwiklou.git Loosened the CLI restriction in RequestContext::importScopedSession() * Jobs can be run via HTTP runners rather than just CLI ones. The old check breaks jobs run on HHVM fcgi runners for example. * Always check the validity of the IP for sanity. Change-Id: I1d03c2ab6628b2d124bc7b9f6936788dea22e3e4 --- diff --git a/includes/context/RequestContext.php b/includes/context/RequestContext.php index b1bebe7c2b..059f18c133 100644 --- a/includes/context/RequestContext.php +++ b/includes/context/RequestContext.php @@ -474,10 +474,14 @@ class RequestContext implements IContextSource { } /** - * Import the resolved user IP, HTTP headers, user ID, and session ID. + * Import an client IP address, HTTP headers, user ID, and session ID + * * This sets the current session and sets $wgUser and $wgRequest. * Once the return value falls out of scope, the old context is restored. - * This function can only be called within CLI mode scripts. + * This method should only be called in contexts (CLI or HTTP job runners) + * where there is no session ID or end user receiving the response. This + * is partly enforced, and is done so to avoid leaking cookies if certain + * error conditions arise. * * This will setup the session from the given ID. This is useful when * background scripts inherit context when acting on behalf of a user. @@ -490,11 +494,12 @@ class RequestContext implements IContextSource { * @since 1.21 */ public static function importScopedSession( array $params ) { - if ( PHP_SAPI !== 'cli' ) { - // Don't send random private cookies or turn $wgRequest into FauxRequest - throw new MWException( "Sessions can only be imported in cli mode." ); - } elseif ( !strlen( $params['sessionId'] ) ) { - throw new MWException( "No session ID was specified." ); + if ( session_id() != '' && strlen( $params['sessionId'] ) ) { + // Sanity check to avoid sending random cookies for the wrong users. + // This method should only called by CLI scripts or by HTTP job runners. + throw new MWException( "Sessions can only be imported when none is active." ); + } elseif ( !IP::isValid( $params['ip'] ) ) { + throw new MWException( "Invalid client IP address '{$params['ip']}'." ); } if ( $params['userId'] ) { // logged-in user @@ -503,13 +508,11 @@ class RequestContext implements IContextSource { if ( !$user->getId() ) { throw new MWException( "No user with ID '{$params['userId']}'." ); } - } elseif ( !IP::isValid( $params['ip'] ) ) { - throw new MWException( "Could not load user '{$params['ip']}'." ); } else { // anon user $user = User::newFromName( $params['ip'], false ); } - $importSessionFunction = function ( User $user, array $params ) { + $importSessionFunc = function ( User $user, array $params ) { global $wgRequest, $wgUser; $context = RequestContext::getMain(); @@ -542,12 +545,19 @@ class RequestContext implements IContextSource { // Stash the old session and load in the new one $oUser = self::getMain()->getUser(); $oParams = self::getMain()->exportSession(); - $importSessionFunction( $user, $params ); + $oRequest = self::getMain()->getRequest(); + $importSessionFunc( $user, $params ); // Set callback to save and close the new session and reload the old one - return new ScopedCallback( function () use ( $importSessionFunction, $oUser, $oParams ) { - $importSessionFunction( $oUser, $oParams ); - } ); + return new ScopedCallback( + function () use ( $importSessionFunc, $oUser, $oParams, $oRequest ) { + global $wgRequest; + $importSessionFunc( $oUser, $oParams ); + // Restore the exact previous Request object (instead of leaving FauxRequest) + RequestContext::getMain()->setRequest( $oRequest ); + $wgRequest = RequestContext::getMain()->getRequest(); // b/c + } + ); } /**