2016-05-15 15:35:33 +00:00
|
|
|
<?php
|
|
|
|
|
2021-01-03 11:12:16 +00:00
|
|
|
namespace MediaWiki\Extension\AbuseFilter;
|
|
|
|
|
2016-05-15 15:35:33 +00:00
|
|
|
use MediaWiki\Auth\AbstractPreAuthenticationProvider;
|
2019-02-24 05:29:09 +00:00
|
|
|
use MediaWiki\Auth\AuthenticationRequest;
|
2022-04-09 15:07:45 +00:00
|
|
|
use MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGeneratorFactory;
|
2023-12-10 19:03:19 +00:00
|
|
|
use MediaWiki\SpecialPage\SpecialPage;
|
|
|
|
use MediaWiki\User\User;
|
2022-04-09 15:07:45 +00:00
|
|
|
use MediaWiki\User\UserFactory;
|
2021-01-03 11:12:16 +00:00
|
|
|
use StatusValue;
|
2024-10-19 19:55:40 +00:00
|
|
|
use Wikimedia\Stats\IBufferingStatsdDataFactory;
|
2016-05-15 15:35:33 +00:00
|
|
|
|
2022-04-09 15:07:45 +00:00
|
|
|
/**
|
|
|
|
* AuthenticationProvider used to filter account creations. This runs after normal preauth providers
|
|
|
|
* to keep the log cleaner.
|
|
|
|
*/
|
2016-05-15 15:35:33 +00:00
|
|
|
class AbuseFilterPreAuthenticationProvider extends AbstractPreAuthenticationProvider {
|
2022-04-09 15:07:45 +00:00
|
|
|
/** @var VariableGeneratorFactory */
|
|
|
|
private $variableGeneratorFactory;
|
|
|
|
/** @var FilterRunnerFactory */
|
|
|
|
private $filterRunnerFactory;
|
|
|
|
/** @var IBufferingStatsdDataFactory */
|
|
|
|
private $statsd;
|
|
|
|
/** @var UserFactory */
|
|
|
|
private $userFactory;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param VariableGeneratorFactory $variableGeneratorFactory
|
|
|
|
* @param FilterRunnerFactory $filterRunnerFactory
|
|
|
|
* @param IBufferingStatsdDataFactory $statsd
|
|
|
|
* @param UserFactory $userFactory
|
|
|
|
*/
|
|
|
|
public function __construct(
|
|
|
|
VariableGeneratorFactory $variableGeneratorFactory,
|
|
|
|
FilterRunnerFactory $filterRunnerFactory,
|
|
|
|
IBufferingStatsdDataFactory $statsd,
|
|
|
|
UserFactory $userFactory
|
|
|
|
) {
|
|
|
|
$this->variableGeneratorFactory = $variableGeneratorFactory;
|
|
|
|
$this->filterRunnerFactory = $filterRunnerFactory;
|
|
|
|
$this->statsd = $statsd;
|
|
|
|
$this->userFactory = $userFactory;
|
|
|
|
}
|
|
|
|
|
2018-04-04 21:14:25 +00:00
|
|
|
/**
|
|
|
|
* @param User $user
|
|
|
|
* @param User $creator
|
|
|
|
* @param AuthenticationRequest[] $reqs
|
|
|
|
* @return StatusValue
|
|
|
|
*/
|
2022-04-09 15:07:45 +00:00
|
|
|
public function testForAccountCreation( $user, $creator, array $reqs ): StatusValue {
|
2016-05-15 15:35:33 +00:00
|
|
|
return $this->testUser( $user, $creator, false );
|
|
|
|
}
|
|
|
|
|
2018-04-04 21:14:25 +00:00
|
|
|
/**
|
|
|
|
* @param User $user
|
|
|
|
* @param bool|string $autocreate
|
|
|
|
* @param array $options
|
|
|
|
* @return StatusValue
|
|
|
|
*/
|
2022-04-09 15:07:45 +00:00
|
|
|
public function testUserForCreation( $user, $autocreate, array $options = [] ): StatusValue {
|
2016-05-15 15:35:33 +00:00
|
|
|
// if this is not an autocreation, testForAccountCreation already handled it
|
2024-09-05 14:25:35 +00:00
|
|
|
if ( $autocreate && !( $options['canAlwaysAutocreate'] ?? false ) ) {
|
2022-04-09 15:07:45 +00:00
|
|
|
// Make sure to use an anon as the creator, see T272244
|
|
|
|
return $this->testUser( $user, $this->userFactory->newAnonymous(), true );
|
2016-05-15 15:35:33 +00:00
|
|
|
}
|
|
|
|
return StatusValue::newGood();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param User $user The user being created or autocreated
|
2021-01-17 16:16:46 +00:00
|
|
|
* @param User $creator The user who caused $user to be created (can be anonymous)
|
2016-05-15 15:35:33 +00:00
|
|
|
* @param bool $autocreate Is this an autocreation?
|
|
|
|
* @return StatusValue
|
|
|
|
*/
|
2022-04-09 15:07:45 +00:00
|
|
|
private function testUser( $user, $creator, $autocreate ): StatusValue {
|
2019-09-16 16:53:36 +00:00
|
|
|
$startTime = microtime( true );
|
2018-08-26 08:34:42 +00:00
|
|
|
if ( $user->getName() === wfMessage( 'abusefilter-blocker' )->inContentLanguage()->text() ) {
|
2016-05-15 15:35:33 +00:00
|
|
|
return StatusValue::newFatal( 'abusefilter-accountreserved' );
|
|
|
|
}
|
|
|
|
|
2019-06-25 16:39:57 +00:00
|
|
|
$title = SpecialPage::getTitleFor( 'Userlogin' );
|
2022-04-09 15:07:45 +00:00
|
|
|
$builder = $this->variableGeneratorFactory->newRunGenerator( $creator, $title );
|
2019-06-25 16:39:57 +00:00
|
|
|
$vars = $builder->getAccountCreationVars( $user, $autocreate );
|
2016-05-15 15:35:33 +00:00
|
|
|
|
|
|
|
// pass creator in explicitly to prevent recording the current user on autocreation - T135360
|
2022-04-09 15:07:45 +00:00
|
|
|
$runner = $this->filterRunnerFactory->newRunner( $creator, $title, $vars, 'default' );
|
Add a new class for methods related to running filters
Currently we strongly abuse (pardon the pun) the AbuseFilter class: its
purpose should be to hold static functions intended as generic utility
functions (e.g. to format messages, determine whether a filter is global
etc.), but we actually use it for all methods related to running filters.
This patch creates a new class, AbuseFilterRunner, containing all such
methods, which have been made non-static. This leads to several
improvements (also for related methods and the parser), and opens the
way to further improve the code.
Aside from making the code prettier, less global and easier to test,
this patch could also produce a performance improvement, although I
don't have tools to measure that.
Also note that many public methods have been removed, and almost any of
them has been made protected; a couple of them (the ones used from outside)
are left for back-compat, and will be removed in the future.
Change-Id: I2eab2e50356eeb5224446ee2d0df9c787ae95b80
2018-12-07 17:46:02 +00:00
|
|
|
$status = $runner->run();
|
2016-05-15 15:35:33 +00:00
|
|
|
|
2022-04-09 15:07:45 +00:00
|
|
|
$this->statsd->timing( 'timing.createaccountAbuseFilter', microtime( true ) - $startTime );
|
2019-09-16 16:53:36 +00:00
|
|
|
|
2016-05-15 15:35:33 +00:00
|
|
|
return $status->getStatusValue();
|
|
|
|
}
|
|
|
|
}
|