3 use Wikimedia\TestingAccessWrapper
;
12 class ApiLoginTest
extends ApiTestCase
{
15 * Test result of attempted login with an empty username
17 public function testApiLoginNoName() {
19 'wsTokenSecrets' => [ 'login' => 'foobar' ],
21 $data = $this->doApiRequest( [ 'action' => 'login',
22 'lgname' => '', 'lgpassword' => self
::$users['sysop']->getPassword(),
23 'lgtoken' => (string)( new MediaWiki\Session\
Token( 'foobar', '' ) )
25 $this->assertEquals( 'Failed', $data[0]['login']['result'] );
28 public function testApiLoginBadPass() {
31 $user = self
::$users['sysop'];
32 $userName = $user->getUser()->getName();
33 $user->getUser()->logout();
35 if ( !isset( $wgServer ) ) {
36 $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' );
38 $ret = $this->doApiRequest( [
40 "lgname" => $userName,
41 "lgpassword" => "bad",
46 $this->assertNotInternalType( "bool", $result );
47 $a = $result["login"]["result"];
48 $this->assertEquals( "NeedToken", $a );
50 $token = $result["login"]["token"];
52 $ret = $this->doApiRequest(
56 "lgname" => $userName,
57 "lgpassword" => "badnowayinhell",
64 $this->assertNotInternalType( "bool", $result );
65 $a = $result["login"]["result"];
67 $this->assertEquals( 'Failed', $a );
70 public function testApiLoginGoodPass() {
73 if ( !isset( $wgServer ) ) {
74 $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' );
77 $user = self
::$users['sysop'];
78 $userName = $user->getUser()->getName();
79 $password = $user->getPassword();
80 $user->getUser()->logout();
82 $ret = $this->doApiRequest( [
84 "lgname" => $userName,
85 "lgpassword" => $password,
90 $this->assertNotInternalType( "bool", $result );
91 $this->assertNotInternalType( "null", $result["login"] );
93 $a = $result["login"]["result"];
94 $this->assertEquals( "NeedToken", $a );
95 $token = $result["login"]["token"];
97 $ret = $this->doApiRequest(
101 "lgname" => $userName,
102 "lgpassword" => $password,
109 $this->assertNotInternalType( "bool", $result );
110 $a = $result["login"]["result"];
112 $this->assertEquals( "Success", $a );
118 public function testApiLoginGotCookie() {
119 $this->markTestIncomplete( "The server can't do external HTTP requests, "
120 . "and the internal one won't give cookies" );
122 global $wgServer, $wgScriptPath;
124 if ( !isset( $wgServer ) ) {
125 $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' );
127 $user = self
::$users['sysop'];
128 $userName = $user->getUser()->getName();
129 $password = $user->getPassword();
131 $req = MWHttpRequest
::factory( self
::$apiUrl . "?action=login&format=xml",
132 [ "method" => "POST",
134 "lgname" => $userName,
135 "lgpassword" => $password
142 libxml_use_internal_errors( true );
143 $sxe = simplexml_load_string( $req->getContent() );
144 $this->assertNotInternalType( "bool", $sxe );
145 $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) );
146 $this->assertNotInternalType( "null", $sxe->login
[0] );
148 $a = $sxe->login
[0]->attributes()->result
[0];
149 $this->assertEquals( ' result="NeedToken"', $a->asXML() );
150 $token = (string)$sxe->login
[0]->attributes()->token
;
154 "lgname" => $userName,
155 "lgpassword" => $password ] );
158 $cj = $req->getCookieJar();
159 $serverName = parse_url( $wgServer, PHP_URL_HOST
);
160 $this->assertNotEquals( false, $serverName );
161 $serializedCookie = $cj->serializeToHttpRequest( $wgScriptPath, $serverName );
162 $this->assertNotEquals( '', $serializedCookie );
164 '/_session=[^;]*; .*UserID=[0-9]*; .*UserName=' . $user->userName
. '; .*Token=/',
169 public function testRunLogin() {
170 $user = self
::$users['sysop'];
171 $userName = $user->getUser()->getName();
172 $password = $user->getPassword();
174 $data = $this->doApiRequest( [
176 'lgname' => $userName,
177 'lgpassword' => $password ] );
179 $this->assertArrayHasKey( "login", $data[0] );
180 $this->assertArrayHasKey( "result", $data[0]['login'] );
181 $this->assertEquals( "NeedToken", $data[0]['login']['result'] );
182 $token = $data[0]['login']['token'];
184 $data = $this->doApiRequest( [
187 "lgname" => $userName,
188 "lgpassword" => $password ], $data[2] );
190 $this->assertArrayHasKey( "login", $data[0] );
191 $this->assertArrayHasKey( "result", $data[0]['login'] );
192 $this->assertEquals( "Success", $data[0]['login']['result'] );
195 public function testBotPassword() {
196 global $wgServer, $wgSessionProviders;
198 if ( !isset( $wgServer ) ) {
199 $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' );
202 $this->setMwGlobals( [
203 'wgSessionProviders' => array_merge( $wgSessionProviders, [
205 'class' => MediaWiki\Session\BotPasswordSessionProvider
::class,
206 'args' => [ [ 'priority' => 40 ] ],
209 'wgEnableBotPasswords' => true,
210 'wgBotPasswordsDatabase' => false,
211 'wgCentralIdLookupProvider' => 'local',
212 'wgGrantPermissions' => [
213 'test' => [ 'read' => true ],
217 // Make sure our session provider is present
218 $manager = TestingAccessWrapper
::newFromObject( MediaWiki\Session\SessionManager
::singleton() );
219 if ( !isset( $manager->sessionProviders
[MediaWiki\Session\BotPasswordSessionProvider
::class] ) ) {
220 $tmp = $manager->sessionProviders
;
221 $manager->sessionProviders
= null;
222 $manager->sessionProviders
= $tmp +
$manager->getProviders();
224 $this->assertNotNull(
225 MediaWiki\Session\SessionManager
::singleton()->getProvider(
226 MediaWiki\Session\BotPasswordSessionProvider
::class
231 $user = self
::$users['sysop'];
232 $centralId = CentralIdLookup
::factory()->centralIdFromLocalUser( $user->getUser() );
233 $this->assertNotEquals( 0, $centralId, 'sanity check' );
235 $password = 'ngfhmjm64hv0854493hsj5nncjud2clk';
236 $passwordFactory = new PasswordFactory();
237 $passwordFactory->init( RequestContext
::getMain()->getConfig() );
238 // A is unsalted MD5 (thus fast) ... we don't care about security here, this is test only
239 $passwordHash = $passwordFactory->newFromPlaintext( $password );
241 $dbw = wfGetDB( DB_MASTER
);
245 'bp_user' => $centralId,
246 'bp_app_id' => 'foo',
247 'bp_password' => $passwordHash->toString(),
249 'bp_restrictions' => MWRestrictions
::newDefault()->toJson(),
250 'bp_grants' => '["test"]',
255 $lgName = $user->getUser()->getName() . BotPassword
::getSeparator() . 'foo';
257 $ret = $this->doApiRequest( [
260 'lgpassword' => $password,
264 $this->assertNotInternalType( 'bool', $result );
265 $this->assertNotInternalType( 'null', $result['login'] );
267 $a = $result['login']['result'];
268 $this->assertEquals( 'NeedToken', $a );
269 $token = $result['login']['token'];
271 $ret = $this->doApiRequest( [
275 'lgpassword' => $password,
279 $this->assertNotInternalType( 'bool', $result );
280 $a = $result['login']['result'];
282 $this->assertEquals( 'Success', $a );