10 class ApiLoginTest
extends ApiTestCase
{
13 * Test result of attempted login with an empty username
15 public function testApiLoginNoName() {
16 global $wgDisableAuthManager;
19 'wsTokenSecrets' => [ 'login' => 'foobar' ],
21 $data = $this->doApiRequest( [ 'action' => 'login',
22 'lgname' => '', 'lgpassword' => self
::$users['sysop']->password
,
23 'lgtoken' => (string)( new MediaWiki\Session\
Token( 'foobar', '' ) )
25 $this->assertEquals( $wgDisableAuthManager ?
'NoName' : 'Failed', $data[0]['login']['result'] );
28 public function testApiLoginBadPass() {
29 global $wgServer, $wgDisableAuthManager;
31 $user = self
::$users['sysop'];
32 $user->getUser()->logout();
34 if ( !isset( $wgServer ) ) {
35 $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' );
37 $ret = $this->doApiRequest( [
39 "lgname" => $user->username
,
40 "lgpassword" => "bad",
45 $this->assertNotInternalType( "bool", $result );
46 $a = $result["login"]["result"];
47 $this->assertEquals( "NeedToken", $a );
49 $token = $result["login"]["token"];
51 $ret = $this->doApiRequest(
55 "lgname" => $user->username
,
56 "lgpassword" => "badnowayinhell",
63 $this->assertNotInternalType( "bool", $result );
64 $a = $result["login"]["result"];
66 $this->assertEquals( $wgDisableAuthManager ?
'WrongPass' : 'Failed', $a );
69 public function testApiLoginGoodPass() {
72 if ( !isset( $wgServer ) ) {
73 $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' );
76 $user = self
::$users['sysop'];
77 $user->getUser()->logout();
79 $ret = $this->doApiRequest( [
81 "lgname" => $user->username
,
82 "lgpassword" => $user->password
,
87 $this->assertNotInternalType( "bool", $result );
88 $this->assertNotInternalType( "null", $result["login"] );
90 $a = $result["login"]["result"];
91 $this->assertEquals( "NeedToken", $a );
92 $token = $result["login"]["token"];
94 $ret = $this->doApiRequest(
98 "lgname" => $user->username
,
99 "lgpassword" => $user->password
,
106 $this->assertNotInternalType( "bool", $result );
107 $a = $result["login"]["result"];
109 $this->assertEquals( "Success", $a );
115 public function testApiLoginGotCookie() {
116 $this->markTestIncomplete( "The server can't do external HTTP requests, "
117 . "and the internal one won't give cookies" );
119 global $wgServer, $wgScriptPath;
121 if ( !isset( $wgServer ) ) {
122 $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' );
124 $user = self
::$users['sysop'];
126 $req = MWHttpRequest
::factory( self
::$apiUrl . "?action=login&format=xml",
127 [ "method" => "POST",
129 "lgname" => $user->username
,
130 "lgpassword" => $user->password
137 libxml_use_internal_errors( true );
138 $sxe = simplexml_load_string( $req->getContent() );
139 $this->assertNotInternalType( "bool", $sxe );
140 $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) );
141 $this->assertNotInternalType( "null", $sxe->login
[0] );
143 $a = $sxe->login
[0]->attributes()->result
[0];
144 $this->assertEquals( ' result="NeedToken"', $a->asXML() );
145 $token = (string)$sxe->login
[0]->attributes()->token
;
149 "lgname" => $user->username
,
150 "lgpassword" => $user->password
] );
153 $cj = $req->getCookieJar();
154 $serverName = parse_url( $wgServer, PHP_URL_HOST
);
155 $this->assertNotEquals( false, $serverName );
156 $serializedCookie = $cj->serializeToHttpRequest( $wgScriptPath, $serverName );
157 $this->assertNotEquals( '', $serializedCookie );
159 '/_session=[^;]*; .*UserID=[0-9]*; .*UserName=' . $user->userName
. '; .*Token=/',
164 public function testRunLogin() {
165 $sysopUser = self
::$users['sysop'];
166 $data = $this->doApiRequest( [
168 'lgname' => $sysopUser->username
,
169 'lgpassword' => $sysopUser->password
] );
171 $this->assertArrayHasKey( "login", $data[0] );
172 $this->assertArrayHasKey( "result", $data[0]['login'] );
173 $this->assertEquals( "NeedToken", $data[0]['login']['result'] );
174 $token = $data[0]['login']['token'];
176 $data = $this->doApiRequest( [
179 "lgname" => $sysopUser->username
,
180 "lgpassword" => $sysopUser->password
], $data[2] );
182 $this->assertArrayHasKey( "login", $data[0] );
183 $this->assertArrayHasKey( "result", $data[0]['login'] );
184 $this->assertEquals( "Success", $data[0]['login']['result'] );
185 $this->assertArrayHasKey( 'lgtoken', $data[0]['login'] );
188 public function testBotPassword() {
189 global $wgServer, $wgSessionProviders;
191 if ( !isset( $wgServer ) ) {
192 $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' );
195 $this->setMwGlobals( [
196 'wgSessionProviders' => array_merge( $wgSessionProviders, [
198 'class' => MediaWiki\Session\BotPasswordSessionProvider
::class,
199 'args' => [ [ 'priority' => 40 ] ],
202 'wgEnableBotPasswords' => true,
203 'wgBotPasswordsDatabase' => false,
204 'wgCentralIdLookupProvider' => 'local',
205 'wgGrantPermissions' => [
206 'test' => [ 'read' => true ],
210 // Make sure our session provider is present
211 $manager = TestingAccessWrapper
::newFromObject( MediaWiki\Session\SessionManager
::singleton() );
212 if ( !isset( $manager->sessionProviders
[MediaWiki\Session\BotPasswordSessionProvider
::class] ) ) {
213 $tmp = $manager->sessionProviders
;
214 $manager->sessionProviders
= null;
215 $manager->sessionProviders
= $tmp +
$manager->getProviders();
217 $this->assertNotNull(
218 MediaWiki\Session\SessionManager
::singleton()->getProvider(
219 MediaWiki\Session\BotPasswordSessionProvider
::class
224 $user = self
::$users['sysop'];
225 $centralId = CentralIdLookup
::factory()->centralIdFromLocalUser( $user->getUser() );
226 $this->assertNotEquals( 0, $centralId, 'sanity check' );
228 $passwordFactory = new PasswordFactory();
229 $passwordFactory->init( RequestContext
::getMain()->getConfig() );
230 // A is unsalted MD5 (thus fast) ... we don't care about security here, this is test only
231 $passwordHash = $passwordFactory->newFromPlaintext( 'foobaz' );
233 $dbw = wfGetDB( DB_MASTER
);
237 'bp_user' => $centralId,
238 'bp_app_id' => 'foo',
239 'bp_password' => $passwordHash->toString(),
241 'bp_restrictions' => MWRestrictions
::newDefault()->toJson(),
242 'bp_grants' => '["test"]',
247 $lgName = $user->username
. BotPassword
::getSeparator() . 'foo';
249 $ret = $this->doApiRequest( [
252 'lgpassword' => 'foobaz',
256 $this->assertNotInternalType( 'bool', $result );
257 $this->assertNotInternalType( 'null', $result['login'] );
259 $a = $result['login']['result'];
260 $this->assertEquals( 'NeedToken', $a );
261 $token = $result['login']['token'];
263 $ret = $this->doApiRequest( [
267 'lgpassword' => 'foobaz',
271 $this->assertNotInternalType( 'bool', $result );
272 $a = $result['login']['result'];
274 $this->assertEquals( 'Success', $a );