Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.96% covered (success)
97.96%
48 / 49
90.91% covered (success)
90.91%
10 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
ConsequencesFactory
97.96% covered (success)
97.96%
48 / 49
90.91% covered (success)
90.91%
10 / 11
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
 newBlock
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
 newRangeBlock
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 newDegroup
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 newBlockAutopromote
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 newThrottle
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 newWarn
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 newDisallow
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 newTag
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setSession
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSession
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
1<?php
2
3namespace MediaWiki\Extension\AbuseFilter\Consequences;
4
5use MediaWiki\Block\BlockUserFactory;
6use MediaWiki\Block\DatabaseBlockStore;
7use MediaWiki\Block\UnblockUserFactory;
8use MediaWiki\Config\ServiceOptions;
9use MediaWiki\Extension\AbuseFilter\BlockAutopromoteStore;
10use MediaWiki\Extension\AbuseFilter\ChangeTags\ChangeTagger;
11use MediaWiki\Extension\AbuseFilter\Consequences\Consequence\Block;
12use MediaWiki\Extension\AbuseFilter\Consequences\Consequence\BlockAutopromote;
13use MediaWiki\Extension\AbuseFilter\Consequences\Consequence\Degroup;
14use MediaWiki\Extension\AbuseFilter\Consequences\Consequence\Disallow;
15use MediaWiki\Extension\AbuseFilter\Consequences\Consequence\RangeBlock;
16use MediaWiki\Extension\AbuseFilter\Consequences\Consequence\Tag;
17use MediaWiki\Extension\AbuseFilter\Consequences\Consequence\Throttle;
18use MediaWiki\Extension\AbuseFilter\Consequences\Consequence\Warn;
19use MediaWiki\Extension\AbuseFilter\FilterUser;
20use MediaWiki\Extension\AbuseFilter\Variables\VariableHolder;
21use MediaWiki\Session\Session;
22use MediaWiki\Session\SessionManager;
23use MediaWiki\User\Registration\UserRegistrationLookup;
24use MediaWiki\User\UserEditTracker;
25use MediaWiki\User\UserGroupManager;
26use MediaWiki\User\UserIdentityUtils;
27use MessageLocalizer;
28use Psr\Log\LoggerInterface;
29use Wikimedia\ObjectCache\BagOStuff;
30
31class ConsequencesFactory {
32    public const SERVICE_NAME = 'AbuseFilterConsequencesFactory';
33
34    public const CONSTRUCTOR_OPTIONS = [
35        'AbuseFilterCentralDB',
36        'AbuseFilterIsCentral',
37        'AbuseFilterRangeBlockSize',
38        'BlockCIDRLimit',
39    ];
40
41    /** @var ?Session */
42    private $session;
43
44    /**
45     * @todo This might drag in unwanted dependencies. The alternative is to use ObjectFactory, but that's harder
46     *   to understand for humans and static analysis tools, so do that only if the dependencies list starts growing.
47     */
48    public function __construct(
49        private readonly ServiceOptions $options,
50        private readonly LoggerInterface $logger,
51        private readonly BlockUserFactory $blockUserFactory,
52        private readonly UnblockUserFactory $unblockUserFactory,
53        private readonly DatabaseBlockStore $databaseBlockStore,
54        private readonly UserGroupManager $userGroupManager,
55        private readonly BagOStuff $mainStash,
56        private readonly ChangeTagger $changeTagger,
57        private readonly BlockAutopromoteStore $blockAutopromoteStore,
58        private readonly FilterUser $filterUser,
59        private readonly MessageLocalizer $messageLocalizer,
60        private readonly UserEditTracker $userEditTracker,
61        private readonly UserRegistrationLookup $userRegistrationLookup,
62        private readonly UserIdentityUtils $userIdentityUtils
63    ) {
64        $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
65    }
66
67    // Each class has its factory method for better type inference and static analysis
68
69    /**
70     * @param Parameters $params
71     * @param string $expiry
72     * @param bool $preventsTalk
73     * @return Block
74     */
75    public function newBlock( Parameters $params, string $expiry, bool $preventsTalk ): Block {
76        return new Block(
77            $params,
78            $expiry,
79            $preventsTalk,
80            $this->blockUserFactory,
81            $this->unblockUserFactory,
82            $this->databaseBlockStore,
83            $this->filterUser,
84            $this->messageLocalizer,
85            $this->logger
86        );
87    }
88
89    /**
90     * @param Parameters $params
91     * @param string $expiry
92     * @return RangeBlock
93     */
94    public function newRangeBlock( Parameters $params, string $expiry ): RangeBlock {
95        return new RangeBlock(
96            $params,
97            $expiry,
98            $this->blockUserFactory,
99            $this->filterUser,
100            $this->messageLocalizer,
101            $this->logger,
102            $this->options->get( 'AbuseFilterRangeBlockSize' ),
103            $this->options->get( 'BlockCIDRLimit' )
104        );
105    }
106
107    /**
108     * @param Parameters $params
109     * @param VariableHolder $vars
110     * @return Degroup
111     */
112    public function newDegroup( Parameters $params, VariableHolder $vars ): Degroup {
113        return new Degroup(
114            $params,
115            $vars,
116            $this->userGroupManager,
117            $this->userIdentityUtils,
118            $this->filterUser,
119            $this->messageLocalizer
120        );
121    }
122
123    /**
124     * @param Parameters $params
125     * @param int $duration
126     * @return BlockAutopromote
127     */
128    public function newBlockAutopromote( Parameters $params, int $duration ): BlockAutopromote {
129        return new BlockAutopromote( $params, $duration, $this->blockAutopromoteStore, $this->messageLocalizer,
130            $this->userIdentityUtils );
131    }
132
133    /**
134     * @param Parameters $params
135     * @param array $throttleParams
136     * @phan-param array{id:int|string,count:int,period:int,groups:string[]} $throttleParams
137     * @return Throttle
138     */
139    public function newThrottle( Parameters $params, array $throttleParams ): Throttle {
140        return new Throttle(
141            $params,
142            $throttleParams,
143            $this->mainStash,
144            $this->userEditTracker,
145            $this->userRegistrationLookup,
146            $this->logger,
147            $this->options->get( 'AbuseFilterIsCentral' ),
148            $this->options->get( 'AbuseFilterCentralDB' )
149        );
150    }
151
152    /**
153     * @param Parameters $params
154     * @param string $message
155     * @return Warn
156     */
157    public function newWarn( Parameters $params, string $message ): Warn {
158        return new Warn( $params, $message, $this->getSession() );
159    }
160
161    /**
162     * @param Parameters $params
163     * @param string $message
164     * @return Disallow
165     */
166    public function newDisallow( Parameters $params, string $message ): Disallow {
167        return new Disallow( $params, $message );
168    }
169
170    /**
171     * @param Parameters $params
172     * @param string[] $tags
173     * @return Tag
174     */
175    public function newTag( Parameters $params, array $tags ): Tag {
176        return new Tag( $params, $tags, $this->changeTagger );
177    }
178
179    public function setSession( Session $session ): void {
180        $this->session = $session;
181    }
182
183    private function getSession(): Session {
184        if ( $this->session === null ) {
185            $this->session = SessionManager::getGlobalSession();
186        }
187
188        return $this->session;
189    }
190}