mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/AbuseFilter.git
synced 2024-11-24 06:03:49 +00:00
4720c97530
Currently we strongly abuse (pardon the pun) the AbuseFilter class: its purpose should be to hold static functions intended as generic utility functions (e.g. to format messages, determine whether a filter is global etc.), but we actually use it for all methods related to running filters. This patch creates a new class, AbuseFilterRunner, containing all such methods, which have been made non-static. This leads to several improvements (also for related methods and the parser), and opens the way to further improve the code. Aside from making the code prettier, less global and easier to test, this patch could also produce a performance improvement, although I don't have tools to measure that. Also note that many public methods have been removed, and almost any of them has been made protected; a couple of them (the ones used from outside) are left for back-compat, and will be removed in the future. Change-Id: I2eab2e50356eeb5224446ee2d0df9c787ae95b80
401 lines
14 KiB
JSON
401 lines
14 KiB
JSON
{
|
||
"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.34.0"
|
||
},
|
||
"AvailableRights": [
|
||
"abusefilter-modify",
|
||
"abusefilter-log-detail",
|
||
"abusefilter-view",
|
||
"abusefilter-log",
|
||
"abusefilter-private",
|
||
"abusefilter-private-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-modify": true
|
||
}
|
||
},
|
||
"GrantPermissions": {
|
||
"basic": {
|
||
"abusefilter-log": true,
|
||
"abusefilter-log-detail": true,
|
||
"abusefilter-view": true
|
||
},
|
||
"rollback": {
|
||
"abusefilter-revert": true
|
||
},
|
||
"viewrestrictedlogs": {
|
||
"abusefilter-hidden-log": true,
|
||
"abusefilter-view-private": true
|
||
}
|
||
},
|
||
"SpecialPages": {
|
||
"AbuseLog": "SpecialAbuseLog",
|
||
"AbuseFilter": "SpecialAbuseFilter"
|
||
},
|
||
"LogTypes": [
|
||
"abusefilter",
|
||
"abusefilterprivatedetails"
|
||
],
|
||
"LogNames": {
|
||
"abusefilter": "abusefilter-log-name",
|
||
"abusefilterprivatedetails": "abusefilterprivatedetails-log-name"
|
||
},
|
||
"LogHeaders": {
|
||
"abusefilter": "abusefilter-log-header"
|
||
},
|
||
"LogActionsHandlers": {
|
||
"abusefilter/hit": "AbuseLogHitFormatter",
|
||
"abusefilter/modify": "AbuseFilterModifyLogFormatter",
|
||
"abusefilter/create": "AbuseFilterModifyLogFormatter",
|
||
"abusefilterprivatedetails/access": "LogFormatter",
|
||
"suppress/hide-afl": "AbuseFilterSuppressLogFormatter",
|
||
"suppress/unhide-afl": "AbuseFilterSuppressLogFormatter"
|
||
},
|
||
"ActionFilteredLogs": {
|
||
"abusefilter": {
|
||
"modify": [
|
||
"modify"
|
||
],
|
||
"create": [
|
||
"create"
|
||
]
|
||
}
|
||
},
|
||
"LogRestrictions": {
|
||
"abusefilterprivatedetails": "abusefilter-private-log"
|
||
},
|
||
"APIModules": {
|
||
"abusefilterchecksyntax": "ApiAbuseFilterCheckSyntax",
|
||
"abusefilterevalexpression": "ApiAbuseFilterEvalExpression",
|
||
"abusefilterunblockautopromote": "ApiAbuseFilterUnblockAutopromote",
|
||
"abusefiltercheckmatch": "ApiAbuseFilterCheckMatch"
|
||
},
|
||
"APIListModules": {
|
||
"abuselog": "ApiQueryAbuseLog",
|
||
"abusefilters": "ApiQueryAbuseFilters"
|
||
},
|
||
"MessagesDirs": {
|
||
"AbuseFilter": [
|
||
"i18n",
|
||
"i18n/api"
|
||
]
|
||
},
|
||
"ExtensionMessagesFiles": {
|
||
"AbuseFilterAliases": "AbuseFilter.alias.php"
|
||
},
|
||
"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",
|
||
"SpecialAbuseLog": "includes/special/SpecialAbuseLog.php",
|
||
"AbuseLogPager": "includes/pagers/AbuseLogPager.php",
|
||
"SpecialAbuseFilter": "includes/special/SpecialAbuseFilter.php",
|
||
"AbuseLogHitFormatter": "includes/AbuseLogHitFormatter.php",
|
||
"AbuseFilterModifyLogFormatter": "includes/AbuseFilterModifyLogFormatter.php",
|
||
"AbuseFilterSuppressLogFormatter": "includes/AbuseFilterSuppressLogFormatter.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",
|
||
"AFComputedVariable": "includes/AFComputedVariable.php",
|
||
"AFPData": "includes/parser/AFPData.php",
|
||
"AFPException": "includes/parser/AFPException.php",
|
||
"AFPParserState": "includes/parser/AFPParserState.php",
|
||
"AFPToken": "includes/parser/AFPToken.php",
|
||
"AFPTreeNode": "includes/parser/AFPTreeNode.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",
|
||
"NormalizeThrottleParameters": "maintenance/normalizeThrottleParameters.php",
|
||
"AbuseFilterConsequencesTest": "tests/phpunit/AbuseFilterConsequencesTest.php",
|
||
"AbuseFilterParserTestCase": "tests/phpunit/AbuseFilterParserTestCase.php",
|
||
"FixOldLogEntries": "maintenance/fixOldLogEntries.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",
|
||
"unknown-error"
|
||
],
|
||
"dependencies": [
|
||
"mediawiki.api",
|
||
"mediawiki.notify",
|
||
"user.tokens",
|
||
"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",
|
||
"Hooks": {
|
||
"EditFilterMergedContent": "AbuseFilterHooks::onEditFilterMergedContent",
|
||
"GetAutoPromoteGroups": "AbuseFilterHooks::onGetAutoPromoteGroups",
|
||
"TitleMove": "AbuseFilterHooks::onTitleMove",
|
||
"ArticleDelete": "AbuseFilterHooks::onArticleDelete",
|
||
"RecentChange_save": "AbuseFilterHooks::onRecentChangeSave",
|
||
"ListDefinedTags": "AbuseFilterHooks::onListDefinedTags",
|
||
"ChangeTagsListActive": "AbuseFilterHooks::onChangeTagsListActive",
|
||
"LoadExtensionSchemaUpdates": "AbuseFilterHooks::onLoadExtensionSchemaUpdates",
|
||
"ContributionsToolLinks": "AbuseFilterHooks::onContributionsToolLinks",
|
||
"HistoryPageToolLinks": "AbuseFilterHooks::onHistoryPageToolLinks",
|
||
"UploadVerifyUpload": "AbuseFilterHooks::onUploadVerifyUpload",
|
||
"UploadStashFile": "AbuseFilterHooks::onUploadStashFile",
|
||
"PageContentSaveComplete": "AbuseFilterHooks::onPageContentSaveComplete",
|
||
"UserMergeAccountFields": "AbuseFilterHooks::onUserMergeAccountFields",
|
||
"ParserOutputStashForEdit": "AbuseFilterHooks::onParserOutputStashForEdit",
|
||
"UnitTestsAfterDatabaseSetup": "AbuseFilterHooks::onUnitTestsAfterDatabaseSetup",
|
||
"UnitTestsBeforeDatabaseTeardown": "AbuseFilterHooks::onUnitTestsBeforeDatabaseTeardown"
|
||
},
|
||
"config": {
|
||
"AbuseFilterActions": {
|
||
"value": {
|
||
"throttle": true,
|
||
"warn": true,
|
||
"disallow": true,
|
||
"blockautopromote": true,
|
||
"block": true,
|
||
"rangeblock": false,
|
||
"degroup": true,
|
||
"tag": true
|
||
},
|
||
"_merge_strategy": "array_plus",
|
||
"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"
|
||
},
|
||
"AbuseFilterEmergencyDisableThreshold": {
|
||
"value": {
|
||
"default": 0.05
|
||
},
|
||
"_merge_strategy": "array_plus",
|
||
"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
|
||
},
|
||
"_merge_strategy": "array_plus",
|
||
"description": "See description for AbuseFilterEmergencyDisableThreshold"
|
||
},
|
||
"AbuseFilterEmergencyDisableAge": {
|
||
"value": {
|
||
"default": 86400
|
||
},
|
||
"_merge_strategy": "array_plus",
|
||
"description": "See description for AbuseFilterEmergencyDisableThreshold"
|
||
},
|
||
"AbuseFilterRestrictions": {
|
||
"value": {
|
||
"throttle": false,
|
||
"warn": false,
|
||
"disallow": false,
|
||
"blockautopromote": true,
|
||
"block": true,
|
||
"rangeblock": true,
|
||
"degroup": true,
|
||
"tag": false
|
||
},
|
||
"_merge_strategy": "array_plus",
|
||
"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"
|
||
},
|
||
"AbuseFilterDisallowGlobalLocalBlocks": {
|
||
"value": false,
|
||
"description": "Disallow centralised filters from taking actions that locally block, remove from groups, or revoke permissions"
|
||
},
|
||
"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."
|
||
},
|
||
"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"
|
||
},
|
||
"_merge_strategy": "array_plus",
|
||
"description": "Default warning messages, per filter group"
|
||
},
|
||
"AbuseFilterDefaultDisallowMessage": {
|
||
"value": {
|
||
"default": "abusefilter-disallowed"
|
||
},
|
||
"description": "Default disallow messages, per filter group",
|
||
"_merge_strategy": "array_plus"
|
||
},
|
||
"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."
|
||
},
|
||
"AbuseFilterPrivateLog": {
|
||
"value": false,
|
||
"description": "Whether accessing private information from a filter log entry is logged."
|
||
},
|
||
"AbuseFilterForceSummary": {
|
||
"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
|
||
}
|