Ejemplo n.º 1
0
 function show()
 {
     $out = $this->getOutput();
     $user = $this->getUser();
     // Header
     $out->addWikiMsg('abusefilter-tools-text');
     // Expression evaluator
     $eval = '';
     $eval .= AbuseFilter::buildEditBox('', 'wpTestExpr');
     // Only let users with permission actually test it
     if ($user->isAllowed('abusefilter-modify')) {
         $eval .= Xml::tags('p', null, Xml::element('input', array('type' => 'button', 'id' => 'mw-abusefilter-submitexpr', 'value' => $this->msg('abusefilter-tools-submitexpr')->text())));
         $eval .= Xml::element('p', array('id' => 'mw-abusefilter-expr-result'), ' ');
     }
     $eval = Xml::fieldset($this->msg('abusefilter-tools-expr')->text(), $eval);
     $out->addHTML($eval);
     $out->addModules('ext.abuseFilter.tools');
     if ($user->isAllowed('abusefilter-modify')) {
         // Hacky little box to re-enable autoconfirmed if it got disabled
         $rac = '';
         $rac .= Xml::inputLabel($this->msg('abusefilter-tools-reautoconfirm-user')->text(), 'wpReAutoconfirmUser', 'reautoconfirm-user', 45);
         $rac .= ' ';
         $rac .= Xml::element('input', array('type' => 'button', 'id' => 'mw-abusefilter-reautoconfirmsubmit', 'value' => $this->msg('abusefilter-tools-reautoconfirm-submit')->text()));
         $rac = Xml::fieldset($this->msg('abusefilter-tools-reautoconfirm')->text(), $rac);
         $out->addHTML($rac);
     }
 }
Ejemplo n.º 2
0
 function show()
 {
     global $wgOut, $wgUser;
     // Header
     $wgOut->setSubTitle(wfMsg('abusefilter-tools-subtitle'));
     $wgOut->addWikiMsg('abusefilter-tools-text');
     // Expression evaluator
     $eval = '';
     $eval .= AbuseFilter::buildEditBox('', 'wpTestExpr');
     // Only let users with permission actually test it
     if ($wgUser->isAllowed('abusefilter-modify')) {
         $eval .= Xml::tags('p', null, Xml::element('input', array('type' => 'button', 'id' => 'mw-abusefilter-submitexpr', 'onclick' => 'doExprSubmit();', 'value' => wfMsg('abusefilter-tools-submitexpr'))));
         $eval .= Xml::element('p', array('id' => 'mw-abusefilter-expr-result'), ' ');
     }
     $eval = Xml::fieldset(wfMsg('abusefilter-tools-expr'), $eval);
     $wgOut->addHTML($eval);
     // Associated script
     $exprScript = file_get_contents(dirname(__FILE__) . '/tools.js');
     $wgOut->addInlineScript($exprScript);
     global $wgUser;
     if ($wgUser->isAllowed('abusefilter-modify')) {
         // Hacky little box to re-enable autoconfirmed if it got disabled
         $rac = '';
         $rac .= Xml::inputLabel(wfMsg('abusefilter-tools-reautoconfirm-user'), 'wpReAutoconfirmUser', 'reautoconfirm-user', 45);
         $rac .= ' ';
         $rac .= Xml::element('input', array('type' => 'button', 'id' => 'mw-abusefilter-reautoconfirmsubmit', 'onclick' => 'doReautoSubmit();', 'value' => wfMsg('abusefilter-tools-reautoconfirm-submit')));
         $rac = Xml::fieldset(wfMsg('abusefilter-tools-reautoconfirm'), $rac);
         $wgOut->addHTML($rac);
     }
 }
Ejemplo n.º 3
0
 public function execute()
 {
     $params = $this->extractRequestParams();
     $this->requireOnlyOneParameter($params, 'vars', 'rcid', 'logid');
     // "Anti-DoS"
     if (!$this->getUser()->isAllowed('abusefilter-modify')) {
         $this->dieUsageMsg('permissiondenied');
     }
     if ($params['vars']) {
         $vars = FormatJson::decode($params['vars'], true);
     } elseif ($params['rcid']) {
         $dbr = wfGetDB(DB_SLAVE);
         $row = $dbr->selectRow('recentchanges', '*', array('rc_id' => $params['rcid']), __METHOD__);
         if (!$row) {
             $this->dieUsageMsg(array('nosuchrcid', $params['rcid']));
         }
         $vars = AbuseFilter::getVarsFromRCRow($row);
     } elseif ($params['logid']) {
         $dbr = wfGetDB(DB_SLAVE);
         $row = $dbr->selectRow('abuse_filter_log', '*', array('afl_id' => $params['logid']), __METHOD__);
         if (!$row) {
             $this->dieUsage("There is no abuselog entry with the id ``{$params['logid']}''", 'nosuchlogid');
         }
         $vars = AbuseFilter::loadVarDump($row->afl_var_dump);
     }
     if (AbuseFilter::checkSyntax($params['filter']) !== true) {
         $this->dieUsage('The filter has invalid syntax', 'badsyntax');
     }
     $result = AbuseFilter::checkConditions($params['filter'], $vars);
     $this->getResult()->addValue(null, $this->getModuleName(), array('result' => $result));
 }
Ejemplo n.º 4
0
 /**
  * @return array
  */
 protected function getMessageParameters()
 {
     $entry = $this->entry->getParameters();
     $params = parent::getMessageParameters();
     $filter_title = SpecialPage::getTitleFor('AbuseFilter', $entry['filter']);
     $filter_caption = $this->msg('abusefilter-log-detailedentry-local')->params($entry['filter']);
     $log_title = SpecialPage::getTitleFor('AbuseLog', $entry['log']);
     $log_caption = $this->msg('abusefilter-log-detailslink');
     $params[4] = $entry['action'];
     if ($this->plaintext) {
         $params[3] = '[[' . $filter_title->getPrefixedText() . '|' . $filter_caption . ']]';
         $params[8] = '[[' . $log_title->getPrefixedText() . '|' . $log_caption . ']]';
     } else {
         $params[3] = Message::rawParam(Linker::link($filter_title, htmlspecialchars($filter_caption)));
         $params[8] = Message::rawParam(Linker::link($log_title, htmlspecialchars($log_caption)));
     }
     $actions_taken = $entry['actions'];
     if (!strlen(trim($actions_taken))) {
         $actions_taken = $this->msg('abusefilter-log-noactions');
     } else {
         $actions = explode(',', $actions_taken);
         $displayActions = array();
         foreach ($actions as $action) {
             $displayActions[] = AbuseFilter::getActionDisplay($action);
         }
         $actions_taken = $this->context->getLanguage()->commaList($displayActions);
     }
     $params[5] = $actions_taken;
     // Bad things happen if the numbers are not in correct order
     ksort($params);
     return $params;
 }
 function doTest()
 {
     // Quick syntax check.
     $out = $this->getOutput();
     $result = AbuseFilter::checkSyntax($this->mFilter);
     if ($result !== true) {
         $out->addWikiMsg('abusefilter-test-syntaxerr');
         return;
     }
     $dbr = wfGetDB(DB_SLAVE);
     $conds = array('rc_user_text' => $this->mTestUser, 'rc_type != ' . RC_EXTERNAL);
     if ($this->mTestPeriodStart) {
         $conds[] = 'rc_timestamp >= ' . $dbr->addQuotes($dbr->timestamp(strtotime($this->mTestPeriodStart)));
     }
     if ($this->mTestPeriodEnd) {
         $conds[] = 'rc_timestamp <= ' . $dbr->addQuotes($dbr->timestamp(strtotime($this->mTestPeriodEnd)));
     }
     if ($this->mTestPage) {
         $title = Title::newFromText($this->mTestPage);
         if ($title instanceof Title) {
             $conds['rc_namespace'] = $title->getNamespace();
             $conds['rc_title'] = $title->getDBkey();
         } else {
             $out->addWikiMsg('abusefilter-test-badtitle');
             return;
         }
     }
     // Get our ChangesList
     $changesList = new AbuseFilterChangesList($this->getSkin());
     $output = $changesList->beginRecentChangesList();
     $res = $dbr->select('recentchanges', '*', array_filter($conds), __METHOD__, array('LIMIT' => self::$mChangeLimit, 'ORDER BY' => 'rc_timestamp desc'));
     $counter = 1;
     foreach ($res as $row) {
         $vars = AbuseFilter::getVarsFromRCRow($row);
         if (!$vars) {
             continue;
         }
         $result = AbuseFilter::checkConditions($this->mFilter, $vars);
         if ($result || $this->mShowNegative) {
             // Stash result in RC item
             $rc = RecentChange::newFromRow($row);
             $rc->examineParams['testfilter'] = $this->mFilter;
             $rc->filterResult = $result;
             $rc->counter = $counter++;
             $output .= $changesList->recentChangesLine($rc, false);
         }
     }
     $output .= $changesList->endRecentChangesList();
     $out->addHTML($output);
 }
 public function execute()
 {
     // "Anti-DoS"
     if (!$this->getUser()->isAllowed('abusefilter-modify')) {
         $this->dieUsage('You don\'t have permission to check syntax of abuse filters', 'permissiondenied');
     }
     $params = $this->extractRequestParams();
     $result = AbuseFilter::checkSyntax($params['filter']);
     $r = array();
     if ($result === true) {
         // Everything went better than expected :)
         $r['status'] = 'ok';
     } else {
         $r = array('status' => 'error', 'message' => $result[0], 'character' => $result[1]);
     }
     $this->getResult()->addValue(null, $this->getModuleName(), $r);
 }
 public function execute()
 {
     if (!$this->getUser()->isAllowed('abusefilter-modify')) {
         $this->dieUsage('You do not have permissions to unblock autopromotion', 'permissiondenied');
     }
     $params = $this->extractRequestParams();
     $user = User::newFromName($params['user']);
     if ($user === false) {
         // Oh god this is so bad but this message uses GENDER
         $msg = wfMessage('abusefilter-reautoconfirm-none', $params['user'])->text();
         $this->dieUsage($msg, 'notsuspended');
     }
     global $wgMemc;
     $key = AbuseFilter::autoPromoteBlockKey($user);
     if (!$wgMemc->get($key)) {
         // Same as above :(
         $msg = wfMessage('abusefilter-reautoconfirm-none', $params['user'])->text();
         $this->dieUsage($msg, 'notsuspended');
     }
     $wgMemc->delete($key);
     $res = array('user' => $params['user']);
     $this->getResult()->addValue(null, $this->getModuleName(), $res);
 }
