Why: * The default value of wgAutoCreateTempUser has not changed since the decision to use a different prefix for temporary accounts (T332805). * The default needs to be updated to reduce the number of overrides in operations/mediawiki-config and also to make the development experience more consistent with what is happening on WMF production. What: * Update the wgAutoCreateTempUser default in the following ways: ** Set expireAfterDays as 365 ** Set notifyBeforeExpirationDays as 10 ** Set genPattern and reservedPattern to '~$1' ** Set matchPattern to null, which will mean that the genPattern is used as the value. * Update RealTempUserConfig::getPlaceholderName to add the year to the placeholder name so that if the match pattern includes the first digit of the year, then the placeholder name still is considered a valid temporary account username. * Replace modifications of the wgAutoCreateTempUser config in integration tests with a use of the TempUserTestTrait to make the code cleaner and make it easier to find tests that relies on the values in wgAutoCreateTempUser. * Update multiple tests to handle the new defaults for the config. Bug: T359335 Change-Id: Ifa5a0123cd915bdb7c87e473c51fb93321622f12
284 lines
7.8 KiB
PHP
284 lines
7.8 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Tests\Integration\User\TempUser;
|
|
|
|
use MediaWiki\Permissions\SimpleAuthority;
|
|
use MediaWiki\Tests\MockDatabase;
|
|
use MediaWiki\Tests\User\TempUser\TempUserTestTrait;
|
|
use MediaWiki\User\TempUser\Pattern;
|
|
use MediaWiki\User\UserIdentityValue;
|
|
use Wikimedia\Rdbms\IExpression;
|
|
use Wikimedia\TestingAccessWrapper;
|
|
use Wikimedia\Timestamp\ConvertibleTimestamp;
|
|
|
|
/**
|
|
* @covers \MediaWiki\User\TempUser\RealTempUserConfig
|
|
* @group Database
|
|
*/
|
|
class RealTempUserConfigTest extends \MediaWikiIntegrationTestCase {
|
|
|
|
use TempUserTestTrait;
|
|
|
|
public static function provideIsAutoCreateAction() {
|
|
return [
|
|
'disabled' => [
|
|
'enabled' => false,
|
|
'configOverrides' => [],
|
|
'action' => 'edit',
|
|
'expected' => false
|
|
],
|
|
'disabled by action' => [
|
|
'enabled' => true,
|
|
'configOverrides' => [ 'actions' => [] ],
|
|
'action' => 'edit',
|
|
'expected' => false
|
|
],
|
|
'enabled' => [
|
|
'enabled' => true,
|
|
'configOverrides' => [],
|
|
'action' => 'edit',
|
|
'expected' => true
|
|
],
|
|
// Create isn't an action in the ActionFactory sense, but is is an
|
|
// action in PermissionManager
|
|
'create' => [
|
|
'enabled' => true,
|
|
'configOverrides' => [],
|
|
'action' => 'create',
|
|
'expected' => true
|
|
],
|
|
'unknown action' => [
|
|
'enabled' => true,
|
|
'configOverrides' => [],
|
|
'action' => 'foo',
|
|
'expected' => false
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider provideIsAutoCreateAction
|
|
* @param bool $enabled
|
|
* @param array $configOverrides
|
|
* @param string $action
|
|
* @param bool $expected
|
|
*/
|
|
public function testIsAutoCreateAction( $enabled, $configOverrides, $action, $expected ) {
|
|
if ( $enabled ) {
|
|
$this->enableAutoCreateTempUser( $configOverrides );
|
|
} else {
|
|
$this->disableAutoCreateTempUser( $configOverrides['reservedPattern'] ?? null );
|
|
}
|
|
$tuc = $this->getServiceContainer()->getTempUserConfig();
|
|
$this->assertSame( $expected, $tuc->isAutoCreateAction( $action ) );
|
|
}
|
|
|
|
public static function provideShouldAutoCreate() {
|
|
return [
|
|
'enabled' => [
|
|
'enabled' => true,
|
|
'id' => 0,
|
|
'rights' => [ 'createaccount' ],
|
|
'action' => 'edit',
|
|
'expected' => true
|
|
],
|
|
'disabled by config' => [
|
|
'enabled' => false,
|
|
'id' => 0,
|
|
'rights' => [ 'createaccount' ],
|
|
'action' => 'edit',
|
|
'expected' => false
|
|
],
|
|
'logged in' => [
|
|
'enabled' => true,
|
|
'id' => 1,
|
|
'rights' => [ 'createaccount' ],
|
|
'action' => 'edit',
|
|
'expected' => false
|
|
],
|
|
'no createaccount right' => [
|
|
'enabled' => true,
|
|
'id' => 0,
|
|
'rights' => [ 'edit' ],
|
|
'action' => 'edit',
|
|
'expected' => false
|
|
],
|
|
'wrong action' => [
|
|
'enabled' => true,
|
|
'id' => 0,
|
|
'rights' => [ 'createaccount' ],
|
|
'action' => 'upload',
|
|
'expected' => false
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider provideShouldAutoCreate
|
|
* @param bool $enabled
|
|
* @param int $id
|
|
* @param string[] $rights
|
|
* @param string $action
|
|
* @param bool $expected
|
|
*/
|
|
public function testShouldAutoCreate( $enabled, $id, $rights, $action, $expected ) {
|
|
if ( $enabled ) {
|
|
$this->enableAutoCreateTempUser();
|
|
} else {
|
|
$this->disableAutoCreateTempUser();
|
|
}
|
|
$tuc = $this->getServiceContainer()->getTempUserConfig();
|
|
$user = new SimpleAuthority(
|
|
new UserIdentityValue( $id, $id ? 'Test' : '127.0.0.1' ),
|
|
$rights
|
|
);
|
|
$this->assertSame( $expected, $tuc->shouldAutoCreate( $user, $action ) );
|
|
}
|
|
|
|
public static function provideIsTempName() {
|
|
return [
|
|
'disabled' => [
|
|
'enabled' => false,
|
|
'name' => '~Some user',
|
|
'expected' => false,
|
|
],
|
|
'default mismatch' => [
|
|
'enabled' => true,
|
|
'name' => 'Test',
|
|
'expected' => false,
|
|
],
|
|
'default match' => [
|
|
'enabled' => true,
|
|
'name' => '~Some user',
|
|
'expected' => true,
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider provideIsTempName
|
|
* @param bool $enabled
|
|
* @param string $name
|
|
* @param bool $expected
|
|
*/
|
|
public function testIsTempName( $enabled, $name, $expected ) {
|
|
if ( $enabled ) {
|
|
$this->enableAutoCreateTempUser();
|
|
} else {
|
|
$this->disableAutoCreateTempUser();
|
|
}
|
|
$tuc = $this->getServiceContainer()->getTempUserConfig();
|
|
$this->assertSame( $expected, $tuc->isTempName( $name ) );
|
|
}
|
|
|
|
/** @dataProvider provideGetPlaceholderName */
|
|
public function testGetPlaceholderName( $useYear, $expected ) {
|
|
$this->enableAutoCreateTempUser( [ 'serialProvider' => [ 'type' => 'local', 'useYear' => $useYear ] ] );
|
|
ConvertibleTimestamp::setFakeTime( '20210101000000' );
|
|
$this->assertSame( $expected, $this->getServiceContainer()->getTempUserConfig()->getPlaceholderName() );
|
|
}
|
|
|
|
public static function provideGetPlaceholderName() {
|
|
return [
|
|
'no year' => [ false, '~*' ],
|
|
'with year' => [ true, '~2021-*' ],
|
|
];
|
|
}
|
|
|
|
public static function provideIsReservedName() {
|
|
return [
|
|
'no matchPattern when disabled' => [
|
|
'enabled' => false,
|
|
'configOverrides' => [],
|
|
'name' => '~39',
|
|
'expected' => false,
|
|
],
|
|
'matchPattern match' => [
|
|
'enabled' => true,
|
|
'configOverrides' => [],
|
|
'name' => '~39',
|
|
'expected' => true,
|
|
],
|
|
'genPattern match' => [
|
|
'enabled' => true,
|
|
'configOverrides' => [ 'matchPattern' => null ],
|
|
'name' => '~39',
|
|
'expected' => true,
|
|
],
|
|
'reservedPattern match with enabled=false' => [
|
|
'enabled' => false,
|
|
'configOverrides' => [ 'reservedPattern' => '~$1' ],
|
|
'name' => '~Foo*',
|
|
'expected' => true
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider provideIsReservedName
|
|
* @param bool $enabled
|
|
* @param array $configOverrides
|
|
* @param string $name
|
|
* @param bool $expected
|
|
*/
|
|
public function testIsReservedName( $enabled, $configOverrides, $name, $expected ) {
|
|
if ( $enabled ) {
|
|
$this->enableAutoCreateTempUser( $configOverrides );
|
|
} else {
|
|
$this->disableAutoCreateTempUser( $configOverrides['reservedPattern'] ?? null );
|
|
}
|
|
$tuc = $this->getServiceContainer()->getTempUserConfig();
|
|
$this->assertSame( $expected, $tuc->isReservedName( $name ) );
|
|
}
|
|
|
|
public function testGetMatchPatterns() {
|
|
$this->enableAutoCreateTempUser( [ 'matchPattern' => [ '*$1', '~$1' ] ] );
|
|
$tuc = $this->getServiceContainer()->getTempUserConfig();
|
|
$this->assertCount( 2, $tuc->getMatchPatterns() );
|
|
$actualPatterns = array_map( static function ( Pattern $pattern ) {
|
|
return TestingAccessWrapper::newFromObject( $pattern )->pattern;
|
|
}, $tuc->getMatchPatterns() );
|
|
$this->assertArrayEquals( [ '*$1', '~$1' ], $actualPatterns );
|
|
}
|
|
|
|
public function testGetMatchPattern() {
|
|
$this->hideDeprecated( 'MediaWiki\User\TempUser\RealTempUserConfig::getMatchPattern' );
|
|
$this->enableAutoCreateTempUser( [ 'matchPattern' => [ '*$1', '~$1' ] ] );
|
|
$tuc = $this->getServiceContainer()->getTempUserConfig();
|
|
$this->assertSame( '*$1', TestingAccessWrapper::newFromObject( $tuc->getMatchPattern() )->pattern );
|
|
}
|
|
|
|
public function testGetMatchCondition() {
|
|
$db = new MockDatabase;
|
|
|
|
$this->enableAutoCreateTempUser( [ 'matchPattern' => [ '*$1', '~$1' ] ] );
|
|
$tuc = $this->getServiceContainer()->getTempUserConfig();
|
|
|
|
$this->assertEquals(
|
|
"(foo LIKE '*%' ESCAPE '`' OR foo LIKE '~%' ESCAPE '`')",
|
|
$tuc->getMatchCondition( $db, 'foo', IExpression::LIKE )->toSql( $db ),
|
|
'LIKE allows any of the patterns'
|
|
);
|
|
|
|
$this->assertEquals(
|
|
"(foo NOT LIKE '*%' ESCAPE '`' AND foo NOT LIKE '~%' ESCAPE '`')",
|
|
$tuc->getMatchCondition( $db, 'foo', IExpression::NOT_LIKE )->toSql( $db ),
|
|
'NOT LIKE disallows all of the patterns'
|
|
);
|
|
|
|
$this->enableAutoCreateTempUser( [ 'matchPattern' => [ '*$1' ] ] );
|
|
$tuc = $this->getServiceContainer()->getTempUserConfig();
|
|
|
|
$this->assertEquals(
|
|
"foo LIKE '*%' ESCAPE '`'",
|
|
$tuc->getMatchCondition( $db, 'foo', IExpression::LIKE )->toSql( $db ),
|
|
'With a single pattern, parentheses are omitted'
|
|
);
|
|
|
|
$this->assertEquals(
|
|
"foo NOT LIKE '*%' ESCAPE '`'",
|
|
$tuc->getMatchCondition( $db, 'foo', IExpression::NOT_LIKE )->toSql( $db ),
|
|
'With a single pattern, parentheses are omitted'
|
|
);
|
|
}
|
|
}
|