2015-11-22 20:17:00 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace MediaWiki\Auth;
|
|
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
use FauxRequest;
|
2021-04-16 13:17:10 +00:00
|
|
|
use HashConfig;
|
2019-05-13 14:18:07 +00:00
|
|
|
use MediaWiki\Block\DatabaseBlock;
|
2021-05-13 16:02:38 +00:00
|
|
|
use MediaWiki\Tests\Unit\Auth\AuthenticationProviderTestTrait;
|
2022-08-27 05:10:13 +00:00
|
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
|
|
|
|
use User;
|
2017-04-19 19:37:35 +00:00
|
|
|
use Wikimedia\TestingAccessWrapper;
|
|
|
|
|
|
2015-11-22 20:17:00 +00:00
|
|
|
/**
|
|
|
|
|
* @group AuthManager
|
|
|
|
|
* @group Database
|
2018-11-01 11:48:52 +00:00
|
|
|
* @covers \MediaWiki\Auth\CheckBlocksSecondaryAuthenticationProvider
|
2015-11-22 20:17:00 +00:00
|
|
|
*/
|
2020-06-30 15:09:24 +00:00
|
|
|
class CheckBlocksSecondaryAuthenticationProviderTest extends \MediaWikiIntegrationTestCase {
|
2021-05-13 16:02:38 +00:00
|
|
|
use AuthenticationProviderTestTrait;
|
|
|
|
|
|
2015-11-22 20:17:00 +00:00
|
|
|
public function testConstructor() {
|
|
|
|
|
$provider = new CheckBlocksSecondaryAuthenticationProvider();
|
2017-04-19 19:37:35 +00:00
|
|
|
$providerPriv = TestingAccessWrapper::newFromObject( $provider );
|
2015-11-22 20:17:00 +00:00
|
|
|
$config = new \HashConfig( [
|
|
|
|
|
'BlockDisablesLogin' => false
|
|
|
|
|
] );
|
2021-05-13 16:02:38 +00:00
|
|
|
$this->initProvider( $provider, $config );
|
2015-11-22 20:17:00 +00:00
|
|
|
$this->assertSame( false, $providerPriv->blockDisablesLogin );
|
|
|
|
|
|
|
|
|
|
$provider = new CheckBlocksSecondaryAuthenticationProvider(
|
|
|
|
|
[ 'blockDisablesLogin' => true ]
|
|
|
|
|
);
|
2017-04-19 19:37:35 +00:00
|
|
|
$providerPriv = TestingAccessWrapper::newFromObject( $provider );
|
2015-11-22 20:17:00 +00:00
|
|
|
$config = new \HashConfig( [
|
|
|
|
|
'BlockDisablesLogin' => false
|
|
|
|
|
] );
|
2021-05-13 16:02:38 +00:00
|
|
|
$this->initProvider( $provider, $config );
|
2015-11-22 20:17:00 +00:00
|
|
|
$this->assertSame( true, $providerPriv->blockDisablesLogin );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testBasics() {
|
|
|
|
|
$provider = new CheckBlocksSecondaryAuthenticationProvider();
|
|
|
|
|
$user = \User::newFromName( 'UTSysop' );
|
|
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
|
AuthenticationResponse::newAbstain(),
|
|
|
|
|
$provider->beginSecondaryAccountCreation( $user, $user, [] )
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provideGetAuthenticationRequests
|
|
|
|
|
* @param string $action
|
|
|
|
|
* @param array $response
|
|
|
|
|
*/
|
|
|
|
|
public function testGetAuthenticationRequests( $action, $response ) {
|
|
|
|
|
$provider = new CheckBlocksSecondaryAuthenticationProvider();
|
|
|
|
|
|
|
|
|
|
$this->assertEquals( $response, $provider->getAuthenticationRequests( $action, [] ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function provideGetAuthenticationRequests() {
|
|
|
|
|
return [
|
|
|
|
|
[ AuthManager::ACTION_LOGIN, [] ],
|
|
|
|
|
[ AuthManager::ACTION_CREATE, [] ],
|
|
|
|
|
[ AuthManager::ACTION_LINK, [] ],
|
|
|
|
|
[ AuthManager::ACTION_CHANGE, [] ],
|
|
|
|
|
[ AuthManager::ACTION_REMOVE, [] ],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
/**
|
|
|
|
|
* @param array $blockOptions Options for DatabaseBlock
|
|
|
|
|
* @return User
|
|
|
|
|
*/
|
|
|
|
|
private function getBlockedUser( array $blockOptions ): User {
|
|
|
|
|
$user = $this->getMutableTestUser()->getUser();
|
|
|
|
|
$wrappedUser = TestingAccessWrapper::newFromObject( $user );
|
|
|
|
|
$block = new DatabaseBlock( $blockOptions + [
|
|
|
|
|
'address' => $user,
|
2021-06-02 09:44:38 +00:00
|
|
|
'by' => $this->getTestSysop()->getUser(),
|
2015-11-22 20:17:00 +00:00
|
|
|
'reason' => __METHOD__,
|
|
|
|
|
'expiry' => time() + 100500,
|
2022-08-27 05:10:13 +00:00
|
|
|
] );
|
|
|
|
|
$wrappedUser->mBlock = $block;
|
|
|
|
|
$wrappedUser->mBlockedby = $block->getByName();
|
|
|
|
|
$wrappedUser->mBlockreason = $block->getReason();
|
|
|
|
|
$wrappedUser->mHideName = false;
|
|
|
|
|
|
2015-11-22 20:17:00 +00:00
|
|
|
return $user;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
/**
|
|
|
|
|
* @param array $blockOptions Options for DatabaseBlock
|
|
|
|
|
* @return User
|
|
|
|
|
*/
|
|
|
|
|
private function getIpBlockedUser( array $blockOptions ) {
|
|
|
|
|
static $ip = 10;
|
|
|
|
|
return $this->getBlockedUser( [
|
|
|
|
|
'address' => '10.10.10.' . $ip++,
|
|
|
|
|
] + $blockOptions );
|
|
|
|
|
}
|
2015-11-22 20:17:00 +00:00
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
/**
|
|
|
|
|
* @param array $blockOptions Options for DatabaseBlock
|
|
|
|
|
* @return User
|
|
|
|
|
*/
|
|
|
|
|
private function getGloballyIpBlockedUser( array $blockOptions ) {
|
|
|
|
|
static $ip = 100;
|
|
|
|
|
$user = $this->getMutableTestUser()->getUser();
|
|
|
|
|
TestingAccessWrapper::newFromObject( $user )->mGlobalBlock = new DatabaseBlock( $blockOptions + [
|
|
|
|
|
'address' => '10.10.10.' . $ip++,
|
|
|
|
|
'by' => $this->getTestSysop()->getUser(),
|
|
|
|
|
'reason' => __METHOD__,
|
|
|
|
|
'expiry' => time() + 100500,
|
|
|
|
|
] );
|
|
|
|
|
return $user;
|
|
|
|
|
}
|
2015-11-22 20:17:00 +00:00
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
/**
|
|
|
|
|
* @param string $blockType One of 'user', 'ip', 'global-ip', 'none'
|
|
|
|
|
* @param array $blockOptions Options for DatabaseBlock
|
|
|
|
|
* @return User
|
|
|
|
|
*/
|
|
|
|
|
private function getAnyBlockedUser( string $blockType, array $blockOptions = [] ) {
|
|
|
|
|
if ( $blockType === 'user' ) {
|
|
|
|
|
$user = $this->getBlockedUser( $blockOptions );
|
|
|
|
|
} elseif ( $blockType === 'ip' ) {
|
|
|
|
|
$user = $this->getIpBlockedUser( $blockOptions );
|
|
|
|
|
} elseif ( $blockType === 'global-ip' ) {
|
|
|
|
|
$user = $this->getGloballyIpBlockedUser( $blockOptions );
|
|
|
|
|
} elseif ( $blockType === 'none' ) {
|
|
|
|
|
$user = $this->getTestUser()->getUser();
|
|
|
|
|
} else {
|
|
|
|
|
$this->fail( 'Invalid block type' );
|
|
|
|
|
}
|
|
|
|
|
return $user;
|
2015-11-22 20:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
/**
|
|
|
|
|
* @dataProvider provideBeginSecondaryAuthentication
|
|
|
|
|
*/
|
|
|
|
|
public function testBeginSecondaryAuthentication(
|
|
|
|
|
string $blockType,
|
|
|
|
|
array $blockOptions,
|
|
|
|
|
bool $blockDisablesLogin,
|
|
|
|
|
string $expectedResponseStatus
|
|
|
|
|
) {
|
|
|
|
|
/** @var AuthManager|MockObject $authManager */
|
|
|
|
|
$authManager = $this->createNoOpMock( AuthManager::class );
|
2015-11-22 20:17:00 +00:00
|
|
|
$provider = new CheckBlocksSecondaryAuthenticationProvider(
|
2022-08-27 05:10:13 +00:00
|
|
|
[ 'blockDisablesLogin' => $blockDisablesLogin ]
|
2015-11-22 20:17:00 +00:00
|
|
|
);
|
2022-08-27 05:10:13 +00:00
|
|
|
$this->initProvider( $provider, new HashConfig(), null, $authManager );
|
2021-04-16 13:17:10 +00:00
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
$user = $this->getAnyBlockedUser( $blockType, $blockOptions );
|
2015-11-22 20:17:00 +00:00
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
$response = $provider->beginSecondaryAuthentication( $user, [] );
|
|
|
|
|
$this->assertEquals( $expectedResponseStatus, $response->status );
|
|
|
|
|
}
|
2015-11-22 20:17:00 +00:00
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
public function provideBeginSecondaryAuthentication() {
|
|
|
|
|
// all blocks prevent login on $wgBlockDisablesLogin wikis; global blocks are not handled
|
|
|
|
|
return [
|
|
|
|
|
// block type (user/ip/global/none), block options, wgBlockDisablesLogin, expected response status
|
|
|
|
|
'block does not disable login' => [ 'user', [], false, AuthenticationResponse::ABSTAIN ],
|
|
|
|
|
'not blocked' => [ 'none', [], true, AuthenticationResponse::PASS ],
|
|
|
|
|
'partial block' => [ 'user', [ 'sitewide' => false ], true, AuthenticationResponse::FAIL ],
|
|
|
|
|
'ip block' => [ 'ip', [], true, AuthenticationResponse::FAIL ],
|
|
|
|
|
'block' => [ 'user', [], true, AuthenticationResponse::FAIL ],
|
|
|
|
|
'global block' => [ 'global-ip', [], true, AuthenticationResponse::PASS ],
|
|
|
|
|
];
|
|
|
|
|
}
|
2015-11-22 20:17:00 +00:00
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
/**
|
|
|
|
|
* @dataProvider provideTestUserForCreation
|
|
|
|
|
*/
|
|
|
|
|
public function testTestUserForCreation(
|
|
|
|
|
bool $autocreate,
|
|
|
|
|
string $blockType,
|
|
|
|
|
array $blockOptions,
|
|
|
|
|
bool $blockDisablesLogin,
|
|
|
|
|
bool $expectedStatus
|
|
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
/** @var AuthManager|MockObject $authManager */
|
|
|
|
|
$authManager = $this->createNoOpMock( AuthManager::class, [ 'getRequest' ] );
|
|
|
|
|
$authManager->method( 'getRequest' )->willReturn( new FauxRequest() );
|
|
|
|
|
$provider = new CheckBlocksSecondaryAuthenticationProvider(
|
|
|
|
|
[ 'blockDisablesLogin' => $blockDisablesLogin ]
|
2015-11-22 20:17:00 +00:00
|
|
|
);
|
2022-08-27 05:10:13 +00:00
|
|
|
$this->initProvider( $provider, new HashConfig(), null, $authManager );
|
2015-11-22 20:17:00 +00:00
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
$user = $this->getAnyBlockedUser( $blockType, $blockOptions );
|
2015-11-22 20:17:00 +00:00
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
$status = $provider->testUserForCreation( $user,
|
|
|
|
|
$autocreate ? AuthManager::AUTOCREATE_SOURCE_SESSION : false );
|
|
|
|
|
$this->assertSame( $expectedStatus, $status->isGood() );
|
2015-11-22 20:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
public function provideTestUserForCreation() {
|
|
|
|
|
// blocks with createAccount flag prevent account signup, other blocks are ignored
|
|
|
|
|
$signupTests = [
|
|
|
|
|
// block type (user/ip/global/none), block options, wgBlockDisablesLogin, expected status
|
|
|
|
|
'not blocked' => [ 'none', [], true, true ],
|
|
|
|
|
'blocked' => [ 'user', [], false, true ],
|
|
|
|
|
'createaccount-blocked' => [ 'user', [ 'createAccount' => true ], false, false ],
|
|
|
|
|
'blocked with wgBlockDisablesLogin' => [ 'user', [], true, true ],
|
|
|
|
|
'ip-blocked' => [ 'ip', [], false, true ],
|
|
|
|
|
'createaccount-ip-blocked' => [ 'ip', [ 'createAccount' => true ], false, false ],
|
|
|
|
|
'ip-blocked with wgBlockDisablesLogin' => [ 'ip', [], true, true ],
|
|
|
|
|
'partially blocked' => [ 'user', [ 'createAccount' => true, 'sitewide' => false ], true, false ],
|
|
|
|
|
'globally blocked' => [ 'global-ip', [], false, true ],
|
|
|
|
|
'globally blocked with wgBlockDisablesLogin' => [ 'global-ip', [], true, true ],
|
2015-11-22 20:17:00 +00:00
|
|
|
];
|
|
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
$autocreateTests = $signupTests;
|
2015-11-22 20:17:00 +00:00
|
|
|
|
2022-08-27 05:10:13 +00:00
|
|
|
foreach ( $signupTests as $name => $test ) {
|
|
|
|
|
// add autocreate parameter
|
|
|
|
|
yield 'signup, ' . $name => array_merge( [ false ], $test );
|
|
|
|
|
}
|
|
|
|
|
foreach ( $autocreateTests as $name => $test ) {
|
|
|
|
|
yield 'autocreate, ' . $name => array_merge( [ true ], $test );
|
|
|
|
|
}
|
2015-11-22 20:17:00 +00:00
|
|
|
}
|
2022-08-27 05:10:13 +00:00
|
|
|
|
2015-11-22 20:17:00 +00:00
|
|
|
}
|