Ejemplo n.º 8
0
 protected function setUserVariable($name, $value)
 {
     $builderValues = AbuseFilter::getBuilderValues();
     if (array_key_exists($name, $builderValues['vars'])) {
         throw new AFPUserVisibleException('overridebuiltin', $this->mCur->pos, array($name));
     }
     $this->mVars->setVar($name, $value);
 }
Ejemplo n.º 9
0
 public function execute()
 {
     global $wgUser;
     if (!$wgUser->isAllowed('abusefilter-log')) {
         $this->dieUsage('You don\'t have permission to view the abuse log', 'permissiondenied');
     }
     $params = $this->extractRequestParams();
     $prop = array_flip($params['prop']);
     $fld_ids = isset($prop['ids']);
     $fld_filter = isset($prop['filter']);
     $fld_user = isset($prop['user']);
     $fld_ip = isset($prop['ip']);
     $fld_title = isset($prop['title']);
     $fld_action = isset($prop['action']);
     $fld_details = isset($prop['details']);
     $fld_result = isset($prop['result']);
     $fld_timestamp = isset($prop['timestamp']);
     $fld_hidden = isset($prop['hidden']);
     if ($fld_ip && !$wgUser->isAllowed('abusefilter-private')) {
         $this->dieUsage('You don\'t have permission to view IP addresses', 'permissiondenied');
     }
     if ($fld_details && !$wgUser->isAllowed('abusefilter-log-detail')) {
         $this->dieUsage('You don\'t have permission to view detailed abuse log entries', 'permissiondenied');
     }
     $result = $this->getResult();
     $this->addTables('abuse_filter_log');
     $this->addFields('afl_timestamp');
     $this->addFieldsIf(array('afl_id', 'afl_filter'), $fld_ids);
     $this->addFieldsIf('afl_user_text', $fld_user);
     $this->addFieldsIf('afl_ip', $fld_ip);
     $this->addFieldsIf(array('afl_namespace', 'afl_title'), $fld_title);
     $this->addFieldsIf('afl_action', $fld_action);
     $this->addFieldsIf('afl_var_dump', $fld_details);
     $this->addFieldsIf('afl_actions', $fld_result);
     $this->addFieldsIf('afl_deleted', $fld_hidden);
     if ($fld_filter) {
         $this->addTables('abuse_filter');
         $this->addFields('af_public_comments');
         $this->addJoinConds(array('abuse_filter' => array('LEFT JOIN', 'af_id=afl_filter')));
     }
     $this->addOption('LIMIT', $params['limit'] + 1);
     $this->addWhereRange('afl_timestamp', $params['dir'], $params['start'], $params['end']);
     $db = $this->getDB();
     $notDeletedCond = SpecialAbuseLog::getNotDeletedCond($db);
     $this->addWhereIf(array('afl_user_text' => $params['user']), isset($params['user']));
     $this->addWhereIf(array('afl_filter' => $params['filter']), isset($params['filter']));
     $this->addWhereIf($notDeletedCond, !SpecialAbuseLog::canSeeHidden());
     $title = $params['title'];
     if (!is_null($title)) {
         $titleObj = Title::newFromText($title);
         if (is_null($titleObj)) {
             $this->dieUsageMsg(array('invalidtitle', $title));
         }
         $this->addWhereFld('afl_namespace', $titleObj->getNamespace());
         $this->addWhereFld('afl_title', $titleObj->getDBkey());
     }
     $res = $this->select(__METHOD__);
     $count = 0;
     foreach ($res as $row) {
         if (++$count > $params['limit']) {
             // We've had enough
             $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->afl_timestamp));
             break;
         }
         $entry = array();
         if ($fld_ids) {
             $entry['id'] = intval($row->afl_id);
             $entry['filter_id'] = intval($row->afl_filter);
         }
         if ($fld_filter) {
             $entry['filter'] = $row->af_public_comments;
         }
         if ($fld_user) {
             $entry['user'] = $row->afl_user_text;
         }
         if ($fld_ip) {
             $entry['ip'] = $row->afl_ip;
         }
         if ($fld_title) {
             $title = Title::makeTitle($row->afl_namespace, $row->afl_title);
             ApiQueryBase::addTitleInfo($entry, $title);
         }
         if ($fld_action) {
             $entry['action'] = $row->afl_action;
         }
         if ($fld_result) {
             $entry['result'] = $row->afl_actions;
         }
         if ($fld_timestamp) {
             $entry['timestamp'] = wfTimestamp(TS_ISO_8601, $row->afl_timestamp);
         }
         if ($fld_details) {
             $vars = AbuseFilter::loadVarDump($row->afl_var_dump);
             if ($vars instanceof AbuseFilterVariableHolder) {
                 $entry['details'] = $vars->exportAllVars();
             } else {
                 $entry['details'] = array_change_key_case($vars, CASE_LOWER);
             }
         }
         if ($fld_hidden) {
             $entry['hidden'] = $row->afl_deleted;
         }
         if ($entry) {
             $fit = $result->addValue(array('query', $this->getModuleName()), null, $entry);
             if (!$fit) {
                 $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->afl_timestamp));
                 break;
             }
         }
     }
     $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'item');
 }
Ejemplo n.º 10
0
 /**
  * Handler for the UploadVerifyFile hook
  *
  * @param $upload UploadBase
  * @param $mime
  * @param $error array
  *
  * @return bool
  */
 public static function onUploadVerifyFile($upload, $mime, &$error)
 {
     global $wgUser, $wgVersion;
     $vars = new AbuseFilterVariableHolder();
     $title = $upload->getTitle();
     if (!$title) {
         // If there's no valid title assigned to the upload
         // it wont proceed anyway, so no point in filtering it.
         return true;
     }
     $vars->addHolders(AbuseFilter::generateUserVars($wgUser), AbuseFilter::generateTitleVars($title, 'FILE'));
     $vars->setVar('ACTION', 'upload');
     // We us the hexadecimal version of the file sha1
     if (version_compare($wgVersion, '1.21', '>=')) {
         // Use UploadBase::getTempFileSha1Base36 so that we don't have to calculate the sha1 sum again
         $sha1 = wfBaseConvert($upload->getTempFileSha1Base36(), 36, 16, 40);
     } else {
         // UploadBase::getTempFileSha1Base36 wasn't public until 1.21
         $sha1 = sha1_file($upload->getTempPath());
     }
     $vars->setVar('file_sha1', $sha1);
     $filter_result = AbuseFilter::filterAction($vars, $title);
     if (!$filter_result->isOK()) {
         $error = $filter_result->getErrorsArray();
         $error = $error[0];
     }
     return $filter_result->isOK();
 }
