Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.67% covered (warning)
86.67%
13 / 15
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
AbuseFilterPreAuthenticationProvider
86.67% covered (warning)
86.67%
13 / 15
50.00% covered (danger)
50.00%
2 / 4
7.12
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 testForAccountCreation
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 testUserForCreation
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
3.33
 testUser
90.00% covered (success)
90.00%
9 / 10
0.00% covered (danger)
0.00%
0 / 1
2.00
1<?php
2
3namespace MediaWiki\Extension\AbuseFilter;
4
5use MediaWiki\Auth\AbstractPreAuthenticationProvider;
6use MediaWiki\Auth\AuthenticationRequest;
7use MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGeneratorFactory;
8use MediaWiki\SpecialPage\SpecialPage;
9use MediaWiki\User\User;
10use MediaWiki\User\UserFactory;
11use StatusValue;
12use Wikimedia\Stats\IBufferingStatsdDataFactory;
13
14/**
15 * AuthenticationProvider used to filter account creations. This runs after normal preauth providers
16 * to keep the log cleaner.
17 */
18class AbuseFilterPreAuthenticationProvider extends AbstractPreAuthenticationProvider {
19
20    /**
21     * @param VariableGeneratorFactory $variableGeneratorFactory
22     * @param FilterRunnerFactory $filterRunnerFactory
23     * @param IBufferingStatsdDataFactory $statsd
24     * @param UserFactory $userFactory
25     */
26    public function __construct(
27        private readonly VariableGeneratorFactory $variableGeneratorFactory,
28        private readonly FilterRunnerFactory $filterRunnerFactory,
29        private readonly IBufferingStatsdDataFactory $statsd,
30        private readonly UserFactory $userFactory
31    ) {
32    }
33
34    /**
35     * @param User $user
36     * @param User $creator
37     * @param AuthenticationRequest[] $reqs
38     * @return StatusValue
39     */
40    public function testForAccountCreation( $user, $creator, array $reqs ): StatusValue {
41        return $this->testUser( $user, $creator, false );
42    }
43
44    /**
45     * @param User $user
46     * @param bool|string $autocreate
47     * @param array $options
48     * @return StatusValue
49     */
50    public function testUserForCreation( $user, $autocreate, array $options = [] ): StatusValue {
51        // if this is not an autocreation, testForAccountCreation already handled it
52        if ( $autocreate && !( $options['canAlwaysAutocreate'] ?? false ) ) {
53            // Make sure to use an anon as the creator, see T272244
54            return $this->testUser( $user, $this->userFactory->newAnonymous(), true );
55        }
56        return StatusValue::newGood();
57    }
58
59    /**
60     * @param User $user The user being created or autocreated
61     * @param User $creator The user who caused $user to be created (can be anonymous)
62     * @param bool $autocreate Is this an autocreation?
63     * @return StatusValue
64     */
65    private function testUser( $user, $creator, $autocreate ): StatusValue {
66        $startTime = microtime( true );
67        if ( $user->getName() === wfMessage( 'abusefilter-blocker' )->inContentLanguage()->text() ) {
68            return StatusValue::newFatal( 'abusefilter-accountreserved' );
69        }
70
71        $title = SpecialPage::getTitleFor( 'Userlogin' );
72        $builder = $this->variableGeneratorFactory->newRunGenerator( $creator, $title );
73        $vars = $builder->getAccountCreationVars( $user, $autocreate );
74
75        // pass creator in explicitly to prevent recording the current user on autocreation - T135360
76        $runner = $this->filterRunnerFactory->newRunner( $creator, $title, $vars, 'default' );
77        $status = $runner->run();
78
79        $this->statsd->timing( 'timing.createaccountAbuseFilter', microtime( true ) - $startTime );
80
81        return $status->getStatusValue();
82    }
83}