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