Ejemplo n.º 11
0
 function formatValue($name, $value)
 {
     global $wgOut, $wgLang;
     static $sk = null;
     if (empty($sk)) {
         global $wgUser;
         $sk = $wgUser->getSkin();
     }
     $row = $this->mCurrentRow;
     switch ($name) {
         case 'af_id':
             return $sk->link(SpecialPage::getTitleFor('AbuseFilter', intval($value)), intval($value));
         case 'af_public_comments':
             return $sk->link(SpecialPage::getTitleFor('AbuseFilter', intval($row->af_id)), $wgOut->parseInline($value));
         case 'af_actions':
             $actions = explode(',', $value);
             $displayActions = array();
             foreach ($actions as $action) {
                 $displayActions[] = AbuseFilter::getActionDisplay($action);
             }
             return htmlspecialchars($wgLang->commaList($displayActions));
         case 'af_enabled':
             $statuses = array();
             if ($row->af_deleted) {
                 $statuses[] = wfMsgExt('abusefilter-deleted', 'parseinline');
             } elseif ($row->af_enabled) {
                 $statuses[] = wfMsgExt('abusefilter-enabled', 'parseinline');
             } else {
                 $statuses[] = wfMsgExt('abusefilter-disabled', 'parseinline');
             }
             global $wgAbuseFilterIsCentral;
             if ($row->af_global && $wgAbuseFilterIsCentral) {
                 $statuses[] = wfMsgExt('abusefilter-status-global', 'parseinline');
             }
             return $wgLang->commaList($statuses);
         case 'af_hidden':
             $msg = $value ? 'abusefilter-hidden' : 'abusefilter-unhidden';
             return wfMsgExt($msg, 'parseinline');
         case 'af_hit_count':
             $count_display = wfMsgExt('abusefilter-hitcount', array('parseinline'), $wgLang->formatNum($value));
             $link = $sk->makeKnownLinkObj(SpecialPage::getTitleFor('AbuseLog'), $count_display, 'wpSearchFilter=' . $row->af_id);
             return $link;
         case 'af_timestamp':
             $userLink = $sk->userLink($row->af_user, $row->af_user_text) . $sk->userToolLinks($row->af_user, $row->af_user_text);
             $user = $row->af_user_text;
             return wfMsgExt('abusefilter-edit-lastmod-text', array('replaceafter', 'parseinline'), array($wgLang->timeanddate($value, true), $userLink, $wgLang->date($value, true), $wgLang->time($value, true), $user));
         default:
             throw new MWException("Unknown row type {$name}!");
     }
 }
Ejemplo n.º 12
0
 /**
  * @param $action
  * @param $parameters
  * @return String
  */
 static function formatAction($action, $parameters)
 {
     /** @var $wgLang Language */
     global $wgLang;
     if (count($parameters) == 0) {
         $displayAction = AbuseFilter::getActionDisplay($action);
     } else {
         $displayAction = AbuseFilter::getActionDisplay($action) . wfMessage('colon-separator')->escaped() . $wgLang->semicolonList($parameters);
     }
     return $displayAction;
 }
Ejemplo n.º 13
0
 function formatValue($name, $value)
 {
     global $wgOut, $wgLang;
     static $sk = null;
     if (empty($sk)) {
         global $wgUser;
         $sk = $wgUser->getSkin();
     }
     $row = $this->mCurrentRow;
     $formatted = '';
     switch ($name) {
         case 'afh_timestamp':
             $title = SpecialPage::getTitleFor('AbuseFilter', 'history/' . $row->afh_filter . '/item/' . $row->afh_id);
             $formatted = $sk->link($title, $wgLang->timeanddate($row->afh_timestamp, true));
             break;
         case 'afh_user_text':
             $formatted = $sk->userLink($row->afh_user, $row->afh_user_text) . ' ' . $sk->userToolLinks($row->afh_user, $row->afh_user_text);
             break;
         case 'afh_public_comments':
             $formatted = $wgOut->parse($value);
             break;
         case 'afh_flags':
             $formatted = AbuseFilter::formatFlags($value);
             break;
         case 'afh_actions':
             $actions = unserialize($value);
             $display_actions = '';
             foreach ($actions as $action => $parameters) {
                 $displayAction = AbuseFilter::formatAction($action, $parameters);
                 $display_actions .= Xml::tags('li', null, $displayAction);
             }
             $display_actions = Xml::tags('ul', null, $display_actions);
             $formatted = $display_actions;
             break;
         case 'afh_filter':
             $title = $this->mPage->getTitle(strval($value));
             $formatted = $sk->link($title, $value);
             break;
         case 'afh_id':
             $title = $this->mPage->getTitle('history/' . $row->afh_filter . "/diff/prev/{$value}");
             $formatted = $sk->link($title, wfMsgExt('abusefilter-history-diff', 'parseinline'));
             break;
         default:
             $formatted = "Unable to format {$name}";
             break;
     }
     $mappings = array_flip(AbuseFilter::$history_mappings) + array('afh_actions' => 'actions', 'afh_id' => 'id');
     $changed = explode(',', $row->afh_changed_fields);
     $fieldChanged = false;
     if ($name == 'afh_flags') {
         // This is a bit freaky, but it works.
         // Basically, returns true if any of those filters are in the $changed array.
         $filters = array('af_enabled', 'af_hidden', 'af_deleted', 'af_global');
         if (count(array_diff($filters, $changed)) < count($filters)) {
             $fieldChanged = true;
         }
     } elseif (in_array($mappings[$name], $changed)) {
         $fieldChanged = true;
     }
     if ($fieldChanged) {
         $formatted = Xml::tags('div', array('class' => 'mw-abusefilter-history-changed'), $formatted);
     }
     return $formatted;
 }
