Move "block-autopromote" key from $wgMainStash to 'db-replicated'

Keep the key mutation methods in the AbuseFilter class

Bug: T227376
Change-Id: I03feb05218789a3b73a31c9a94216daafcb7c145
This commit is contained in:
Aaron Schulz 2019-07-06 16:35:03 -07:00
parent 2bdb44d58b
commit 9e44f1a9e9
4 changed files with 65 additions and 34 deletions

View file

@ -960,6 +960,48 @@ class AbuseFilter {
return $cache->makeKey( 'abusefilter', 'rules', $group );
}
/**
* Gets the autopromotion block status for the given user
*
* @param User $target
* @return int
*/
public static function getAutoPromoteBlockStatus( User $target ) {
$store = ObjectCache::getInstance( 'db-replicated' );
return (int)$store->get( self::autoPromoteBlockKey( $store, $target ) );
}
/**
* Blocks autopromotion for the given user
*
* @param User $target
* @param User $performer
* @param string $msg The message to show in the log
* @param int $ttl Block duration, in seconds
* @return bool True on success, false on failure
*/
public static function blockAutoPromote( User $target, User $performer, $msg, $ttl ) {
$store = ObjectCache::getInstance( 'db-replicated' );
if ( !$store->set( self::autoPromoteBlockKey( $store, $target ), 1, $ttl ) ) {
// Failed to set key
return false;
}
$logEntry = new ManualLogEntry( 'rights', 'blockautopromote' );
$logEntry->setPerformer( $performer );
$logEntry->setTarget( $target->getUserPage() );
// These parameters are unused in our message, but some parts of the code check for them
$logEntry->setParameters( [
'4::oldgroups' => [],
'5::newgroups' => []
] );
$logEntry->setComment( $msg );
$logEntry->publish( $logEntry->insert() );
return true;
}
/**
* Unblocks autopromotion for the given user
*
@ -969,13 +1011,13 @@ class AbuseFilter {
* @return bool True on success, false on failure
*/
public static function unblockAutopromote( User $target, User $performer, $msg ) {
$key = self::autoPromoteBlockKey( $target );
$stash = MediaWikiServices::getInstance()->getMainObjectStash();
if ( !$stash->get( $key ) ) {
// Probably we already removed it
// Immediately expire (delete) the key, failing if it does not exist
$store = ObjectCache::getInstance( 'db-replicated' );
$expireAt = time() - $store::TTL_HOUR;
if ( !$store->changeTTL( self::autoPromoteBlockKey( $store, $target ), $expireAt ) ) {
// Key did not exist to begin with; nothing to do
return false;
}
$stash->delete( $key );
$logEntry = new ManualLogEntry( 'rights', 'restoreautopromote' );
$logEntry->setTarget( Title::makeTitle( NS_USER, $target->getName() ) );
@ -987,17 +1029,17 @@ class AbuseFilter {
] );
$logEntry->setPerformer( $performer );
$logEntry->publish( $logEntry->insert() );
return true;
}
/**
* @param User $user
* @param BagOStuff $store
* @param User $target
* @return string
*/
public static function autoPromoteBlockKey( User $user ) {
$cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
return $cache->makeKey( 'abusefilter', 'block-autopromote', $user->getId() );
private static function autoPromoteBlockKey( BagOStuff $store, User $target ) {
return $store->makeKey( 'abusefilter', 'block-autopromote', $target->getId() );
}
/**

View file

@ -327,12 +327,12 @@ class AbuseFilterHooks {
*/
public static function onGetAutoPromoteGroups( User $user, &$promote ) {
if ( $promote ) {
$key = AbuseFilter::autoPromoteBlockKey( $user );
$blocked = (bool)ObjectCache::getInstance( 'hash' )->getWithSetCallback(
$key,
30,
function () use ( $key ) {
return (int)MediaWikiServices::getInstance()->getMainObjectStash()->get( $key );
$cache = ObjectCache::getInstance( 'hash' );
$blocked = (bool)$cache->getWithSetCallback(
$cache->makeKey( 'abusefilter', 'block-autopromote', $user->getId() ),
$cache::TTL_PROC_LONG,
function () use ( $user ) {
return AbuseFilter::getAutoPromoteBlockStatus( $user );
}
);

View file

@ -958,27 +958,17 @@ class AbuseFilterRunner {
break;
case 'blockautopromote':
if ( !$this->user->isAnon() ) {
// Block for 5 days.
MediaWikiServices::getInstance()->getMainObjectStash()->set(
AbuseFilter::autoPromoteBlockKey( $this->user ), true, 5 * 86400
);
$logEntry = new ManualLogEntry( 'rights', 'blockautopromote' );
$logEntry->setPerformer( AbuseFilter::getFilterUser() );
$logEntry->setTarget( $this->user->getUserPage() );
// These parameters are unused in our message, but some parts of the code check for them
$logEntry->setParameters( [
'4::oldgroups' => [],
'5::newgroups' => []
] );
$logEntry->setComment(
// Block for 5 days
AbuseFilter::blockAutoPromote(
$this->user,
AbuseFilter::getFilterUser(),
5 * 86400,
wfMessage(
'abusefilter-blockautopromotereason',
$ruleDescription,
$ruleNumber
)->inContentLanguage()->text()
);
$logEntry->publish( $logEntry->insert() );
$message = [
'abusefilter-autopromote-blocked',

View file

@ -717,9 +717,8 @@ class AbuseFilterConsequencesTest extends MediaWikiTestCase {
case 'blockautopromote':
// Aborts the hook with 'abusefilter-autopromote-blocked' error and prevent promotion.
$expectedErrors['blockautopromote'][] = 'abusefilter-autopromote-blocked';
$key = MediaWikiServices::getInstance()->getMainObjectStash()->get(
AbuseFilter::autoPromoteBlockKey( self::$mUser ) );
if ( !$key ) {
$value = AbuseFilter::getAutoPromoteBlockStatus( self::$mUser );
if ( !$value ) {
$testErrorMessage = "The key for blocking autopromotion wasn't set.";
}
break;