10 class ApiLoginTest
extends ApiTestCase
{
13 * Test result of attempted login with an empty username
15 public function testApiLoginNoName() {
17 'wsTokenSecrets' => [ 'login' => 'foobar' ],
19 $data = $this->doApiRequest( [ 'action' => 'login',
20 'lgname' => '', 'lgpassword' => self
::$users['sysop']->getPassword(),
21 'lgtoken' => (string)( new MediaWiki\Session\
Token( 'foobar', '' ) )
23 $this->assertEquals( 'Failed', $data[0]['login']['result'] );
26 public function testApiLoginBadPass() {
29 $user = self
::$users['sysop'];
30 $userName = $user->getUser()->getName();
31 $user->getUser()->logout();
33 if ( !isset( $wgServer ) ) {
34 $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' );
36 $ret = $this->doApiRequest( [
38 "lgname" => $userName,
39 "lgpassword" => "bad",
44 $this->assertNotInternalType( "bool", $result );
45 $a = $result["login"]["result"];
46 $this->assertEquals( "NeedToken", $a );
48 $token = $result["login"]["token"];
50 $ret = $this->doApiRequest(
54 "lgname" => $userName,
55 "lgpassword" => "badnowayinhell",
62 $this->assertNotInternalType( "bool", $result );
63 $a = $result["login"]["result"];
65 $this->assertEquals( 'Failed', $a );
68 public function testApiLoginGoodPass() {
71 if ( !isset( $wgServer ) ) {
72 $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' );
75 $user = self
::$users['sysop'];
76 $userName = $user->getUser()->getName();
77 $password = $user->getPassword();
78 $user->getUser()->logout();
80 $ret = $this->doApiRequest( [
82 "lgname" => $userName,
83 "lgpassword" => $password,
88 $this->assertNotInternalType( "bool", $result );
89 $this->assertNotInternalType( "null", $result["login"] );
91 $a = $result["login"]["result"];
92 $this->assertEquals( "NeedToken", $a );
93 $token = $result["login"]["token"];
95 $ret = $this->doApiRequest(
99 "lgname" => $userName,
100 "lgpassword" => $password,
107 $this->assertNotInternalType( "bool", $result );
108 $a = $result["login"]["result"];
110 $this->assertEquals( "Success", $a );
116 public function testApiLoginGotCookie() {
117 $this->markTestIncomplete( "The server can't do external HTTP requests, "
118 . "and the internal one won't give cookies" );
120 global $wgServer, $wgScriptPath;
122 if ( !isset( $wgServer ) ) {
123 $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' );
125 $user = self
::$users['sysop'];
126 $userName = $user->getUser()->getName();
127 $password = $user->getPassword();
129 $req = MWHttpRequest
::factory( self
::$apiUrl . "?action=login&format=xml",
130 [ "method" => "POST",
132 "lgname" => $userName,
133 "lgpassword" => $password
140 libxml_use_internal_errors( true );
141 $sxe = simplexml_load_string( $req->getContent() );
142 $this->assertNotInternalType( "bool", $sxe );
143 $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) );
144 $this->assertNotInternalType( "null", $sxe->login
[0] );
146 $a = $sxe->login
[0]->attributes()->result
[0];
147 $this->assertEquals( ' result="NeedToken"', $a->asXML() );
148 $token = (string)$sxe->login
[0]->attributes()->token
;
152 "lgname" => $userName,
153 "lgpassword" => $password ] );
156 $cj = $req->getCookieJar();
157 $serverName = parse_url( $wgServer, PHP_URL_HOST
);
158 $this->assertNotEquals( false, $serverName );
159 $serializedCookie = $cj->serializeToHttpRequest( $wgScriptPath, $serverName );
160 $this->assertNotEquals( '', $serializedCookie );
162 '/_session=[^;]*; .*UserID=[0-9]*; .*UserName=' . $user->userName
. '; .*Token=/',
167 public function testRunLogin() {
168 $user = self
::$users['sysop'];
169 $userName = $user->getUser()->getName();
170 $password = $user->getPassword();
172 $data = $this->doApiRequest( [
174 'lgname' => $userName,
175 'lgpassword' => $password ] );
177 $this->assertArrayHasKey( "login", $data[0] );
178 $this->assertArrayHasKey( "result", $data[0]['login'] );
179 $this->assertEquals( "NeedToken", $data[0]['login']['result'] );
180 $token = $data[0]['login']['token'];
182 $data = $this->doApiRequest( [
185 "lgname" => $userName,
186 "lgpassword" => $password ], $data[2] );
188 $this->assertArrayHasKey( "login", $data[0] );
189 $this->assertArrayHasKey( "result", $data[0]['login'] );
190 $this->assertEquals( "Success", $data[0]['login']['result'] );
193 public function testBotPassword() {
194 global $wgServer, $wgSessionProviders;
196 if ( !isset( $wgServer ) ) {
197 $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' );
200 $this->setMwGlobals( [
201 'wgSessionProviders' => array_merge( $wgSessionProviders, [
203 'class' => MediaWiki\Session\BotPasswordSessionProvider
::class,
204 'args' => [ [ 'priority' => 40 ] ],
207 'wgEnableBotPasswords' => true,
208 'wgBotPasswordsDatabase' => false,
209 'wgCentralIdLookupProvider' => 'local',
210 'wgGrantPermissions' => [
211 'test' => [ 'read' => true ],
215 // Make sure our session provider is present
216 $manager = TestingAccessWrapper
::newFromObject( MediaWiki\Session\SessionManager
::singleton() );
217 if ( !isset( $manager->sessionProviders
[MediaWiki\Session\BotPasswordSessionProvider
::class] ) ) {
218 $tmp = $manager->sessionProviders
;
219 $manager->sessionProviders
= null;
220 $manager->sessionProviders
= $tmp +
$manager->getProviders();
222 $this->assertNotNull(
223 MediaWiki\Session\SessionManager
::singleton()->getProvider(
224 MediaWiki\Session\BotPasswordSessionProvider
::class
229 $user = self
::$users['sysop'];
230 $centralId = CentralIdLookup
::factory()->centralIdFromLocalUser( $user->getUser() );
231 $this->assertNotEquals( 0, $centralId, 'sanity check' );
233 $password = 'ngfhmjm64hv0854493hsj5nncjud2clk';
234 $passwordFactory = new PasswordFactory();
235 $passwordFactory->init( RequestContext
::getMain()->getConfig() );
236 // A is unsalted MD5 (thus fast) ... we don't care about security here, this is test only
237 $passwordHash = $passwordFactory->newFromPlaintext( $password );
239 $dbw = wfGetDB( DB_MASTER
);
243 'bp_user' => $centralId,
244 'bp_app_id' => 'foo',
245 'bp_password' => $passwordHash->toString(),
247 'bp_restrictions' => MWRestrictions
::newDefault()->toJson(),
248 'bp_grants' => '["test"]',
253 $lgName = $user->getUser()->getName() . BotPassword
::getSeparator() . 'foo';
255 $ret = $this->doApiRequest( [
258 'lgpassword' => $password,
262 $this->assertNotInternalType( 'bool', $result );
263 $this->assertNotInternalType( 'null', $result['login'] );
265 $a = $result['login']['result'];
266 $this->assertEquals( 'NeedToken', $a );
267 $token = $result['login']['token'];
269 $ret = $this->doApiRequest( [
273 'lgpassword' => $password,
277 $this->assertNotInternalType( 'bool', $result );
278 $a = $result['login']['result'];
280 $this->assertEquals( 'Success', $a );