Ejemplo n.º 14
0
 function formatValue($name, $value)
 {
     $lang = $this->getLanguage();
     $row = $this->mCurrentRow;
     switch ($name) {
         case 'af_id':
             return $lang->formatNum(intval($value));
         case 'af_public_comments':
             return $this->getOutput()->parseInline($value);
         case 'af_actions':
             $actions = explode(',', $value);
             $displayActions = array();
             foreach ($actions as $action) {
                 $displayActions[] = AbuseFilter::getActionDisplay($action);
             }
             return htmlspecialchars($lang->commaList($displayActions));
         case 'af_enabled':
             $statuses = array();
             if ($row->af_deleted) {
                 $statuses[] = $this->msg('abusefilter-deleted')->parse();
             } elseif ($row->af_enabled) {
                 $statuses[] = $this->msg('abusefilter-enabled')->parse();
             } else {
                 $statuses[] = $this->msg('abusefilter-disabled')->parse();
             }
             if ($row->af_global) {
                 $statuses[] = $this->msg('abusefilter-status-global')->parse();
             }
             return $lang->commaList($statuses);
         case 'af_hidden':
             $msg = $value ? 'abusefilter-hidden' : 'abusefilter-unhidden';
             return $this->msg($msg, 'parseinline')->parse();
         case 'af_hit_count':
             // If the rule is hidden, don't show it, even to priviledged local admins
             if ($row->af_hidden) {
                 return '';
             }
             return $this->msg('abusefilter-hitcount')->numParams($value)->parse();
         case 'af_timestamp':
             $user = $row->af_user_text;
             return $this->msg('abusefilter-edit-lastmod-text', $lang->timeanddate($value, true), $user, $lang->date($value, true), $lang->time($value, true), $user)->parse();
         case 'af_group':
             // If this is global, local name probably doesn't exist, but try
             return AbuseFilter::nameGroup($value);
             break;
         default:
             throw new MWException("Unknown row type {$name}!");
     }
 }
 /**
  * @param $vars AbuseFilterVariableHolder
  * @return AFPData|array|int|mixed|null|string
  * @throws MWException
  * @throws AFPException
  */
 function compute($vars)
 {
     $parameters = $this->mParameters;
     $result = null;
     if (!wfRunHooks('AbuseFilter-interceptVariable', array($this->mMethod, $vars, $parameters, &$result))) {
         return $result instanceof AFPData ? $result : AFPData::newFromPHPVar($result);
     }
     switch ($this->mMethod) {
         case 'diff':
             $text1Var = $parameters['oldtext-var'];
             $text2Var = $parameters['newtext-var'];
             $text1 = $vars->getVar($text1Var)->toString() . "\n";
             $text2 = $vars->getVar($text2Var)->toString() . "\n";
             $result = wfDiff($text1, $text2);
             break;
         case 'diff-split':
             $diff = $vars->getVar($parameters['diff-var'])->toString();
             $line_prefix = $parameters['line-prefix'];
             $diff_lines = explode("\n", $diff);
             $interest_lines = array();
             foreach ($diff_lines as $line) {
                 if (substr($line, 0, 1) === $line_prefix) {
                     $interest_lines[] = substr($line, strlen($line_prefix));
                 }
             }
             $result = $interest_lines;
             break;
         case 'links-from-wikitext':
             // This should ONLY be used when sharing a parse operation with the edit.
             /* @var WikiPage $article */
             $article = $parameters['article'];
             if ($article !== null && (!defined('MW_SUPPORTS_CONTENTHANDLER') || $article->getContentModel() === CONTENT_MODEL_WIKITEXT)) {
                 $textVar = $parameters['text-var'];
                 // XXX: Use prepareContentForEdit. But we need a Content object for that.
                 $new_text = $vars->getVar($textVar)->toString();
                 $content = ContentHandler::makeContent($new_text, $article->getTitle());
                 $editInfo = $article->prepareContentForEdit($content);
                 $links = array_keys($editInfo->output->getExternalLinks());
                 $result = $links;
                 break;
             }
             // Otherwise fall back to database
         // Otherwise fall back to database
         case 'links-from-wikitext-nonedit':
         case 'links-from-wikitext-or-database':
             // TODO: use Content object instead, if available! In any case, use WikiPage, not Article.
             $article = self::articleFromTitle($parameters['namespace'], $parameters['title']);
             if ($vars->getVar('context')->toString() == 'filter') {
                 $links = $this->getLinksFromDB($article);
                 wfDebug("AbuseFilter: loading old links from DB\n");
             } elseif (!defined('MW_SUPPORTS_CONTENTHANDLER') || $article->getContentModel() === CONTENT_MODEL_WIKITEXT) {
                 wfDebug("AbuseFilter: loading old links from Parser\n");
                 $textVar = $parameters['text-var'];
                 $wikitext = $vars->getVar($textVar)->toString();
                 $editInfo = $this->parseNonEditWikitext($wikitext, $article);
                 $links = array_keys($editInfo->output->getExternalLinks());
             } else {
                 // TODO: Get links from Content object. But we don't have the content object.
                 //      And for non-text content, $wikitext is usually not going to be a valid
                 //      serialization, but rather some dummy text for filtering.
                 $links = array();
             }
             $result = $links;
             break;
         case 'link-diff-added':
         case 'link-diff-removed':
             $oldLinkVar = $parameters['oldlink-var'];
             $newLinkVar = $parameters['newlink-var'];
             $oldLinks = $vars->getVar($oldLinkVar)->toString();
             $newLinks = $vars->getVar($newLinkVar)->toString();
             $oldLinks = explode("\n", $oldLinks);
             $newLinks = explode("\n", $newLinks);
             if ($this->mMethod == 'link-diff-added') {
                 $result = array_diff($newLinks, $oldLinks);
             }
             if ($this->mMethod == 'link-diff-removed') {
                 $result = array_diff($oldLinks, $newLinks);
             }
             break;
         case 'parse-wikitext':
             // Should ONLY be used when sharing a parse operation with the edit.
             $article = $parameters['article'];
             if ($article !== null && (!defined('MW_SUPPORTS_CONTENTHANDLER') || $article->getContentModel() === CONTENT_MODEL_WIKITEXT)) {
                 $textVar = $parameters['wikitext-var'];
                 // XXX: Use prepareContentForEdit. But we need a Content object for that.
                 $new_text = $vars->getVar($textVar)->toString();
                 $editInfo = $article->prepareTextForEdit($new_text);
                 if (isset($parameters['pst']) && $parameters['pst']) {
                     $result = $editInfo->pstContent->serialize($editInfo->format);
                 } else {
                     $newHTML = $editInfo->output->getText();
                     // Kill the PP limit comments. Ideally we'd just remove these by not setting the
                     // parser option, but then we can't share a parse operation with the edit, which is bad.
                     $result = preg_replace('/<!--\\s*NewPP limit report[^>]*-->\\s*$/si', '', $newHTML);
                 }
                 break;
             }
             // Otherwise fall back to database
         // Otherwise fall back to database
         case 'parse-wikitext-nonedit':
             // TODO: use Content object instead, if available! In any case, use WikiPage, not Article.
             $article = self::articleFromTitle($parameters['namespace'], $parameters['title']);
             $textVar = $parameters['wikitext-var'];
             if (!defined('MW_SUPPORTS_CONTENTHANDLER') || $article->getContentModel() === CONTENT_MODEL_WIKITEXT) {
                 if (isset($parameters['pst']) && $parameters['pst']) {
                     // $textVar is already PSTed when it's not loaded from an ongoing edit.
                     $result = $vars->getVar($textVar)->toString();
                 } else {
                     $text = $vars->getVar($textVar)->toString();
                     $editInfo = $this->parseNonEditWikitext($text, $article);
                     $result = $editInfo->output->getText();
                 }
             } else {
                 // TODO: Parser Output from Content object. But we don't have the content object.
                 //      And for non-text content, $wikitext is usually not going to be a valid
                 //      serialization, but rather some dummy text for filtering.
                 $result = '';
             }
             break;
         case 'strip-html':
             $htmlVar = $parameters['html-var'];
             $html = $vars->getVar($htmlVar)->toString();
             $result = StringUtils::delimiterReplace('<', '>', '', $html);
             break;
         case 'load-recent-authors':
             $cutOff = $parameters['cutoff'];
             $title = Title::makeTitle($parameters['namespace'], $parameters['title']);
             if (!$title->exists()) {
                 $result = '';
                 break;
             }
             $dbr = wfGetDB(DB_SLAVE);
             $res = $dbr->select('revision', 'DISTINCT rev_user_text', array('rev_page' => $title->getArticleID(), 'rev_timestamp<' . $dbr->addQuotes($dbr->timestamp($cutOff))), __METHOD__, array('ORDER BY' => 'rev_timestamp DESC', 'LIMIT' => 10));
             $users = array();
             foreach ($res as $row) {
                 $users[] = $row->rev_user_text;
             }
             $result = $users;
             break;
         case 'get-page-restrictions':
             $action = $parameters['action'];
             $title = Title::makeTitle($parameters['namespace'], $parameters['title']);
             $rights = $title->getRestrictions($action);
             $rights = count($rights) ? $rights : array();
             $result = $rights;
             break;
         case 'simple-user-accessor':
             $user = $parameters['user'];
             $method = $parameters['method'];
             if (!$user) {
                 throw new MWException('No user parameter given.');
             }
             $obj = self::getUserObject($user);
             if (!$obj) {
                 throw new MWException("Invalid username {$user}");
             }
             $result = call_user_func(array($obj, $method));
             break;
         case 'user-age':
             $user = $parameters['user'];
             $asOf = $parameters['asof'];
             $obj = self::getUserObject($user);
             if ($obj->getId() == 0) {
                 $result = 0;
                 break;
             }
             $registration = $obj->getRegistration();
             $result = wfTimestamp(TS_UNIX, $asOf) - wfTimestampOrNull(TS_UNIX, $registration);
             break;
         case 'user-groups':
             // Deprecated but needed by old log entries
             $user = $parameters['user'];
             $obj = self::getUserObject($user);
             $result = $obj->getEffectiveGroups();
             break;
         case 'length':
             $s = $vars->getVar($parameters['length-var'])->toString();
             $result = strlen($s);
             break;
         case 'subtract':
             $v1 = $vars->getVar($parameters['val1-var'])->toFloat();
             $v2 = $vars->getVar($parameters['val2-var'])->toFloat();
             $result = $v1 - $v2;
             break;
         case 'revision-text-by-id':
             $rev = Revision::newFromId($parameters['revid']);
             $result = AbuseFilter::revisionToString($rev);
             break;
         case 'revision-text-by-timestamp':
             $timestamp = $parameters['timestamp'];
             $title = Title::makeTitle($parameters['namespace'], $parameters['title']);
             $dbr = wfGetDB(DB_SLAVE);
             $rev = Revision::loadFromTimestamp($dbr, $title, $timestamp);
             $result = AbuseFilter::revisionToString($rev);
             break;
         default:
             if (wfRunHooks('AbuseFilter-computeVariable', array($this->mMethod, $vars, $parameters, &$result))) {
                 throw new AFPException('Unknown variable compute type ' . $this->mMethod);
             }
     }
     return $result instanceof AFPData ? $result : AFPData::newFromPHPVar($result);
 }
Ejemplo n.º 16
0
 function stringifyActions($actions)
 {
     $lines = array();
     ksort($actions);
     foreach ($actions as $action => $parameters) {
         $lines[] = AbuseFilter::formatAction($action, $parameters);
     }
     if (!count($lines)) {
         $lines[] = '';
     }
     return $lines;
 }
Ejemplo n.º 17
0
 function loadHistoryItem($id)
 {
     $dbr = wfGetDB(DB_SLAVE);
     // Load the row.
     $row = $dbr->selectRow('abuse_filter_history', '*', array('afh_id' => $id), __METHOD__);
     return AbuseFilter::translateFromHistory($row);
 }
