Expose automatic temporary user info in the API

action=query&prop=info&intestactions=...:
  Add &intestactionsautocreate=1 to also check whether the actions
  would result in a creation of a temporary user account.

action=query&meta=siteinfo:
  Add &siprop=autocreatetempuser to output the configuration
  of temporary user accounts.

Bug: T335532
Change-Id: I62b4bb630decac92cbb8c7ddf00307df0dadb516
This commit is contained in:
Bartosz Dziewoński 2023-04-27 21:22:02 +02:00
parent b9fdedcc39
commit 77927cc2fa
7 changed files with 166 additions and 1 deletions

View file

@ -114,6 +114,7 @@ class ApiQuery extends ApiBase {
'LanguageConverterFactory',
'RestrictionStore',
'LinksMigration',
'TempUserCreator',
],
],
'links' => [

View file

@ -29,6 +29,7 @@ use MediaWiki\Permissions\PermissionStatus;
use MediaWiki\Permissions\RestrictionStore;
use MediaWiki\Title\Title;
use MediaWiki\Title\TitleFactory;
use MediaWiki\User\TempUser\TempUserCreator;
use Wikimedia\ParamValidator\ParamValidator;
use Wikimedia\ParamValidator\TypeDef\EnumDef;
@ -55,6 +56,8 @@ class ApiQueryInfo extends ApiQueryBase {
private $restrictionStore;
/** @var LinksMigration */
private $linksMigration;
/** @var TempUserCreator */
private $tempUserCreator;
private $fld_protection = false, $fld_talkid = false,
$fld_subjectid = false, $fld_url = false,
@ -117,6 +120,7 @@ class ApiQueryInfo extends ApiQueryBase {
* @param LanguageConverterFactory $languageConverterFactory
* @param RestrictionStore $restrictionStore
* @param LinksMigration $linksMigration
* @param TempUserCreator $tempUserCreator
*/
public function __construct(
ApiQuery $queryModule,
@ -129,7 +133,8 @@ class ApiQueryInfo extends ApiQueryBase {
WatchedItemStore $watchedItemStore,
LanguageConverterFactory $languageConverterFactory,
RestrictionStore $restrictionStore,
LinksMigration $linksMigration
LinksMigration $linksMigration,
TempUserCreator $tempUserCreator
) {
parent::__construct( $queryModule, $moduleName, 'in' );
$this->languageConverter = $languageConverterFactory->getLanguageConverter( $contentLanguage );
@ -140,6 +145,7 @@ class ApiQueryInfo extends ApiQueryBase {
$this->watchedItemStore = $watchedItemStore;
$this->restrictionStore = $restrictionStore;
$this->linksMigration = $linksMigration;
$this->tempUserCreator = $tempUserCreator;
}
/**
@ -428,6 +434,17 @@ class ApiQueryInfo extends ApiQueryBase {
$pageInfo['actions'][$action] = $errorFormatter->arrayFromStatus( $status );
}
}
if ( $this->params['testactionsautocreate'] ) {
$pageInfo['wouldautocreate'] = [];
foreach ( $this->params['testactions'] as $action ) {
// Copied from EditPage::maybeActivateTempUserCreate
$pageInfo['wouldautocreate'][$action] =
!$this->getUser()->isRegistered()
&& $this->tempUserCreator->isAutoCreateAction( $action )
&& $this->getAuthority()->isAllowed( 'createaccount' );
}
}
}
return $pageInfo;
@ -880,6 +897,7 @@ class ApiQueryInfo extends ApiQueryBase {
ParamValidator::PARAM_DEFAULT => 'boolean',
ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
],
'testactionsautocreate' => false,
'continue' => [
ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
],

View file

@ -172,6 +172,9 @@ class ApiQuerySiteinfo extends ApiQueryBase {
case 'usergroups':
$fit = $this->appendUserGroups( $p, $params['numberingroup'] );
break;
case 'autocreatetempuser':
$fit = $this->appendAutoCreateTempUser( $p );
break;
case 'libraries':
$fit = $this->appendInstalledLibraries( $p );
break;
@ -678,6 +681,25 @@ class ApiQuerySiteinfo extends ApiQueryBase {
return $result->addValue( 'query', $property, $data );
}
protected function appendAutoCreateTempUser( $property ) {
$config = $this->getConfig()->get( MainConfigNames::AutoCreateTempUser );
$data = [ 'enabled' => false ];
if ( $config['enabled'] ?? false ) {
$data['enabled'] = true;
$data['actions'] = $config['actions'];
$data['genPattern'] = $config['genPattern'];
$data['matchPattern'] = $config['matchPattern'] ?? $data['genPattern'];
$data['serialProvider'] = $config['serialProvider'];
$data['serialMapping'] = $config['serialMapping'];
}
if ( isset( $config['reservedPattern'] ) ) {
$data['reservedPattern'] = $config['reservedPattern'];
}
return $this->getResult()->addValue( 'query', $property, $data );
}
protected function appendFileExtensions( $property ) {
$data = [];
foreach (
@ -1034,6 +1056,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
'dbrepllag',
'statistics',
'usergroups',
'autocreatetempuser',
'libraries',
'extensions',
'fileextensions',

View file

@ -954,6 +954,7 @@
"apihelp-query+info-paramvalue-testactionsdetail-boolean": "Return a boolean value for each action.",
"apihelp-query+info-paramvalue-testactionsdetail-full": "Return messages describing why the action is disallowed, or an empty array if it is allowed.",
"apihelp-query+info-paramvalue-testactionsdetail-quick": "Like <kbd>full</kbd> but skipping expensive checks.",
"apihelp-query+info-param-testactionsautocreate": "Test whether performing <var>$1testactions</var> would automatically create a temporary account.",
"apihelp-query+info-example-simple": "Get information about the page <kbd>Main Page</kbd>.",
"apihelp-query+info-example-protection": "Get general and protection information about the page <kbd>Main Page</kbd>.",
@ -1254,6 +1255,7 @@
"apihelp-query+siteinfo-paramvalue-prop-interwikimap": "Returns interwiki map (optionally filtered, optionally localised by using <var>$1inlanguagecode</var>).",
"apihelp-query+siteinfo-paramvalue-prop-dbrepllag": "Returns database server with the highest replication lag.",
"apihelp-query+siteinfo-paramvalue-prop-usergroups": "Returns user groups and the associated permissions.",
"apihelp-query+siteinfo-paramvalue-prop-autocreatetempuser": "Returns configuration for the automatic creation of temporary user accounts (also known as IP masking).",
"apihelp-query+siteinfo-paramvalue-prop-libraries": "Returns libraries installed on the wiki.",
"apihelp-query+siteinfo-paramvalue-prop-extensions": "Returns extensions installed on the wiki.",
"apihelp-query+siteinfo-paramvalue-prop-fileextensions": "Returns list of file extensions (file types) allowed to be uploaded.",

View file

@ -904,6 +904,7 @@
"apihelp-query+info-paramvalue-testactionsdetail-boolean": "{{doc-apihelp-paramvalue|query+info|testactionsdetail|boolean}}",
"apihelp-query+info-paramvalue-testactionsdetail-full": "{{doc-apihelp-paramvalue|query+info|testactionsdetail|full}}",
"apihelp-query+info-paramvalue-testactionsdetail-quick": "{{doc-apihelp-paramvalue|query+info|testactionsdetail|quick}}",
"apihelp-query+info-param-testactionsautocreate": "{{doc-apihelp-param|query+info|testactionsautocreate}}",
"apihelp-query+info-example-simple": "{{doc-apihelp-example|query+info}}",
"apihelp-query+info-example-protection": "{{doc-apihelp-example|query+info}}",
"apihelp-query+iwbacklinks-summary": "{{doc-apihelp-summary|query+iwbacklinks}}",
@ -1183,6 +1184,7 @@
"apihelp-query+siteinfo-paramvalue-prop-interwikimap": "{{doc-apihelp-paramvalue|query+siteinfo|prop|interwikimap}}",
"apihelp-query+siteinfo-paramvalue-prop-dbrepllag": "{{doc-apihelp-paramvalue|query+siteinfo|prop|dbrepllag}}",
"apihelp-query+siteinfo-paramvalue-prop-usergroups": "{{doc-apihelp-paramvalue|query+siteinfo|prop|usergroups}}",
"apihelp-query+siteinfo-paramvalue-prop-autocreatetempuser": "{{doc-apihelp-paramvalue|query+siteinfo|prop|autocreatetempuser}}",
"apihelp-query+siteinfo-paramvalue-prop-libraries": "{{doc-apihelp-paramvalue|query+siteinfo|prop|libraries}}",
"apihelp-query+siteinfo-paramvalue-prop-extensions": "{{doc-apihelp-paramvalue|query+siteinfo|prop|extensions}}",
"apihelp-query+siteinfo-paramvalue-prop-fileextensions": "{{doc-apihelp-paramvalue|query+siteinfo|prop|fileextensions}}",

View file

@ -126,6 +126,92 @@ class ApiQueryInfoTest extends ApiTestCase {
$this->assertTrue( $info['actions']['edit'] );
}
/**
* @covers ::execute
* @covers ::extractPageInfo
*/
public function testExecuteEditActionsAutoCreate() {
$page = $this->getExistingTestPage( 'Pluto' );
$title = $page->getTitle();
// Disabled
$this->overrideConfigValue( MainConfigNames::AutoCreateTempUser, [
'enabled' => false,
] );
[ $data ] = $this->doApiRequest( [
'action' => 'query',
'prop' => 'info',
'titles' => $title->getText(),
'intestactions' => 'edit',
'intestactionsautocreate' => true,
], null, false, new User() );
$result = $data['query']['pages'][$page->getId()]['wouldautocreate']['edit'];
$this->assertFalse( $result );
// Enabled
$this->setGroupPermissions( '*', 'createaccount', true );
$this->overrideConfigValue( MainConfigNames::AutoCreateTempUser, [
'enabled' => true,
'actions' => [ 'edit' ],
'genPattern' => 'Unregistered $1',
'serialProvider' => [],
'serialMapping' => [],
] );
[ $data ] = $this->doApiRequest( [
'action' => 'query',
'prop' => 'info',
'titles' => $title->getText(),
'intestactions' => 'edit',
'intestactionsautocreate' => true,
], null, false, new User() );
$result = $data['query']['pages'][$page->getId()]['wouldautocreate']['edit'];
$this->assertTrue( $result );
[ $data ] = $this->doApiRequest( [
'action' => 'query',
'prop' => 'info',
'titles' => $title->getText(),
'intestactions' => 'create',
'intestactionsautocreate' => true,
], null, false, new User() );
$result = $data['query']['pages'][$page->getId()]['wouldautocreate']['create'];
$this->assertTrue( $result );
// Enabled - 'read' is not an autocreate action
[ $data ] = $this->doApiRequest( [
'action' => 'query',
'prop' => 'info',
'titles' => $title->getText(),
'intestactions' => 'read',
'intestactionsautocreate' => true,
], null, false, new User() );
$result = $data['query']['pages'][$page->getId()]['wouldautocreate']['read'];
$this->assertFalse( $result );
// Enabled - but the user is logged in
[ $data ] = $this->doApiRequest( [
'action' => 'query',
'prop' => 'info',
'titles' => $title->getText(),
'intestactions' => 'edit',
'intestactionsautocreate' => true,
], null, false, static::getTestSysop()->getAuthority() );
$result = $data['query']['pages'][$page->getId()]['wouldautocreate']['edit'];
$this->assertFalse( $result );
// Enabled - but the user isn't allowed to create accounts
$this->setGroupPermissions( '*', 'createaccount', false );
[ $data ] = $this->doApiRequest( [
'action' => 'query',
'prop' => 'info',
'titles' => $title->getText(),
'intestactions' => 'edit',
'intestactionsautocreate' => true,
], null, false, new User() );
$result = $data['query']['pages'][$page->getId()]['wouldautocreate']['edit'];
$this->assertFalse( $result );
}
/**
* @covers ::execute
* @covers ::extractPageInfo

View file

@ -365,6 +365,39 @@ class ApiQuerySiteinfoTest extends ApiTestCase {
}
}
public function testAutoCreateTempUser() {
$config = $expected = [ 'enabled' => false ];
$this->overrideConfigValue( MainConfigNames::AutoCreateTempUser, $config );
$this->assertSame(
$expected,
$this->doQuery( 'autocreatetempuser' ),
'When disabled, no other properties are present'
);
$config = [
'enabled' => true,
'actions' => [ 'edit' ],
'genPattern' => 'Unregistered $1',
'reservedPattern' => null,
'serialProvider' => [ 'type' => 'local' ],
'serialMapping' => [ 'type' => 'plain-numeric' ],
];
$expected = [
'enabled' => true,
'actions' => [ 'edit' ],
'genPattern' => 'Unregistered $1',
'matchPattern' => 'Unregistered $1',
'serialProvider' => [ 'type' => 'local' ],
'serialMapping' => [ 'type' => 'plain-numeric' ],
];
$this->overrideConfigValue( MainConfigNames::AutoCreateTempUser, $config );
$this->assertSame(
$expected,
$this->doQuery( 'autocreatetempuser' ),
'When enabled, some properties are filled in or cleaned up'
);
}
public function testFileExtensions() {
// Add duplicate
$this->overrideConfigValue( MainConfigNames::FileExtensions, [ 'png', 'gif', 'jpg', 'png' ] );