mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/AbuseFilter.git
synced 2024-12-18 00:20:37 +00:00
bf28dbce0e
Some exposed variables (eg. `user_ip`) used in filters are sensitive and need to only be available to restricted groups of users. Back-end changes: - Add `AbuseFilterProtectedVariables` which defines what variables are protected by the new right `abusefilter-access-protected-vars` - Add the concept of a `protected` variable, the use of which will denote the entire filter as protected via a flag on `af_hidden` New UX features: - Display changes to the protected status of filters on history and diff pages - Check for protected variables and the right to see them in filter validation and don't allow a filter to be saved if it uses a variable that the user doesn't have access to - Check for the right to view protected variables before allowing access and edits to existing filters that use them Bug: T364465 Bug: T363906 Change-Id: I828bbb4015e87040f69a8e10c7888273c4f24dd3
228 lines
5.6 KiB
PHP
228 lines
5.6 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Extension\AbuseFilter;
|
|
|
|
use MediaWiki\Config\ServiceOptions;
|
|
use MediaWiki\Extension\AbuseFilter\Filter\AbstractFilter;
|
|
use MediaWiki\Permissions\Authority;
|
|
|
|
/**
|
|
* This class simplifies the interactions between the AbuseFilter code and Authority, knowing
|
|
* what rights are required to perform AF-related actions.
|
|
*/
|
|
class AbuseFilterPermissionManager {
|
|
public const SERVICE_NAME = 'AbuseFilterPermissionManager';
|
|
|
|
public const CONSTRUCTOR_OPTIONS = [
|
|
'AbuseFilterProtectedVariables',
|
|
];
|
|
|
|
/**
|
|
* @var string[] Protected variables defined in config via AbuseFilterProtectedVariables
|
|
*/
|
|
private $protectedVariables;
|
|
|
|
/**
|
|
* @param ServiceOptions $options
|
|
*/
|
|
public function __construct(
|
|
ServiceOptions $options
|
|
) {
|
|
$this->protectedVariables = $options->get( 'AbuseFilterProtectedVariables' );
|
|
}
|
|
|
|
/**
|
|
* @param Authority $performer
|
|
* @return bool
|
|
*/
|
|
public function canEdit( Authority $performer ): bool {
|
|
$block = $performer->getBlock();
|
|
return (
|
|
!( $block && $block->isSitewide() ) &&
|
|
$performer->isAllowed( 'abusefilter-modify' )
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param Authority $performer
|
|
* @return bool
|
|
*/
|
|
public function canEditGlobal( Authority $performer ): bool {
|
|
return $performer->isAllowed( 'abusefilter-modify-global' );
|
|
}
|
|
|
|
/**
|
|
* Whether the user can edit the given filter.
|
|
*
|
|
* @param Authority $performer
|
|
* @param AbstractFilter $filter
|
|
* @return bool
|
|
*/
|
|
public function canEditFilter( Authority $performer, AbstractFilter $filter ): bool {
|
|
return (
|
|
$this->canEdit( $performer ) &&
|
|
!( $filter->isGlobal() && !$this->canEditGlobal( $performer ) )
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Whether the user can edit a filter with restricted actions enabled.
|
|
*
|
|
* @param Authority $performer
|
|
* @return bool
|
|
*/
|
|
public function canEditFilterWithRestrictedActions( Authority $performer ): bool {
|
|
return $performer->isAllowed( 'abusefilter-modify-restricted' );
|
|
}
|
|
|
|
/**
|
|
* @param Authority $performer
|
|
* @return bool
|
|
*/
|
|
public function canViewPrivateFilters( Authority $performer ): bool {
|
|
$block = $performer->getBlock();
|
|
return (
|
|
!( $block && $block->isSitewide() ) &&
|
|
$performer->isAllowedAny(
|
|
'abusefilter-modify',
|
|
'abusefilter-view-private'
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param Authority $performer
|
|
* @return bool
|
|
*/
|
|
public function canViewProtectedVariables( Authority $performer ) {
|
|
$block = $performer->getBlock();
|
|
return (
|
|
!( $block && $block->isSitewide() ) &&
|
|
$performer->isAllowed( 'abusefilter-access-protected-vars' )
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if the filter should be protected:
|
|
* - Return false if it uses no protected variables
|
|
* - Return true if it uses protected variables and the performer has view permissions
|
|
* - Return an array of used protected variables if the performer doesn't have
|
|
* view permissions
|
|
*
|
|
* @param Authority $performer
|
|
* @param string[] $usedVariables
|
|
* @return string[]|bool
|
|
*/
|
|
public function shouldProtectFilter( Authority $performer, $usedVariables ) {
|
|
$usedProtectedVariables = array_intersect( $usedVariables, $this->protectedVariables );
|
|
// Protected variables aren't used
|
|
if ( count( $usedProtectedVariables ) === 0 ) {
|
|
return false;
|
|
} else {
|
|
// Check for permissions if they are
|
|
if ( $this->canViewProtectedVariables( $performer ) ) {
|
|
return true;
|
|
} else {
|
|
return $usedProtectedVariables;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param Authority $performer
|
|
* @return bool
|
|
*/
|
|
public function canViewPrivateFiltersLogs( Authority $performer ): bool {
|
|
return $this->canViewPrivateFilters( $performer ) ||
|
|
$performer->isAllowed( 'abusefilter-log-private' );
|
|
}
|
|
|
|
/**
|
|
* @param Authority $performer
|
|
* @return bool
|
|
*/
|
|
public function canViewAbuseLog( Authority $performer ): bool {
|
|
return $performer->isAllowed( 'abusefilter-log' );
|
|
}
|
|
|
|
/**
|
|
* @param Authority $performer
|
|
* @return bool
|
|
*/
|
|
public function canHideAbuseLog( Authority $performer ): bool {
|
|
return $performer->isAllowed( 'abusefilter-hide-log' );
|
|
}
|
|
|
|
/**
|
|
* @param Authority $performer
|
|
* @return bool
|
|
*/
|
|
public function canRevertFilterActions( Authority $performer ): bool {
|
|
return $performer->isAllowed( 'abusefilter-revert' );
|
|
}
|
|
|
|
/**
|
|
* @param Authority $performer
|
|
* @param int $privacyLevel Bitmask of privacy flags
|
|
* @todo Take a Filter parameter
|
|
* @return bool
|
|
*/
|
|
public function canSeeLogDetailsForFilter( Authority $performer, int $privacyLevel ): bool {
|
|
if ( $privacyLevel ) {
|
|
$res = true;
|
|
if ( FilterUtils::isHidden( $privacyLevel ) ) {
|
|
if (
|
|
!$this->canSeeLogDetails( $performer ) ||
|
|
!$this->canViewPrivateFiltersLogs( $performer )
|
|
) {
|
|
$res = false;
|
|
}
|
|
}
|
|
|
|
if ( FilterUtils::isProtected( $privacyLevel ) ) {
|
|
if ( !$this->canViewProtectedVariables( $performer ) ) {
|
|
$res = false;
|
|
}
|
|
}
|
|
|
|
return $res;
|
|
}
|
|
|
|
return $this->canSeeLogDetails( $performer );
|
|
}
|
|
|
|
/**
|
|
* @param Authority $performer
|
|
* @return bool
|
|
*/
|
|
public function canSeeLogDetails( Authority $performer ): bool {
|
|
return $performer->isAllowed( 'abusefilter-log-detail' );
|
|
}
|
|
|
|
/**
|
|
* @param Authority $performer
|
|
* @return bool
|
|
*/
|
|
public function canSeePrivateDetails( Authority $performer ): bool {
|
|
return $performer->isAllowed( 'abusefilter-privatedetails' );
|
|
}
|
|
|
|
/**
|
|
* @param Authority $performer
|
|
* @return bool
|
|
*/
|
|
public function canSeeHiddenLogEntries( Authority $performer ): bool {
|
|
return $performer->isAllowed( 'abusefilter-hidden-log' );
|
|
}
|
|
|
|
/**
|
|
* @param Authority $performer
|
|
* @return bool
|
|
*/
|
|
public function canUseTestTools( Authority $performer ): bool {
|
|
// TODO: make independent
|
|
return $this->canViewPrivateFilters( $performer );
|
|
}
|
|
|
|
}
|