/** * Given a target and the target's type, get an existing Block object if possible. * @param string|User|int $specificTarget A block target, which may be one of several types: * * A user to block, in which case $target will be a User * * An IP to block, in which case $target will be a User generated by using * User::newFromName( $ip, false ) to turn off name validation * * An IP range, in which case $target will be a String "123.123.123.123/18" etc * * The ID of an existing block, in the format "#12345" (since pure numbers are valid * usernames * Calling this with a user, IP address or range will not select autoblocks, and will * only select a block where the targets match exactly (so looking for blocks on * 1.2.3.4 will not select 1.2.0.0/16 or even 1.2.3.4/32) * @param string|User|int $vagueTarget As above, but we will search for *any* block which * affects that target (so for an IP address, get ranges containing that IP; and also * get any relevant autoblocks). Leave empty or blank to skip IP-based lookups. * @param bool $fromMaster Whether to use the DB_MASTER database * @return Block|null (null if no relevant block could be found). The target and type * of the returned Block will refer to the actual block which was found, which might * not be the same as the target you gave if you used $vagueTarget! */ public static function newFromTarget($specificTarget, $vagueTarget = null, $fromMaster = false) { list($target, $type) = self::parseTarget($specificTarget); if ($type == Block::TYPE_ID || $type == Block::TYPE_AUTO) { return Block::newFromID($target); } elseif ($target === null && $vagueTarget == '') { # We're not going to find anything useful here # Be aware that the == '' check is explicit, since empty values will be # passed by some callers (bug 29116) return null; } elseif (in_array($type, array(Block::TYPE_USER, Block::TYPE_IP, Block::TYPE_RANGE, null))) { $block = new Block(); $block->fromMaster($fromMaster); if ($type !== null) { $block->setTarget($target); } if ($block->newLoad($vagueTarget)) { return $block; } } return null; }
/** * Get blocking information * @private * @param bool $bFromSlave Specify whether to check slave or master. To improve performance, * non-critical checks are done against slaves. Check when actually saving should be done against * master. */ function getBlockedStatus($bFromSlave = true) { global $wgEnableSorbs, $wgProxyWhitelist; if (-1 != $this->mBlockedby) { wfDebug("User::getBlockedStatus: already loaded.\n"); return; } $fname = 'User::getBlockedStatus'; wfProfileIn($fname); wfDebug("{$fname}: checking...\n"); $this->mBlockedby = 0; $ip = wfGetIP(); # User/IP blocking $block = new Block(); $block->fromMaster(!$bFromSlave); if ($block->load($ip, $this->mId)) { wfDebug("{$fname}: Found block.\n"); $this->mBlockedby = $block->mBy; $this->mBlockreason = $block->mReason; if ($this->isLoggedIn()) { $this->spreadBlock(); } } else { wfDebug("{$fname}: No block.\n"); } # Proxy blocking # FIXME ? proxyunbannable is to deprecate the old isSysop() if (!$this->isAllowed('proxyunbannable') && !in_array($ip, $wgProxyWhitelist)) { # Local list if (wfIsLocallyBlockedProxy($ip)) { $this->mBlockedby = wfMsg('proxyblocker'); $this->mBlockreason = wfMsg('proxyblockreason'); } # DNSBL if (!$this->mBlockedby && $wgEnableSorbs && !$this->getID()) { if ($this->inSorbsBlacklist($ip)) { $this->mBlockedby = wfMsg('sorbs'); $this->mBlockreason = wfMsg('sorbsreason'); } } } # Extensions wfRunHooks('GetBlockedStatus', array(&$this)); wfProfileOut($fname); }
/** * @param string $ip * @param bool $xfor * @param string $reason * Get all IPs used by a user * Shows first and last date and number of edits */ function doUserIPsRequest($user, $reason = '') { global $wgOut, $wgTitle, $wgLang, $wgUser, $wgDBname; $fname = 'CheckUser::doUserIPsRequest'; $userTitle = Title::newFromText($user, NS_USER); if (!is_null($userTitle)) { // normalize the username $user = $userTitle->getText(); } #IPs are passed in as a blank string if (!$user) { $s = wfMsgHtml('nouserspecified'); $wgOut->addHTML($s); return; } #get ID, works better than text as user may have been renamed $user_id = User::idFromName($user); #if user is not IP or nonexistant if (!$user_id) { $s = wfMsgExt('nosuchusershort', array('parseinline'), $user); $wgOut->addHTML($s); return; } if (!$this->addLogEntry('userips', 'user', $user, $reason, $user_id)) { $wgOut->addHTML('<p>' . wfMsgHtml('checkuser-log-fail') . '</p>'); } $dbr = wfGetDB(DB_SLAVE); # Ordering by the latest timestamp makes a small filesort on the IP list $cu_changes = $dbr->tableName('cu_changes'); $use_index = $dbr->useIndexClause('cuc_user_ip_time'); $sql = "SELECT cuc_ip,cuc_ip_hex, COUNT(*) AS count, \n\t\t\tMIN(cuc_timestamp) AS first, MAX(cuc_timestamp) AS last \n\t\t\tFROM {$cu_changes} {$use_index} WHERE cuc_user = {$user_id} \n\t\t\tGROUP BY cuc_ip ORDER BY last DESC"; $ret = $dbr->query($sql, __METHOD__); if (!$dbr->numRows($ret)) { $s = wfMsgHtml("checkuser-nomatch") . "\n"; } else { $blockip = SpecialPage::getTitleFor('blockip'); $ips_edits = array(); while ($row = $dbr->fetchObject($ret)) { $ips_edits[$row->cuc_ip] = $row->count; $ips_first[$row->cuc_ip] = $row->first; $ips_last[$row->cuc_ip] = $row->last; $ips_hex[$row->cuc_ip] = $row->cuc_ip_hex; } $logs = SpecialPage::getTitleFor('Log'); $blocklist = SpecialPage::getTitleFor('Ipblocklist'); $s = '<ul>'; foreach ($ips_edits as $ip => $edits) { $s .= '<li>'; $s .= '<a href="' . $wgTitle->escapeLocalURL('user='******'&reason=' . urlencode($reason)) . '">' . htmlspecialchars($ip) . '</a>'; $s .= ' (<a href="' . $blockip->escapeLocalURL('ip=' . urlencode($ip)) . '">' . wfMsgHtml('blocklink') . '</a>)'; if ($ips_first[$ip] == $ips_last[$ip]) { $s .= ' (' . $wgLang->timeanddate($ips_first[$ip], true) . ') '; } else { $s .= ' (' . $wgLang->timeanddate($ips_first[$ip], true) . ' -- ' . $wgLang->timeanddate($ips_last[$ip], true) . ') '; } $s .= ' <strong>[' . $edits . ']</strong>'; # If we get some results, it helps to know if the IP in general # has a lot more edits, e.g. "tip of the iceberg"... global $wgMiserMode; if ($wgMiserMode) { $ipedits = $dbr->estimateRowCount('cu_changes', '*', array('cuc_ip_hex' => $ips_hex[$ip]), __METHOD__); } else { $ipedits = $dbr->selectField('cu_changes', 'COUNT(*)', array('cuc_ip_hex' => $ips_hex[$ip]), __METHOD__); } # Kludge a little for estimates... if (!$wgMiserMode || $ipedits > 1.5 * $ips_edits[$ip]) { $s .= ' <i>(' . wfMsgHtml('checkuser-ipeditcount', $ipedits) . ')</i>'; } # If this IP is blocked, give a link to the block log $block = new Block(); $block->fromMaster(false); // use slaves if ($block->load($ip, 0)) { if (IP::isIPAddress($block->mAddress) && strpos($block->mAddress, '/')) { $userpage = Title::makeTitle(NS_USER, $block->mAddress); $blocklog = $this->sk->makeKnownLinkObj($logs, wfMsgHtml('checkuser-blocked'), 'type=block&page=' . urlencode($userpage->getPrefixedText())); $s .= ' <strong>(' . $blocklog . ' - ' . $block->mAddress . ')</strong>'; } else { if ($block->mAuto) { $blocklog = $this->sk->makeKnownLinkObj($blocklist, wfMsgHtml('checkuser-blocked'), 'ip=' . urlencode("#{$block->mId}")); $s .= ' <strong>(' . $blocklog . ')</strong>'; } else { $userpage = Title::makeTitle(NS_USER, $ip); $blocklog = $this->sk->makeKnownLinkObj($logs, wfMsgHtml('checkuser-blocked'), 'type=block&page=' . urlencode($userpage->getPrefixedText())); $s .= ' <strong>(' . $blocklog . ')</strong>'; } } } $s .= "</li>\n"; } $s .= '</ul>'; } $wgOut->addHTML($s); $dbr->freeResult($ret); }