/**
  * @covers FauxRequest::setHeader
  * @covers FauxRequest::getHeader
  */
 public function testGetSetHeader()
 {
     $value = 'test/test';
     $request = new FauxRequest();
     $request->setHeader('Content-Type', $value);
     $this->assertEquals($request->getHeader('Content-Type'), $value);
     $this->assertEquals($request->getHeader('CONTENT-TYPE'), $value);
     $this->assertEquals($request->getHeader('content-type'), $value);
 }
Ejemplo n.º 2
0
 /**
  * @covers FauxRequest::setHeader
  * @covers FauxRequest::getHeader
  */
 public function testGetSetHeader()
 {
     $value = 'text/plain, text/html';
     $request = new FauxRequest();
     $request->setHeader('Accept', $value);
     $this->assertEquals($request->getHeader('Nonexistent'), false);
     $this->assertEquals($request->getHeader('Accept'), $value);
     $this->assertEquals($request->getHeader('ACCEPT'), $value);
     $this->assertEquals($request->getHeader('accept'), $value);
     $this->assertEquals($request->getHeader('Accept', WebRequest::GETHEADER_LIST), array('text/plain', 'text/html'));
 }
Ejemplo n.º 3
0
 /**
  * Import an client IP address, HTTP headers, user ID, and session ID
  *
  * This sets the current session, $wgUser, and $wgRequest from $params.
  * Once the return value falls out of scope, the old context is restored.
  * This method should only be called in contexts where there is no session
  * ID or end user receiving the response (CLI or HTTP job runners). This
  * is partly enforced, and is done so to avoid leaking cookies if certain
  * error conditions arise.
  *
  * This is useful when background scripts inherit context when acting on
  * behalf of a user. In general the 'sessionId' parameter should be set
  * to an empty string unless session importing is *truly* needed. This
  * feature is somewhat deprecated.
  *
  * @note suhosin.session.encrypt may interfere with this method.
  *
  * @param array $params Result of RequestContext::exportSession()
  * @return ScopedCallback
  * @throws MWException
  * @since 1.21
  */
 public static function importScopedSession(array $params)
 {
     if (strlen($params['sessionId']) && MediaWiki\Session\SessionManager::getGlobalSession()->isPersistent()) {
         // 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
         $user = User::newFromId($params['userId']);
         $user->load();
         if (!$user->getId()) {
             throw new MWException("No user with ID '{$params['userId']}'.");
         }
     } else {
         // anon user
         $user = User::newFromName($params['ip'], false);
     }
     $importSessionFunc = function (User $user, array $params) {
         global $wgRequest, $wgUser;
         $context = RequestContext::getMain();
         // Commit and close any current session
         if (MediaWiki\Session\PHPSessionHandler::isEnabled()) {
             session_write_close();
             // persist
             session_id('');
             // detach
             $_SESSION = [];
             // clear in-memory array
         }
         // Get new session, if applicable
         $session = null;
         if (strlen($params['sessionId'])) {
             // don't make a new random ID
             $manager = MediaWiki\Session\SessionManager::singleton();
             $session = $manager->getSessionById($params['sessionId'], true) ?: $manager->getEmptySession();
         }
         // Remove any user IP or agent information, and attach the request
         // with the new session.
         $context->setRequest(new FauxRequest([], false, $session));
         $wgRequest = $context->getRequest();
         // b/c
         // Now that all private information is detached from the user, it should
         // be safe to load the new user. If errors occur or an exception is thrown
         // and caught (leaving the main context in a mixed state), there is no risk
         // of the User object being attached to the wrong IP, headers, or session.
         $context->setUser($user);
         $wgUser = $context->getUser();
         // b/c
         if ($session && MediaWiki\Session\PHPSessionHandler::isEnabled()) {
             session_id($session->getId());
             MediaWiki\quietCall('session_start');
         }
         $request = new FauxRequest([], false, $session);
         $request->setIP($params['ip']);
         foreach ($params['headers'] as $name => $value) {
             $request->setHeader($name, $value);
         }
         // Set the current context to use the new WebRequest
         $context->setRequest($request);
         $wgRequest = $context->getRequest();
         // b/c
     };
     // Stash the old session and load in the new one
     $oUser = self::getMain()->getUser();
     $oParams = self::getMain()->exportSession();
     $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($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
     });
 }
Ejemplo n.º 4
0
 /**
  * @covers ApiMain::lacksSameOriginSecurity
  */
 public function testLacksSameOriginSecurity()
 {
     // Basic test
     $main = new ApiMain(new FauxRequest(array('action' => 'query', 'meta' => 'siteinfo')));
     $this->assertFalse($main->lacksSameOriginSecurity(), 'Basic test, should have security');
     // JSONp
     $main = new ApiMain(new FauxRequest(array('action' => 'query', 'format' => 'xml', 'callback' => 'foo')));
     $this->assertTrue($main->lacksSameOriginSecurity(), 'JSONp, should lack security');
     // Header
     $request = new FauxRequest(array('action' => 'query', 'meta' => 'siteinfo'));
     $request->setHeader('TrEaT-As-UnTrUsTeD', '');
     // With falsey value!
     $main = new ApiMain($request);
     $this->assertTrue($main->lacksSameOriginSecurity(), 'Header supplied, should lack security');
     // Hook
     $this->mergeMwGlobalArrayValue('wgHooks', array('RequestHasSameOriginSecurity' => array(function () {
         return false;
     })));
     $main = new ApiMain(new FauxRequest(array('action' => 'query', 'meta' => 'siteinfo')));
     $this->assertTrue($main->lacksSameOriginSecurity(), 'Hook, should lack security');
 }
 /**
  * Import the resolved user IP, 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 will setup the session from the given ID. This is useful when
  * background scripts inherit context when acting on behalf of a user.
  *
  * $param array $params Result of RequestContext::exportSession()
  * @return ScopedCallback
  * @throws MWException
  * @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 ($params['userId']) {
         // logged-in user
         $user = User::newFromId($params['userId']);
         if (!$user) {
             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) {
         global $wgRequest, $wgUser;
         $context = RequestContext::getMain();
         // Commit and close any current session
         session_write_close();
         // persist
         session_id('');
         // detach
         $_SESSION = array();
         // clear in-memory array
         // Remove any user IP or agent information
         $context->setRequest(new FauxRequest());
         $wgRequest = $context->getRequest();
         // b/c
         // Now that all private information is detached from the user, it should
         // be safe to load the new user. If errors occur or an exception is thrown
         // and caught (leaving the main context in a mixed state), there is no risk
         // of the User object being attached to the wrong IP, headers, or session.
         $context->setUser($user);
         $wgUser = $context->getUser();
         // b/c
         if (strlen($params['sessionId'])) {
             // don't make a new random ID
             wfSetupSession($params['sessionId']);
             // sets $_SESSION
         }
         $request = new FauxRequest(array(), false, $_SESSION);
         $request->setIP($params['ip']);
         foreach ($params['headers'] as $name => $value) {
             $request->setHeader($name, $value);
         }
         // Set the current context to use the new WebRequest
         $context->setRequest($request);
         $wgRequest = $context->getRequest();
         // b/c
     };
     // Stash the old session and load in the new one
     $oUser = self::getMain()->getUser();
     $oParams = self::getMain()->exportSession();
     $importSessionFunction($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);
     });
 }