From: Brad Jorsch Date: Fri, 14 Feb 2020 20:22:36 +0000 (-0500) Subject: API: Fix fetching login token from action=query&meta=tokens on private wikis X-Git-Tag: 1.34.1~6 X-Git-Url: http://git.cyclocoop.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=5e55aeed717707bdf095bdea7ec74b5aeeea3127 API: Fix fetching login token from action=query&meta=tokens on private wikis Accidentally broken by I991809acf. Also added a test that should hopefully prevent this from accidentally being broken again. Bug: T245149 Change-Id: Ia7985397db50efe8af81f643f2a0a89d0ece179e (cherry picked from commit e0f3a29349ffd8a3be14cec164c1e0f719e0e74b) --- diff --git a/includes/api/ApiQuery.php b/includes/api/ApiQuery.php index a7ff729e84..9e937f5e04 100644 --- a/includes/api/ApiQuery.php +++ b/includes/api/ApiQuery.php @@ -509,15 +509,14 @@ class ApiQuery extends ApiBase { // parameters either. We do allow the 'rawcontinue' and 'indexpageids' // parameters since frameworks might add these unconditionally and they // can't expose anything here. + $allowedParams = [ 'rawcontinue' => 1, 'indexpageids' => 1 ]; $this->mParams = $this->extractRequestParams(); - $params = array_filter( - array_diff_key( - $this->mParams + $this->getPageSet()->extractRequestParams(), - [ 'rawcontinue' => 1, 'indexpageids' => 1 ] - ) - ); - if ( array_keys( $params ) !== [ 'meta' ] ) { - return true; + $request = $this->getRequest(); + foreach ( $this->mParams + $this->getPageSet()->extractRequestParams() as $param => $value ) { + $needed = $param === 'meta'; + if ( !isset( $allowedParams[$param] ) && $request->getCheck( $param ) !== $needed ) { + return true; + } } // Ask each module if it requires read mode. Any true => this returns diff --git a/tests/phpunit/includes/api/query/ApiQueryTest.php b/tests/phpunit/includes/api/query/ApiQueryTest.php index 20bd8557d0..bdbd64ce7e 100644 --- a/tests/phpunit/includes/api/query/ApiQueryTest.php +++ b/tests/phpunit/includes/api/query/ApiQueryTest.php @@ -172,4 +172,48 @@ class ApiQueryTest extends ApiTestCase { // This response field contains an XML document even if no pages were exported $this->assertNotContains( $title->getPrefixedText(), $data[0]['query']['export'] ); } + + public function testIsReadMode() { + $api = new ApiMain( + new FauxRequest( [ 'action' => 'query', 'meta' => 'tokens', 'type' => 'login' ] ) + ); + $queryApi = new ApiQuery( $api, 'query' ); + $this->assertFalse( $queryApi->isReadMode(), + 'isReadMode() => false when meta=tokens is the only module' ); + + $api = new ApiMain( new FauxRequest( [ + 'action' => 'query', 'meta' => 'tokens', 'type' => 'login', 'rawcontinue' => 1, + 'indexpageids' => 1 + ] ) + ); + $queryApi = new ApiQuery( $api, 'query' ); + $this->assertFalse( $queryApi->isReadMode(), + 'rawcontinue and indexpageids are also allowed' ); + + $api = new ApiMain( + new FauxRequest( [ 'action' => 'query', 'meta' => 'tokens|siteinfo', 'type' => 'login' ] ) + ); + $queryApi = new ApiQuery( $api, 'query' ); + $this->assertTrue( $queryApi->isReadMode(), + 'isReadMode() => true when other meta modules are present' ); + + $api = new ApiMain( new FauxRequest( [ + 'action' => 'query', 'meta' => 'tokens', 'type' => 'login', 'list' => 'allpages' + ] ) ); + $queryApi = new ApiQuery( $api, 'query' ); + $this->assertTrue( $queryApi->isReadMode(), + 'isReadMode() => true when other modules are present' ); + + $api = new ApiMain( new FauxRequest( [ + 'action' => 'query', 'meta' => 'tokens', 'type' => 'login', 'titles' => 'Foo' + ] ) ); + $queryApi = new ApiQuery( $api, 'query' ); + $this->assertTrue( $queryApi->isReadMode(), + 'isReadMode() => true when other ApiQuery parameters are present' ); + + $api = new ApiMain( new FauxRequest( [ 'action' => 'query' ] ) ); + $queryApi = new ApiQuery( $api, 'query' ); + $this->assertTrue( $queryApi->isReadMode(), + 'isReadMode() => true when no modules are requested' ); + } }