Ejemplo n.º 18
0
 public function execute($subpage)
 {
     $out = $this->getOutput();
     $request = $this->getRequest();
     $out->addModuleStyles('ext.abuseFilter');
     $view = 'AbuseFilterViewList';
     $this->setHeaders();
     $this->loadParameters($subpage);
     $out->setPageTitle($this->msg('abusefilter-management'));
     // Are we allowed?
     $this->checkPermissions();
     if ($request->getVal('result') == 'success') {
         $out->setSubtitle(wfMsg('abusefilter-edit-done-subtitle'));
         $changedFilter = intval($request->getVal('changedfilter'));
         $out->wrapWikiMsg('<p class="success">$1</p>', array('abusefilter-edit-done', $changedFilter));
     }
     $this->mHistoryID = null;
     $pageType = 'home';
     $params = explode('/', $subpage);
     // Filter by removing blanks.
     foreach ($params as $index => $param) {
         if ($param === '') {
             unset($params[$index]);
         }
     }
     $params = array_values($params);
     if ($subpage == 'tools') {
         $view = 'AbuseFilterViewTools';
         $pageType = 'tools';
     }
     if (count($params) == 2 && $params[0] == 'revert' && is_numeric($params[1])) {
         $this->mFilter = $params[1];
         $view = 'AbuseFilterViewRevert';
         $pageType = 'revert';
     }
     if (count($params) && $params[0] == 'test') {
         $view = 'AbuseFilterViewTestBatch';
         $pageType = 'test';
     }
     if (count($params) && $params[0] == 'examine') {
         $view = 'AbuseFilterViewExamine';
         $pageType = 'examine';
     }
     if (!empty($params[0]) && ($params[0] == 'history' || $params[0] == 'log')) {
         $pageType = '';
         if (count($params) == 1) {
             $view = 'AbuseFilterViewHistory';
             $pageType = 'recentchanges';
         } elseif (count($params) == 2) {
             # Second param is a filter ID
             $view = 'AbuseFilterViewHistory';
             $this->mFilter = $params[1];
         } elseif (count($params) == 4 && $params[2] == 'item') {
             $this->mFilter = $params[1];
             $this->mHistoryID = $params[3];
             $view = 'AbuseFilterViewEdit';
         } elseif (count($params) == 5 && $params[2] == 'diff') {
             // Special:AbuseFilter/history/<filter>/diff/<oldid>/<newid>
             $view = 'AbuseFilterViewDiff';
         }
     }
     if (is_numeric($subpage) || $subpage == 'new') {
         $this->mFilter = $subpage;
         $view = 'AbuseFilterViewEdit';
         $pageType = 'edit';
     }
     if ($subpage == 'import') {
         $view = 'AbuseFilterViewImport';
         $pageType = 'import';
     }
     // Links at the top
     AbuseFilter::addNavigationLinks($this->getContext(), $pageType);
     $v = new $view($this, $params);
     $v->show();
 }
Ejemplo n.º 19
0
 function formatRow($row, $li = true)
 {
     global $wgLang, $wgUser;
     # One-time setup
     static $sk = null;
     $actionLinks = array();
     if (is_null($sk)) {
         $sk = $wgUser->getSkin();
     }
     $title = Title::makeTitle($row->afl_namespace, $row->afl_title);
     if (!$row->afl_wiki) {
         $pageLink = $sk->link($title);
     } else {
         $pageLink = WikiMap::makeForeignLink($row->afl_wiki, $row->afl_title);
     }
     if (!$row->afl_wiki) {
         // Local user
         $user = $sk->userLink($row->afl_user, $row->afl_user_text) . $sk->userToolLinks($row->afl_user, $row->afl_user_text);
     } else {
         $user = WikiMap::foreignUserLink($row->afl_wiki, $row->afl_user_text);
         $user .= ' (' . WikiMap::getWikiName($row->afl_wiki) . ')';
     }
     $timestamp = $wgLang->timeanddate($row->afl_timestamp, true);
     $actions_taken = $row->afl_actions;
     if (!strlen(trim($actions_taken))) {
         $actions_taken = wfMsg('abusefilter-log-noactions');
     } else {
         $actions = explode(',', $actions_taken);
         $displayActions = array();
         foreach ($actions as $action) {
             $displayActions[] = AbuseFilter::getActionDisplay($action);
         }
         $actions_taken = $wgLang->commaList($displayActions);
     }
     $globalIndex = AbuseFilter::decodeGlobalName($row->afl_filter);
     global $wgOut;
     if ($globalIndex) {
         // Pull global filter description
         $parsed_comments = $wgOut->parseInline(AbuseFilter::getGlobalFilterDescription($globalIndex));
     } else {
         $parsed_comments = $wgOut->parseInline($row->af_public_comments);
     }
     if (self::canSeeDetails()) {
         $examineTitle = SpecialPage::getTitleFor('AbuseFilter', 'examine/log/' . $row->afl_id);
         $detailsLink = $sk->makeKnownLinkObj($this->getTitle($row->afl_id), wfMsg('abusefilter-log-detailslink'));
         $examineLink = $sk->link($examineTitle, wfMsgExt('abusefilter-changeslist-examine', 'parseinline'), array());
         $actionLinks[] = $detailsLink;
         $actionLinks[] = $examineLink;
         if ($wgUser->isAllowed('abusefilter-hide-log')) {
             $hideLink = $sk->link($this->getTitle(), wfMsg('abusefilter-log-hidelink'), array(), array('hide' => $row->afl_id));
             $actionLinks[] = $hideLink;
         }
         if ($globalIndex) {
             global $wgAbuseFilterCentralDB;
             $globalURL = WikiMap::getForeignURL($wgAbuseFilterCentralDB, 'Special:AbuseFilter/' . $globalIndex);
             $linkText = wfMsgExt('abusefilter-log-detailedentry-global', 'parseinline', array($globalIndex));
             $filterLink = $sk->makeExternalLink($globalURL, $linkText);
         } else {
             $title = SpecialPage::getTitleFor('AbuseFilter', $row->afl_filter);
             $linkText = wfMsgExt('abusefilter-log-detailedentry-local', 'parseinline', array($row->afl_filter));
             $filterLink = $sk->link($title, $linkText);
         }
         $description = wfMsgExt('abusefilter-log-detailedentry-meta', array('parseinline', 'replaceafter'), array($timestamp, $user, $filterLink, $row->afl_action, $pageLink, $actions_taken, $parsed_comments, $wgLang->pipeList($actionLinks)));
     } else {
         $description = wfMsgExt('abusefilter-log-entry', array('parseinline', 'replaceafter'), array($timestamp, $user, $row->afl_action, $sk->link($title), $actions_taken, $parsed_comments));
     }
     if ($row->afl_deleted) {
         $description .= ' ' . wfMsgExt('abusefilter-log-hidden', 'parseinline');
     }
     return $li ? Xml::tags('li', null, $description) : $description;
 }
 public function execute()
 {
     $params = $this->extractRequestParams();
     $result = AbuseFilter::evaluateExpression($params['expression']);
     $this->getResult()->addValue(null, $this->getModuleName(), array('result' => $result));
 }
Ejemplo n.º 21
0
 static function formatAction($action, $parameters)
 {
     global $wgLang;
     if (count($parameters) == 0) {
         $displayAction = AbuseFilter::getActionDisplay($action);
     } else {
         $displayAction = AbuseFilter::getActionDisplay($action) . wfMsgExt('colon-separator', 'escapenoentities') . $wgLang->semicolonList($parameters);
     }
     return $displayAction;
 }
