public function onCheckUserInsertForRecentChange($rc, &$fields) { $fields['cuc_ip'] = IP::sanitizeIP($this->ip); $fields['cuc_ip_hex'] = $this->ip ? IP::toHex($this->ip) : null; $fields['cuc_agent'] = $this->ua; if (method_exists('CheckUserHooks', 'getClientIPfromXFF')) { list($xff_ip, $isSquidOnly) = CheckUserHooks::getClientIPfromXFF($this->xff); $fields['cuc_xff'] = !$isSquidOnly ? $this->xff : ''; $fields['cuc_xff_hex'] = $xff_ip && !$isSquidOnly ? IP::toHex($xff_ip) : null; } else { $fields['cuc_xff'] = ''; $fields['cuc_xff_hex'] = null; } }
/** * @param $actions_taken * @param $log_template * @param $action * @param $vars AbuseFilterVariableHolder * @param string $group * @return mixed */ public static function addLogEntries($actions_taken, $log_template, $action, $vars, $group = 'default') { wfProfileIn(__METHOD__); $dbw = wfGetDB(DB_MASTER); $central_log_template = array('afl_wiki' => wfWikiID()); $log_rows = array(); $central_log_rows = array(); $logged_local_filters = array(); $logged_global_filters = array(); foreach ($actions_taken as $filter => $actions) { $globalIndex = self::decodeGlobalName($filter); $thisLog = $log_template; $thisLog['afl_filter'] = $filter; $thisLog['afl_action'] = $action; $thisLog['afl_actions'] = implode(',', $actions); // Don't log if we were only throttling. if ($thisLog['afl_actions'] != 'throttle') { $log_rows[] = $thisLog; if (!$globalIndex) { $logged_local_filters[] = $filter; } // Global logging if ($globalIndex) { $title = Title::makeTitle($thisLog['afl_namespace'], $thisLog['afl_title']); $centralLog = $thisLog + $central_log_template; $centralLog['afl_filter'] = $globalIndex; $centralLog['afl_title'] = $title->getPrefixedText(); $centralLog['afl_namespace'] = 0; $central_log_rows[] = $centralLog; $logged_global_filters[] = $globalIndex; } } } if (!count($log_rows)) { wfProfileOut(__METHOD__); return; } // Only store the var dump if we're actually going to add log rows. $var_dump = self::storeVarDump($vars); $var_dump = "stored-text:{$var_dump}"; // To distinguish from stuff stored directly wfProfileIn(__METHOD__ . '-hitstats'); global $wgMemc; // Increment trigger counter $wgMemc->incr(self::filterMatchesKey()); $local_log_ids = array(); global $wgAbuseFilterNotifications, $wgAbuseFilterNotificationsPrivate; foreach ($log_rows as $data) { $data['afl_var_dump'] = $var_dump; $data['afl_id'] = $dbw->nextSequenceValue('abuse_filter_log_afl_id_seq'); $dbw->insert('abuse_filter_log', $data, __METHOD__); $local_log_ids[] = $dbw->insertId(); if ($data['afl_id'] === null) { $data['afl_id'] = $dbw->insertId(); } $entry = new ManualLogEntry('abusefilter', 'hit'); // Construct a user object $user = User::newFromId($data['afl_user']); $user->setName($data['afl_user_text']); $entry->setPerformer($user); // Set action target $entry->setTarget(Title::makeTitle($data['afl_namespace'], $data['afl_title'])); // Additional info $entry->setParameters(array('action' => $data['afl_action'], 'filter' => $data['afl_filter'], 'actions' => $data['afl_actions'], 'log' => $data['afl_id'])); // Send data to CheckUser if installed and we // aren't already sending a notification to recentchanges // Requires MW 1.23+ if (is_callable('CheckUserHooks::updateCheckUserData') && is_callable('ManualLogEntry::getRecentChange') && strpos($wgAbuseFilterNotifications, 'rc') === false) { $rc = $entry->getRecentChange(); CheckUserHooks::updateCheckUserData($rc); } if ($wgAbuseFilterNotifications !== false) { if (self::filterHidden($data['afl_filter']) && !$wgAbuseFilterNotificationsPrivate) { continue; } $entry->publish(0, $wgAbuseFilterNotifications); } } $method = __METHOD__; if (count($logged_local_filters)) { // Update hit-counter. $dbw->onTransactionPreCommitOrIdle(function () use($dbw, $logged_local_filters, $method) { $dbw->update('abuse_filter', array('af_hit_count=af_hit_count+1'), array('af_id' => $logged_local_filters), $method); }); } $global_log_ids = array(); // Global stuff if (count($logged_global_filters)) { $vars->computeDBVars(); $global_var_dump = self::storeVarDump($vars, true); $global_var_dump = "stored-text:{$global_var_dump}"; foreach ($central_log_rows as $index => $data) { $central_log_rows[$index]['afl_var_dump'] = $global_var_dump; } global $wgAbuseFilterCentralDB; $fdb = wfGetDB(DB_MASTER, array(), $wgAbuseFilterCentralDB); foreach ($central_log_rows as $row) { $fdb->insert('abuse_filter_log', $row, __METHOD__); $global_log_ids[] = $dbw->insertId(); } $fdb->onTransactionPreCommitOrIdle(function () use($fdb, $logged_global_filters, $method) { $fdb->update('abuse_filter', array('af_hit_count=af_hit_count+1'), array('af_id' => $logged_global_filters), $method); }); } $vars->setVar('global_log_ids', $global_log_ids); $vars->setVar('local_log_ids', $local_log_ids); // Check for emergency disabling. $total = $wgMemc->get(AbuseFilter::filterUsedKey($group)); self::checkEmergencyDisable($group, $logged_local_filters, $total); wfProfileOut(__METHOD__ . '-hitstats'); wfProfileOut(__METHOD__); }
/** * @param Row $row * @param string $reason * @return a streamlined recent changes line with IP data */ protected function CUChangesLine($row, $reason) { global $wgLang; static $cuTitle, $flagCache; $cuTitle = SpecialPage::getTitleFor('CheckUser'); # Add date headers as needed $date = $wgLang->date(wfTimestamp(TS_MW, $row->cuc_timestamp), true, true); if (!isset($this->lastdate)) { $this->lastdate = $date; $line = "\n<h4>{$date}</h4>\n<ul class=\"special\">"; } elseif ($date != $this->lastdate) { $line = "</ul>\n<h4>{$date}</h4>\n<ul class=\"special\">"; $this->lastdate = $date; } else { $line = ''; } $line .= '<li>'; # Create diff/hist/page links $line .= $this->getLinksFromRow($row); # Show date $line .= ' . . ' . $wgLang->time(wfTimestamp(TS_MW, $row->cuc_timestamp), true, true) . ' . . '; # Userlinks $line .= $this->sk->userLink($row->cuc_user, $row->cuc_user_text); $line .= $this->sk->userToolLinks($row->cuc_user, $row->cuc_user_text); # Get block info if (isset($flagCache[$row->cuc_user_text])) { $flags = $flagCache[$row->cuc_user_text]; } else { $user = User::newFromName($row->cuc_user_text, false); $ip = IP::isIPAddress($row->cuc_user_text) ? $row->cuc_user_text : ''; $flags = $this->userBlockFlags($ip, $row->cuc_user, $user); $flagCache[$row->cuc_user_text] = $flags; } # Add any block information if (count($flags)) { $line .= ' ' . implode(' ', $flags); } # Action text, hackish ... if ($row->cuc_actiontext) { $line .= ' ' . $this->sk->formatComment($row->cuc_actiontext) . ' '; } # Comment $line .= $this->sk->commentBlock($row->cuc_comment); $line .= '<br />        <small>'; # IP $line .= ' <strong>IP</strong>: ' . $this->sk->makeKnownLinkObj($cuTitle, htmlspecialchars($row->cuc_ip), 'user='******'&reason=' . urlencode($reason)); # XFF if ($row->cuc_xff != null) { # Flag our trusted proxies list($client, $trusted) = CheckUserHooks::getClientIPfromXFF($row->cuc_xff, $row->cuc_ip); $c = $trusted ? '#F0FFF0' : '#FFFFCC'; $line .= '   <span class="mw-checkuser-xff" style="background-color: ' . $c . '">' . '<strong>XFF</strong>: '; $line .= $this->sk->makeKnownLinkObj($cuTitle, htmlspecialchars($row->cuc_xff), 'user='******'/xff&reason=' . urlencode($reason)) . '</span>'; } # User agent $line .= '   <span class="mw-checkuser-agent" style="color:#888;">' . htmlspecialchars($row->cuc_agent) . '</span>'; $line .= "</small></li>\n"; return $line; }
/** * When CheckUser extension is installed log events. * @param string $action that occurred * @param integer $id of the collection that was operated on. * @throws MWException */ private function logEntry($action, $id) { // If CheckUser installed, give it a heads up $user = $this->getUser(); $target = SpecialPage::getTitleFor('Gather')->getSubPage('id')->getSubPage($id); $entry = new ManualLogEntry('gather', 'action'); $entry->setPerformer($user); $entry->setTarget($target); $params = array('action' => $action); $entry->setParameters($params); $rc = $entry->getRecentChange(); if (is_callable('\\CheckUserHooks::updateCheckUserData')) { \CheckUserHooks::updateCheckUserData($rc); } // Surface hide, unhide and approve actions in Special:Log if ($action === 'hidelist' || $action === 'showlist' || $action === 'approve') { $logId = $entry->insert(); $entry->publish($logId, 'udp'); } }