BlockedExternalDomains: Make this a special right, prohibit direct editing

Bug: T337431
Bug: T279275
Change-Id: I96d1e2c8d8728c26e38515032ef773770e26dda4
This commit is contained in:
James D. Forrester 2023-06-01 09:01:14 -04:00
parent 32ea2e5d76
commit fb50c1f019
6 changed files with 72 additions and 9 deletions

View file

@ -27,7 +27,8 @@
"abusefilter-log-private",
"abusefilter-hidden-log",
"abusefilter-hide-log",
"abusefilter-modify-global"
"abusefilter-modify-global",
"abusefilter-modify-blocked-external-domains"
],
"GroupPermissions": {
"*": {
@ -40,7 +41,8 @@
"abusefilter-log-private": true,
"abusefilter-modify": true,
"abusefilter-modify-restricted": true,
"abusefilter-revert": true
"abusefilter-revert": true,
"abusefilter-modify-blocked-external-domains": true
},
"suppress": {
"abusefilter-hidden-log": true,
@ -349,6 +351,9 @@
"UserRename": {
"class": "MediaWiki\\Extension\\AbuseFilter\\Hooks\\Handlers\\UserRenameHandler"
},
"EditPermission": {
"class": "MediaWiki\\Extension\\AbuseFilter\\Hooks\\Handlers\\EditPermissionHandler"
},
"PageSave": {
"class": "MediaWiki\\Extension\\AbuseFilter\\Hooks\\Handlers\\PageSaveHandler",
"services": [
@ -397,6 +402,7 @@
"UploadStashFile": "FilteredActions",
"PageSaveComplete": "PageSave",
"RenameUserSQL": "UserRename",
"getUserPermissionsErrors": "EditPermission",
"CheckUserInsertChangesRow": "CheckUser",
"CheckUserInsertPrivateEventRow": "CheckUser",
"CheckUserInsertLogEventRow": "CheckUser",

View file

@ -593,5 +593,8 @@
"notification-header-throttle-filter-actions": "The abuse filter $2 {{GENDER:$1|you}} recently edited had a high rate of matches and the following {{PLURAL:$4|action was|actions were}} automatically disabled: $3.",
"notification-header-throttle-filter-no-actions": "The abuse filter $2 {{GENDER:$1|you}} recently edited had a high rate of matches but no actions were automatically disabled.",
"notification-subject-throttle-filter": "An abuse filter {{GENDER:$1|you}} edited was throttled on {{SITENAME}}",
"notification-link-text-show-filter": "Show filter"
"notification-link-text-show-filter": "Show filter",
"right-abusefilter-modify-blocked-external-domains": "Create or modify what external domains are blocked from being linked",
"action-abusefilter-modify-blocked-external-domains": "create or modify what external domains are blocked from being linked",
"abusefilter-blocked-domains-cannot-edit-directly": "Create or modify what external domains are blocked from being linked must be done through [[Special:BlockedExternalDomains|the special page]]."
}

View file

@ -635,5 +635,8 @@
"notification-header-throttle-filter-actions": "Header text for a notification when an abuse filter was throttled after the user edited it and some actions were automatically disabled. Parameters:\n* $1 - the username of the viewing user, for use in GENDER\n* $2 - filter ID\n* $3 - list of actions that were disabled\n* $4 - number of disabled actions, for PLURAL",
"notification-header-throttle-filter-no-actions": "Header text for a notification when an abuse filter was throttled after the user edited it but no actions were automatically disabled. Parameters:\n* $1 - the username of the viewing user, for use in GENDER\n* $2 - filter ID",
"notification-subject-throttle-filter": "Email subject line for email notice when an abuse filter was throttled after the user edited it. Parameters:\n* $1 - the username of the receiving user, for use in GENDER",
"notification-link-text-show-filter": "Label for button that links to the filter that was throttled."
"notification-link-text-show-filter": "Label for button that links to the filter that was throttled.",
"right-abusefilter-modify-blocked-external-domains": "{{doc-right|abusefilter-modify-blocked-external-domains}}",
"action-abusefilter-modify-blocked-external-domains": "{{doc-action|abusefilter-modify-blocked-external-domains}}",
"abusefilter-blocked-domains-cannot-edit-directly": "Error message shown when someone tries to edit the list of blocked domains directly and bypass the Special page."
}

View file

@ -44,6 +44,8 @@ use Wikimedia\LightweightObjectStore\ExpirationAwareness;
class BlockedDomainStorage implements IDBAccessObject {
public const SERVICE_NAME = 'AbuseFilterBlockedDomainStorage';
public const TARGET_PAGE = 'BlockedExternalDomains.json';
private RevisionLookup $revisionLookup;
private BagOStuff $cache;
private UserFactory $userFactory;
@ -279,6 +281,6 @@ class BlockedDomainStorage implements IDBAccessObject {
* @return TitleValue TitleValue of the config json page
*/
public function getBlockedDomainPage() {
return new TitleValue( NS_MEDIAWIKI, 'BlockedExternalDomains.json' );
return new TitleValue( NS_MEDIAWIKI, self::TARGET_PAGE );
}
}

View file

@ -0,0 +1,51 @@
<?php
// phpcs:disable MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName
namespace MediaWiki\Extension\AbuseFilter\Hooks\Handlers;
use MediaWiki\Extension\AbuseFilter\BlockedDomainStorage;
use MediaWiki\MediaWikiServices;
use MediaWiki\Permissions\Hook\GetUserPermissionsErrorsHook;
use MessageSpecifier;
use Title;
use User;
/**
* This hook handler is for very simple checks, rather than the much more advanced ones
* undertaken by the FilteredActionsHandler.
*/
class EditPermissionHandler implements GetUserPermissionsErrorsHook {
/**
* @see https://www.mediawiki.org/wiki/Manual:Hooks/getUserPermissionsErrors
*
* @param Title $title
* @param User $user
* @param string $action
* @param array|string|MessageSpecifier &$result
* @return bool|void
*/
public function onGetUserPermissionsErrors( $title, $user, $action, &$result ) {
$services = MediaWikiServices::getInstance();
// Only do anything if we're enabled on this wiki.
if ( !$services->getMainConfig()->get( 'AbuseFilterEnableBlockedExternalDomain' ) ) {
return;
}
// Ignore all actions and pages except MediaWiki: edits (and creates)
// to the page we care about
if (
!( $action == 'create' || $action == 'edit' ) ||
!$title->inNamespace( NS_MEDIAWIKI ) ||
$title->getDBkey() !== BlockedDomainStorage::TARGET_PAGE
) {
return;
}
// Prohibit direct actions on our page.
$result = [ 'abusefilter-blocked-domains-cannot-edit-directly', BlockedDomainStorage::TARGET_PAGE ];
return false;
}
}

View file

@ -72,10 +72,8 @@ class BlockedExternalDomains extends SpecialPage {
$out->setPageTitle( $this->msg( 'abusefilter-blocked-domains-title' ) );
$out->wrapWikiMsg( "$1", 'abusefilter-blocked-domains-intro' );
// Since everything is stored as a json page in MediaWiki namespace, if we use any
// other right, it could be bypassed by the user simply editing the json directly
// so let's make the right the exact same to avoid complications.
$userCanManage = $this->getAuthority()->isAllowed( 'editsitejson' );
// Direct editing of this page is blocked via EditPermissionHandler
$userCanManage = $this->getAuthority()->isAllowed( 'abusefilter-modify-blocked-external-domains' );
// Show form to add a blocked domain
if ( $userCanManage ) {