Ejemplo n.º 22
0
 public static function onUploadVerification($saveName, $tempName, &$error)
 {
     $vars = new AbuseFilterVariableHolder();
     global $wgUser;
     $title = Title::makeTitle(NS_FILE, $saveName);
     $vars->addHolder(AbuseFilterVariableHolder::merge(AbuseFilter::generateUserVars($wgUser), AbuseFilter::generateTitleVars($title, 'FILE')));
     $vars->setVar('ACTION', 'upload');
     $vars->setVar('file_sha1', sha1_file($tempName));
     // TODO share with save
     $filter_result = AbuseFilter::filterAction($vars, $title);
     if (is_string($filter_result)) {
         $error = $filter_result;
     }
     return $filter_result == '' || $filter_result === true;
 }
 function formatValue($name, $value)
 {
     $lang = $this->getLanguage();
     $row = $this->mCurrentRow;
     switch ($name) {
         case 'afh_filter':
             $formatted = $lang->formatNum($row->afh_filter);
             break;
         case 'afh_timestamp':
             $title = SpecialPage::getTitleFor('AbuseFilter', 'history/' . $row->afh_filter . '/item/' . $row->afh_id);
             $formatted = Linker::link($title, $lang->timeanddate($row->afh_timestamp, true));
             break;
         case 'afh_user_text':
             $formatted = Linker::userLink($row->afh_user, $row->afh_user_text) . ' ' . Linker::userToolLinks($row->afh_user, $row->afh_user_text);
             break;
         case 'afh_public_comments':
             $formatted = htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false);
             break;
         case 'afh_flags':
             $formatted = AbuseFilter::formatFlags($value);
             break;
         case 'afh_actions':
             $actions = unserialize($value);
             $display_actions = '';
             foreach ($actions as $action => $parameters) {
                 $displayAction = AbuseFilter::formatAction($action, $parameters);
                 $display_actions .= Xml::tags('li', null, $displayAction);
             }
             $display_actions = Xml::tags('ul', null, $display_actions);
             $formatted = $display_actions;
             break;
         case 'afh_id':
             $formatted = '';
             if (AbuseFilter::getFirstFilterChange($row->afh_filter) != $value) {
                 // Set a link to a diff with the previous version if this isn't the first edit to the filter
                 $title = $this->mPage->getTitle('history/' . $row->afh_filter . "/diff/prev/{$value}");
                 $formatted = Linker::link($title, $this->msg('abusefilter-history-diff')->parse());
             }
             break;
         default:
             $formatted = "Unable to format {$name}";
             break;
     }
     $mappings = array_flip(AbuseFilter::$history_mappings) + array('afh_actions' => 'actions', 'afh_id' => 'id');
     $changed = explode(',', $row->afh_changed_fields);
     $fieldChanged = false;
     if ($name == 'afh_flags') {
         // This is a bit freaky, but it works.
         // Basically, returns true if any of those filters are in the $changed array.
         $filters = array('af_enabled', 'af_hidden', 'af_deleted', 'af_global');
         if (count(array_diff($filters, $changed)) < count($filters)) {
             $fieldChanged = true;
         }
     } elseif (in_array($mappings[$name], $changed)) {
         $fieldChanged = true;
     }
     if ($fieldChanged) {
         $formatted = Xml::tags('div', array('class' => 'mw-abusefilter-history-changed'), $formatted);
     }
     return $formatted;
 }
Ejemplo n.º 24
0
 function revertAction($action, $result)
 {
     switch ($action) {
         case 'block':
             $block = Block::newFromTarget(User::whoIs($result['userid']));
             if (!$block || $block->getBy() != AbuseFilter::getFilterUser()->getId()) {
                 return false;
                 // Not blocked by abuse filter.
             }
             $block->delete();
             $log = new LogPage('block');
             $log->addEntry('unblock', Title::makeTitle(NS_USER, $result['user']), wfMsgForContent('abusefilter-revert-reason', $this->mPage->mFilter, $this->mReason));
             break;
         case 'blockautopromote':
             global $wgMemc;
             $wgMemc->delete(AbuseFilter::autopromoteBlockKey(User::newFromId($result['userid'])));
             break;
         case 'degroup':
             // Pull the user's groups from the vars.
             $oldGroups = $result['vars']['USER_GROUPS'];
             $oldGroups = explode(',', $oldGroups);
             $oldGroups = array_diff($oldGroups, array_intersect($oldGroups, User::getImplicitGroups()));
             $rows = array();
             foreach ($oldGroups as $group) {
                 $rows[] = array('ug_user' => $result['userid'], 'ug_group' => $group);
             }
             // Cheat a little bit. User::addGroup repeatedly is too slow.
             $user = User::newFromId($result['userid']);
             $currentGroups = $user->getGroups();
             $newGroups = array_merge($oldGroups, $currentGroups);
             // Don't do anything if there are no groups to add.
             if (!count(array_diff($newGroups, $currentGroups))) {
                 return;
             }
             $dbw = wfGetDB(DB_MASTER);
             $dbw->insert('user_groups', $rows, __METHOD__, array('IGNORE'));
             $user->invalidateCache();
             $log = new LogPage('rights');
             $log->addEntry('rights', $user->getUserPage(), wfMsgForContent('abusefilter-revert-reason', $this->mPage->mFilter, $this->mReason), array(implode(',', $currentGroups), implode(',', $newGroups)));
     }
 }
 function showExaminer($vars)
 {
     $output = $this->getOutput();
     if (!$vars) {
         $output->addWikiMsg('abusefilter-examine-incompatible');
         return;
     }
     if ($vars instanceof AbuseFilterVariableHolder) {
         $vars = $vars->exportAllVars();
     }
     $html = '';
     $output->addModules('ext.abuseFilter.examine');
     // Add test bit
     if ($this->getUser()->isAllowed('abusefilter-modify')) {
         $tester = Xml::tags('h2', null, $this->msg('abusefilter-examine-test')->parse());
         $tester .= AbuseFilter::buildEditBox($this->mTestFilter, 'wpTestFilter', false);
         $tester .= "\n" . Xml::inputLabel($this->msg('abusefilter-test-load-filter')->text(), 'wpInsertFilter', 'mw-abusefilter-load-filter', 10, '') . '&#160;' . Xml::element('input', array('type' => 'button', 'value' => $this->msg('abusefilter-test-load')->text(), 'id' => 'mw-abusefilter-load'));
         $html .= Xml::tags('div', array('id' => 'mw-abusefilter-examine-editor'), $tester);
         $html .= Xml::tags('p', null, Xml::element('input', array('type' => 'button', 'value' => $this->msg('abusefilter-examine-test-button')->text(), 'id' => 'mw-abusefilter-examine-test')) . Xml::element('div', array('id' => 'mw-abusefilter-syntaxresult', 'style' => 'display: none;'), '&#160;'));
     }
     // Variable dump
     $html .= Xml::tags('h2', null, $this->msg('abusefilter-examine-vars', 'parseinline')->parse());
     $html .= AbuseFilter::buildVarDumpTable($vars);
     $output->addHTML($html);
 }
 /**
  * Check for abusive or spammy content
  *
  * Check the following in sequence (cheapest processing to most expensive,
  * returning if we get a hit):
  *  1) Respect $wgSpamRegex
  *  2) Check SpamBlacklist
  *  3) Check AbuseFilter
  *
  * @param $value  string the text to check
  * @param $pageId int    the page ID
  */
 private function findAbuse(&$value, $pageId)
 {
     // Respect $wgSpamRegex
     global $wgSpamRegex;
     if (is_array($wgSpamRegex) && count($wgSpamRegex) > 0 || is_string($wgSpamRegex) && strlen($wgSpamRegex) > 0) {
         // In older versions, $wgSpamRegex may be a single string rather than
         // an array of regexes, so make it compatible.
         $regexes = (array) $wgSpamRegex;
         foreach ($regexes as $regex) {
             if (preg_match($regex, $value)) {
                 return true;
             }
         }
     }
     // Create a fake title so we can pretend this is an article edit
     $title = Title::newFromText('__article_feedback_5__');
     // Check SpamBlacklist, if installed
     if (function_exists('wfSpamBlacklistObject')) {
         $spam = wfSpamBlacklistObject();
         $ret = $spam->filter($title, $value, '');
         if ($ret !== false) {
             return true;
         }
     }
     // Check AbuseFilter, if installed
     if (class_exists('AbuseFilter')) {
         global $wgUser;
         $vars = new AbuseFilterVariableHolder();
         $vars->addHolder(AbuseFilter::generateUserVars($wgUser));
         $vars->addHolder(AbuseFilter::generateTitleVars($title, 'FEEDBACK'));
         $vars->setVar('SUMMARY', 'Article Feedback 5');
         $vars->setVar('ACTION', 'feedback');
         $vars->setVar('old_wikitext', '');
         $vars->setVar('new_wikitext', $value);
         $vars->addHolder(AbuseFilter::getEditVars($title));
         $filter_result = AbuseFilter::filterAction($vars, $title);
         return $filter_result != '' && $filter_result !== true;
     }
     return false;
 }
