Merge "API: Make jsonfm the default output format"
[lhc/web/wiklou.git] / includes / context / RequestContext.php
index ede10fe..059f18c 100644 (file)
@@ -140,11 +140,22 @@ class RequestContext implements IContextSource {
                if ( $this->title === null ) {
                        global $wgTitle; # fallback to $wg till we can improve this
                        $this->title = $wgTitle;
+                       wfDebugLog( 'GlobalTitleFail', __METHOD__ . ' called by ' . wfGetCaller() . ' with no title set.' );
                }
 
                return $this->title;
        }
 
+       /**
+        * Check, if a Title object is set
+        *
+        * @since 1.25
+        * @return bool
+        */
+       public function hasTitle() {
+               return $this->title !== null;
+       }
+
        /**
         * Check whether a WikiPage object can be get with getWikiPage().
         * Callers should expect that an exception is thrown from getWikiPage()
@@ -463,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.
@@ -479,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
@@ -492,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();
@@ -531,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
+                       }
+               );
        }
 
        /**