function loadData()
 {
     $oldSpec = $this->mParams[3];
     $newSpec = $this->mParams[4];
     $this->mFilter = $this->mParams[1];
     if (AbuseFilter::filterHidden($this->mFilter) && !$this->getUser()->isAllowed('abusefilter-modify')) {
         $this->getOutput()->addWikiMsg('abusefilter-history-error-hidden');
         return false;
     }
     $this->mOldVersion = $this->loadSpec($oldSpec, $newSpec);
     $this->mNewVersion = $this->loadSpec($newSpec, $oldSpec);
     if (is_null($this->mOldVersion) || is_null($this->mNewVersion)) {
         $this->getOutput()->addWikiMsg('abusefilter-diff-invalid');
         return false;
     }
     return true;
 }
Example #2
0
 function loadSpec($spec, $otherSpec)
 {
     static $dependentSpecs = array('prev', 'next');
     static $cache = array();
     global $wgUser;
     if (AbuseFilter::filterHidden($this->mFilter) && !$wgUser->isAllowed('abusefilter-modify')) {
         return null;
     }
     if (isset($cache[$spec])) {
         return $cache[$spec];
     }
     $dbr = wfGetDB(DB_SLAVE);
     if (is_numeric($spec)) {
         $row = $dbr->selectRow('abuse_filter_history', '*', array('afh_id' => $spec, 'afh_filter' => $this->mFilter), __METHOD__);
     } elseif ($spec == 'cur') {
         $row = $dbr->selectRow('abuse_filter_history', '*', array('afh_filter' => $this->mFilter), __METHOD__, array('ORDER BY' => 'afh_timestamp desc'));
     } elseif ($spec == 'prev' && !in_array($otherSpec, $dependentSpecs)) {
         // cached
         $other = $this->loadSpec($otherSpec, $spec);
         $row = $dbr->selectRow('abuse_filter_history', '*', array('afh_filter' => $this->mFilter, 'afh_id<' . $dbr->addQuotes($other['meta']['history_id'])), __METHOD__, array('ORDER BY' => 'afh_timestamp desc'));
         if ($other && !$row) {
             $t = $this->getTitle('history/' . $this->mFilter . '/item/' . $other['meta']['history_id']);
             global $wgOut;
             $wgOut->redirect($t->getFullURL());
             return;
         }
     } elseif ($spec == 'next' && !in_array($otherSpec, $dependentSpecs)) {
         // cached
         $other = $this->loadSpec($otherSpec, $spec);
         $row = $dbr->selectRow('abuse_filter_history', '*', array('afh_filter' => $this->mFilter, 'afh_id>' . $dbr->addQuotes($other['meta']['history_id'])), __METHOD__, array('ORDER BY' => 'afh_timestamp DESC'));
         if ($other && !$row) {
             $t = $this->getTitle('history/' . $this->mFilter . '/item/' . $other['meta']['history_id']);
             global $wgOut;
             $wgOut->redirect($t->getFullURL());
             return;
         }
     }
     if (!$row) {
         return null;
     }
     $data = $this->loadFromHistoryRow($row);
     $cache[$spec] = $data;
     return $data;
 }
 function show()
 {
     global $wgRequest, $wgOut, $wgLang, $wgUser;
     $filter = $this->mFilter;
     if ($filter) {
         $wgOut->setPageTitle(wfMsg('abusefilter-history', $filter));
     } else {
         $wgOut->setPageTitle(wfMsg('abusefilter-filter-log'));
     }
     # Check perms
     if ($filter && !$wgUser->isAllowed('abusefilter-modify') && AbuseFilter::filterHidden($filter)) {
         $wgOut->addWikiMsg('abusefilter-history-error-hidden');
         return;
     }
     # Useful links
     $sk = $wgUser->getSkin();
     $links = array();
     if ($filter) {
         $links['abusefilter-history-backedit'] = $this->getTitle($filter);
     }
     foreach ($links as $msg => $title) {
         $links[$msg] = $sk->link($title, wfMsgExt($msg, 'parseinline'));
     }
     $backlinks = $wgLang->pipeList($links);
     $wgOut->addHTML(Xml::tags('p', null, $backlinks));
     # For user
     $user = $wgRequest->getText('user');
     if ($user) {
         $wgOut->setSubtitle(wfMsg('abusefilter-history-foruser', $sk->userLink(1, $user), $user));
     }
     // Add filtering of changes et al.
     $fields['abusefilter-history-select-user'] = Xml::input('user', 45, $user);
     $filterForm = Xml::buildForm($fields, 'abusefilter-history-select-submit');
     $filterForm .= "\n" . Xml::hidden('title', $this->getTitle("history/{$filter}"));
     $filterForm = Xml::tags('form', array('action' => $this->getTitle("history/{$filter}")->getLocalURL(), 'method' => 'get'), $filterForm);
     $filterForm = Xml::fieldset(wfMsg('abusefilter-history-select-legend'), $filterForm);
     $wgOut->addHTML($filterForm);
     $pager = new AbuseFilterHistoryPager($filter, $this, $user);
     $table = $pager->getBody();
     $wgOut->addHTML($pager->getNavigationBar() . $table . $pager->getNavigationBar());
 }
 function show()
 {
     $out = $this->getOutput();
     $filter = $this->mFilter;
     if ($filter) {
         $out->setPageTitle($this->msg('abusefilter-history', $filter));
     } else {
         $out->setPageTitle($this->msg('abusefilter-filter-log'));
     }
     # Check perms
     if ($filter && !$this->getUser()->isAllowed('abusefilter-modify') && AbuseFilter::filterHidden($filter)) {
         $out->addWikiMsg('abusefilter-history-error-hidden');
         return;
     }
     # Useful links
     $links = array();
     if ($filter) {
         $links['abusefilter-history-backedit'] = $this->getTitle($filter);
     }
     foreach ($links as $msg => $title) {
         $links[$msg] = Linker::link($title, $this->msg($msg)->parse());
     }
     $backlinks = $this->getLanguage()->pipeList($links);
     $out->addHTML(Xml::tags('p', null, $backlinks));
     # For user
     $user = User::getCanonicalName($this->getRequest()->getText('user'), 'valid');
     if ($user) {
         $out->addSubtitle($this->msg('abusefilter-history-foruser', Linker::userLink(1, $user), $user)->text());
     }
     // Add filtering of changes et al.
     $fields['abusefilter-history-select-user'] = Xml::input('user', 45, $user);
     $filterForm = Xml::buildForm($fields, 'abusefilter-history-select-submit');
     $filterForm .= "\n" . Html::hidden('title', $this->getTitle("history/{$filter}"));
     $filterForm = Xml::tags('form', array('action' => $this->getTitle("history/{$filter}")->getLocalURL(), 'method' => 'get'), $filterForm);
     $filterForm = Xml::fieldset($this->msg('abusefilter-history-select-legend')->text(), $filterForm);
     $out->addHTML($filterForm);
     $pager = new AbuseFilterHistoryPager($filter, $this, $user);
     $table = $pager->getBody();
     $out->addHTML($pager->getNavigationBar() . $table . $pager->getNavigationBar());
 }
 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');
 }
 function buildFilterEditor($error, $filter, $history_id = null)
 {
     if ($filter === null) {
         return false;
     }
     // Build the edit form
     $out = $this->getOutput();
     $lang = $this->getLanguage();
     $user = $this->getUser();
     $sk = $this->getSkin();
     // Load from request OR database.
     list($row, $actions) = $this->loadRequest($filter, $history_id);
     if (!$row) {
         $out->addWikiMsg('abusefilter-edit-badfilter');
         $out->addHTML($sk->link($this->getTitle(), wfMsg('abusefilter-return')));
         return;
     }
     $out->setSubtitle(wfMsg('abusefilter-edit-subtitle', $filter, $history_id));
     // Hide hidden filters.
     if ((isset($row->af_hidden) && $row->af_hidden || AbuseFilter::filterHidden($filter)) && !$this->canViewPrivate()) {
         return wfMsg('abusefilter-edit-denied');
     }
     $output = '';
     if ($error) {
         $out->addHTML("<span class=\"error\">{$error}</span>");
     }
     // Read-only attribute
     $readOnlyAttrib = array();
     $cbReadOnlyAttrib = array();
     // For checkboxes
     if (!$this->canEdit()) {
         $readOnlyAttrib['readonly'] = 'readonly';
         $cbReadOnlyAttrib['disabled'] = 'disabled';
     }
     $fields = array();
     $fields['abusefilter-edit-id'] = $this->mFilter == 'new' ? wfMsg('abusefilter-edit-new') : $lang->formatNum($filter);
     $fields['abusefilter-edit-description'] = Xml::input('wpFilterDescription', 45, isset($row->af_public_comments) ? $row->af_public_comments : '', $readOnlyAttrib);
     // Hit count display
     if (!empty($row->af_hit_count)) {
         $count = (int) $row->af_hit_count;
         $count_display = wfMsgExt('abusefilter-hitcount', array('parseinline'), $lang->formatNum($count));
         $hitCount = $sk->makeKnownLinkObj(SpecialPage::getTitleFor('AbuseLog'), $count_display, 'wpSearchFilter=' . $row->af_id);
         $fields['abusefilter-edit-hitcount'] = $hitCount;
     }
     if ($filter !== 'new') {
         // Statistics
         global $wgMemc;
         $matches_count = $wgMemc->get(AbuseFilter::filterMatchesKey($filter));
         $total = $wgMemc->get(AbuseFilter::filterUsedKey());
         if ($total > 0) {
             $matches_percent = sprintf('%.2f', 100 * $matches_count / $total);
             list($timeProfile, $condProfile) = AbuseFilter::getFilterProfile($filter);
             $fields['abusefilter-edit-status-label'] = wfMsgExt('abusefilter-edit-status', array('parsemag', 'escape'), array($lang->formatNum($total), $lang->formatNum($matches_count), $lang->formatNum($matches_percent), $lang->formatNum($timeProfile), $lang->formatNum($condProfile)));
         }
     }
     $fields['abusefilter-edit-rules'] = AbuseFilter::buildEditBox($row->af_pattern, 'wpFilterRules', true, $this->canEdit());
     $fields['abusefilter-edit-notes'] = Xml::textarea('wpFilterNotes', isset($row->af_comments) ? $row->af_comments . "\n" : "\n", 40, 5, $readOnlyAttrib);
     // Build checkboxen
     $checkboxes = array('hidden', 'enabled', 'deleted');
     $flags = '';
     global $wgAbuseFilterIsCentral;
     if ($wgAbuseFilterIsCentral) {
         $checkboxes[] = 'global';
     }
     if (isset($row->af_throttled) && $row->af_throttled) {
         global $wgAbuseFilterEmergencyDisableThreshold;
         $threshold_percent = sprintf('%.2f', $wgAbuseFilterEmergencyDisableThreshold * 100);
         $flags .= $out->parse(wfMsg('abusefilter-edit-throttled', $lang->formatNum($threshold_percent)));
     }
     foreach ($checkboxes as $checkboxId) {
         $message = "abusefilter-edit-{$checkboxId}";
         $dbField = "af_{$checkboxId}";
         $postVar = 'wpFilter' . ucfirst($checkboxId);
         $checkbox = Xml::checkLabel(wfMsg($message), $postVar, $postVar, isset($row->{$dbField}) ? $row->{$dbField} : false, $cbReadOnlyAttrib);
         $checkbox = Xml::tags('p', null, $checkbox);
         $flags .= $checkbox;
     }
     $fields['abusefilter-edit-flags'] = $flags;
     $tools = '';
     if ($filter != 'new' && $user->isAllowed('abusefilter-revert')) {
         $tools .= Xml::tags('p', null, $sk->link($this->getTitle('revert/' . $filter), wfMsg('abusefilter-edit-revert')));
     }
     if ($filter != 'new') {
         // Test link
         $tools .= Xml::tags('p', null, $sk->link($this->getTitle("test/{$filter}"), wfMsgExt('abusefilter-edit-test-link', 'parseinline')));
         // Last modification details
         $userLink = $sk->userLink($row->af_user, $row->af_user_text) . $sk->userToolLinks($row->af_user, $row->af_user_text);
         $userName = $row->af_user_text;
         $fields['abusefilter-edit-lastmod'] = wfMsgExt('abusefilter-edit-lastmod-text', array('parseinline', 'replaceafter'), array($lang->timeanddate($row->af_timestamp, true), $userLink, $lang->date($row->af_timestamp, true), $lang->time($row->af_timestamp, true), $userName));
         $history_display = wfMsgExt('abusefilter-edit-viewhistory', array('parseinline'));
         $fields['abusefilter-edit-history'] = $sk->makeKnownLinkObj($this->getTitle('history/' . $filter), $history_display);
     }
     // Add export
     $exportText = json_encode(array('row' => $row, 'actions' => $actions));
     $tools .= Xml::tags('a', array('href' => '#', 'id' => 'mw-abusefilter-export-link'), wfMsgExt('abusefilter-edit-export', 'parseinline'));
     $tools .= Xml::element('textarea', array('readonly' => 'readonly', 'id' => 'mw-abusefilter-export'), $exportText);
     $fields['abusefilter-edit-tools'] = $tools;
     $form = Xml::buildForm($fields);
     $form = Xml::fieldset(wfMsg('abusefilter-edit-main'), $form);
     $form .= Xml::fieldset(wfMsg('abusefilter-edit-consequences'), $this->buildConsequenceEditor($row, $actions));
     if ($this->canEdit()) {
         $form .= Xml::submitButton(wfMsg('abusefilter-edit-save'), array('accesskey' => 's'));
         $form .= Html::hidden('wpEditToken', $user->getEditToken(array('abusefilter', $filter)));
     }
     $form = Xml::tags('form', array('action' => $this->getTitle($filter)->getFullURL(), 'method' => 'post'), $form);
     $output .= $form;
     return $output;
 }
 /**
  * @param $filter_id null
  * @param $filter_hidden null
  * @return bool
  */
 static function canSeeDetails($filter_id = null, $filter_hidden = null)
 {
     global $wgUser;
     if ($filter_id !== null) {
         if ($filter_hidden === null) {
             $filter_hidden = AbuseFilter::filterHidden($filter_id);
         }
         if ($filter_hidden) {
             return $wgUser->isAllowed('abusefilter-log-detail') && (AbuseFilterView::canViewPrivate() || $wgUser->isAllowed('abusefilter-log-private'));
         }
     }
     return $wgUser->isAllowed('abusefilter-log-detail');
 }