Ejemplo n.º 27
0
 public function execute()
 {
     $user = $this->getUser();
     $errors = $this->getTitle()->getUserPermissionsErrors('abusefilter-log', $user);
     if (count($errors)) {
         $this->dieUsageMsg($errors[0]);
         return;
     }
     $params = $this->extractRequestParams();
     $prop = array_flip($params['prop']);
     $fld_ids = isset($prop['ids']);
     $fld_filter = isset($prop['filter']);
     $fld_user = isset($prop['user']);
     $fld_ip = isset($prop['ip']);
     $fld_title = isset($prop['title']);
     $fld_action = isset($prop['action']);
     $fld_details = isset($prop['details']);
     $fld_result = isset($prop['result']);
     $fld_timestamp = isset($prop['timestamp']);
     $fld_hidden = isset($prop['hidden']);
     $fld_revid = isset($prop['revid']);
     if ($fld_ip && !$user->isAllowed('abusefilter-private')) {
         $this->dieUsage('You don\'t have permission to view IP addresses', 'permissiondenied');
     }
     if ($fld_details && !$user->isAllowed('abusefilter-log-detail')) {
         $this->dieUsage('You don\'t have permission to view detailed abuse log entries', 'permissiondenied');
     }
     // Match permissions for viewing events on private filters to SpecialAbuseLog (bug 42814)
     if ($params['filter'] && !(AbuseFilterView::canViewPrivate() || $user->isAllowed('abusefilter-log-private'))) {
         // A specific filter parameter is set but the user isn't allowed to view all filters
         if (!is_array($params['filter'])) {
             $params['filter'] = array($params['filter']);
         }
         foreach ($params['filter'] as $filter) {
             if (AbuseFilter::filterHidden($filter)) {
                 $this->dieUsage('You don\'t have permission to view log entries for private filters', 'permissiondenied');
             }
         }
     }
     $result = $this->getResult();
     $this->addTables('abuse_filter_log');
     $this->addFields('afl_timestamp');
     $this->addFields('afl_rev_id');
     $this->addFields('afl_deleted');
     $this->addFields('afl_filter');
     $this->addFieldsIf('afl_id', $fld_ids);
     $this->addFieldsIf('afl_user_text', $fld_user);
     $this->addFieldsIf('afl_ip', $fld_ip);
     $this->addFieldsIf(array('afl_namespace', 'afl_title'), $fld_title);
     $this->addFieldsIf('afl_action', $fld_action);
     $this->addFieldsIf('afl_var_dump', $fld_details);
     $this->addFieldsIf('afl_actions', $fld_result);
     if ($fld_filter) {
         $this->addTables('abuse_filter');
         $this->addFields('af_public_comments');
         $this->addJoinConds(array('abuse_filter' => array('LEFT JOIN', 'af_id=afl_filter')));
     }
     $this->addOption('LIMIT', $params['limit'] + 1);
     $this->addWhereRange('afl_timestamp', $params['dir'], $params['start'], $params['end']);
     $db = $this->getDB();
     $notDeletedCond = SpecialAbuseLog::getNotDeletedCond($db);
     if (isset($params['user'])) {
         $u = User::newFromName($params['user']);
         if ($u) {
             // Username normalisation
             $params['user'] = $u->getName();
             $userId = $u->getId();
         } elseif (IP::isIPAddress($params['user'])) {
             // It's an IP, sanitize it
             $params['user'] = IP::sanitizeIP($params['user']);
             $userId = 0;
         }
         if (isset($userId)) {
             // Only add the WHERE for user in case it's either a valid user (but not necessary an existing one) or an IP
             $this->addWhere(array('afl_user' => $userId, 'afl_user_text' => $params['user']));
         }
     }
     $this->addWhereIf(array('afl_filter' => $params['filter']), isset($params['filter']));
     $this->addWhereIf($notDeletedCond, !SpecialAbuseLog::canSeeHidden($user));
     $title = $params['title'];
     if (!is_null($title)) {
         $titleObj = Title::newFromText($title);
         if (is_null($titleObj)) {
             $this->dieUsageMsg(array('invalidtitle', $title));
         }
         $this->addWhereFld('afl_namespace', $titleObj->getNamespace());
         $this->addWhereFld('afl_title', $titleObj->getDBkey());
     }
     $res = $this->select(__METHOD__);
     $count = 0;
     foreach ($res as $row) {
         if (++$count > $params['limit']) {
             // We've had enough
             $ts = new MWTimestamp($row->afl_timestamp);
             $this->setContinueEnumParameter('start', $ts->getTimestamp(TS_ISO_8601));
             break;
         }
         if (SpecialAbuseLog::isHidden($row) && !SpecialAbuseLog::canSeeHidden($user)) {
             continue;
         }
         $canSeeDetails = SpecialAbuseLog::canSeeDetails($row->afl_filter);
         $entry = array();
         if ($fld_ids) {
             $entry['id'] = intval($row->afl_id);
             $entry['filter_id'] = '';
             if ($canSeeDetails) {
                 $entry['filter_id'] = $row->afl_filter;
             }
         }
         if ($fld_filter) {
             $entry['filter'] = $row->af_public_comments;
         }
         if ($fld_user) {
             $entry['user'] = $row->afl_user_text;
         }
         if ($fld_ip) {
             $entry['ip'] = $row->afl_ip;
         }
         if ($fld_title) {
             $title = Title::makeTitle($row->afl_namespace, $row->afl_title);
             ApiQueryBase::addTitleInfo($entry, $title);
         }
         if ($fld_action) {
             $entry['action'] = $row->afl_action;
         }
         if ($fld_result) {
             $entry['result'] = $row->afl_actions;
         }
         if ($fld_revid && !is_null($row->afl_rev_id)) {
             $entry['revid'] = '';
             if ($canSeeDetails) {
                 $entry['revid'] = $row->afl_rev_id;
             }
         }
         if ($fld_timestamp) {
             $ts = new MWTimestamp($row->afl_timestamp);
             $entry['timestamp'] = $ts->getTimestamp(TS_ISO_8601);
         }
         if ($fld_details) {
             $entry['details'] = array();
             if ($canSeeDetails) {
                 $vars = AbuseFilter::loadVarDump($row->afl_var_dump);
                 if ($vars instanceof AbuseFilterVariableHolder) {
                     $entry['details'] = $vars->exportAllVars();
                 } else {
                     $entry['details'] = array_change_key_case($vars, CASE_LOWER);
                 }
             }
         }
         if ($fld_hidden) {
             $val = SpecialAbuseLog::isHidden($row);
             if ($val) {
                 $entry['hidden'] = $val;
             }
         }
         if ($entry) {
             $fit = $result->addValue(array('query', $this->getModuleName()), null, $entry);
             if (!$fit) {
                 $ts = new MWTimestamp($row->afl_timestamp);
                 $this->setContinueEnumParameter('start', $ts->getTimestamp(TS_ISO_8601));
                 break;
             }
         }
     }
     $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'item');
 }
