Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
98.41% covered (success)
98.41%
62 / 63
90.91% covered (success)
90.91%
10 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
ConsequencesFactory
98.41% covered (success)
98.41%
62 / 63
90.91% covered (success)
90.91%
10 / 11
12
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
15 / 15
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\UserEditTracker;
24use MediaWiki\User\UserFactory;
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 ServiceOptions */
42    private $options;
43
44    /** @var LoggerInterface */
45    private $logger;
46
47    /** @var BlockUserFactory */
48    private $blockUserFactory;
49
50    /** @var UnblockUserFactory */
51    private $unblockUserFactory;
52
53    /** @var DatabaseBlockStore */
54    private $databaseBlockStore;
55
56    /** @var UserGroupManager */
57    private $userGroupManager;
58
59    /** @var BagOStuff */
60    private $mainStash;
61
62    /** @var ChangeTagger */
63    private $changeTagger;
64
65    /** @var BlockAutopromoteStore */
66    private $blockAutopromoteStore;
67
68    /** @var FilterUser */
69    private $filterUser;
70
71    /** @var MessageLocalizer */
72    private $messageLocalizer;
73
74    /** @var UserEditTracker */
75    private $userEditTracker;
76
77    /** @var UserFactory */
78    private $userFactory;
79
80    /** @var UserIdentityUtils */
81    private $userIdentityUtils;
82
83    /** @var ?Session */
84    private $session;
85
86    /**
87     * @todo This might drag in unwanted dependencies. The alternative is to use ObjectFactory, but that's harder
88     *   to understand for humans and static analysis tools, so do that only if the dependencies list starts growing.
89     * @param ServiceOptions $options
90     * @param LoggerInterface $logger
91     * @param BlockUserFactory $blockUserFactory
92     * @param UnblockUserFactory $unblockUserFactory
93     * @param DatabaseBlockStore $databaseBlockStore
94     * @param UserGroupManager $userGroupManager
95     * @param BagOStuff $mainStash
96     * @param ChangeTagger $changeTagger
97     * @param BlockAutopromoteStore $blockAutopromoteStore
98     * @param FilterUser $filterUser
99     * @param MessageLocalizer $messageLocalizer
100     * @param UserEditTracker $userEditTracker
101     * @param UserFactory $userFactory
102     * @param UserIdentityUtils $userIdentityUtils
103     */
104    public function __construct(
105        ServiceOptions $options,
106        LoggerInterface $logger,
107        BlockUserFactory $blockUserFactory,
108        UnblockUserFactory $unblockUserFactory,
109        DatabaseBlockStore $databaseBlockStore,
110        UserGroupManager $userGroupManager,
111        BagOStuff $mainStash,
112        ChangeTagger $changeTagger,
113        BlockAutopromoteStore $blockAutopromoteStore,
114        FilterUser $filterUser,
115        MessageLocalizer $messageLocalizer,
116        UserEditTracker $userEditTracker,
117        UserFactory $userFactory,
118        UserIdentityUtils $userIdentityUtils
119    ) {
120        $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
121        $this->options = $options;
122        $this->logger = $logger;
123        $this->blockUserFactory = $blockUserFactory;
124        $this->unblockUserFactory = $unblockUserFactory;
125        $this->databaseBlockStore = $databaseBlockStore;
126        $this->userGroupManager = $userGroupManager;
127        $this->mainStash = $mainStash;
128        $this->changeTagger = $changeTagger;
129        $this->blockAutopromoteStore = $blockAutopromoteStore;
130        $this->filterUser = $filterUser;
131        $this->messageLocalizer = $messageLocalizer;
132        $this->userEditTracker = $userEditTracker;
133        $this->userFactory = $userFactory;
134        $this->userIdentityUtils = $userIdentityUtils;
135    }
136
137    // Each class has its factory method for better type inference and static analysis
138
139    /**
140     * @param Parameters $params
141     * @param string $expiry
142     * @param bool $preventsTalk
143     * @return Block
144     */
145    public function newBlock( Parameters $params, string $expiry, bool $preventsTalk ): Block {
146        return new Block(
147            $params,
148            $expiry,
149            $preventsTalk,
150            $this->blockUserFactory,
151            $this->unblockUserFactory,
152            $this->databaseBlockStore,
153            $this->filterUser,
154            $this->messageLocalizer,
155            $this->logger
156        );
157    }
158
159    /**
160     * @param Parameters $params
161     * @param string $expiry
162     * @return RangeBlock
163     */
164    public function newRangeBlock( Parameters $params, string $expiry ): RangeBlock {
165        return new RangeBlock(
166            $params,
167            $expiry,
168            $this->blockUserFactory,
169            $this->filterUser,
170            $this->messageLocalizer,
171            $this->logger,
172            $this->options->get( 'AbuseFilterRangeBlockSize' ),
173            $this->options->get( 'BlockCIDRLimit' )
174        );
175    }
176
177    /**
178     * @param Parameters $params
179     * @param VariableHolder $vars
180     * @return Degroup
181     */
182    public function newDegroup( Parameters $params, VariableHolder $vars ): Degroup {
183        return new Degroup(
184            $params,
185            $vars,
186            $this->userGroupManager,
187            $this->userIdentityUtils,
188            $this->filterUser,
189            $this->messageLocalizer
190        );
191    }
192
193    /**
194     * @param Parameters $params
195     * @param int $duration
196     * @return BlockAutopromote
197     */
198    public function newBlockAutopromote( Parameters $params, int $duration ): BlockAutopromote {
199        return new BlockAutopromote( $params, $duration, $this->blockAutopromoteStore, $this->messageLocalizer,
200            $this->userIdentityUtils );
201    }
202
203    /**
204     * @param Parameters $params
205     * @param array $throttleParams
206     * @phan-param array{id:int|string,count:int,period:int,groups:string[]} $throttleParams
207     * @return Throttle
208     */
209    public function newThrottle( Parameters $params, array $throttleParams ): Throttle {
210        return new Throttle(
211            $params,
212            $throttleParams,
213            $this->mainStash,
214            $this->userEditTracker,
215            $this->userFactory,
216            $this->logger,
217            $this->options->get( 'AbuseFilterIsCentral' ),
218            $this->options->get( 'AbuseFilterCentralDB' )
219        );
220    }
221
222    /**
223     * @param Parameters $params
224     * @param string $message
225     * @return Warn
226     */
227    public function newWarn( Parameters $params, string $message ): Warn {
228        return new Warn( $params, $message, $this->getSession() );
229    }
230
231    /**
232     * @param Parameters $params
233     * @param string $message
234     * @return Disallow
235     */
236    public function newDisallow( Parameters $params, string $message ): Disallow {
237        return new Disallow( $params, $message );
238    }
239
240    /**
241     * @param Parameters $params
242     * @param string[] $tags
243     * @return Tag
244     */
245    public function newTag( Parameters $params, array $tags ): Tag {
246        return new Tag( $params, $tags, $this->changeTagger );
247    }
248
249    /**
250     * @param Session $session
251     * @return void
252     */
253    public function setSession( Session $session ): void {
254        $this->session = $session;
255    }
256
257    /**
258     * @return Session
259     */
260    private function getSession(): Session {
261        if ( $this->session === null ) {
262            $this->session = SessionManager::getGlobalSession();
263        }
264
265        return $this->session;
266    }
267}