]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blobdiff - tests/phpunit/includes/auth/ThrottlePreAuthenticationProviderTest.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / tests / phpunit / includes / auth / ThrottlePreAuthenticationProviderTest.php
diff --git a/tests/phpunit/includes/auth/ThrottlePreAuthenticationProviderTest.php b/tests/phpunit/includes/auth/ThrottlePreAuthenticationProviderTest.php
new file mode 100644 (file)
index 0000000..58982de
--- /dev/null
@@ -0,0 +1,236 @@
+<?php
+
+namespace MediaWiki\Auth;
+
+use Wikimedia\TestingAccessWrapper;
+
+/**
+ * @group AuthManager
+ * @group Database
+ * @covers MediaWiki\Auth\ThrottlePreAuthenticationProvider
+ */
+class ThrottlePreAuthenticationProviderTest extends \MediaWikiTestCase {
+       public function testConstructor() {
+               $provider = new ThrottlePreAuthenticationProvider();
+               $providerPriv = TestingAccessWrapper::newFromObject( $provider );
+               $config = new \HashConfig( [
+                       'AccountCreationThrottle' => [ [
+                               'count' => 123,
+                               'seconds' => 86400,
+                       ] ],
+                       'PasswordAttemptThrottle' => [ [
+                               'count' => 5,
+                               'seconds' => 300,
+                       ] ],
+               ] );
+               $provider->setConfig( $config );
+               $this->assertSame( [
+                       'accountCreationThrottle' => [ [ 'count' => 123, 'seconds' => 86400 ] ],
+                       'passwordAttemptThrottle' => [ [ 'count' => 5, 'seconds' => 300 ] ]
+               ], $providerPriv->throttleSettings );
+               $accountCreationThrottle = TestingAccessWrapper::newFromObject(
+                       $providerPriv->accountCreationThrottle );
+               $this->assertSame( [ [ 'count' => 123, 'seconds' => 86400 ] ],
+                       $accountCreationThrottle->conditions );
+               $passwordAttemptThrottle = TestingAccessWrapper::newFromObject(
+                       $providerPriv->passwordAttemptThrottle );
+               $this->assertSame( [ [ 'count' => 5, 'seconds' => 300 ] ],
+                       $passwordAttemptThrottle->conditions );
+
+               $provider = new ThrottlePreAuthenticationProvider( [
+                       'accountCreationThrottle' => [ [ 'count' => 43, 'seconds' => 10000 ] ],
+                       'passwordAttemptThrottle' => [ [ 'count' => 11, 'seconds' => 100 ] ],
+               ] );
+               $providerPriv = TestingAccessWrapper::newFromObject( $provider );
+               $config = new \HashConfig( [
+                       'AccountCreationThrottle' => [ [
+                               'count' => 123,
+                               'seconds' => 86400,
+                       ] ],
+                       'PasswordAttemptThrottle' => [ [
+                               'count' => 5,
+                               'seconds' => 300,
+                       ] ],
+               ] );
+               $provider->setConfig( $config );
+               $this->assertSame( [
+                       'accountCreationThrottle' => [ [ 'count' => 43, 'seconds' => 10000 ] ],
+                       'passwordAttemptThrottle' => [ [ 'count' => 11, 'seconds' => 100 ] ],
+               ], $providerPriv->throttleSettings );
+
+               $cache = new \HashBagOStuff();
+               $provider = new ThrottlePreAuthenticationProvider( [ 'cache' => $cache ] );
+               $providerPriv = TestingAccessWrapper::newFromObject( $provider );
+               $provider->setConfig( new \HashConfig( [
+                       'AccountCreationThrottle' => [ [ 'count' => 1, 'seconds' => 1 ] ],
+                       'PasswordAttemptThrottle' => [ [ 'count' => 1, 'seconds' => 1 ] ],
+               ] ) );
+               $accountCreationThrottle = TestingAccessWrapper::newFromObject(
+                       $providerPriv->accountCreationThrottle );
+               $this->assertSame( $cache, $accountCreationThrottle->cache );
+               $passwordAttemptThrottle = TestingAccessWrapper::newFromObject(
+                       $providerPriv->passwordAttemptThrottle );
+               $this->assertSame( $cache, $passwordAttemptThrottle->cache );
+       }
+
+       public function testDisabled() {
+               $provider = new ThrottlePreAuthenticationProvider( [
+                       'accountCreationThrottle' => [],
+                       'passwordAttemptThrottle' => [],
+                       'cache' => new \HashBagOStuff(),
+               ] );
+               $provider->setLogger( new \Psr\Log\NullLogger() );
+               $provider->setConfig( new \HashConfig( [
+                       'AccountCreationThrottle' => null,
+                       'PasswordAttemptThrottle' => null,
+               ] ) );
+               $provider->setManager( AuthManager::singleton() );
+
+               $this->assertEquals(
+                       \StatusValue::newGood(),
+                       $provider->testForAccountCreation(
+                               \User::newFromName( 'Created' ),
+                               \User::newFromName( 'Creator' ),
+                               []
+                       )
+               );
+               $this->assertEquals(
+                       \StatusValue::newGood(),
+                       $provider->testForAuthentication( [] )
+               );
+       }
+
+       /**
+        * @dataProvider provideTestForAccountCreation
+        * @param string $creatorname
+        * @param bool $succeed
+        * @param bool $hook
+        */
+       public function testTestForAccountCreation( $creatorname, $succeed, $hook ) {
+               $provider = new ThrottlePreAuthenticationProvider( [
+                       'accountCreationThrottle' => [ [ 'count' => 2, 'seconds' => 86400 ] ],
+                       'cache' => new \HashBagOStuff(),
+               ] );
+               $provider->setLogger( new \Psr\Log\NullLogger() );
+               $provider->setConfig( new \HashConfig( [
+                       'AccountCreationThrottle' => null,
+                       'PasswordAttemptThrottle' => null,
+               ] ) );
+               $provider->setManager( AuthManager::singleton() );
+
+               $user = \User::newFromName( 'RandomUser' );
+               $creator = \User::newFromName( $creatorname );
+               if ( $hook ) {
+                       $mock = $this->getMockBuilder( 'stdClass' )
+                               ->setMethods( [ 'onExemptFromAccountCreationThrottle' ] )
+                               ->getMock();
+                       $mock->expects( $this->any() )->method( 'onExemptFromAccountCreationThrottle' )
+                               ->will( $this->returnValue( false ) );
+                       $this->mergeMwGlobalArrayValue( 'wgHooks', [
+                               'ExemptFromAccountCreationThrottle' => [ $mock ],
+                       ] );
+               }
+
+               $this->assertEquals(
+                       true,
+                       $provider->testForAccountCreation( $user, $creator, [] )->isOK(),
+                       'attempt #1'
+               );
+               $this->assertEquals(
+                       true,
+                       $provider->testForAccountCreation( $user, $creator, [] )->isOK(),
+                       'attempt #2'
+               );
+               $this->assertEquals(
+                       $succeed ? true : false,
+                       $provider->testForAccountCreation( $user, $creator, [] )->isOK(),
+                       'attempt #3'
+               );
+       }
+
+       public static function provideTestForAccountCreation() {
+               return [
+                       'Normal user' => [ 'NormalUser', false, false ],
+                       'Sysop' => [ 'UTSysop', true, false ],
+                       'Normal user with hook' => [ 'NormalUser', true, true ],
+               ];
+       }
+
+       public function testTestForAuthentication() {
+               $provider = new ThrottlePreAuthenticationProvider( [
+                       'passwordAttemptThrottle' => [ [ 'count' => 2, 'seconds' => 86400 ] ],
+                       'cache' => new \HashBagOStuff(),
+               ] );
+               $provider->setLogger( new \Psr\Log\NullLogger() );
+               $provider->setConfig( new \HashConfig( [
+                       'AccountCreationThrottle' => null,
+                       'PasswordAttemptThrottle' => null,
+               ] ) );
+               $provider->setManager( AuthManager::singleton() );
+
+               $req = new UsernameAuthenticationRequest;
+               $req->username = 'SomeUser';
+               for ( $i = 1; $i <= 3; $i++ ) {
+                       $status = $provider->testForAuthentication( [ $req ] );
+                       $this->assertEquals( $i < 3, $status->isGood(), "attempt #$i" );
+               }
+               $this->assertCount( 1, $status->getErrors() );
+               $msg = new \Message( $status->getErrors()[0]['message'], $status->getErrors()[0]['params'] );
+               $this->assertEquals( 'login-throttled', $msg->getKey() );
+
+               $provider->postAuthentication( \User::newFromName( 'SomeUser' ),
+                       AuthenticationResponse::newFail( wfMessage( 'foo' ) ) );
+               $this->assertFalse( $provider->testForAuthentication( [ $req ] )->isGood(), 'after FAIL' );
+
+               $provider->postAuthentication( \User::newFromName( 'SomeUser' ),
+                       AuthenticationResponse::newPass() );
+               $this->assertTrue( $provider->testForAuthentication( [ $req ] )->isGood(), 'after PASS' );
+
+               $req1 = new UsernameAuthenticationRequest;
+               $req1->username = 'foo';
+               $req2 = new UsernameAuthenticationRequest;
+               $req2->username = 'bar';
+               $this->assertTrue( $provider->testForAuthentication( [ $req1, $req2 ] )->isGood() );
+
+               $req = new UsernameAuthenticationRequest;
+               $req->username = 'Some user';
+               $provider->testForAuthentication( [ $req ] );
+               $req->username = 'Some_user';
+               $provider->testForAuthentication( [ $req ] );
+               $req->username = 'some user';
+               $status = $provider->testForAuthentication( [ $req ] );
+               $this->assertFalse( $status->isGood(), 'denormalized usernames are normalized' );
+       }
+
+       public function testPostAuthentication() {
+               $provider = new ThrottlePreAuthenticationProvider( [
+                       'passwordAttemptThrottle' => [],
+                       'cache' => new \HashBagOStuff(),
+               ] );
+               $provider->setLogger( new \TestLogger );
+               $provider->setConfig( new \HashConfig( [
+                       'AccountCreationThrottle' => null,
+                       'PasswordAttemptThrottle' => null,
+               ] ) );
+               $provider->setManager( AuthManager::singleton() );
+               $provider->postAuthentication( \User::newFromName( 'SomeUser' ),
+                       AuthenticationResponse::newPass() );
+
+               $provider = new ThrottlePreAuthenticationProvider( [
+                       'passwordAttemptThrottle' => [ [ 'count' => 2, 'seconds' => 86400 ] ],
+                       'cache' => new \HashBagOStuff(),
+               ] );
+               $logger = new \TestLogger( true );
+               $provider->setLogger( $logger );
+               $provider->setConfig( new \HashConfig( [
+                       'AccountCreationThrottle' => null,
+                       'PasswordAttemptThrottle' => null,
+               ] ) );
+               $provider->setManager( AuthManager::singleton() );
+               $provider->postAuthentication( \User::newFromName( 'SomeUser' ),
+                       AuthenticationResponse::newPass() );
+               $this->assertSame( [
+                       [ \Psr\Log\LogLevel::INFO, 'throttler data not found for {user}' ],
+               ], $logger->getBuffer() );
+       }
+}