Ejemplo n.º 28
0
 /**
  * @param $row
  * @param $isListItem bool
  * @return String
  */
 function formatRow($row, $isListItem = true)
 {
     $user = $this->getUser();
     $lang = $this->getLanguage();
     $actionLinks = array();
     $title = Title::makeTitle($row->afl_namespace, $row->afl_title);
     $diffLink = false;
     if (self::isHidden($row) && !$this->canSeeHidden()) {
         return '';
     }
     if (!$row->afl_wiki) {
         $pageLink = Linker::link($title);
         if ($row->afl_rev_id) {
             $diffLink = Linker::link($title, wfMessage('abusefilter-log-diff')->parse(), array(), array('diff' => 'prev', 'oldid' => $row->afl_rev_id));
         }
     } else {
         $pageLink = WikiMap::makeForeignLink($row->afl_wiki, $row->afl_title);
         if ($row->afl_rev_id) {
             $diffUrl = WikiMap::getForeignURL($row->afl_wiki, $row->afl_title);
             $diffUrl = wfAppendQuery($diffUrl, array('diff' => 'prev', 'oldid' => $row->afl_rev_id));
             $diffLink = Linker::makeExternalLink($diffUrl, wfMessage('abusefilter-log-diff')->parse());
         }
     }
     if (!$row->afl_wiki) {
         // Local user
         $userLink = Linker::userLink($row->afl_user, $row->afl_user_text) . Linker::userToolLinks($row->afl_user, $row->afl_user_text, true);
     } else {
         $userLink = WikiMap::foreignUserLink($row->afl_wiki, $row->afl_user_text);
         $userLink .= ' (' . WikiMap::getWikiName($row->afl_wiki) . ')';
     }
     $timestamp = $lang->timeanddate($row->afl_timestamp, true);
     $actions_taken = $row->afl_actions;
     if (!strlen(trim($actions_taken))) {
         $actions_taken = $this->msg('abusefilter-log-noactions')->text();
     } else {
         $actions = explode(',', $actions_taken);
         $displayActions = array();
         foreach ($actions as $action) {
             $displayActions[] = AbuseFilter::getActionDisplay($action);
         }
         $actions_taken = $lang->commaList($displayActions);
     }
     $globalIndex = AbuseFilter::decodeGlobalName($row->afl_filter);
     if ($globalIndex) {
         // Pull global filter description
         $parsed_comments = $this->getOutput()->parseInline(AbuseFilter::getGlobalFilterDescription($globalIndex));
         $filter_hidden = null;
     } else {
         $parsed_comments = $this->getOutput()->parseInline($row->af_public_comments);
         $filter_hidden = $row->af_hidden;
     }
     if (self::canSeeDetails($row->afl_filter, $filter_hidden)) {
         if ($isListItem) {
             $detailsLink = Linker::linkKnown($this->getPageTitle($row->afl_id), $this->msg('abusefilter-log-detailslink')->escaped());
             $actionLinks[] = $detailsLink;
         }
         $examineTitle = SpecialPage::getTitleFor('AbuseFilter', 'examine/log/' . $row->afl_id);
         $examineLink = Linker::link($examineTitle, $this->msg('abusefilter-changeslist-examine')->parse(), array());
         $actionLinks[] = $examineLink;
         if ($diffLink) {
             $actionLinks[] = $diffLink;
         }
         if ($user->isAllowed('abusefilter-hide-log')) {
             $hideLink = Linker::link($this->getPageTitle(), $this->msg('abusefilter-log-hidelink')->text(), array(), array('hide' => $row->afl_id));
             $actionLinks[] = $hideLink;
         }
         if ($globalIndex) {
             global $wgAbuseFilterCentralDB;
             $globalURL = WikiMap::getForeignURL($wgAbuseFilterCentralDB, 'Special:AbuseFilter/' . $globalIndex);
             $linkText = wfMessage('abusefilter-log-detailedentry-global')->numParams($globalIndex)->escaped();
             $filterLink = Linker::makeExternalLink($globalURL, $linkText);
         } else {
             $title = SpecialPage::getTitleFor('AbuseFilter', $row->afl_filter);
             $linkText = wfMessage('abusefilter-log-detailedentry-local')->numParams($row->afl_filter)->escaped();
             $filterLink = Linker::link($title, $linkText);
         }
         $description = $this->msg('abusefilter-log-detailedentry-meta')->rawParams($timestamp, $userLink, $filterLink, $row->afl_action, $pageLink, $actions_taken, $parsed_comments, $lang->pipeList($actionLinks), $row->afl_user_text)->parse();
     } else {
         if ($diffLink) {
             $msg = 'abusefilter-log-entry-withdiff';
         } else {
             $msg = 'abusefilter-log-entry';
         }
         $description = $this->msg($msg)->rawParams($timestamp, $userLink, $row->afl_action, $pageLink, $actions_taken, $parsed_comments, $diffLink)->parse();
     }
     if (self::isHidden($row) === true) {
         $description .= ' ' . $this->msg('abusefilter-log-hidden')->parse();
         $class = 'afl-hidden';
     } elseif (self::isHidden($row) === 'implicit') {
         $description .= ' ' . $this->msg('abusefilter-log-hidden-implicit')->parse();
     }
     if ($isListItem) {
         return Xml::tags('li', isset($class) ? array('class' => $class) : null, $description);
     } else {
         return Xml::tags('span', isset($class) ? array('class' => $class) : null, $description);
     }
 }
Ejemplo n.º 29
0
 public function execute($subpage)
 {
     global $wgUser, $wgOut, $wgRequest, $wgAbuseFilterStyleVersion, $wgScriptPath;
     $wgOut->addScript('<style type="text/css" media="all">/*<![CDATA[*/ @import "/extensions/AbuseFilter/abusefilter.css"/*]]>*/</style>');
     $view = 'AbuseFilterViewList';
     $this->setHeaders();
     $this->loadParameters($subpage);
     $wgOut->setPageTitle(wfMsg('abusefilter-management'));
     // Are we allowed?
     if (!$wgUser->isAllowed('abusefilter-view')) {
         $this->displayRestrictionError();
         return;
     }
     if ($wgRequest->getVal('result') == 'success') {
         $wgOut->setSubtitle(wfMsg('abusefilter-edit-done-subtitle'));
         $changedFilter = intval($wgRequest->getVal('changedfilter'));
         $wgOut->wrapWikiMsg('<p class="success">$1</p>', array('abusefilter-edit-done', $changedFilter));
     }
     $this->mSkin = $wgUser->getSkin();
     $this->mHistoryID = null;
     $pageType = 'home';
     $params = explode('/', $subpage);
     // Filter by removing blanks.
     foreach ($params as $index => $param) {
         if ($param === '') {
             unset($params[$index]);
         }
     }
     $params = array_values($params);
     if ($subpage == 'tools') {
         $view = 'AbuseFilterViewTools';
         $pageType = 'tools';
     }
     if (count($params) == 2 && $params[0] == 'revert' && is_numeric($params[1])) {
         $this->mFilter = $params[1];
         $view = 'AbuseFilterViewRevert';
         $pageType = 'revert';
     }
     if (count($params) && $params[0] == 'test') {
         $view = 'AbuseFilterViewTestBatch';
         $pageType = 'test';
     }
     if (count($params) && $params[0] == 'examine') {
         $view = 'AbuseFilterViewExamine';
         $pageType = 'examine';
     }
     if (!empty($params[0]) && ($params[0] == 'history' || $params[0] == 'log')) {
         $pageType = '';
         if (count($params) == 1) {
             $view = 'AbuseFilterViewHistory';
             $pageType = 'recentchanges';
         } elseif (count($params) == 2) {
             # # Second param is a filter ID
             $view = 'AbuseFilterViewHistory';
             $this->mFilter = $params[1];
         } elseif (count($params) == 4 && $params[2] == 'item') {
             $this->mFilter = $params[1];
             $this->mHistoryID = $params[3];
             $view = 'AbuseFilterViewEdit';
         } elseif (count($params) == 5 && $params[2] == 'diff') {
             // Special:AbuseFilter/history/<filter>/diff/<oldid>/<newid>
             $view = 'AbuseFilterViewDiff';
         }
     }
     if (is_numeric($subpage) || $subpage == 'new') {
         $this->mFilter = $subpage;
         $view = 'AbuseFilterViewEdit';
         $pageType = 'edit';
     }
     if ($subpage == 'import') {
         $view = 'AbuseFilterViewImport';
         $pageType = 'import';
     }
     // Links at the top
     AbuseFilter::addNavigationLinks($wgOut, $this->mSkin, $pageType);
     $v = new $view($this, $params);
     $v->show();
 }
Ejemplo n.º 30
0
 function showExaminer($vars)
 {
     global $wgOut, $wgUser;
     if (!$vars) {
         $wgOut->addWikiMsg('abusefilter-examine-incompatible');
         return;
     }
     if ($vars instanceof AbuseFilterVariableHolder) {
         $vars = $vars->exportAllVars();
     }
     $output = '';
     // Send armoured as JSON -- I totally give up on trying to send it as a proper object.
     $wgOut->addInlineScript("var wgExamineVars = " . Xml::encodeJsVar(json_encode($vars)) . ";");
     $wgOut->addInlineScript(file_get_contents(dirname(__FILE__) . '/examine.js'));
     // Add messages
     $msg = array();
     $msg['match'] = wfMsg('abusefilter-examine-match');
     $msg['nomatch'] = wfMsg('abusefilter-examine-nomatch');
     $msg['syntaxerror'] = wfMsg('abusefilter-examine-syntaxerror');
     $wgOut->addInlineScript("var wgMessageMatch = " . Xml::encodeJsVar($msg['match']) . ";\n" . "var wgMessageNomatch = " . Xml::encodeJsVar($msg['nomatch']) . ";\n" . "var wgMessageError = " . Xml::encodeJsVar($msg['syntaxerror']) . ";\n");
     // Add test bit
     if ($wgUser->isAllowed('abusefilter-modify')) {
         $tester = Xml::tags('h2', null, wfMsgExt('abusefilter-examine-test', 'parseinline'));
         $tester .= AbuseFilter::buildEditBox($this->mTestFilter, 'wpTestFilter', false);
         $tester .= "\n" . Xml::inputLabel(wfMsg('abusefilter-test-load-filter'), 'wpInsertFilter', 'mw-abusefilter-load-filter', 10, '') . '&nbsp;' . Xml::element('input', array('type' => 'button', 'value' => wfMsg('abusefilter-test-load'), 'id' => 'mw-abusefilter-load'));
         $output .= Xml::tags('div', array('id' => 'mw-abusefilter-examine-editor'), $tester);
         $output .= Xml::tags('p', null, Xml::element('input', array('type' => 'button', 'value' => wfMsg('abusefilter-examine-test-button'), 'id' => 'mw-abusefilter-examine-test')) . Xml::element('div', array('id' => 'mw-abusefilter-syntaxresult', 'style' => 'display: none;'), '&nbsp;'));
     }
     // Variable dump
     $output .= Xml::tags('h2', null, wfMsgExt('abusefilter-examine-vars', 'parseinline'));
     $output .= AbuseFilter::buildVarDumpTable($vars);
     $wgOut->addHTML($output);
 }