From ddf37fec6d3e7c6a382dc94087e380864eac60d4 Mon Sep 17 00:00:00 2001 From: James Montalvo Date: Wed, 23 Jan 2019 14:14:37 -0600 Subject: [PATCH] Don't check anon permissions for maint scripts in autoCreateUser() AuthManager::autoCreateUser() causes createAndPromote.php to give error "Automatic account creation is not allowed." when $wgGroupPermissions['*']['createaccount']=false is set. Anonymous user checks should be skipped for maintenance scripts. Change-Id: Ib61889a758e542abe991707d8b7853a25cfed8e9 --- includes/auth/AuthManager.php | 4 ++- .../phpunit/includes/auth/AuthManagerTest.php | 33 +++++++++++++++---- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/includes/auth/AuthManager.php b/includes/auth/AuthManager.php index 9686555a41..f9174a78fc 100644 --- a/includes/auth/AuthManager.php +++ b/includes/auth/AuthManager.php @@ -1635,7 +1635,9 @@ class AuthManager implements LoggerAwareInterface { // Is the IP user able to create accounts? $anon = new User; - if ( !$anon->isAllowedAny( 'createaccount', 'autocreateaccount' ) ) { + if ( $source !== self::AUTOCREATE_SOURCE_MAINT && + !$anon->isAllowedAny( 'createaccount', 'autocreateaccount' ) + ) { $this->logger->debug( __METHOD__ . ': IP lacks the ability to create or autocreate accounts', [ 'username' => $username, 'ip' => $anon->getName(), diff --git a/tests/phpunit/includes/auth/AuthManagerTest.php b/tests/phpunit/includes/auth/AuthManagerTest.php index 564336e3b1..e8981ec24f 100644 --- a/tests/phpunit/includes/auth/AuthManagerTest.php +++ b/tests/phpunit/includes/auth/AuthManagerTest.php @@ -2361,6 +2361,7 @@ class AuthManagerTest extends \MediaWikiTestCase { $workaroundPHPUnitBug = false; $username = self::usernameForCreation(); + $expectedSource = AuthManager::AUTOCREATE_SOURCE_SESSION; $this->initializeManager(); $this->setGroupPermissions( '*', 'createaccount', true ); @@ -2380,14 +2381,20 @@ class AuthManagerTest extends \MediaWikiTestCase { } $good = StatusValue::newGood(); + $ok = StatusValue::newFatal( 'ok' ); $callback = $this->callback( function ( $user ) use ( &$username, &$workaroundPHPUnitBug ) { return $workaroundPHPUnitBug || $user->getName() === $username; } ); + $callback2 = $this->callback( + function ( $source ) use ( &$expectedSource, &$workaroundPHPUnitBug ) { + return $workaroundPHPUnitBug || $source === $expectedSource; + } + ); - $mocks['pre']->expects( $this->exactly( 12 ) )->method( 'testUserForCreation' ) - ->with( $callback, $this->identicalTo( AuthManager::AUTOCREATE_SOURCE_SESSION ) ) + $mocks['pre']->expects( $this->exactly( 13 ) )->method( 'testUserForCreation' ) + ->with( $callback, $callback2 ) ->will( $this->onConsecutiveCalls( - StatusValue::newFatal( 'ok' ), StatusValue::newFatal( 'ok' ), // For testing permissions + $ok, $ok, $ok, // For testing permissions StatusValue::newFatal( 'fail-in-pre' ), $good, $good, $good, // backoff test $good, // addToDatabase fails test @@ -2401,7 +2408,7 @@ class AuthManagerTest extends \MediaWikiTestCase { $mocks['primary']->expects( $this->any() )->method( 'testUserExists' ) ->will( $this->returnValue( true ) ); $mocks['primary']->expects( $this->exactly( 9 ) )->method( 'testUserForCreation' ) - ->with( $callback, $this->identicalTo( AuthManager::AUTOCREATE_SOURCE_SESSION ) ) + ->with( $callback, $callback2 ) ->will( $this->onConsecutiveCalls( StatusValue::newFatal( 'fail-in-primary' ), $good, $good, // backoff test @@ -2411,10 +2418,10 @@ class AuthManagerTest extends \MediaWikiTestCase { $good, $good, $good ) ); $mocks['primary']->expects( $this->exactly( 3 ) )->method( 'autoCreatedAccount' ) - ->with( $callback, $this->identicalTo( AuthManager::AUTOCREATE_SOURCE_SESSION ) ); + ->with( $callback, $callback2 ); $mocks['secondary']->expects( $this->exactly( 8 ) )->method( 'testUserForCreation' ) - ->with( $callback, $this->identicalTo( AuthManager::AUTOCREATE_SOURCE_SESSION ) ) + ->with( $callback, $callback2 ) ->will( $this->onConsecutiveCalls( StatusValue::newFatal( 'fail-in-secondary' ), $good, // backoff test @@ -2424,7 +2431,7 @@ class AuthManagerTest extends \MediaWikiTestCase { $good, $good, $good ) ); $mocks['secondary']->expects( $this->exactly( 3 ) )->method( 'autoCreatedAccount' ) - ->with( $callback, $this->identicalTo( AuthManager::AUTOCREATE_SOURCE_SESSION ) ); + ->with( $callback, $callback2 ); $this->preauthMocks = [ $mocks['pre'] ]; $this->primaryauthMocks = [ $mocks['primary'] ]; @@ -2564,8 +2571,20 @@ class AuthManagerTest extends \MediaWikiTestCase { 'authmanager-autocreate-noperm', $session->get( 'AuthManager::AutoCreateBlacklist' ) ); + // maintenance scripts always work + $expectedSource = AuthManager::AUTOCREATE_SOURCE_MAINT; + $this->setGroupPermissions( '*', 'createaccount', false ); + $this->setGroupPermissions( '*', 'autocreateaccount', false ); + $session->clear(); + $user = \User::newFromName( $username ); + $this->hook( 'LocalUserCreated', $this->never() ); + $ret = $this->manager->autoCreateUser( $user, AuthManager::AUTOCREATE_SOURCE_MAINT, true ); + $this->unhook( 'LocalUserCreated' ); + $this->assertEquals( \Status::newFatal( 'ok' ), $ret ); + // Test that both permutations of permissions are allowed // (this hits the two "ok" entries in $mocks['pre']) + $expectedSource = AuthManager::AUTOCREATE_SOURCE_SESSION; $this->setGroupPermissions( '*', 'createaccount', false ); $this->setGroupPermissions( '*', 'autocreateaccount', true ); $session->clear(); -- 2.20.1