/** * @param $action string * @param $parameters array * @param $title Title * @param $vars AbuseFilterVariableHolder * @param $rule_desc * @param $rule_number int|string * * @return array|null a message describing the action that was taken, * or null if no action was taken. The message is given as an array * containing the message key followed by any message parameters. * * @note: Returning the message as an array instead of a Message object is * needed for compatibility with MW 1.20: we will be constructing a * Status object from these messages, and before 1.21, Status did * not accept Message objects to be added directly. */ public static function takeConsequenceAction($action, $parameters, $title, $vars, $rule_desc, $rule_number) { global $wgAbuseFilterCustomActionsHandlers, $wgRequest; $message = null; switch ($action) { case 'disallow': if (strlen($parameters[0])) { $message = array($parameters[0], $rule_desc, $rule_number); } else { // Generic message. $message = array('abusefilter-disallowed', $rule_desc, $rule_number); } break; case 'block': global $wgUser, $wgAbuseFilterBlockDuration, $wgAbuseFilterAnonBlockDuration; $filterUser = AbuseFilter::getFilterUser(); // Create a block. $block = new Block(); $block->setTarget($wgUser->getName()); $block->setBlocker($filterUser); $block->mReason = wfMessage('abusefilter-blockreason', $rule_desc, $rule_number)->inContentLanguage()->text(); $block->isHardblock(false); $block->isAutoblocking(true); $block->prevents('createaccount', true); $block->prevents('editownusertalk', false); if ($wgUser->isAnon() && $wgAbuseFilterAnonBlockDuration !== null) { // The user isn't logged in and the anon block duration doesn't default to $wgAbuseFilterBlockDuration $expiry = $wgAbuseFilterAnonBlockDuration; } else { $expiry = $wgAbuseFilterBlockDuration; } $block->mExpiry = SpecialBlock::parseExpiryInput($expiry); $block->insert(); // Log it # Prepare log parameters $logParams = array(); if ($block->mExpiry == 'infinity') { $logParams[] = 'indefinite'; } else { $logParams[] = $expiry; } $logParams[] = 'nocreate'; $log = new LogPage('block'); $log->addEntry('block', Title::makeTitle(NS_USER, $wgUser->getName()), wfMessage('abusefilter-blockreason', $rule_desc, $rule_number)->inContentLanguage()->text(), $logParams, self::getFilterUser()); $message = array('abusefilter-blocked-display', $rule_desc, $rule_number); break; case 'rangeblock': $filterUser = AbuseFilter::getFilterUser(); $range = IP::sanitizeRange($wgRequest->getIP() . '/16'); // Create a block. $block = new Block(); $block->setTarget($range); $block->setBlocker($filterUser); $block->mReason = wfMessage('abusefilter-blockreason', $rule_desc, $rule_number)->inContentLanguage()->text(); $block->isHardblock(false); $block->prevents('createaccount', true); $block->prevents('editownusertalk', false); $block->mExpiry = SpecialBlock::parseExpiryInput('1 week'); $block->insert(); // Log it # Prepare log parameters $logParams = array(); $logParams[] = 'indefinite'; $logParams[] = 'nocreate'; $log = new LogPage('block'); $log->addEntry('block', Title::makeTitle(NS_USER, $range), wfMessage('abusefilter-blockreason', $rule_desc, $rule_number)->inContentLanguage()->text(), $logParams, self::getFilterUser()); $message = array('abusefilter-blocked-display', $rule_desc, $rule_number); break; case 'degroup': global $wgUser; if (!$wgUser->isAnon()) { // Remove all groups from the user. Ouch. $groups = $wgUser->getGroups(); foreach ($groups as $group) { $wgUser->removeGroup($group); } $message = array('abusefilter-degrouped', $rule_desc, $rule_number); // Don't log it if there aren't any groups being removed! if (!count($groups)) { break; } // Log it. $log = new LogPage('rights'); $log->addEntry('rights', $wgUser->getUserPage(), wfMessage('abusefilter-degroupreason', $rule_desc, $rule_number)->inContentLanguage()->text(), array(implode(', ', $groups), ''), self::getFilterUser()); } break; case 'blockautopromote': global $wgUser, $wgMemc; if (!$wgUser->isAnon()) { $blockPeriod = (int) mt_rand(3 * 86400, 7 * 86400); // Block for 3-7 days. $wgMemc->set(self::autoPromoteBlockKey($wgUser), true, $blockPeriod); $message = array('abusefilter-autopromote-blocked', $rule_desc, $rule_number); } break; case 'flag': // Do nothing. Here for completeness. break; case 'tag': // Mark with a tag on recentchanges. global $wgUser; $actionID = implode('-', array($title->getPrefixedText(), $wgUser->getName(), $vars->getVar('ACTION')->toString())); if (!isset(AbuseFilter::$tagsToSet[$actionID])) { AbuseFilter::$tagsToSet[$actionID] = $parameters; } else { AbuseFilter::$tagsToSet[$actionID] = array_merge(AbuseFilter::$tagsToSet[$actionID], $parameters); } break; default: if (isset($wgAbuseFilterCustomActionsHandlers[$action])) { $custom_function = $wgAbuseFilterCustomActionsHandlers[$action]; if (is_callable($custom_function)) { $msg = call_user_func($custom_function, $action, $parameters, $title, $vars, $rule_desc, $rule_number); } if (isset($msg)) { $message = array($msg); } } else { wfDebugLog('AbuseFilter', "Unrecognised action {$action}"); } } return $message; }
/** * Block a list of selected users * * @param $users Array * @param $reason String * @param $tag String: replaces user pages * @param $talkTag String: replaces user talk pages * @return Array: list of html-safe usernames */ public static function doMassUserBlockInternal($users, $reason = '', $tag = '', $talkTag = '') { global $wgUser; $counter = $blockSize = 0; $safeUsers = array(); $log = new LogPage('block'); foreach ($users as $name) { # Enforce limits $counter++; $blockSize++; # Lets not go *too* fast if ($blockSize >= 20) { $blockSize = 0; wfWaitForSlaves(5); } $u = User::newFromName($name, false); // If user doesn't exist, it ought to be an IP then if (is_null($u) || !$u->getId() && !IP::isIPAddress($u->getName())) { continue; } $userTitle = $u->getUserPage(); $userTalkTitle = $u->getTalkPage(); $userpage = new Article($userTitle); $usertalk = new Article($userTalkTitle); $safeUsers[] = '[[' . $userTitle->getPrefixedText() . '|' . $userTitle->getText() . ']]'; $expirestr = $u->getId() ? 'indefinite' : '1 week'; $expiry = SpecialBlock::parseExpiryInput($expirestr); $anonOnly = IP::isIPAddress($u->getName()) ? 1 : 0; // Create the block $block = new Block(); $block->setTarget($u); $block->setBlocker($wgUser); $block->mReason = $reason; $block->mExpiry = $expiry; $block->isHardblock(!IP::isIPAddress($u->getName())); $block->isAutoblocking(true); $block->prevents('createaccount', true); $block->prevents('sendemail', false); $block->prevents('editownusertalk', false); $oldblock = Block::newFromTarget($u->getName()); if (!$oldblock) { $block->insert(); # Prepare log parameters $logParams = array(); $logParams[] = $expirestr; if ($anonOnly) { $logParams[] = 'anononly'; } $logParams[] = 'nocreate'; # Add log entry $log->addEntry('block', $userTitle, $reason, $logParams); } # Tag userpage! (check length to avoid mistakes) if (strlen($tag) > 2) { $userpage->doEdit($tag, $reason, EDIT_MINOR); } if (strlen($talkTag) > 2) { $usertalk->doEdit($talkTag, $reason, EDIT_MINOR); } } return $safeUsers; }
/** * @param $result ApiResult * @param $vals array * @param $params string * @param $type string * @param $action string * @param $ts * @return array */ public static function addLogParams($result, &$vals, $params, $type, $action, $ts) { $params = explode("\n", $params); switch ($type) { case 'move': if (isset($params[0])) { $title = Title::newFromText($params[0]); if ($title) { $vals2 = array(); ApiQueryBase::addTitleInfo($vals2, $title, 'new_'); $vals[$type] = $vals2; } } if (isset($params[1]) && $params[1]) { $vals[$type]['suppressedredirect'] = ''; } $params = null; break; case 'patrol': $vals2 = array(); list($vals2['cur'], $vals2['prev'], $vals2['auto']) = $params; $vals[$type] = $vals2; $params = null; break; case 'rights': $vals2 = array(); list($vals2['old'], $vals2['new']) = $params; $vals[$type] = $vals2; $params = null; break; case 'block': if ($action == 'unblock') { break; } $vals2 = array(); list($vals2['duration'], $vals2['flags']) = $params; // Indefinite blocks have no expiry time if (SpecialBlock::parseExpiryInput($params[0]) !== wfGetDB(DB_SLAVE)->getInfinity()) { $vals2['expiry'] = wfTimestamp(TS_ISO_8601, strtotime($params[0], wfTimestamp(TS_UNIX, $ts))); } $vals[$type] = $vals2; $params = null; break; } if (!is_null($params)) { $result->setIndexedTagName($params, 'param'); $vals = array_merge($vals, $params); } return $vals; }
/** * @param ApiResult $result * @param array $vals * @param string $params * @param string $type * @param string $action * @param string $ts * @param bool $legacy * @return array */ public static function addLogParams($result, &$vals, $params, $type, $action, $ts, $legacy = false) { switch ($type) { case 'move': if ($legacy) { $targetKey = 0; $noredirKey = 1; } else { $targetKey = '4::target'; $noredirKey = '5::noredir'; } if (isset($params[$targetKey])) { $title = Title::newFromText($params[$targetKey]); if ($title) { $vals2 = array(); ApiQueryBase::addTitleInfo($vals2, $title, 'new_'); $vals[$type] = $vals2; } } if (isset($params[$noredirKey]) && $params[$noredirKey]) { $vals[$type]['suppressedredirect'] = ''; } $params = null; break; case 'patrol': if ($legacy) { $cur = 0; $prev = 1; $auto = 2; } else { $cur = '4::curid'; $prev = '5::previd'; $auto = '6::auto'; } $vals2 = array(); $vals2['cur'] = $params[$cur]; $vals2['prev'] = $params[$prev]; $vals2['auto'] = $params[$auto]; $vals[$type] = $vals2; $params = null; break; case 'rights': $vals2 = array(); if ($legacy) { list($vals2['old'], $vals2['new']) = $params; } else { $vals2['new'] = implode(', ', $params['5::newgroups']); $vals2['old'] = implode(', ', $params['4::oldgroups']); } $vals[$type] = $vals2; $params = null; break; case 'block': if ($action == 'unblock') { break; } $vals2 = array(); list($vals2['duration'], $vals2['flags']) = $params; // Indefinite blocks have no expiry time if (SpecialBlock::parseExpiryInput($params[0]) !== wfGetDB(DB_SLAVE)->getInfinity()) { $vals2['expiry'] = wfTimestamp(TS_ISO_8601, strtotime($params[0], wfTimestamp(TS_UNIX, $ts))); } $vals[$type] = $vals2; $params = null; break; case 'upload': if (isset($params['img_timestamp'])) { $params['img_timestamp'] = wfTimestamp(TS_ISO_8601, $params['img_timestamp']); } break; } if (!is_null($params)) { $logParams = array(); // Keys like "4::paramname" can't be used for output so we change them to "paramname" foreach ($params as $key => $value) { if (strpos($key, ':') === false) { $logParams[$key] = $value; continue; } $logParam = explode(':', $key, 3); $logParams[$logParam[2]] = $value; } $result->setIndexedTagName($logParams, 'param'); $result->setIndexedTagName_recursive($logParams, 'param'); $vals = array_merge($vals, $logParams); } return $vals; }
/** * Convert a submitted expiry time, which may be relative ("2 weeks", etc) or absolute * ("24 May 2034"), into an absolute timestamp we can put into the database. * @param $expiry String: whatever was typed into the form * @return String: timestamp or "infinity" string for th DB implementation * @deprecated since 1.18 moved to SpecialBlock::parseExpiryInput() */ public static function parseExpiryInput($expiry) { wfDeprecated(__METHOD__, '1.18'); return SpecialBlock::parseExpiryInput($expiry); }
/** * @param $result ApiResult * @param $vals array * @param $params string * @param $type string * @param $action string * @param $ts * @param $legacy bool * @return array */ public static function addLogParams($result, &$vals, $params, $type, $action, $ts, $legacy = false) { switch ($type) { case 'move': if ($legacy) { $targetKey = 0; $noredirKey = 1; } else { $targetKey = '4::target'; $noredirKey = '5::noredir'; } if (isset($params[$targetKey])) { $title = Title::newFromText($params[$targetKey]); if ($title) { $vals2 = array(); ApiQueryBase::addTitleInfo($vals2, $title, 'new_'); $vals[$type] = $vals2; } } if (isset($params[$noredirKey]) && $params[$noredirKey]) { $vals[$type]['suppressedredirect'] = ''; } $params = null; break; case 'patrol': if ($legacy) { $cur = 0; $prev = 1; $auto = 2; } else { $cur = '4::curid'; $prev = '5::previd'; $auto = '6::auto'; } $vals2 = array(); $vals2['cur'] = $params[$cur]; $vals2['prev'] = $params[$prev]; $vals2['auto'] = $params[$auto]; $vals[$type] = $vals2; $params = null; break; case 'rights': $vals2 = array(); list($vals2['old'], $vals2['new']) = $params; $vals[$type] = $vals2; $params = null; break; case 'block': if ($action == 'unblock') { break; } $vals2 = array(); list($vals2['duration'], $vals2['flags']) = $params; // Indefinite blocks have no expiry time if (SpecialBlock::parseExpiryInput($params[0]) !== wfGetDB(DB_SLAVE)->getInfinity()) { $vals2['expiry'] = wfTimestamp(TS_ISO_8601, strtotime($params[0], wfTimestamp(TS_UNIX, $ts))); } $vals[$type] = $vals2; $params = null; break; } if (!is_null($params)) { $result->setIndexedTagName($params, 'param'); $result->setIndexedTagName_recursive($params, 'param'); $vals = array_merge($vals, $params); } return $vals; }
public static function takeConsequenceAction($action, $parameters, $title, $vars, $rule_desc) { $display = ''; switch ($action) { case 'disallow': if (strlen($parameters[0])) { $display .= wfMsgExt($parameters[0], 'parseinline', array($rule_desc)) . "\n"; } else { // Generic message. $display .= wfMsgExt('abusefilter-disallowed', 'parseinline', array($rule_desc)) . "<br />\n"; } break; case 'block': global $wgUser, $wgAbuseFilterBlockDuration; $filterUser = AbuseFilter::getFilterUser(); // Create a block. $block = new Block(); $block->setTarget($wgUser->getName()); $block->setBlocker($filterUser); $block->mReason = wfMsgForContent('abusefilter-blockreason', $rule_desc); $block->isHardblock(false); $block->prevents('createaccount', true); $block->mExpiry = SpecialBlock::parseExpiryInput($wgAbuseFilterBlockDuration); $block->insert(); // Log it # Prepare log parameters $logParams = array(); if ($block->mExpiry == 'infinity') { $logParams[] = 'indefinite'; } else { $logParams[] = $wgAbuseFilterBlockDuration; } $logParams[] = 'nocreate, angry-autoblock'; $log = new LogPage('block'); $log->addEntry('block', Title::makeTitle(NS_USER, $wgUser->getName()), wfMsgForContent('abusefilter-blockreason', $rule_desc), $logParams, self::getFilterUser()); $display .= wfMsgExt('abusefilter-blocked-display', 'parseinline', array($rule_desc)) . "<br />\n"; break; case 'rangeblock': $filterUser = AbuseFilter::getFilterUser(); $range = IP::sanitizeRange(wfGetIP() . '/16'); // Create a block. $block = new Block(); $block->setTarget($range); $block->setBlocker($filterUser); $block->mReason = wfMsgForContent('abusefilter-blockreason', $rule_desc); $block->isHardblock(false); $block->prevents('createaccount', true); $block->mExpiry = SpecialBlock::parseExpiryInput('1 week'); $block->insert(); // Log it # Prepare log parameters $logParams = array(); $logParams[] = 'indefinite'; $logParams[] = 'nocreate, angry-autoblock'; $log = new LogPage('block'); $log->addEntry('block', Title::makeTitle(NS_USER, $range), wfMsgForContent('abusefilter-blockreason', $rule_desc), $logParams, self::getFilterUser()); $display .= wfMsgExt('abusefilter-blocked-display', 'parseinline', $rule_desc) . "<br />\n"; break; case 'degroup': global $wgUser; if (!$wgUser->isAnon()) { // Remove all groups from the user. Ouch. $groups = $wgUser->getGroups(); foreach ($groups as $group) { $wgUser->removeGroup($group); } $display .= wfMsgExt('abusefilter-degrouped', 'parseinline', array($rule_desc)) . "<br />\n"; // Don't log it if there aren't any groups being removed! if (!count($groups)) { break; } // Log it. $log = new LogPage('rights'); $log->addEntry('rights', $wgUser->getUserPage(), wfMsgForContent('abusefilter-degroupreason', $rule_desc), array(implode(', ', $groups), wfMsgForContent('rightsnone')), self::getFilterUser()); } break; case 'blockautopromote': global $wgUser, $wgMemc; if (!$wgUser->isAnon()) { $blockPeriod = (int) mt_rand(3 * 86400, 7 * 86400); // Block for 3-7 days. $wgMemc->set(self::autoPromoteBlockKey($wgUser), true, $blockPeriod); $display .= wfMsgExt('abusefilter-autopromote-blocked', 'parseinline', array($rule_desc)) . "<br />\n"; } break; case 'flag': // Do nothing. Here for completeness. break; case 'tag': // Mark with a tag on recentchanges. global $wgUser; $actionID = implode('-', array($title->getPrefixedText(), $wgUser->getName(), $vars->getVar('ACTION')->toString())); AbuseFilter::$tagsToSet[$actionID] = $parameters; break; default: wfDebugLog('AbuseFilter', "Unrecognised action {$action}"); } return $display; }
static function block($address, $reason, $expiry, $options = array()) { global $wgContLang; $expiry = SpecialBlock::parseExpiryInput($expiry); $errors = self::insertBlock($address, $reason, $expiry, $options); if (count($errors) > 0) { return $errors; } $anonOnly = in_array('anon-only', $options); $modify = in_array('modify', $options); // Log it. $logAction = $modify ? 'modify' : 'gblock2'; $flags = array(); if ($anonOnly) { $flags[] = wfMsgForContent('globalblocking-list-anononly'); } if ($expiry != 'infinity') { $displayExpiry = $wgContLang->timeanddate($expiry); $flags[] = wfMsgForContent('globalblocking-logentry-expiry', $displayExpiry); } else { $flags[] = wfMsgForContent('globalblocking-logentry-noexpiry'); } $info = implode(', ', $flags); $page = new LogPage('gblblock'); $page->addEntry($logAction, Title::makeTitleSafe(NS_USER, $address), $reason, array($info, $address)); return array(); }