Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
1<?php
2
3use MediaWiki\Config\ServiceOptions;
4use MediaWiki\Context\RequestContext;
5use MediaWiki\Extension\AbuseFilter\AbuseFilterLogDetailsLookup;
6use MediaWiki\Extension\AbuseFilter\AbuseFilterPermissionManager as PermManager;
7use MediaWiki\Extension\AbuseFilter\AbuseLogConditionFactory;
8use MediaWiki\Extension\AbuseFilter\AbuseLoggerFactory;
9use MediaWiki\Extension\AbuseFilter\AbuseLogLookup;
10use MediaWiki\Extension\AbuseFilter\BlockAutopromoteStore;
11use MediaWiki\Extension\AbuseFilter\BlockedDomains\BlockedDomainConfigProvider;
12use MediaWiki\Extension\AbuseFilter\BlockedDomains\BlockedDomainFilter;
13use MediaWiki\Extension\AbuseFilter\BlockedDomains\BlockedDomainValidator;
14use MediaWiki\Extension\AbuseFilter\BlockedDomains\CustomBlockedDomainStorage;
15use MediaWiki\Extension\AbuseFilter\BlockedDomains\IBlockedDomainFilter;
16use MediaWiki\Extension\AbuseFilter\BlockedDomains\IBlockedDomainStorage;
17use MediaWiki\Extension\AbuseFilter\BlockedDomains\NoopBlockedDomainFilter;
18use MediaWiki\Extension\AbuseFilter\CentralDBManager;
19use MediaWiki\Extension\AbuseFilter\ChangeTags\ChangeTagger;
20use MediaWiki\Extension\AbuseFilter\ChangeTags\ChangeTagsManager;
21use MediaWiki\Extension\AbuseFilter\ChangeTags\ChangeTagValidator;
22use MediaWiki\Extension\AbuseFilter\Consequences\ConsequencesExecutor;
23use MediaWiki\Extension\AbuseFilter\Consequences\ConsequencesExecutorFactory as ConsExecutorFactory;
24use MediaWiki\Extension\AbuseFilter\Consequences\ConsequencesFactory;
25use MediaWiki\Extension\AbuseFilter\Consequences\ConsequencesLookup;
26use MediaWiki\Extension\AbuseFilter\Consequences\ConsequencesRegistry;
27use MediaWiki\Extension\AbuseFilter\EchoNotifier;
28use MediaWiki\Extension\AbuseFilter\EditBox\EditBoxBuilderFactory;
29use MediaWiki\Extension\AbuseFilter\EditRevUpdater;
30use MediaWiki\Extension\AbuseFilter\EmergencyCache;
31use MediaWiki\Extension\AbuseFilter\FilterCompare;
32use MediaWiki\Extension\AbuseFilter\FilterImporter;
33use MediaWiki\Extension\AbuseFilter\FilterLookup;
34use MediaWiki\Extension\AbuseFilter\FilterProfiler;
35use MediaWiki\Extension\AbuseFilter\FilterRunner;
36use MediaWiki\Extension\AbuseFilter\FilterRunnerFactory;
37use MediaWiki\Extension\AbuseFilter\FilterStore;
38use MediaWiki\Extension\AbuseFilter\FilterUser;
39use MediaWiki\Extension\AbuseFilter\FilterValidator;
40use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner;
41use MediaWiki\Extension\AbuseFilter\KeywordsManager;
42use MediaWiki\Extension\AbuseFilter\Parser\RuleCheckerFactory;
43use MediaWiki\Extension\AbuseFilter\ServiceNames;
44use MediaWiki\Extension\AbuseFilter\SpecsFormatter;
45use MediaWiki\Extension\AbuseFilter\TemporaryAccountIPsViewerSpecification;
46use MediaWiki\Extension\AbuseFilter\TextExtractor;
47use MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGeneratorFactory;
48use MediaWiki\Extension\AbuseFilter\Variables\AbuseFilterProtectedVariablesLookup;
49use MediaWiki\Extension\AbuseFilter\Variables\LazyVariableComputer;
50use MediaWiki\Extension\AbuseFilter\Variables\VariablesBlobStore;
51use MediaWiki\Extension\AbuseFilter\Variables\VariablesFormatter;
52use MediaWiki\Extension\AbuseFilter\Variables\VariablesManager;
53use MediaWiki\Extension\AbuseFilter\Watcher\EmergencyWatcher;
54use MediaWiki\Extension\AbuseFilter\Watcher\UpdateHitCountWatcher;
55use MediaWiki\Extension\CommunityConfiguration\CommunityConfigurationServices;
56use MediaWiki\Logger\LoggerFactory;
57use MediaWiki\MediaWikiServices;
58use MediaWiki\Registration\ExtensionRegistry;
59use MediaWiki\WikiMap\WikiMap;
60use Wikimedia\Equivset\Equivset;
61
62// This file is actually covered by AbuseFilterServicesTest, but it's not possible to specify a path
63// in @covers annotations (https://github.com/sebastianbergmann/phpunit/issues/3794)
64// @codeCoverageIgnoreStart
65
66return [
67    ServiceNames::AbuseFilterHookRunner => static function ( MediaWikiServices $services ): AbuseFilterHookRunner {
68        return new AbuseFilterHookRunner( $services->getHookContainer() );
69    },
70    ServiceNames::KeywordsManager => static function ( MediaWikiServices $services ): KeywordsManager {
71        return new KeywordsManager( $services->get( AbuseFilterHookRunner::SERVICE_NAME ) );
72    },
73    ServiceNames::FilterProfiler => static function ( MediaWikiServices $services ): FilterProfiler {
74        return new FilterProfiler(
75            $services->getWRStatsFactory(),
76            new ServiceOptions(
77                FilterProfiler::CONSTRUCTOR_OPTIONS,
78                $services->getMainConfig()
79            ),
80            WikiMap::getCurrentWikiDbDomain()->getId(),
81            $services->getStatsFactory(),
82            LoggerFactory::getInstance( 'AbuseFilter' )
83        );
84    },
85    ServiceNames::PermManager => static function ( MediaWikiServices $services ): PermManager {
86        return new PermManager(
87            $services->getTempUserConfig(),
88            $services->get( AbuseFilterProtectedVariablesLookup::SERVICE_NAME ),
89            $services->get( RuleCheckerFactory::SERVICE_NAME ),
90            $services->get( AbuseFilterHookRunner::SERVICE_NAME ),
91            $services->has( 'CheckUserPermissionManager' )
92                ? $services->get( 'CheckUserPermissionManager' )
93                : null
94        );
95    },
96    ServiceNames::ChangeTagger => static function ( MediaWikiServices $services ): ChangeTagger {
97        return new ChangeTagger(
98            $services->getService( ChangeTagsManager::SERVICE_NAME )
99        );
100    },
101    ServiceNames::ChangeTagsManager => static function ( MediaWikiServices $services ): ChangeTagsManager {
102        return new ChangeTagsManager(
103            $services->getChangeTagsStore(),
104            $services->getDBLoadBalancerFactory(),
105            $services->getMainWANObjectCache(),
106            $services->get( CentralDBManager::SERVICE_NAME )
107        );
108    },
109    ServiceNames::ChangeTagValidator => static function ( MediaWikiServices $services ): ChangeTagValidator {
110        return new ChangeTagValidator(
111            $services->getService( ChangeTagsManager::SERVICE_NAME )
112        );
113    },
114    ServiceNames::CentralDBManager => static function ( MediaWikiServices $services ): CentralDBManager {
115        return new CentralDBManager(
116            $services->getDBLoadBalancerFactory(),
117            $services->getMainConfig()->get( 'AbuseFilterCentralDB' ),
118            $services->getMainConfig()->get( 'AbuseFilterIsCentral' )
119        );
120    },
121    ServiceNames::BlockAutopromoteStore => static function ( MediaWikiServices $services ): BlockAutopromoteStore {
122        return new BlockAutopromoteStore(
123            $services->getMainObjectStash(),
124            LoggerFactory::getInstance( 'AbuseFilter' ),
125            $services->get( FilterUser::SERVICE_NAME )
126        );
127    },
128    ServiceNames::FilterUser => static function ( MediaWikiServices $services ): FilterUser {
129        return new FilterUser(
130            // TODO We need a proper MessageLocalizer, see T247127
131            RequestContext::getMain(),
132            $services->getUserGroupManager(),
133            $services->getUserNameUtils(),
134            LoggerFactory::getInstance( 'AbuseFilter' )
135        );
136    },
137    ServiceNames::RuleCheckerFactory => static function ( MediaWikiServices $services ): RuleCheckerFactory {
138        return new RuleCheckerFactory(
139            $services->getContentLanguage(),
140            $services->getObjectCacheFactory()->getLocalServerInstance( CACHE_HASH ),
141            LoggerFactory::getInstance( 'AbuseFilter' ),
142            $services->getService( KeywordsManager::SERVICE_NAME ),
143            $services->get( VariablesManager::SERVICE_NAME ),
144            $services->getStatsFactory(),
145            new Equivset(),
146            $services->getMainConfig()->get( 'AbuseFilterConditionLimit' )
147        );
148    },
149    ServiceNames::FilterLookup => static function ( MediaWikiServices $services ): FilterLookup {
150        return new FilterLookup(
151            $services->getDBLoadBalancer(),
152            $services->getMainWANObjectCache(),
153            $services->get( CentralDBManager::SERVICE_NAME )
154        );
155    },
156    ServiceNames::EmergencyCache => static function ( MediaWikiServices $services ): EmergencyCache {
157        return new EmergencyCache(
158            $services->getMainObjectStash(),
159            $services->getMainConfig()->get( 'AbuseFilterEmergencyDisableAge' )
160        );
161    },
162    ServiceNames::EmergencyWatcher => static function ( MediaWikiServices $services ): EmergencyWatcher {
163        return new EmergencyWatcher(
164            $services->getService( EmergencyCache::SERVICE_NAME ),
165            $services->getDBLoadBalancerFactory(),
166            $services->getService( FilterLookup::SERVICE_NAME ),
167            $services->getService( EchoNotifier::SERVICE_NAME ),
168            new ServiceOptions(
169                EmergencyWatcher::CONSTRUCTOR_OPTIONS,
170                $services->getMainConfig()
171            )
172        );
173    },
174    ServiceNames::EchoNotifier => static function ( MediaWikiServices $services ): EchoNotifier {
175        return new EchoNotifier(
176            $services->getService( FilterLookup::SERVICE_NAME ),
177            $services->getService( ConsequencesRegistry::SERVICE_NAME ),
178            ExtensionRegistry::getInstance()->isLoaded( 'Echo' )
179        );
180    },
181    ServiceNames::FilterValidator => static function ( MediaWikiServices $services ): FilterValidator {
182        return new FilterValidator(
183            $services->get( ChangeTagValidator::SERVICE_NAME ),
184            $services->get( RuleCheckerFactory::SERVICE_NAME ),
185            $services->get( PermManager::SERVICE_NAME ),
186            new ServiceOptions(
187                FilterValidator::CONSTRUCTOR_OPTIONS,
188                $services->getMainConfig()
189            )
190        );
191    },
192    ServiceNames::FilterCompare => static function ( MediaWikiServices $services ): FilterCompare {
193        return new FilterCompare(
194            $services->get( ConsequencesRegistry::SERVICE_NAME )
195        );
196    },
197    ServiceNames::FilterImporter => static function ( MediaWikiServices $services ): FilterImporter {
198        return new FilterImporter(
199            new ServiceOptions(
200                FilterImporter::CONSTRUCTOR_OPTIONS,
201                $services->getMainConfig()
202            ),
203            $services->get( ConsequencesRegistry::SERVICE_NAME )
204        );
205    },
206    ServiceNames::FilterStore => static function ( MediaWikiServices $services ): FilterStore {
207        return new FilterStore(
208            $services->get( ConsequencesRegistry::SERVICE_NAME ),
209            $services->getDBLoadBalancerFactory(),
210            $services->getActorNormalization(),
211            $services->get( FilterProfiler::SERVICE_NAME ),
212            $services->get( FilterLookup::SERVICE_NAME ),
213            $services->get( ChangeTagsManager::SERVICE_NAME ),
214            $services->get( FilterValidator::SERVICE_NAME ),
215            $services->get( FilterCompare::SERVICE_NAME ),
216            $services->get( EmergencyCache::SERVICE_NAME )
217        );
218    },
219    ServiceNames::ConsequencesFactory => static function ( MediaWikiServices $services ): ConsequencesFactory {
220        return new ConsequencesFactory(
221            new ServiceOptions(
222                ConsequencesFactory::CONSTRUCTOR_OPTIONS,
223                $services->getMainConfig()
224            ),
225            LoggerFactory::getInstance( 'AbuseFilter' ),
226            $services->getBlockUserFactory(),
227            $services->getUnblockUserFactory(),
228            $services->getDatabaseBlockStore(),
229            $services->getUserGroupManager(),
230            $services->getMainObjectStash(),
231            $services->get( ChangeTagger::SERVICE_NAME ),
232            $services->get( BlockAutopromoteStore::SERVICE_NAME ),
233            $services->get( FilterUser::SERVICE_NAME ),
234            // TODO: Use a proper MessageLocalizer once available (T247127)
235            RequestContext::getMain(),
236            $services->getUserEditTracker(),
237            $services->getUserRegistrationLookup(),
238            $services->getUserIdentityUtils()
239        );
240    },
241    ServiceNames::EditBoxBuilderFactory => static function ( MediaWikiServices $services ): EditBoxBuilderFactory {
242        $config = $services->getMainConfig();
243        return new EditBoxBuilderFactory(
244            $services->get( PermManager::SERVICE_NAME ),
245            $services->get( KeywordsManager::SERVICE_NAME ),
246            $config->get( 'AbuseFilterUseCodeEditor' ) && ExtensionRegistry::getInstance()->isLoaded( 'CodeEditor' ),
247            $config->get( 'AbuseFilterUseCodeMirror' ) && ExtensionRegistry::getInstance()->isLoaded( 'CodeMirror' )
248        );
249    },
250    ServiceNames::ConsequencesLookup => static function ( MediaWikiServices $services ): ConsequencesLookup {
251        return new ConsequencesLookup(
252            $services->getDBLoadBalancerFactory(),
253            $services->get( CentralDBManager::SERVICE_NAME ),
254            $services->get( ConsequencesRegistry::SERVICE_NAME ),
255            LoggerFactory::getInstance( 'AbuseFilter' )
256        );
257    },
258    ServiceNames::ConsequencesRegistry => static function ( MediaWikiServices $services ): ConsequencesRegistry {
259        return new ConsequencesRegistry(
260            $services->get( AbuseFilterHookRunner::SERVICE_NAME ),
261            $services->getMainConfig()->get( 'AbuseFilterActions' )
262        );
263    },
264    ServiceNames::AbuseLoggerFactory => static function ( MediaWikiServices $services ): AbuseLoggerFactory {
265        return new AbuseLoggerFactory(
266            $services->get( CentralDBManager::SERVICE_NAME ),
267            $services->get( FilterLookup::SERVICE_NAME ),
268            $services->get( VariablesBlobStore::SERVICE_NAME ),
269            $services->get( VariablesManager::SERVICE_NAME ),
270            $services->get( EditRevUpdater::SERVICE_NAME ),
271            $services->get( PermManager::SERVICE_NAME ),
272            $services->get( RuleCheckerFactory::SERVICE_NAME ),
273            $services->getDBLoadBalancerFactory(),
274            $services->getActorStore(),
275            $services->getTitleFactory(),
276            new ServiceOptions(
277                AbuseLoggerFactory::CONSTRUCTOR_OPTIONS,
278                $services->getMainConfig()
279            ),
280            WikiMap::getCurrentWikiDbDomain()->getId(),
281            RequestContext::getMain()->getRequest()->getIP(),
282            LoggerFactory::getInstance( 'AbuseFilter' ),
283            $services->get( AbuseFilterHookRunner::SERVICE_NAME ),
284            $services->has( 'CheckUserInsert' )
285                ? $services->get( 'CheckUserInsert' )
286                : null
287        );
288    },
289    ServiceNames::UpdateHitCountWatcher => static function ( MediaWikiServices $services ): UpdateHitCountWatcher {
290        return new UpdateHitCountWatcher(
291            $services->getDBLoadBalancerFactory(),
292            $services->get( CentralDBManager::SERVICE_NAME )
293        );
294    },
295    ServiceNames::VariablesBlobStore => static function ( MediaWikiServices $services ): VariablesBlobStore {
296        return new VariablesBlobStore(
297            $services->get( VariablesManager::SERVICE_NAME ),
298            $services->get( PermManager::SERVICE_NAME ),
299            $services->getBlobStoreFactory(),
300            $services->getBlobStore(),
301            $services->getMainConfig()->get( 'AbuseFilterCentralDB' )
302        );
303    },
304    ServiceNames::ConsequencesExecutorFactory => static function ( MediaWikiServices $services ): ConsExecutorFactory {
305        return new ConsExecutorFactory(
306            $services->get( ConsequencesLookup::SERVICE_NAME ),
307            $services->get( ConsequencesFactory::SERVICE_NAME ),
308            $services->get( ConsequencesRegistry::SERVICE_NAME ),
309            $services->get( FilterLookup::SERVICE_NAME ),
310            LoggerFactory::getInstance( 'AbuseFilter' ),
311            $services->getUserIdentityUtils(),
312            new ServiceOptions(
313                ConsequencesExecutor::CONSTRUCTOR_OPTIONS,
314                $services->getMainConfig()
315            )
316        );
317    },
318    ServiceNames::FilterRunnerFactory => static function ( MediaWikiServices $services ): FilterRunnerFactory {
319        return new FilterRunnerFactory(
320            $services->get( AbuseFilterHookRunner::SERVICE_NAME ),
321            $services->get( FilterProfiler::SERVICE_NAME ),
322            $services->get( ChangeTagger::SERVICE_NAME ),
323            $services->get( FilterLookup::SERVICE_NAME ),
324            $services->get( RuleCheckerFactory::SERVICE_NAME ),
325            $services->get( ConsExecutorFactory::SERVICE_NAME ),
326            $services->get( AbuseLoggerFactory::SERVICE_NAME ),
327            $services->get( VariablesManager::SERVICE_NAME ),
328            $services->get( EmergencyCache::SERVICE_NAME ),
329            $services->get( UpdateHitCountWatcher::SERVICE_NAME ),
330            $services->get( EmergencyWatcher::SERVICE_NAME ),
331            $services->getObjectCacheFactory()->getLocalClusterInstance(),
332            LoggerFactory::getInstance( 'AbuseFilter' ),
333            LoggerFactory::getInstance( 'StashEdit' ),
334            $services->getStatsFactory(),
335            new ServiceOptions(
336                FilterRunner::CONSTRUCTOR_OPTIONS,
337                $services->getMainConfig()
338            )
339        );
340    },
341    ServiceNames::VariablesFormatter => static function ( MediaWikiServices $services ): VariablesFormatter {
342        return new VariablesFormatter(
343            $services->get( KeywordsManager::SERVICE_NAME ),
344            $services->get( VariablesManager::SERVICE_NAME ),
345            // TODO: Use a proper MessageLocalizer once available (T247127)
346            RequestContext::getMain()
347        );
348    },
349    ServiceNames::SpecsFormatter => static function ( MediaWikiServices $services ): SpecsFormatter {
350        return new SpecsFormatter(
351            // TODO: Use a proper MessageLocalizer once available (T247127)
352            RequestContext::getMain()
353        );
354    },
355    ServiceNames::LazyVariableComputer => static function ( MediaWikiServices $services ): LazyVariableComputer {
356        return new LazyVariableComputer(
357            $services->get( TextExtractor::SERVICE_NAME ),
358            $services->get( AbuseFilterHookRunner::SERVICE_NAME ),
359            LoggerFactory::getInstance( 'AbuseFilter' ),
360            $services->getDBLoadBalancerFactory(),
361            $services->getMainWANObjectCache(),
362            $services->getRevisionLookup(),
363            $services->getRevisionStore(),
364            $services->getContentLanguage(),
365            $services->getParserFactory(),
366            $services->getUserEditTracker(),
367            $services->getUserGroupManager(),
368            $services->getPermissionManager(),
369            $services->getRestrictionStore(),
370            $services->getUserIdentityUtils(),
371            $services->getUserNameUtils(),
372            WikiMap::getCurrentWikiDbDomain()->getId()
373        );
374    },
375    ServiceNames::TextExtractor => static function ( MediaWikiServices $services ): TextExtractor {
376        return new TextExtractor( $services->get( AbuseFilterHookRunner::SERVICE_NAME ) );
377    },
378    ServiceNames::VariablesManager => static function ( MediaWikiServices $services ): VariablesManager {
379        return new VariablesManager(
380            $services->get( KeywordsManager::SERVICE_NAME ),
381            $services->get( LazyVariableComputer::SERVICE_NAME )
382        );
383    },
384    ServiceNames::VariableGeneratorFactory => static function (
385        MediaWikiServices $services
386    ): VariableGeneratorFactory {
387        return new VariableGeneratorFactory(
388            $services->get( AbuseFilterHookRunner::SERVICE_NAME ),
389            $services->get( TextExtractor::SERVICE_NAME ),
390            $services->getMimeAnalyzer(),
391            $services->getRepoGroup(),
392            $services->getWikiPageFactory(),
393            $services->getUserFactory()
394        );
395    },
396    ServiceNames::EditRevUpdater => static function ( MediaWikiServices $services ): EditRevUpdater {
397        return new EditRevUpdater(
398            $services->get( CentralDBManager::SERVICE_NAME ),
399            $services->getRevisionLookup(),
400            $services->getDBLoadBalancerFactory(),
401            WikiMap::getCurrentWikiDbDomain()->getId()
402        );
403    },
404    ServiceNames::BlockedDomainStorage => static function (
405        MediaWikiServices $services
406    ): IBlockedDomainStorage {
407        if ( $services->getExtensionRegistry()->isLoaded( 'CommunityConfiguration' ) ) {
408            $provider = CommunityConfigurationServices::wrap( $services )
409                ->getConfigurationProviderFactory()
410                ->newProvider( BlockedDomainConfigProvider::PROVIDER_ID );
411            if ( !$provider instanceof BlockedDomainConfigProvider ) {
412                throw new LogicException(
413                    BlockedDomainConfigProvider::PROVIDER_ID . ' is expected to be ' .
414                    'an instance of ' . BlockedDomainConfigProvider::class
415                );
416            }
417            return $provider;
418        } else {
419            return new CustomBlockedDomainStorage(
420                $services->getLocalServerObjectCache(),
421                $services->getRevisionLookup(),
422                $services->getWikiPageFactory(),
423                $services->get( BlockedDomainValidator::SERVICE_NAME )
424            );
425        }
426    },
427    ServiceNames::BlockedDomainValidator => static function (
428        MediaWikiServices $services
429    ): BlockedDomainValidator {
430        return new BlockedDomainValidator(
431            $services->getUrlUtils()
432        );
433    },
434    ServiceNames::BlockedDomainFilter => static function (
435        MediaWikiServices $services
436    ): IBlockedDomainFilter {
437        if (
438            $services->getMainConfig()->get( 'AbuseFilterEnableBlockedExternalDomain' )
439        ) {
440            return new BlockedDomainFilter(
441                $services->get( VariablesManager::SERVICE_NAME ),
442                $services->get( IBlockedDomainStorage::SERVICE_NAME )
443            );
444        } else {
445            return new NoopBlockedDomainFilter();
446        }
447    },
448    ServiceNames::ProtectedVariablesLookup => static function ( MediaWikiServices $services ) {
449        return new AbuseFilterProtectedVariablesLookup(
450            new ServiceOptions(
451                AbuseFilterProtectedVariablesLookup::CONSTRUCTOR_OPTIONS,
452                $services->getMainConfig()
453            ),
454            $services->get( AbuseFilterHookRunner::SERVICE_NAME )
455        );
456    },
457    ServiceNames::LogDetailsLookup => static function ( MediaWikiServices $services ) {
458        return new AbuseFilterLogDetailsLookup(
459            $services->getConnectionProvider(),
460            $services->get( PermManager::SERVICE_NAME ),
461            $services->get( FilterLookup::SERVICE_NAME )
462        );
463    },
464    ServiceNames::AbuseLogConditionFactory => static function (
465        MediaWikiServices $services
466    ): AbuseLogConditionFactory {
467        return new AbuseLogConditionFactory(
468            $services->getConnectionProvider(),
469            $services->getTempUserConfig()
470        );
471    },
472    ServiceNames::AbuseLogLookup => static function (
473        MediaWikiServices $services
474    ): AbuseLogLookup {
475        return new AbuseLogLookup(
476            $services->getConnectionProvider(),
477            $services->get( PermManager::SERVICE_NAME )
478        );
479    },
480    ServiceNames::TemporaryAccountIPsViewerSpecification => static function (
481        MediaWikiServices $services
482    ): TemporaryAccountIPsViewerSpecification {
483        return new TemporaryAccountIPsViewerSpecification(
484            $services->getTempUserConfig(),
485            $services->hasService( 'CheckUserPermissionManager' ) ?
486                $services->get( 'CheckUserPermissionManager' ) :
487                null
488        );
489    },
490    // b/c for extensions
491    'AbuseFilterRunnerFactory' => static function ( MediaWikiServices $services ): FilterRunnerFactory {
492        return $services->get( FilterRunnerFactory::SERVICE_NAME );
493    },
494];
495
496// @codeCoverageIgnoreEnd