{ "name": "Abuse Filter", "author": [ "Andrew Garrett", "[https://www.mediawiki.org/wiki/User:Daimona_Eaytoy Daimona Eaytoy]", "Marius Hoch", "River Tarnell", "Victor Vasiliev" ], "url": "https://www.mediawiki.org/wiki/Extension:AbuseFilter", "descriptionmsg": "abusefilter-desc", "license-name": "GPL-2.0-or-later", "type": "antispam", "requires": { "MediaWiki": ">= 1.36.0" }, "AvailableRights": [ "abusefilter-modify", "abusefilter-log-detail", "abusefilter-view", "abusefilter-log", "abusefilter-privatedetails", "abusefilter-privatedetails-log", "abusefilter-modify-restricted", "abusefilter-revert", "abusefilter-view-private", "abusefilter-log-private", "abusefilter-hidden-log", "abusefilter-hide-log", "abusefilter-modify-global" ], "GroupPermissions": { "*": { "abusefilter-view": true, "abusefilter-log": true }, "sysop": { "abusefilter-log-detail": true, "abusefilter-view-private": true, "abusefilter-log-private": true, "abusefilter-modify": true, "abusefilter-modify-restricted": true, "abusefilter-revert": true }, "suppress": { "abusefilter-hidden-log": true, "abusefilter-hide-log": true } }, "GrantPermissions": { "basic": { "abusefilter-log": true, "abusefilter-log-detail": true, "abusefilter-view": true }, "oversight": { "abusefilter-hide-log": true }, "viewrestrictedlogs": { "abusefilter-hidden-log": true, "abusefilter-log-private": true, "abusefilter-view-private": true } }, "SpecialPages": { "AbuseLog": { "class": "SpecialAbuseLog", "services": [ "LinkBatchFactory", "PermissionManager", "AbuseFilterPermissionManager" ] }, "AbuseFilter": "SpecialAbuseFilter" }, "LogTypes": [ "abusefilter", "abusefilterprivatedetails" ], "LogNames": { "abusefilter": "abusefilter-log-name", "abusefilterprivatedetails": "abusefilterprivatedetails-log-name" }, "LogHeaders": { "abusefilter": "abusefilter-log-header" }, "LogActionsHandlers": { "abusefilter/hit": "MediaWiki\\Extension\\AbuseFilter\\LogFormatter\\AbuseLogHitFormatter", "abusefilter/modify": "MediaWiki\\Extension\\AbuseFilter\\LogFormatter\\AbuseFilterModifyLogFormatter", "abusefilter/create": "MediaWiki\\Extension\\AbuseFilter\\LogFormatter\\AbuseFilterModifyLogFormatter", "abusefilterprivatedetails/access": "LogFormatter", "suppress/hide-afl": "MediaWiki\\Extension\\AbuseFilter\\LogFormatter\\AbuseFilterSuppressLogFormatter", "suppress/unhide-afl": "MediaWiki\\Extension\\AbuseFilter\\LogFormatter\\AbuseFilterSuppressLogFormatter", "rights/blockautopromote": "MediaWiki\\Extension\\AbuseFilter\\LogFormatter\\AbuseFilterRightsLogFormatter", "rights/restoreautopromote": "MediaWiki\\Extension\\AbuseFilter\\LogFormatter\\AbuseFilterRightsLogFormatter" }, "ActionFilteredLogs": { "abusefilter": { "modify": [ "modify" ], "create": [ "create" ] } }, "LogRestrictions": { "abusefilter": "abusefilter-view", "abusefilterprivatedetails": "abusefilter-privatedetails-log" }, "APIModules": { "abusefilterchecksyntax": "ApiAbuseFilterCheckSyntax", "abusefilterevalexpression": "ApiAbuseFilterEvalExpression", "abusefilterunblockautopromote": "ApiAbuseFilterUnblockAutopromote", "abusefiltercheckmatch": "ApiAbuseFilterCheckMatch", "abuselogprivatedetails": "ApiAbuseLogPrivateDetails" }, "APIListModules": { "abuselog": "ApiQueryAbuseLog", "abusefilters": "ApiQueryAbuseFilters" }, "MessagesDirs": { "AbuseFilter": [ "i18n", "i18n/api" ] }, "ExtensionMessagesFiles": { "AbuseFilterAliases": "AbuseFilter.alias.php" }, "AutoloadNamespaces": { "MediaWiki\\Extension\\AbuseFilter\\VariableGenerator\\": "includes/VariableGenerator/", "MediaWiki\\Extension\\AbuseFilter\\Hooks\\": "includes/Hooks/", "MediaWiki\\Extension\\AbuseFilter\\LogFormatter\\": "includes/LogFormatter/", "MediaWiki\\Extension\\AbuseFilter\\Parser\\": "includes/ParserNS/", "MediaWiki\\Extension\\AbuseFilter\\Filter\\": "includes/Filter/", "MediaWiki\\Extension\\AbuseFilter\\Watcher\\": "includes/Watcher/" }, "AutoloadClasses": { "AbuseFilter": "includes/AbuseFilter.php", "AbuseFilterCachingParser" : "includes/parser/AbuseFilterCachingParser.php", "AbuseFilterParser": "includes/parser/AbuseFilterParser.php", "AbuseFilterTokenizer": "includes/parser/AbuseFilterTokenizer.php", "AbuseFilterHooks": "includes/AbuseFilterHooks.php", "AbuseFilterPreAuthenticationProvider": "includes/AbuseFilterPreAuthenticationProvider.php", "AbuseFilterRunner": "includes/AbuseFilterRunner.php", "AbuseFilterSpecialPage": "includes/special/AbuseFilterSpecialPage.php", "SpecialAbuseLog": "includes/special/SpecialAbuseLog.php", "AbuseLogPager": "includes/pagers/AbuseLogPager.php", "SpecialAbuseFilter": "includes/special/SpecialAbuseFilter.php", "AbuseFilterViewList": "includes/Views/AbuseFilterViewList.php", "AbuseFilterPager": "includes/pagers/AbuseFilterPager.php", "GlobalAbuseFilterPager": "includes/pagers/GlobalAbuseFilterPager.php", "AbuseFilterView": "includes/Views/AbuseFilterView.php", "AbuseFilterViewEdit": "includes/Views/AbuseFilterViewEdit.php", "AbuseFilterViewTools": "includes/Views/AbuseFilterViewTools.php", "AbuseFilterViewHistory": "includes/Views/AbuseFilterViewHistory.php", "AbuseFilterHistoryPager": "includes/pagers/AbuseFilterHistoryPager.php", "AbuseFilterViewRevert": "includes/Views/AbuseFilterViewRevert.php", "AbuseFilterViewTestBatch": "includes/Views/AbuseFilterViewTestBatch.php", "AbuseFilterViewExamine": "includes/Views/AbuseFilterViewExamine.php", "AbuseFilterExaminePager": "includes/pagers/AbuseFilterExaminePager.php", "AbuseFilterChangesList": "includes/AbuseFilterChangesList.php", "AbuseFilterViewDiff": "includes/Views/AbuseFilterViewDiff.php", "TableDiffFormatterFullContext": "includes/TableDiffFormatterFullContext.php", "AbuseFilterViewImport": "includes/Views/AbuseFilterViewImport.php", "AbuseFilterVariableHolder": "includes/AbuseFilterVariableHolder.php", "MediaWiki\\Extension\\AbuseFilter\\FilterLookup": "includes/FilterLookup.php", "MediaWiki\\Extension\\AbuseFilter\\KeywordsManager": "includes/KeywordsManager.php", "MediaWiki\\Extension\\AbuseFilter\\AbuseFilterPermissionManager": "includes/AbuseFilterPermissionManager.php", "MediaWiki\\Extension\\AbuseFilter\\AbuseFilterServices": "includes/AbuseFilterServices.php", "MediaWiki\\Extension\\AbuseFilter\\FilterProfiler": "includes/FilterProfiler.php", "MediaWiki\\Extension\\AbuseFilter\\ChangeTagger": "includes/ChangeTagger.php", "MediaWiki\\Extension\\AbuseFilter\\ChangeTagsManager": "includes/ChangeTagsManager.php", "MediaWiki\\Extension\\AbuseFilter\\BlockAutopromoteStore": "includes/BlockAutopromoteStore.php", "MediaWiki\\Extension\\AbuseFilter\\FilterUser": "includes/FilterUser.php", "MediaWiki\\Extension\\AbuseFilter\\CentralDBManager": "includes/CentralDBManager.php", "MediaWiki\\Extension\\AbuseFilter\\CentralDBNotAvailableException": "includes/CentralDBNotAvailableException.php", "MediaWiki\\Extension\\AbuseFilter\\FilterValidator": "includes/FilterValidator.php", "MediaWiki\\Extension\\AbuseFilter\\FilterCompare": "includes/FilterCompare.php", "MediaWiki\\Extension\\AbuseFilter\\FilterImporter": "includes/FilterImporter.php", "MediaWiki\\Extension\\AbuseFilter\\InvalidImportDataException": "includes/InvalidImportDataException.php", "AFComputedVariable": "includes/AFComputedVariable.php", "AFPData": "includes/parser/AFPData.php", "AFPException": "includes/parser/AFPException.php", "AFPParserState": "includes/parser/AFPParserState.php", "AFPToken": "includes/parser/AFPToken.php", "AFPTransitionBase": "includes/parser/AFPTransitionBase.php", "AFPTreeNode": "includes/parser/AFPTreeNode.php", "AFPSyntaxTree": "includes/parser/AFPSyntaxTree.php", "AFPTreeParser": "includes/parser/AFPTreeParser.php", "AFPUserVisibleException": "includes/parser/AFPUserVisibleException.php", "ApiQueryAbuseLog": "includes/api/ApiQueryAbuseLog.php", "ApiQueryAbuseFilters": "includes/api/ApiQueryAbuseFilters.php", "ApiAbuseFilterCheckSyntax": "includes/api/ApiAbuseFilterCheckSyntax.php", "ApiAbuseFilterEvalExpression": "includes/api/ApiAbuseFilterEvalExpression.php", "ApiAbuseFilterUnblockAutopromote": "includes/api/ApiAbuseFilterUnblockAutopromote.php", "ApiAbuseFilterCheckMatch": "includes/api/ApiAbuseFilterCheckMatch.php", "ApiAbuseLogPrivateDetails": "includes/api/ApiAbuseLogPrivateDetails.php", "NormalizeThrottleParameters": "maintenance/normalizeThrottleParameters.php", "FixOldLogEntries": "maintenance/fixOldLogEntries.php", "UpdateVarDumps": "maintenance/updateVarDumps.php" }, "TestAutoloadClasses": { "AbuseFilterConsequencesTest": "tests/phpunit/AbuseFilterConsequencesTest.php", "AbuseFilterParserTestCase": "tests/phpunit/unit/AbuseFilterParserTestCase.php", "AbuseFilterUploadTestTrait": "tests/phpunit/AbuseFilterUploadTestTrait.php", "AbuseFilterCreateAccountTestTrait": "tests/phpunit/AbuseFilterCreateAccountTestTrait.php", "AbuseFilterRowsAndFiltersTestTrait": "tests/phpunit/AbuseFilterRowsAndFiltersTestTrait.php" }, "ResourceModules": { "ext.abuseFilter": { "styles": "ext.abuseFilter.css" }, "ext.abuseFilter.edit": { "scripts": "ext.abuseFilter.edit.js", "messages": [ "abusefilter-edit-syntaxok", "abusefilter-edit-syntaxerr", "abusefilter-http-error", "abusefilter-edit-throttle-placeholder", "abusefilter-edit-tag-placeholder", "abusefilter-edit-warn-leave", "unknown-error" ], "dependencies": [ "mediawiki.util", "mediawiki.api", "mediawiki.confirmCloseWindow", "jquery.textSelection", "jquery.spinner", "oojs-ui-core", "oojs-ui-widgets" ] }, "ext.abuseFilter.tools": { "scripts": "ext.abuseFilter.tools.js", "messages": [ "abusefilter-reautoconfirm-notallowed", "abusefilter-reautoconfirm-none", "abusefilter-reautoconfirm-done", "abusefilter-http-error", "abusefilter-tools-syntax-error", "unknown-error" ], "dependencies": [ "mediawiki.api", "user.options", "jquery.spinner" ] }, "ext.abuseFilter.examine": { "scripts": "ext.abuseFilter.examine.js", "messages": [ "abusefilter-examine-match", "abusefilter-examine-nomatch", "abusefilter-examine-syntaxerror", "abusefilter-examine-notfound", "abusefilter-mustviewprivateoredit", "abusefilter-http-error", "unknown-error" ], "dependencies": [ "jquery.spinner", "mediawiki.api" ] }, "ext.abuseFilter.ace": { "scripts": "mode-abusefilter.js", "dependencies": "ext.codeEditor.ace" }, "ext.abuseFilter.visualEditor": { "scripts": "ve-abusefilter/ve.init.mw.AbuseFilterSaveErrorHandler.js", "targets": [ "desktop", "mobile" ] } }, "attributes": { "VisualEditor": { "PluginModules": [ "ext.abuseFilter.visualEditor" ] } }, "ResourceFileModulePaths": { "localBasePath": "modules", "remoteExtPath": "AbuseFilter/modules" }, "callback": "AbuseFilterHooks::onRegistration", "HookHandlers": { "ToolLinks": { "class": "MediaWiki\\Extension\\AbuseFilter\\Hooks\\Handlers\\ToolLinksHandler", "services": [ "AbuseFilterPermissionManager" ] }, "ChangeTags": { "class": "MediaWiki\\Extension\\AbuseFilter\\Hooks\\Handlers\\ChangeTagsHandler", "services": [ "AbuseFilterChangeTagsManager" ] }, "Tests": { "class": "MediaWiki\\Extension\\AbuseFilter\\Hooks\\Handlers\\TestsHandler" }, "SchemaChanges": { "class": "MediaWiki\\Extension\\AbuseFilter\\Hooks\\Handlers\\SchemaChangesHandler" } }, "Hooks": { "EditFilterMergedContent": "AbuseFilterHooks::onEditFilterMergedContent", "GetAutoPromoteGroups": "AbuseFilterHooks::onGetAutoPromoteGroups", "TitleMove": "AbuseFilterHooks::onTitleMove", "ArticleDelete": "AbuseFilterHooks::onArticleDelete", "RecentChange_save": "AbuseFilterHooks::onRecentChangeSave", "ListDefinedTags": "ChangeTags", "ChangeTagsListActive": "ChangeTags", "LoadExtensionSchemaUpdates": "SchemaChanges", "ContributionsToolLinks": "ToolLinks", "HistoryPageToolLinks": "ToolLinks", "UndeletePageToolLinks": "ToolLinks", "UploadVerifyUpload": "AbuseFilterHooks::onUploadVerifyUpload", "UploadStashFile": "AbuseFilterHooks::onUploadStashFile", "PageSaveComplete": "AbuseFilterHooks::onPageSaveComplete", "RenameUserSQL": "AbuseFilterHooks::onRenameUserSQL", "UserMergeAccountFields": "AbuseFilterHooks::onUserMergeAccountFields", "ParserOutputStashForEdit": "AbuseFilterHooks::onParserOutputStashForEdit", "UnitTestsAfterDatabaseSetup": "Tests", "UnitTestsBeforeDatabaseTeardown": "Tests" }, "ServiceWiringFiles": [ "includes/ServiceWiring.php" ], "config": { "AbuseFilterActions": { "value": { "throttle": true, "warn": true, "disallow": true, "blockautopromote": true, "block": true, "rangeblock": false, "degroup": false, "tag": true }, "description": "Array of enabled actions in the form [action name => is enabled?]. At the end of setup, false values will be filtered out" }, "AbuseFilterConditionLimit": { "value": 1000, "description": "The maximum number of 'conditions' that can be used each time the filters are run against a change. (More complex filters require more 'conditions')." }, "AbuseFilterParserClass": { "value": "AbuseFilterParser", "description": "Class of the parser to use. The only possible values are 'AbuseFilterParser' and 'AbuseFilterCachingParser' (experimental). The code should only use the ParserFactory service." }, "AbuseFilterEmergencyDisableThreshold": { "value": { "default": 0.05 }, "description": "Disable potentially dangerous actions (AbuseFilterRestrictions) of a filter if it matches more than X actions, constituting more than Y% (e.g. 0.05 = 5%) of the last Z actions, and the filter has been modified in the last S seconds. X is AbuseFilterEmergencyDisableCount, Y is AbuseFilterEmergencyDisableThreshold, S is AbuseFilterEmergencyDisableAge and Z is a number between 1 and AbuseFilterProfileActionsCap." }, "AbuseFilterEmergencyDisableCount": { "value": { "default": 2 }, "description": "See description for AbuseFilterEmergencyDisableThreshold" }, "AbuseFilterEmergencyDisableAge": { "value": { "default": 86400 }, "description": "See description for AbuseFilterEmergencyDisableThreshold" }, "AbuseFilterActionRestrictions": { "value": { "throttle": false, "warn": false, "disallow": false, "blockautopromote": true, "block": true, "rangeblock": true, "degroup": true, "tag": false }, "description": "Do users need 'abusefilter-modify-restricted' user right as well as 'abusefilter-modify' in order to create or modify filters which carry out this action? Array like [action name => is restricted?]" }, "AbuseFilterNotifications": { "value": false, "description": "Allows to configure the extension to send hit notifications to Special:RecentChanges or UDP. Available options: rc, udp, rcandudp" }, "AbuseFilterNotificationsPrivate": { "value": false, "description": "Enable notifications for private filters" }, "AbuseFilterCentralDB": { "value": null, "description": "Name of a database where global abuse filters will be stored in. To use a DB with prefixed tables, set this to \"{$databaseName}-{$prefix}\"." }, "AbuseFilterIsCentral": { "value": false, "description": "Set this variable to true for the wiki where global AbuseFilters are stored in" }, "AbuseFilterLocallyDisabledGlobalActions": { "value": { "throttle": false, "warn": false, "disallow": false, "blockautopromote": false, "block": false, "rangeblock": false, "degroup": false, "tag": false }, "description": "An array of actions which, if set on a global filter, will not be used for local hits of such filter (not in the central wiki). The array is [ action => will be disabled? ]. NOTE: Locally disabling throttle or warn will *not* disable the remaining actions." }, "AbuseFilterBlockDuration": { "value": "indefinite", "description": "Old standard block duration for logged in users. Kept for backward compatibility after T32024." }, "AbuseFilterAnonBlockDuration": { "value": null, "description": "Old standard block duration for anonymous users, $wgAbuseFilterBlockDuration will be used if null. Kept for backward compatibility after T32024." }, "AbuseFilterBlockAutopromoteDuration": { "value": 5, "description": "Duration, in days, for which users' autopromotion is blocked by filters." }, "AbuseFilterCustomActionsHandlers": { "value": [], "description": "Callback functions for custom actions" }, "AbuseFilterValidGroups": { "value": [ "default" ], "description": "The list of 'groups' filters can be divided into – used for applying edit filters to certain types of actions. By default there is only one group." }, "AbuseFilterDefaultWarningMessage": { "value": { "default": "abusefilter-warning" }, "description": "Default warning messages, per filter group" }, "AbuseFilterDefaultDisallowMessage": { "value": { "default": "abusefilter-disallowed" }, "description": "Default disallow messages, per filter group" }, "AbuseFilterLogIPMaxAge": { "value": 7776000, "description": "Age used as cutoff when purging old IP log data, defaults to 3 months. Used by maintenance script purgeOldLogIPData.php" }, "AbuseFilterSlowFilterRuntimeLimit": { "value": 500, "description": "Runtime in milliseconds before a filter is considered slow." }, "AbuseFilterProfileActionsCap": { "value": 10000, "description": "Number of action that determines when to reset profiling stats." }, "AbuseFilterRangeBlockSize": { "value": { "IPv4": 16, "IPv6": 19 }, "description": "Size of the range blocked by 'rangeblock' action." }, "AbuseFilterLogPrivateDetailsAccess": { "value": false, "description": "Whether accessing private information from a filter log entry is logged." }, "AbuseFilterPrivateDetailsForceReason": { "value": false, "description": "Whether users are forced to provide a reason for accessing private information from a filter log entry." }, "AbuseFilterLogIP": { "value": true, "description": "Whether to include IP in the abuse_filter_log" } }, "load_composer_autoloader": true, "manifest_version": 2 }