public function test_delete_block() { $params = array('title' => $this->title, 'type' => $this->type); $block = new Block($params); $block->insert(); $count = DB::get_value('SELECT count(*) FROM {blocks}'); $block->delete(); $this->assert_equal($count - 1, DB::get_value('SELECT count(*) FROM {blocks}'), 'Count of blocks should decrease by one'); }
public function addDBData() { for ($i = 1; $i <= 4; $i++) { $this->localUsers[] = $this->getMutableTestUser()->getUser(); } $sysop = static::getTestSysop()->getUser(); $block = new Block(['address' => $this->localUsers[2]->getName(), 'by' => $sysop->getId(), 'reason' => __METHOD__, 'expiry' => '1 day', 'hideName' => false]); $block->insert(); $block = new Block(['address' => $this->localUsers[3]->getName(), 'by' => $sysop->getId(), 'reason' => __METHOD__, 'expiry' => '1 day', 'hideName' => true]); $block->insert(); }
public function addDBData() { for ($i = 1; $i <= 4; $i++) { $user = User::newFromName("UTLocalIdLookup{$i}"); if ($user->getId() == 0) { $user->addToDatabase(); } $this->localUsers["UTLocalIdLookup{$i}"] = $user->getId(); } User::newFromName('UTLocalIdLookup1')->addGroup('local-id-lookup-test'); $block = new Block(array('address' => 'UTLocalIdLookup3', 'by' => User::idFromName('UTSysop'), 'reason' => __METHOD__, 'expiry' => '1 day', 'hideName' => false)); $block->insert(); $block = new Block(array('address' => 'UTLocalIdLookup4', 'by' => User::idFromName('UTSysop'), 'reason' => __METHOD__, 'expiry' => '1 day', 'hideName' => true)); $block->insert(); }
function execute($par) { global $wgRequest, $wgOut, $wgBlockOpenProxies, $wgProxyKey; $this->setHeaders(); $this->outputHeader(); $ip = wfGetIP(); if (!$wgBlockOpenProxies || $wgRequest->getText('ip') != md5($ip . $wgProxyKey)) { $wgOut->addWikiMsg('proxyblocker-disabled'); return; } $user = User::newFromName(wfMsgForContent('proxyblocker')); if (!$user->isLoggedIn()) { $user->addToDatabase(); } $id = $user->getId(); $reason = wfMsg('proxyblockreason'); $block = new Block($ip, 0, $id, $reason, wfTimestampNow()); $block->insert(); $wgOut->addWikiMsg('proxyblocksuccess'); }
function execute($par) { global $wgBlockOpenProxies, $wgProxyKey; $this->setHeaders(); $this->outputHeader(); $ip = $this->getRequest()->getIP(); if (!$wgBlockOpenProxies || $this->getRequest()->getText('ip') != md5($ip . $wgProxyKey)) { $this->getOutput()->addWikiMsg('proxyblocker-disabled'); return; } $user = User::newFromName($this->msg('proxyblocker')->inContentLanguage()->text()); # FIXME: newFromName could return false on a badly configured wiki. if (!$user->isLoggedIn()) { $user->addToDatabase(); } $block = new Block(); $block->setTarget($ip); $block->setBlocker($user); $block->mReason = $this->msg('proxyblockreason')->inContentLanguage()->text(); $block->insert(); $this->getOutput()->addWikiMsg('proxyblocksuccess'); }
/** * */ function wfSpecialBlockme() { global $wgIP, $wgBlockOpenProxies, $wgOut, $wgProxyKey; if (!$wgBlockOpenProxies || $_REQUEST['ip'] != md5($wgIP . $wgProxyKey)) { $wgOut->addWikiText(wfMsg("disabled")); return; } $blockerName = wfMsg("proxyblocker"); $reason = wfMsg("proxyblockreason"); $success = wfMsg("proxyblocksuccess"); $u = User::newFromName($blockerName); $id = $u->idForName(); if (!$id) { $u = User::newFromName($blockerName); $u->addToDatabase(); $u->setPassword(bin2hex(mt_rand(0, 0x7fffffff))); $u->saveSettings(); $id = $u->getID(); } $block = new Block($wgIP, 0, $id, $reason, wfTimestampNow()); $block->insert(); $wgOut->addWikiText($success); }
/** * */ function wfSpecialBlockme() { global $wgRequest, $wgBlockOpenProxies, $wgOut, $wgProxyKey; $ip = wfGetIP(); if (!$wgBlockOpenProxies || $wgRequest->getText('ip') != md5($ip . $wgProxyKey)) { $wgOut->addWikiMsg('proxyblocker-disabled'); return; } $blockerName = wfMsg("proxyblocker"); $reason = wfMsg("proxyblockreason"); $u = User::newFromName($blockerName); $id = $u->idForName(); if (!$id) { $u = User::newFromName($blockerName); $u->addToDatabase(); $u->setPassword(bin2hex(mt_rand(0, 0x7fffffff))); $u->saveSettings(); $id = $u->getID(); } $block = new Block($ip, 0, $id, $reason, wfTimestampNow()); $block->insert(); $wgOut->addWikiMsg("proxyblocksuccess"); }
/** * Block a list of selected users * @param array $users * @param string $reason * @param string $tag replaces user pages * @param string $talkTag replaces user talk pages * @returns array, list of html-safe usernames */ public static function doMassUserBlock($users, $reason = '', $tag = '', $talkTag = '') { global $wgUser; $counter = $blockSize = 0; $safeUsers = array(); $log = new LogPage('block'); foreach ($users as $name) { # Enforce limits $counter++; $blockSize++; # Lets not go *too* fast if ($blockSize >= 20) { $blockSize = 0; wfWaitForSlaves(5); } $u = User::newFromName($name, false); // If user doesn't exist, it ought to be an IP then if (is_null($u) || !$u->getId() && !IP::isIPAddress($u->getName())) { continue; } $userTitle = $u->getUserPage(); $userTalkTitle = $u->getTalkPage(); $userpage = new Article($userTitle); $usertalk = new Article($userTalkTitle); $safeUsers[] = '[[' . $userTitle->getPrefixedText() . '|' . $userTitle->getText() . ']]'; $expirestr = $u->getId() ? 'indefinite' : '1 week'; $expiry = Block::parseExpiryInput($expirestr); $anonOnly = IP::isIPAddress($u->getName()) ? 1 : 0; // Create the block $block = new Block($u->getName(), $u->getId(), $wgUser->getId(), $reason, wfTimestampNow(), 0, $expiry, $anonOnly, 1, 1, 0, 0); $oldblock = Block::newFromDB($u->getName(), $u->getId()); if (!$oldblock) { $block->insert(); # Prepare log parameters $logParams = array(); $logParams[] = $expirestr; if ($anonOnly) { $logParams[] = 'anononly'; } $logParams[] = 'nocreate'; # Add log entry $log->addEntry('block', $userTitle, $reason, $logParams); } # Tag userpage! (check length to avoid mistakes) if (strlen($tag) > 2) { $userpage->doEdit($tag, $reason, EDIT_MINOR); } if (strlen($talkTag) > 2) { $usertalk->doEdit($talkTag, $reason, EDIT_MINOR); } } return $safeUsers; }
public function testCheckAccountCreatePermissions() { global $wgGroupPermissions; $this->stashMwGlobals(['wgGroupPermissions']); $this->initializeManager(true); $wgGroupPermissions['*']['createaccount'] = true; $this->assertEquals(\Status::newGood(), $this->manager->checkAccountCreatePermissions(new \User())); $this->setMwGlobals(['wgReadOnly' => 'Because']); $this->assertEquals(\Status::newFatal('readonlytext', 'Because'), $this->manager->checkAccountCreatePermissions(new \User())); $this->setMwGlobals(['wgReadOnly' => false]); $wgGroupPermissions['*']['createaccount'] = false; $status = $this->manager->checkAccountCreatePermissions(new \User()); $this->assertFalse($status->isOK()); $this->assertTrue($status->hasMessage('badaccess-groups')); $wgGroupPermissions['*']['createaccount'] = true; $user = \User::newFromName('UTBlockee'); if ($user->getID() == 0) { $user->addToDatabase(); \TestUser::setPasswordForUser($user, 'UTBlockeePassword'); $user->saveSettings(); } $oldBlock = \Block::newFromTarget('UTBlockee'); if ($oldBlock) { // An old block will prevent our new one from saving. $oldBlock->delete(); } $blockOptions = ['address' => 'UTBlockee', 'user' => $user->getID(), 'reason' => __METHOD__, 'expiry' => time() + 100500, 'createAccount' => true]; $block = new \Block($blockOptions); $block->insert(); $status = $this->manager->checkAccountCreatePermissions($user); $this->assertFalse($status->isOK()); $this->assertTrue($status->hasMessage('cantcreateaccount-text')); $blockOptions = ['address' => '127.0.0.0/24', 'reason' => __METHOD__, 'expiry' => time() + 100500, 'createAccount' => true]; $block = new \Block($blockOptions); $block->insert(); $scopeVariable = new \ScopedCallback([$block, 'delete']); $status = $this->manager->checkAccountCreatePermissions(new \User()); $this->assertFalse($status->isOK()); $this->assertTrue($status->hasMessage('cantcreateaccount-range-text')); \ScopedCallback::consume($scopeVariable); $this->setMwGlobals(['wgEnableDnsBlacklist' => true, 'wgDnsBlacklistUrls' => ['local.wmftest.net'], 'wgProxyWhitelist' => []]); $status = $this->manager->checkAccountCreatePermissions(new \User()); $this->assertFalse($status->isOK()); $this->assertTrue($status->hasMessage('sorbs_create_account_reason')); $this->setMwGlobals('wgProxyWhitelist', ['127.0.0.1']); $status = $this->manager->checkAccountCreatePermissions(new \User()); $this->assertTrue($status->isGood()); }
public function testRangeBlock() { $blockOptions = ['address' => '127.0.0.0/24', 'reason' => __METHOD__, 'expiry' => time() + 100500, 'createAccount' => true]; $block = new \Block($blockOptions); $block->insert(); $scopeVariable = new \Wikimedia\ScopedCallback([$block, 'delete']); $user = \User::newFromName('UTNormalUser'); if ($user->getID() == 0) { $user->addToDatabase(); \TestUser::setPasswordForUser($user, 'UTNormalUserPassword'); $user->saveSettings(); } $this->setMwGlobals(['wgUser' => $user]); $newuser = \User::newFromName('RandomUser'); $provider = new CheckBlocksSecondaryAuthenticationProvider(['blockDisablesLogin' => true]); $provider->setLogger(new \Psr\Log\NullLogger()); $provider->setConfig(new \HashConfig()); $provider->setManager(AuthManager::singleton()); $ret = $provider->beginSecondaryAuthentication($user, []); $this->assertEquals(AuthenticationResponse::FAIL, $ret->status); $status = $provider->testUserForCreation($newuser, AuthManager::AUTOCREATE_SOURCE_SESSION); $this->assertInstanceOf('StatusValue', $status); $this->assertFalse($status->isOK()); $this->assertTrue($status->hasMessage('cantcreateaccount-range-text')); $status = $provider->testUserForCreation($newuser, false); $this->assertInstanceOf('StatusValue', $status); $this->assertFalse($status->isOK()); $this->assertTrue($status->hasMessage('cantcreateaccount-range-text')); }
/** * Suppresses a local account of a user. * * @param $suppress Bool * @param $wiki String * @param $by String * @param $reason String * @return Array|null Error array on failure */ public function doLocalSuppression($suppress, $wiki, $by, $reason) { global $wgConf; $lb = wfGetLB($wiki); $dbw = $lb->getConnection(DB_MASTER, array(), $wiki); $data = $this->localUserData($wiki); if ($suppress) { list(, $lang) = $wgConf->siteFromDB($wiki); $langNames = Language::fetchLanguageNames(); $lang = isset($langNames[$lang]) ? $lang : 'en'; $blockReason = wfMessage('centralauth-admin-suppressreason', $by, $reason)->inLanguage($lang)->text(); $block = new Block(array('address' => $this->mName, 'user' => $data['id'], 'reason' => $blockReason, 'timestamp' => wfTimestampNow(), 'expiry' => $dbw->getInfinity(), 'createAccount' => true, 'enableAutoblock' => true, 'hideName' => true, 'blockEmail' => true, 'byText' => $by)); # On normal block, BlockIp hook would be run here, but doing # that from CentralAuth doesn't seem a good idea... if (!$block->insert($dbw)) { return array('ipb_already_blocked'); } # Ditto for BlockIpComplete hook. RevisionDeleteUser::suppressUserName($this->mName, $data['id'], $dbw); # Locally log to suppress ? } else { $dbw->delete('ipblocks', array('ipb_user' => $data['id'], 'ipb_by' => 0, 'ipb_deleted' => true), __METHOD__); // Unsuppress only if unblocked if ($dbw->affectedRows()) { RevisionDeleteUser::unsuppressUserName($this->mName, $data['id'], $dbw); } } return null; }
protected function addXffBlocks() { static $inited = false; if ($inited) { return; } $inited = true; $blockList = array(array('target' => '70.2.0.0/16', 'type' => Block::TYPE_RANGE, 'desc' => 'Range Hardblock', 'ACDisable' => false, 'isHardblock' => true, 'isAutoBlocking' => false), array('target' => '2001:4860:4001::/48', 'type' => Block::TYPE_RANGE, 'desc' => 'Range6 Hardblock', 'ACDisable' => false, 'isHardblock' => true, 'isAutoBlocking' => false), array('target' => '60.2.0.0/16', 'type' => Block::TYPE_RANGE, 'desc' => 'Range Softblock with AC Disabled', 'ACDisable' => true, 'isHardblock' => false, 'isAutoBlocking' => false), array('target' => '50.2.0.0/16', 'type' => Block::TYPE_RANGE, 'desc' => 'Range Softblock', 'ACDisable' => false, 'isHardblock' => false, 'isAutoBlocking' => false), array('target' => '50.1.1.1', 'type' => Block::TYPE_IP, 'desc' => 'Exact Softblock', 'ACDisable' => false, 'isHardblock' => false, 'isAutoBlocking' => false)); foreach ($blockList as $insBlock) { $target = $insBlock['target']; if ($insBlock['type'] === Block::TYPE_IP) { $target = User::newFromName(IP::sanitizeIP($target), false)->getName(); } elseif ($insBlock['type'] === Block::TYPE_RANGE) { $target = IP::sanitizeRange($target); } $block = new Block(); $block->setTarget($target); $block->setBlocker('testblocker@global'); $block->mReason = $insBlock['desc']; $block->mExpiry = 'infinity'; $block->prevents('createaccount', $insBlock['ACDisable']); $block->isHardblock($insBlock['isHardblock']); $block->isAutoblocking($insBlock['isAutoBlocking']); $block->insert(); } }
/** * Given the form data, actually implement a block * @param $data Array * @param $context IContextSource * @return Bool|String */ public static function processForm(array $data, IContextSource $context) { global $wgBlockAllowsUTEdit; $performer = $context->getUser(); // Handled by field validator callback // self::validateTargetField( $data['Target'] ); # This might have been a hidden field or a checkbox, so interesting data # can come from it $data['Confirm'] = !in_array($data['Confirm'], array('', '0', null, false), true); list($target, $type) = self::getTargetAndType($data['Target']); if ($type == Block::TYPE_USER) { $user = $target; $target = $user->getName(); $userId = $user->getId(); # Give admins a heads-up before they go and block themselves. Much messier # to do this for IPs, but it's pretty unlikely they'd ever get the 'block' # permission anyway, although the code does allow for it. # Note: Important to use $target instead of $data['Target'] # since both $data['PreviousTarget'] and $target are normalized # but $data['target'] gets overriden by (non-normalized) request variable # from previous request. if ($target === $performer->getName() && ($data['PreviousTarget'] !== $target || !$data['Confirm'])) { return array('ipb-blockingself'); } } elseif ($type == Block::TYPE_RANGE) { $userId = 0; } elseif ($type == Block::TYPE_IP) { $target = $target->getName(); $userId = 0; } else { # This should have been caught in the form field validation return array('badipaddress'); } if (strlen($data['Expiry']) == 0 || strlen($data['Expiry']) > 50 || !self::parseExpiryInput($data['Expiry'])) { return array('ipb_expiry_invalid'); } if (!isset($data['DisableEmail'])) { $data['DisableEmail'] = false; } # If the user has done the form 'properly', they won't even have been given the # option to suppress-block unless they have the 'hideuser' permission if (!isset($data['HideUser'])) { $data['HideUser'] = false; } if ($data['HideUser']) { if (!$performer->isAllowed('hideuser')) { # this codepath is unreachable except by a malicious user spoofing forms, # or by race conditions (user has oversight and sysop, loads block form, # and is de-oversighted before submission); so need to fail completely # rather than just silently disable hiding return array('badaccess-group0'); } # Recheck params here... if ($type != Block::TYPE_USER) { $data['HideUser'] = false; # IP users should not be hidden } elseif (!in_array($data['Expiry'], array('infinite', 'infinity', 'indefinite'))) { # Bad expiry. return array('ipb_expiry_temp'); } elseif ($user->getEditCount() > self::HIDEUSER_CONTRIBLIMIT) { # Typically, the user should have a handful of edits. # Disallow hiding users with many edits for performance. return array('ipb_hide_invalid'); } elseif (!$data['Confirm']) { return array('ipb-confirmhideuser'); } } # Create block object. $block = new Block(); $block->setTarget($target); $block->setBlocker($performer); $block->mReason = $data['Reason'][0]; $block->mExpiry = self::parseExpiryInput($data['Expiry']); $block->prevents('createaccount', $data['CreateAccount']); $block->prevents('editownusertalk', !$wgBlockAllowsUTEdit || $data['DisableUTEdit']); $block->prevents('sendemail', $data['DisableEmail']); $block->isHardblock($data['HardBlock']); $block->isAutoblocking($data['AutoBlock']); $block->mHideName = $data['HideUser']; if (!wfRunHooks('BlockIp', array(&$block, &$performer))) { return array('hookaborted'); } # Try to insert block. Is there a conflicting block? $status = $block->insert(); if (!$status) { # Show form unless the user is already aware of this... if (!$data['Confirm'] || array_key_exists('PreviousTarget', $data) && $data['PreviousTarget'] !== $target) { return array(array('ipb_already_blocked', $block->getTarget())); # Otherwise, try to update the block... } else { # This returns direct blocks before autoblocks/rangeblocks, since we should # be sure the user is blocked by now it should work for our purposes $currentBlock = Block::newFromTarget($target); if ($block->equals($currentBlock)) { return array(array('ipb_already_blocked', $block->getTarget())); } # If the name was hidden and the blocking user cannot hide # names, then don't allow any block changes... if ($currentBlock->mHideName && !$performer->isAllowed('hideuser')) { return array('cant-see-hidden-user'); } $currentBlock->delete(); $status = $block->insert(); $logaction = 'reblock'; # Unset _deleted fields if requested if ($currentBlock->mHideName && !$data['HideUser']) { RevisionDeleteUser::unsuppressUserName($target, $userId); } # If hiding/unhiding a name, this should go in the private logs if ((bool) $currentBlock->mHideName) { $data['HideUser'] = true; } } } else { $logaction = 'block'; } wfRunHooks('BlockIpComplete', array($block, $performer)); # Set *_deleted fields if requested if ($data['HideUser']) { RevisionDeleteUser::suppressUserName($target, $userId); } # Can't watch a rangeblock if ($type != Block::TYPE_RANGE && $data['Watch']) { $performer->addWatch(Title::makeTitle(NS_USER, $target)); } # Block constructor sanitizes certain block options on insert $data['BlockEmail'] = $block->prevents('sendemail'); $data['AutoBlock'] = $block->isAutoblocking(); # Prepare log parameters $logParams = array(); $logParams[] = $data['Expiry']; $logParams[] = self::blockLogFlags($data, $type); # Make log entry, if the name is hidden, put it in the oversight log $log_type = $data['HideUser'] ? 'suppress' : 'block'; $log = new LogPage($log_type); $log_id = $log->addEntry($logaction, Title::makeTitle(NS_USER, $target), $data['Reason'][0], $logParams); # Relate log ID to block IDs (bug 25763) $blockIds = array_merge(array($status['id']), $status['autoIds']); $log->addRelations('ipb_id', $blockIds, $log_id); # Report to the user return true; }
/** * Backend block code. * $userID and $expiry will be filled accordingly * @return array(message key, arguments) on failure, empty array on success */ function doBlock(&$userId = null, &$expiry = null) { global $wgUser, $wgSysopUserBans, $wgSysopRangeBans; $userId = 0; # Expand valid IPv6 addresses, usernames are left as is $this->BlockAddress = IP::sanitizeIP($this->BlockAddress); # isIPv4() and IPv6() are used for final validation $rxIP4 = '\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}'; $rxIP6 = '\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}'; $rxIP = "({$rxIP4}|{$rxIP6})"; # Check for invalid specifications if (!preg_match("/^{$rxIP}\$/", $this->BlockAddress)) { $matches = array(); if (preg_match("/^({$rxIP4})\\/(\\d{1,2})\$/", $this->BlockAddress, $matches)) { # IPv4 if ($wgSysopRangeBans) { if (!IP::isIPv4($this->BlockAddress) || $matches[2] < 16 || $matches[2] > 32) { return array('ip_range_invalid'); } $this->BlockAddress = Block::normaliseRange($this->BlockAddress); } else { # Range block illegal return array('range_block_disabled'); } } else { if (preg_match("/^({$rxIP6})\\/(\\d{1,3})\$/", $this->BlockAddress, $matches)) { # IPv6 if ($wgSysopRangeBans) { if (!IP::isIPv6($this->BlockAddress) || $matches[2] < 64 || $matches[2] > 128) { return array('ip_range_invalid'); } $this->BlockAddress = Block::normaliseRange($this->BlockAddress); } else { # Range block illegal return array('range_block_disabled'); } } else { # Username block if ($wgSysopUserBans) { $user = User::newFromName($this->BlockAddress); if (!is_null($user) && $user->getID()) { # Use canonical name $userId = $user->getID(); $this->BlockAddress = $user->getName(); } else { return array('nosuchusershort', htmlspecialchars($user ? $user->getName() : $this->BlockAddress)); } } else { return array('badipaddress'); } } } } $reasonstr = $this->BlockReasonList; if ($reasonstr != 'other' && $this->BlockReason != '') { // Entry from drop down menu + additional comment $reasonstr .= ': ' . $this->BlockReason; } elseif ($reasonstr == 'other') { $reasonstr = $this->BlockReason; } $expirestr = $this->BlockExpiry; if ($expirestr == 'other') { $expirestr = $this->BlockOther; } if (strlen($expirestr) == 0) { return array('ipb_expiry_invalid'); } if ($expirestr == 'infinite' || $expirestr == 'indefinite') { $expiry = Block::infinity(); } else { # Convert GNU-style date, on error returns -1 for PHP <5.1 and false for PHP >=5.1 $expiry = strtotime($expirestr); if ($expiry < 0 || $expiry === false) { return array('ipb_expiry_invalid'); } $expiry = wfTimestamp(TS_MW, $expiry); } # Create block # Note: for a user block, ipb_address is only for display purposes $block = new Block($this->BlockAddress, $userId, $wgUser->getID(), $reasonstr, wfTimestampNow(), 0, $expiry, $this->BlockAnonOnly, $this->BlockCreateAccount, $this->BlockEnableAutoblock, $this->BlockHideName, $this->BlockEmail); if (wfRunHooks('BlockIp', array(&$block, &$wgUser))) { if (!$block->insert()) { return array('ipb_already_blocked', htmlspecialchars($this->BlockAddress)); } wfRunHooks('BlockIpComplete', array($block, $wgUser)); # Prepare log parameters $logParams = array(); $logParams[] = $expirestr; $logParams[] = $this->blockLogFlags(); # Make log entry, if the name is hidden, put it in the oversight log $log_type = $this->BlockHideName ? 'oversight' : 'block'; $log = new LogPage($log_type); $log->addEntry('block', Title::makeTitle(NS_USER, $this->BlockAddress), $reasonstr, $logParams); # Report to the user return array(); } else { return array('hookaborted'); } }
/** * Autoblocks the given IP, referring to this Block. * * @param $autoblockIP String: the IP to autoblock. * @param $justInserted Boolean: the main block was just inserted * @return Boolean: whether or not an autoblock was inserted. */ public function doAutoblock($autoblockIP, $justInserted = false) { # If autoblocks are disabled, go away. if (!$this->mEnableAutoblock) { return; } # Check for presence on the autoblock whitelist if (Block::isWhitelistedFromAutoblocks($autoblockIP)) { return; } ## Allow hooks to cancel the autoblock. if (!wfRunHooks('AbortAutoblock', array($autoblockIP, &$this))) { wfDebug("Autoblock aborted by hook.\n"); return false; } # It's okay to autoblock. Go ahead and create/insert the block. $ipblock = Block::newFromDB($autoblockIP); if ($ipblock) { # If the user is already blocked. Then check if the autoblock would # exceed the user block. If it would exceed, then do nothing, else # prolong block time if ($this->mExpiry && $this->mExpiry < Block::getAutoblockExpiry($ipblock->mTimestamp)) { return; } # Just update the timestamp if (!$justInserted) { $ipblock->updateTimestamp(); } return; } else { $ipblock = new Block(); } # Make a new block object with the desired properties wfDebug("Autoblocking {$this->mAddress}@" . $autoblockIP . "\n"); $ipblock->mAddress = $autoblockIP; $ipblock->mUser = 0; $ipblock->mBy = $this->mBy; $ipblock->mByName = $this->mByName; $ipblock->mReason = wfMsgForContent('autoblocker', $this->mAddress, $this->mReason); $ipblock->mTimestamp = wfTimestampNow(); $ipblock->mAuto = 1; $ipblock->mCreateAccount = $this->mCreateAccount; # Continue suppressing the name if needed $ipblock->mHideName = $this->mHideName; $ipblock->mAllowUsertalk = $this->mAllowUsertalk; # If the user is already blocked with an expiry date, we don't # want to pile on top of that! if ($this->mExpiry) { $ipblock->mExpiry = min($this->mExpiry, Block::getAutoblockExpiry($this->mTimestamp)); } else { $ipblock->mExpiry = Block::getAutoblockExpiry($this->mTimestamp); } # Insert it return $ipblock->insert(); }
public function testDeprecatedConstructor() { $this->hideDeprecated('Block::__construct with multiple arguments'); $username = '******'; $reason = 'being irrational'; # Set up the target $u = User::newFromName($username); if ($u->getID() == 0) { $u->addToDatabase(); TestUser::setPasswordForUser($u, 'TotallyObvious'); } unset($u); # Make sure the user isn't blocked $this->assertNull(Block::newFromTarget($username), "{$username} should not be blocked"); # Perform the block $block = new Block($username, 0, 0, $reason, 0, false, 0); $block->insert(); # Check target $this->assertEquals($block->getTarget()->getName(), $username, "Target should be set properly"); # Check supplied parameter $this->assertEquals($block->mReason, $reason, "Reason should be non-default"); # Check default parameter $this->assertFalse((bool) $block->prevents('createaccount'), "Account creation should not be blocked by default"); }
/** * Handles AJAX requests from the dashboard */ public function ajax_dashboard($handler_vars) { Utils::check_request_method(array('POST')); $this->create_theme(); $this->get_additem_form(); $available_modules = Plugins::filter('dashboard_block_list', array()); $user_id = User::identify()->id; $dashboard_area = 'dashboard_' . $user_id; switch ($handler_vars['action']) { case 'updateModules': $modules = $_POST['moduleOrder']; $order = 0; foreach ($modules as $module) { $order++; DB::query('UPDATE {blocks_areas} SET display_order = :display_order WHERE block_id = :id AND area = :dashboardarea', array('display_order' => $order, 'id' => $module, 'dashboardarea' => $dashboard_area)); } $ar = new AjaxResponse(200, _t('Modules updated.')); break; case 'addModule': $type = $handler_vars['module_name']; $title = $available_modules[$type]; $block = new Block(array('title' => $title, 'type' => $type)); $block->insert(); $max_display_order = DB::get_value('SELECT max(display_order) FROM {blocks_areas} WHERE area = :dashboardarea and scope_id = 0;', array('dashboardarea' => $dashboard_area)); $max_display_order++; DB::query('INSERT INTO {blocks_areas} (block_id, area, scope_id, display_order) VALUES (:block_id, :dashboardarea, 0, :display_order)', array('block_id' => $block->id, 'display_order' => $max_display_order, 'dashboardarea' => $dashboard_area)); $ar = new AjaxResponse(200, _t('Added module %s.', array($title))); $ar->html('modules', $this->theme->fetch('dashboard_modules')); break; case 'removeModule': $block_id = $handler_vars['moduleid']; DB::delete('{blocks}', array('id' => $block_id)); DB::delete('{blocks_areas}', array('block_id' => $block_id)); $ar = new AjaxResponse(200, _t('Removed module.')); $ar->html('modules', $this->theme->fetch('dashboard_modules')); break; case 'configModule': $block_id = $handler_vars['moduleid']; $block = DB::get_row('SELECT * FROM {blocks} b WHERE b.id = :id', array('id' => $block_id), 'Block'); /** Block $block */ $form = $block->get_form(); $form->_ajax = true; $form->set_option('success_message', _t('Module Configuration Saved.') . '<script type="text/javascript">window.setTimeout(function(){$(".form_message").fadeOut();}, 2000);</script>'); $control_id = new FormControlHidden('moduleid', 'null:null'); $control_id->value = $block->id; $control_id->id = 'moduleid'; $form->append($control_id); $control_action = new FormControlHidden('action', 'null:null'); $control_action->value = 'configModule'; $control_action->id = 'action'; $form->append($control_action); $form->out(); $form_id = $form->name; exit; break; } $ar->out(); }
/** * Autoblocks the given IP, referring to this Block. * @param string $autoblockip The IP to autoblock. * @param bool $justInserted The main block was just inserted * @return bool Whether or not an autoblock was inserted. */ function doAutoblock($autoblockip, $justInserted = false) { # If autoblocks are disabled, go away. if (!$this->mEnableAutoblock) { return; } # Check for presence on the autoblock whitelist # TODO cache this? $lines = explode("\n", wfMsgForContentNoTrans('autoblock_whitelist')); $ip = $autoblockip; wfDebug("Checking the autoblock whitelist..\n"); foreach ($lines as $line) { # List items only if (substr($line, 0, 1) !== '*') { continue; } $wlEntry = substr($line, 1); $wlEntry = trim($wlEntry); wfDebug("Checking {$ip} against {$wlEntry}..."); # Is the IP in this range? if (IP::isInRange($ip, $wlEntry)) { wfDebug(" IP {$ip} matches {$wlEntry}, not autoblocking\n"); #$autoblockip = null; # Don't autoblock a whitelisted IP. return; #This /SHOULD/ introduce a dummy block - but # I don't know a safe way to do so. -werdna } else { wfDebug(" No match\n"); } } # It's okay to autoblock. Go ahead and create/insert the block. $ipblock = Block::newFromDB($autoblockip); if ($ipblock) { # If the user is already blocked. Then check if the autoblock would # exceed the user block. If it would exceed, then do nothing, else # prolong block time if ($this->mExpiry && $this->mExpiry < Block::getAutoblockExpiry($ipblock->mTimestamp)) { return; } # Just update the timestamp if (!$justInserted) { $ipblock->updateTimestamp(); } return; } else { $ipblock = new Block(); } # Make a new block object with the desired properties wfDebug("Autoblocking {$this->mAddress}@" . $autoblockip . "\n"); $ipblock->mAddress = $autoblockip; $ipblock->mUser = 0; $ipblock->mBy = $this->mBy; $ipblock->mReason = wfMsgForContent('autoblocker', $this->mAddress, $this->mReason); $ipblock->mTimestamp = wfTimestampNow(); $ipblock->mAuto = 1; $ipblock->mCreateAccount = $this->mCreateAccount; # Continue suppressing the name if needed $ipblock->mHideName = $this->mHideName; # If the user is already blocked with an expiry date, we don't # want to pile on top of that! if ($this->mExpiry) { $ipblock->mExpiry = min($this->mExpiry, Block::getAutoblockExpiry($this->mTimestamp)); } else { $ipblock->mExpiry = Block::getAutoblockExpiry($this->mTimestamp); } # Insert it return $ipblock->insert(); }
public static function takeConsequenceAction($action, $parameters, $title, $vars, $rule_desc) { $display = ''; switch ($action) { case 'disallow': if (strlen($parameters[0])) { $display .= wfMsgExt($parameters[0], 'parseinline', array($rule_desc)) . "\n"; } else { // Generic message. $display .= wfMsgExt('abusefilter-disallowed', 'parseinline', array($rule_desc)) . "<br />\n"; } break; case 'block': global $wgUser, $wgAbuseFilterBlockDuration; $filterUser = AbuseFilter::getFilterUser(); // Create a block. $block = new Block(); $block->setTarget($wgUser->getName()); $block->setBlocker($filterUser); $block->mReason = wfMsgForContent('abusefilter-blockreason', $rule_desc); $block->isHardblock(false); $block->prevents('createaccount', true); $block->mExpiry = SpecialBlock::parseExpiryInput($wgAbuseFilterBlockDuration); $block->insert(); // Log it # Prepare log parameters $logParams = array(); if ($block->mExpiry == 'infinity') { $logParams[] = 'indefinite'; } else { $logParams[] = $wgAbuseFilterBlockDuration; } $logParams[] = 'nocreate, angry-autoblock'; $log = new LogPage('block'); $log->addEntry('block', Title::makeTitle(NS_USER, $wgUser->getName()), wfMsgForContent('abusefilter-blockreason', $rule_desc), $logParams, self::getFilterUser()); $display .= wfMsgExt('abusefilter-blocked-display', 'parseinline', array($rule_desc)) . "<br />\n"; break; case 'rangeblock': $filterUser = AbuseFilter::getFilterUser(); $range = IP::sanitizeRange(wfGetIP() . '/16'); // Create a block. $block = new Block(); $block->setTarget($range); $block->setBlocker($filterUser); $block->mReason = wfMsgForContent('abusefilter-blockreason', $rule_desc); $block->isHardblock(false); $block->prevents('createaccount', true); $block->mExpiry = SpecialBlock::parseExpiryInput('1 week'); $block->insert(); // Log it # Prepare log parameters $logParams = array(); $logParams[] = 'indefinite'; $logParams[] = 'nocreate, angry-autoblock'; $log = new LogPage('block'); $log->addEntry('block', Title::makeTitle(NS_USER, $range), wfMsgForContent('abusefilter-blockreason', $rule_desc), $logParams, self::getFilterUser()); $display .= wfMsgExt('abusefilter-blocked-display', 'parseinline', $rule_desc) . "<br />\n"; break; case 'degroup': global $wgUser; if (!$wgUser->isAnon()) { // Remove all groups from the user. Ouch. $groups = $wgUser->getGroups(); foreach ($groups as $group) { $wgUser->removeGroup($group); } $display .= wfMsgExt('abusefilter-degrouped', 'parseinline', array($rule_desc)) . "<br />\n"; // Don't log it if there aren't any groups being removed! if (!count($groups)) { break; } // Log it. $log = new LogPage('rights'); $log->addEntry('rights', $wgUser->getUserPage(), wfMsgForContent('abusefilter-degroupreason', $rule_desc), array(implode(', ', $groups), wfMsgForContent('rightsnone')), self::getFilterUser()); } break; case 'blockautopromote': global $wgUser, $wgMemc; if (!$wgUser->isAnon()) { $blockPeriod = (int) mt_rand(3 * 86400, 7 * 86400); // Block for 3-7 days. $wgMemc->set(self::autoPromoteBlockKey($wgUser), true, $blockPeriod); $display .= wfMsgExt('abusefilter-autopromote-blocked', 'parseinline', array($rule_desc)) . "<br />\n"; } break; case 'flag': // Do nothing. Here for completeness. break; case 'tag': // Mark with a tag on recentchanges. global $wgUser; $actionID = implode('-', array($title->getPrefixedText(), $wgUser->getName(), $vars->getVar('ACTION')->toString())); AbuseFilter::$tagsToSet[$actionID] = $parameters; break; default: wfDebugLog('AbuseFilter', "Unrecognised action {$action}"); } return $display; }
function testCrappyCrossWikiBlocks() { // Delete the last round's block if it's still there $oldBlock = Block::newFromTarget('UserOnForeignWiki'); if ($oldBlock) { // An old block will prevent our new one from saving. $oldBlock->delete(); } // Foreign perspective (blockee not on current wiki)... $block = new Block('UserOnForeignWiki', 14146, 0, 'crosswiki block...', wfTimestampNow(), false, $this->db->getInfinity(), false, true, true, true, true, false, 'MetaWikiUser'); $res = $block->insert($this->db); $this->assertTrue((bool) $res['id'], 'Block succeeded'); // Local perspective (blockee on current wiki)... $user = User::newFromName('UserOnForeignWiki'); $user->addToDatabase(); // Set user ID to match the test value $this->db->update('user', array('user_id' => 14146), array('user_id' => $user->getId())); $user = null; // clear $block = Block::newFromID($res['id']); $this->assertEquals('UserOnForeignWiki', $block->getTarget()->getName(), 'Correct blockee name'); $this->assertEquals('14146', $block->getTarget()->getId(), 'Correct blockee id'); $this->assertEquals('MetaWikiUser', $block->getBlocker(), 'Correct blocker name'); $this->assertEquals('MetaWikiUser', $block->getByName(), 'Correct blocker name'); $this->assertEquals(0, $block->getBy(), 'Correct blocker id'); }
/** * Autoblocks the given IP, referring to this Block. * * @param string $autoblockIP The IP to autoblock. * @return int|bool Block ID if an autoblock was inserted, false if not. */ public function doAutoblock($autoblockIP) { # If autoblocks are disabled, go away. if (!$this->isAutoblocking()) { return false; } # Check for presence on the autoblock whitelist. if (self::isWhitelistedFromAutoblocks($autoblockIP)) { return false; } # Allow hooks to cancel the autoblock. if (!wfRunHooks('AbortAutoblock', array($autoblockIP, &$this))) { wfDebug("Autoblock aborted by hook.\n"); return false; } # It's okay to autoblock. Go ahead and insert/update the block... # Do not add a *new* block if the IP is already blocked. $ipblock = Block::newFromTarget($autoblockIP); if ($ipblock) { # Check if the block is an autoblock and would exceed the user block # if renewed. If so, do nothing, otherwise prolong the block time... if ($ipblock->mAuto && $this->mExpiry > Block::getAutoblockExpiry($ipblock->mTimestamp)) { # Reset block timestamp to now and its expiry to # $wgAutoblockExpiry in the future $ipblock->updateTimestamp(); } return false; } # Make a new block object with the desired properties. $autoblock = new Block(); wfDebug("Autoblocking {$this->getTarget()}@" . $autoblockIP . "\n"); $autoblock->setTarget($autoblockIP); $autoblock->setBlocker($this->getBlocker()); $autoblock->mReason = wfMessage('autoblocker', $this->getTarget(), $this->mReason)->inContentLanguage()->plain(); $timestamp = wfTimestampNow(); $autoblock->mTimestamp = $timestamp; $autoblock->mAuto = 1; $autoblock->prevents('createaccount', $this->prevents('createaccount')); # Continue suppressing the name if needed $autoblock->mHideName = $this->mHideName; $autoblock->prevents('editownusertalk', $this->prevents('editownusertalk')); $autoblock->mParentBlockId = $this->mId; if ($this->mExpiry == 'infinity') { # Original block was indefinite, start an autoblock now $autoblock->mExpiry = Block::getAutoblockExpiry($timestamp); } else { # If the user is already blocked with an expiry date, we don't # want to pile on top of that. $autoblock->mExpiry = min($this->mExpiry, Block::getAutoblockExpiry($timestamp)); } # Insert the block... $status = $autoblock->insert(); return $status ? $status['id'] : false; }
public function testAutoCreateUser() { global $wgGroupPermissions; $that = $this; \ObjectCache::$instances[__METHOD__] = new \HashBagOStuff(); $this->setMwGlobals(array('wgMainCacheType' => __METHOD__)); $this->stashMwGlobals(array('wgGroupPermissions')); $wgGroupPermissions['*']['createaccount'] = true; $wgGroupPermissions['*']['autocreateaccount'] = false; // Replace the global singleton with one configured for testing $manager = $this->getManager(); $reset = TestUtils::setSessionManagerSingleton($manager); $logger = new \TestLogger(true, function ($m) { if (substr($m, 0, 15) === 'SessionBackend ') { // Don't care. return null; } $m = str_replace('MediaWiki\\Session\\SessionManager::autoCreateUser: '******'', $m); $m = preg_replace('/ - from: .*$/', ' - from: XXX', $m); return $m; }); $manager->setLogger($logger); $session = SessionManager::getGlobalSession(); // Can't create an already-existing user $user = User::newFromName('UTSysop'); $id = $user->getId(); $this->assertFalse($manager->autoCreateUser($user)); $this->assertSame($id, $user->getId()); $this->assertSame('UTSysop', $user->getName()); $this->assertSame(array(), $logger->getBuffer()); $logger->clearBuffer(); // Sanity check that creation works at all $user = User::newFromName('UTSessionAutoCreate1'); $this->assertSame(0, $user->getId(), 'sanity check'); $this->assertTrue($manager->autoCreateUser($user)); $this->assertNotEquals(0, $user->getId()); $this->assertSame('UTSessionAutoCreate1', $user->getName()); $this->assertEquals($user->getId(), User::idFromName('UTSessionAutoCreate1', User::READ_LATEST)); $this->assertSame(array(array(LogLevel::INFO, 'creating new user (UTSessionAutoCreate1) - from: XXX')), $logger->getBuffer()); $logger->clearBuffer(); // Check lack of permissions $wgGroupPermissions['*']['createaccount'] = false; $wgGroupPermissions['*']['autocreateaccount'] = false; $user = User::newFromName('UTDoesNotExist'); $this->assertFalse($manager->autoCreateUser($user)); $this->assertSame(0, $user->getId()); $this->assertNotSame('UTDoesNotExist', $user->getName()); $this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST)); $session->clear(); $this->assertSame(array(array(LogLevel::DEBUG, 'user is blocked from this wiki, blacklisting')), $logger->getBuffer()); $logger->clearBuffer(); // Check other permission $wgGroupPermissions['*']['createaccount'] = false; $wgGroupPermissions['*']['autocreateaccount'] = true; $user = User::newFromName('UTSessionAutoCreate2'); $this->assertSame(0, $user->getId(), 'sanity check'); $this->assertTrue($manager->autoCreateUser($user)); $this->assertNotEquals(0, $user->getId()); $this->assertSame('UTSessionAutoCreate2', $user->getName()); $this->assertEquals($user->getId(), User::idFromName('UTSessionAutoCreate2', User::READ_LATEST)); $this->assertSame(array(array(LogLevel::INFO, 'creating new user (UTSessionAutoCreate2) - from: XXX')), $logger->getBuffer()); $logger->clearBuffer(); // Test account-creation block $anon = new User(); $block = new \Block(array('address' => $anon->getName(), 'user' => $id, 'reason' => __METHOD__, 'expiry' => time() + 100500, 'createAccount' => true)); $block->insert(); $this->assertInstanceOf('Block', $anon->isBlockedFromCreateAccount(), 'sanity check'); $reset2 = new \ScopedCallback(array($block, 'delete')); $user = User::newFromName('UTDoesNotExist'); $this->assertFalse($manager->autoCreateUser($user)); $this->assertSame(0, $user->getId()); $this->assertNotSame('UTDoesNotExist', $user->getName()); $this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST)); \ScopedCallback::consume($reset2); $session->clear(); $this->assertSame(array(array(LogLevel::DEBUG, 'user is blocked from this wiki, blacklisting')), $logger->getBuffer()); $logger->clearBuffer(); // Sanity check that creation still works $user = User::newFromName('UTSessionAutoCreate3'); $this->assertSame(0, $user->getId(), 'sanity check'); $this->assertTrue($manager->autoCreateUser($user)); $this->assertNotEquals(0, $user->getId()); $this->assertSame('UTSessionAutoCreate3', $user->getName()); $this->assertEquals($user->getId(), User::idFromName('UTSessionAutoCreate3', User::READ_LATEST)); $this->assertSame(array(array(LogLevel::INFO, 'creating new user (UTSessionAutoCreate3) - from: XXX')), $logger->getBuffer()); $logger->clearBuffer(); // Test prevention by AuthPlugin global $wgAuth; $oldWgAuth = $wgAuth; $mockWgAuth = $this->getMock('AuthPlugin', array('autoCreate')); $mockWgAuth->expects($this->once())->method('autoCreate')->will($this->returnValue(false)); $this->setMwGlobals(array('wgAuth' => $mockWgAuth)); $user = User::newFromName('UTDoesNotExist'); $this->assertFalse($manager->autoCreateUser($user)); $this->assertSame(0, $user->getId()); $this->assertNotSame('UTDoesNotExist', $user->getName()); $this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST)); $this->setMwGlobals(array('wgAuth' => $oldWgAuth)); $session->clear(); $this->assertSame(array(array(LogLevel::DEBUG, 'denied by AuthPlugin')), $logger->getBuffer()); $logger->clearBuffer(); // Test prevention by wfReadOnly() $this->setMwGlobals(array('wgReadOnly' => 'Because')); $user = User::newFromName('UTDoesNotExist'); $this->assertFalse($manager->autoCreateUser($user)); $this->assertSame(0, $user->getId()); $this->assertNotSame('UTDoesNotExist', $user->getName()); $this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST)); $this->setMwGlobals(array('wgReadOnly' => false)); $session->clear(); $this->assertSame(array(array(LogLevel::DEBUG, 'denied by wfReadOnly()')), $logger->getBuffer()); $logger->clearBuffer(); // Test prevention by a previous session $session->set('MWSession::AutoCreateBlacklist', 'test'); $user = User::newFromName('UTDoesNotExist'); $this->assertFalse($manager->autoCreateUser($user)); $this->assertSame(0, $user->getId()); $this->assertNotSame('UTDoesNotExist', $user->getName()); $this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST)); $session->clear(); $this->assertSame(array(array(LogLevel::DEBUG, 'blacklisted in session (test)')), $logger->getBuffer()); $logger->clearBuffer(); // Test uncreatable name $user = User::newFromName('UTDoesNotExist@'); $this->assertFalse($manager->autoCreateUser($user)); $this->assertSame(0, $user->getId()); $this->assertNotSame('UTDoesNotExist@', $user->getName()); $this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST)); $session->clear(); $this->assertSame(array(array(LogLevel::DEBUG, 'Invalid username, blacklisting')), $logger->getBuffer()); $logger->clearBuffer(); // Test AbortAutoAccount hook $mock = $this->getMock(__CLASS__, array('onAbortAutoAccount')); $mock->expects($this->once())->method('onAbortAutoAccount')->will($this->returnCallback(function (User $user, &$msg) { $msg = 'No way!'; return false; })); $this->mergeMwGlobalArrayValue('wgHooks', array('AbortAutoAccount' => array($mock))); $user = User::newFromName('UTDoesNotExist'); $this->assertFalse($manager->autoCreateUser($user)); $this->assertSame(0, $user->getId()); $this->assertNotSame('UTDoesNotExist', $user->getName()); $this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST)); $this->mergeMwGlobalArrayValue('wgHooks', array('AbortAutoAccount' => array())); $session->clear(); $this->assertSame(array(array(LogLevel::DEBUG, 'denied by hook: No way!')), $logger->getBuffer()); $logger->clearBuffer(); // Test AbortAutoAccount hook screwing up the name $mock = $this->getMock('stdClass', array('onAbortAutoAccount')); $mock->expects($this->once())->method('onAbortAutoAccount')->will($this->returnCallback(function (User $user) { $user->setName('UTDoesNotExistEither'); })); $this->mergeMwGlobalArrayValue('wgHooks', array('AbortAutoAccount' => array($mock))); try { $user = User::newFromName('UTDoesNotExist'); $manager->autoCreateUser($user); $this->fail('Expected exception not thrown'); } catch (\UnexpectedValueException $ex) { $this->assertSame('AbortAutoAccount hook tried to change the user name', $ex->getMessage()); } $this->assertSame(0, $user->getId()); $this->assertNotSame('UTDoesNotExist', $user->getName()); $this->assertNotSame('UTDoesNotExistEither', $user->getName()); $this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST)); $this->assertEquals(0, User::idFromName('UTDoesNotExistEither', User::READ_LATEST)); $this->mergeMwGlobalArrayValue('wgHooks', array('AbortAutoAccount' => array())); $session->clear(); $this->assertSame(array(), $logger->getBuffer()); $logger->clearBuffer(); // Test for "exception backoff" $user = User::newFromName('UTDoesNotExist'); $cache = \ObjectCache::getLocalClusterInstance(); $backoffKey = wfMemcKey('MWSession', 'autocreate-failed', md5($user->getName())); $cache->set($backoffKey, 1, 60 * 10); $this->assertFalse($manager->autoCreateUser($user)); $this->assertSame(0, $user->getId()); $this->assertNotSame('UTDoesNotExist', $user->getName()); $this->assertEquals(0, User::idFromName('UTDoesNotExist', User::READ_LATEST)); $cache->delete($backoffKey); $session->clear(); $this->assertSame(array(array(LogLevel::DEBUG, 'denied by prior creation attempt failures')), $logger->getBuffer()); $logger->clearBuffer(); // Sanity check that creation still works, and test completion hook $cb = $this->callback(function (User $user) use($that) { $that->assertNotEquals(0, $user->getId()); $that->assertSame('UTSessionAutoCreate4', $user->getName()); $that->assertEquals($user->getId(), User::idFromName('UTSessionAutoCreate4', User::READ_LATEST)); return true; }); $mock = $this->getMock('stdClass', array('onAuthPluginAutoCreate', 'onLocalUserCreated')); $mock->expects($this->once())->method('onAuthPluginAutoCreate')->with($cb); $mock->expects($this->once())->method('onLocalUserCreated')->with($cb, $this->identicalTo(true)); $this->mergeMwGlobalArrayValue('wgHooks', array('AuthPluginAutoCreate' => array($mock), 'LocalUserCreated' => array($mock))); $user = User::newFromName('UTSessionAutoCreate4'); $this->assertSame(0, $user->getId(), 'sanity check'); $this->assertTrue($manager->autoCreateUser($user)); $this->assertNotEquals(0, $user->getId()); $this->assertSame('UTSessionAutoCreate4', $user->getName()); $this->assertEquals($user->getId(), User::idFromName('UTSessionAutoCreate4', User::READ_LATEST)); $this->mergeMwGlobalArrayValue('wgHooks', array('AuthPluginAutoCreate' => array(), 'LocalUserCreated' => array())); $this->assertSame(array(array(LogLevel::INFO, 'creating new user (UTSessionAutoCreate4) - from: XXX')), $logger->getBuffer()); $logger->clearBuffer(); }
function spreadBlock() { # If the (non-anonymous) user is blocked, this function will block any IP address # that they successfully log on from. $fname = 'User::spreadBlock'; wfDebug("User:spreadBlock()\n"); if ($this->mId == 0) { return; } $userblock = Block::newFromDB('', $this->mId); if (!$userblock) { return; } # Check if this IP address is already blocked $ipblock = Block::newFromDB(wfGetIP()); if ($ipblock) { # If the user is already blocked. Then check if the autoblock would # excede the user block. If it would excede, then do nothing, else # prolong block time if ($userblock->mExpiry && $userblock->mExpiry < Block::getAutoblockExpiry($ipblock->mTimestamp)) { return; } # Just update the timestamp $ipblock->updateTimestamp(); return; } else { $ipblock = new Block(); } # Make a new block object with the desired properties wfDebug("Autoblocking {$this->mName}@" . wfGetIP() . "\n"); $ipblock->mAddress = wfGetIP(); $ipblock->mUser = 0; $ipblock->mBy = $userblock->mBy; $ipblock->mReason = wfMsg('autoblocker', $this->getName(), $userblock->mReason); $ipblock->mTimestamp = wfTimestampNow(); $ipblock->mAuto = 1; # If the user is already blocked with an expiry date, we don't # want to pile on top of that! if ($userblock->mExpiry) { $ipblock->mExpiry = min($userblock->mExpiry, Block::getAutoblockExpiry($ipblock->mTimestamp)); } else { $ipblock->mExpiry = Block::getAutoblockExpiry($ipblock->mTimestamp); } # Insert it $ipblock->insert(); }
static function banUser($user, $banningUser, $spammer, $um) { $ret = null; if (!is_object($user)) { /* Skip this one */ } elseif ($user->getID() != 0 && $um) { $ret = $um->merge($user, $spammer, "block", $banningUser); } else { if (!Block::newFromTarget($user->getName())) { $blk = new Block($user->getName(), $user->getId(), $banningUser->getID(), wfMsg('blockandnuke-message'), wfTimestamp(), 0, wfGetDB(DB_SLAVE)->getInfinity(), 0, 1, 0, 0, 1); $blk->isAutoBlocking(true); if ($ret = $blk->insert()) { $log = new LogPage('block'); $log->addEntry('block', Title::makeTitle(NS_USER, $user->getName()), 'Blocked through Special:BlockandNuke', array('infinite', $user->getName(), 'nocreate')); } } } return $ret; }
/** * @param $action string * @param $parameters array * @param $title Title * @param $vars AbuseFilterVariableHolder * @param $rule_desc * @param $rule_number int|string * * @return array|null a message describing the action that was taken, * or null if no action was taken. The message is given as an array * containing the message key followed by any message parameters. * * @note: Returning the message as an array instead of a Message object is * needed for compatibility with MW 1.20: we will be constructing a * Status object from these messages, and before 1.21, Status did * not accept Message objects to be added directly. */ public static function takeConsequenceAction($action, $parameters, $title, $vars, $rule_desc, $rule_number) { global $wgAbuseFilterCustomActionsHandlers, $wgRequest; $message = null; switch ($action) { case 'disallow': if (strlen($parameters[0])) { $message = array($parameters[0], $rule_desc, $rule_number); } else { // Generic message. $message = array('abusefilter-disallowed', $rule_desc, $rule_number); } break; case 'block': global $wgUser, $wgAbuseFilterBlockDuration, $wgAbuseFilterAnonBlockDuration; $filterUser = AbuseFilter::getFilterUser(); // Create a block. $block = new Block(); $block->setTarget($wgUser->getName()); $block->setBlocker($filterUser); $block->mReason = wfMessage('abusefilter-blockreason', $rule_desc, $rule_number)->inContentLanguage()->text(); $block->isHardblock(false); $block->isAutoblocking(true); $block->prevents('createaccount', true); $block->prevents('editownusertalk', false); if ($wgUser->isAnon() && $wgAbuseFilterAnonBlockDuration !== null) { // The user isn't logged in and the anon block duration doesn't default to $wgAbuseFilterBlockDuration $expiry = $wgAbuseFilterAnonBlockDuration; } else { $expiry = $wgAbuseFilterBlockDuration; } $block->mExpiry = SpecialBlock::parseExpiryInput($expiry); $block->insert(); // Log it # Prepare log parameters $logParams = array(); if ($block->mExpiry == 'infinity') { $logParams[] = 'indefinite'; } else { $logParams[] = $expiry; } $logParams[] = 'nocreate'; $log = new LogPage('block'); $log->addEntry('block', Title::makeTitle(NS_USER, $wgUser->getName()), wfMessage('abusefilter-blockreason', $rule_desc, $rule_number)->inContentLanguage()->text(), $logParams, self::getFilterUser()); $message = array('abusefilter-blocked-display', $rule_desc, $rule_number); break; case 'rangeblock': $filterUser = AbuseFilter::getFilterUser(); $range = IP::sanitizeRange($wgRequest->getIP() . '/16'); // Create a block. $block = new Block(); $block->setTarget($range); $block->setBlocker($filterUser); $block->mReason = wfMessage('abusefilter-blockreason', $rule_desc, $rule_number)->inContentLanguage()->text(); $block->isHardblock(false); $block->prevents('createaccount', true); $block->prevents('editownusertalk', false); $block->mExpiry = SpecialBlock::parseExpiryInput('1 week'); $block->insert(); // Log it # Prepare log parameters $logParams = array(); $logParams[] = 'indefinite'; $logParams[] = 'nocreate'; $log = new LogPage('block'); $log->addEntry('block', Title::makeTitle(NS_USER, $range), wfMessage('abusefilter-blockreason', $rule_desc, $rule_number)->inContentLanguage()->text(), $logParams, self::getFilterUser()); $message = array('abusefilter-blocked-display', $rule_desc, $rule_number); break; case 'degroup': global $wgUser; if (!$wgUser->isAnon()) { // Remove all groups from the user. Ouch. $groups = $wgUser->getGroups(); foreach ($groups as $group) { $wgUser->removeGroup($group); } $message = array('abusefilter-degrouped', $rule_desc, $rule_number); // Don't log it if there aren't any groups being removed! if (!count($groups)) { break; } // Log it. $log = new LogPage('rights'); $log->addEntry('rights', $wgUser->getUserPage(), wfMessage('abusefilter-degroupreason', $rule_desc, $rule_number)->inContentLanguage()->text(), array(implode(', ', $groups), ''), self::getFilterUser()); } break; case 'blockautopromote': global $wgUser, $wgMemc; if (!$wgUser->isAnon()) { $blockPeriod = (int) mt_rand(3 * 86400, 7 * 86400); // Block for 3-7 days. $wgMemc->set(self::autoPromoteBlockKey($wgUser), true, $blockPeriod); $message = array('abusefilter-autopromote-blocked', $rule_desc, $rule_number); } break; case 'flag': // Do nothing. Here for completeness. break; case 'tag': // Mark with a tag on recentchanges. global $wgUser; $actionID = implode('-', array($title->getPrefixedText(), $wgUser->getName(), $vars->getVar('ACTION')->toString())); if (!isset(AbuseFilter::$tagsToSet[$actionID])) { AbuseFilter::$tagsToSet[$actionID] = $parameters; } else { AbuseFilter::$tagsToSet[$actionID] = array_merge(AbuseFilter::$tagsToSet[$actionID], $parameters); } break; default: if (isset($wgAbuseFilterCustomActionsHandlers[$action])) { $custom_function = $wgAbuseFilterCustomActionsHandlers[$action]; if (is_callable($custom_function)) { $msg = call_user_func($custom_function, $action, $parameters, $title, $vars, $rule_desc, $rule_number); } if (isset($msg)) { $message = array($msg); } } else { wfDebugLog('AbuseFilter', "Unrecognised action {$action}"); } } return $message; }
/** * Given the form data, actually implement a block. This is also called from ApiBlock. * * @param array $data * @param IContextSource $context * @return bool|string */ public static function processForm(array $data, IContextSource $context) { global $wgBlockAllowsUTEdit, $wgHideUserContribLimit, $wgContLang; $performer = $context->getUser(); // Handled by field validator callback // self::validateTargetField( $data['Target'] ); # This might have been a hidden field or a checkbox, so interesting data # can come from it $data['Confirm'] = !in_array($data['Confirm'], ['', '0', null, false], true); /** @var User $target */ list($target, $type) = self::getTargetAndType($data['Target']); if ($type == Block::TYPE_USER) { $user = $target; $target = $user->getName(); $userId = $user->getId(); # Give admins a heads-up before they go and block themselves. Much messier # to do this for IPs, but it's pretty unlikely they'd ever get the 'block' # permission anyway, although the code does allow for it. # Note: Important to use $target instead of $data['Target'] # since both $data['PreviousTarget'] and $target are normalized # but $data['target'] gets overridden by (non-normalized) request variable # from previous request. if ($target === $performer->getName() && ($data['PreviousTarget'] !== $target || !$data['Confirm'])) { return ['ipb-blockingself', 'ipb-confirmaction']; } } elseif ($type == Block::TYPE_RANGE) { $userId = 0; } elseif ($type == Block::TYPE_IP) { $target = $target->getName(); $userId = 0; } else { # This should have been caught in the form field validation return ['badipaddress']; } $expiryTime = self::parseExpiryInput($data['Expiry']); if (strlen($data['Expiry']) == 0 || strlen($data['Expiry']) > 50 || !$expiryTime) { return ['ipb_expiry_invalid']; } // an expiry time should be in the future, not in the // past (wouldn't make any sense) - bug T123069 if ($expiryTime < wfTimestampNow()) { return ['ipb_expiry_old']; } if (!isset($data['DisableEmail'])) { $data['DisableEmail'] = false; } # If the user has done the form 'properly', they won't even have been given the # option to suppress-block unless they have the 'hideuser' permission if (!isset($data['HideUser'])) { $data['HideUser'] = false; } if ($data['HideUser']) { if (!$performer->isAllowed('hideuser')) { # this codepath is unreachable except by a malicious user spoofing forms, # or by race conditions (user has hideuser and block rights, loads block form, # and loses hideuser rights before submission); so need to fail completely # rather than just silently disable hiding return ['badaccess-group0']; } # Recheck params here... if ($type != Block::TYPE_USER) { $data['HideUser'] = false; # IP users should not be hidden } elseif (!wfIsInfinity($data['Expiry'])) { # Bad expiry. return ['ipb_expiry_temp']; } elseif ($wgHideUserContribLimit !== false && $user->getEditCount() > $wgHideUserContribLimit) { # Typically, the user should have a handful of edits. # Disallow hiding users with many edits for performance. return [['ipb_hide_invalid', Message::numParam($wgHideUserContribLimit)]]; } elseif (!$data['Confirm']) { return ['ipb-confirmhideuser', 'ipb-confirmaction']; } } # Create block object. $block = new Block(); $block->setTarget($target); $block->setBlocker($performer); # Truncate reason for whole multibyte characters $block->mReason = $wgContLang->truncate($data['Reason'][0], 255); $block->mExpiry = $expiryTime; $block->prevents('createaccount', $data['CreateAccount']); $block->prevents('editownusertalk', !$wgBlockAllowsUTEdit || $data['DisableUTEdit']); $block->prevents('sendemail', $data['DisableEmail']); $block->isHardblock($data['HardBlock']); $block->isAutoblocking($data['AutoBlock']); $block->mHideName = $data['HideUser']; $reason = ['hookaborted']; if (!Hooks::run('BlockIp', [&$block, &$performer, &$reason])) { return $reason; } # Try to insert block. Is there a conflicting block? $status = $block->insert(); if (!$status) { # Indicates whether the user is confirming the block and is aware of # the conflict (did not change the block target in the meantime) $blockNotConfirmed = !$data['Confirm'] || array_key_exists('PreviousTarget', $data) && $data['PreviousTarget'] !== $target; # Special case for API - bug 32434 $reblockNotAllowed = array_key_exists('Reblock', $data) && !$data['Reblock']; # Show form unless the user is already aware of this... if ($blockNotConfirmed || $reblockNotAllowed) { return [['ipb_already_blocked', $block->getTarget()]]; # Otherwise, try to update the block... } else { # This returns direct blocks before autoblocks/rangeblocks, since we should # be sure the user is blocked by now it should work for our purposes $currentBlock = Block::newFromTarget($target); if ($block->equals($currentBlock)) { return [['ipb_already_blocked', $block->getTarget()]]; } # If the name was hidden and the blocking user cannot hide # names, then don't allow any block changes... if ($currentBlock->mHideName && !$performer->isAllowed('hideuser')) { return ['cant-see-hidden-user']; } $currentBlock->isHardblock($block->isHardblock()); $currentBlock->prevents('createaccount', $block->prevents('createaccount')); $currentBlock->mExpiry = $block->mExpiry; $currentBlock->isAutoblocking($block->isAutoblocking()); $currentBlock->mHideName = $block->mHideName; $currentBlock->prevents('sendemail', $block->prevents('sendemail')); $currentBlock->prevents('editownusertalk', $block->prevents('editownusertalk')); $currentBlock->mReason = $block->mReason; $status = $currentBlock->update(); $logaction = 'reblock'; # Unset _deleted fields if requested if ($currentBlock->mHideName && !$data['HideUser']) { RevisionDeleteUser::unsuppressUserName($target, $userId); } # If hiding/unhiding a name, this should go in the private logs if ((bool) $currentBlock->mHideName) { $data['HideUser'] = true; } } } else { $logaction = 'block'; } Hooks::run('BlockIpComplete', [$block, $performer]); # Set *_deleted fields if requested if ($data['HideUser']) { RevisionDeleteUser::suppressUserName($target, $userId); } # Can't watch a rangeblock if ($type != Block::TYPE_RANGE && $data['Watch']) { WatchAction::doWatch(Title::makeTitle(NS_USER, $target), $performer, User::IGNORE_USER_RIGHTS); } # Block constructor sanitizes certain block options on insert $data['BlockEmail'] = $block->prevents('sendemail'); $data['AutoBlock'] = $block->isAutoblocking(); # Prepare log parameters $logParams = []; $logParams['5::duration'] = $data['Expiry']; $logParams['6::flags'] = self::blockLogFlags($data, $type); # Make log entry, if the name is hidden, put it in the suppression log $log_type = $data['HideUser'] ? 'suppress' : 'block'; $logEntry = new ManualLogEntry($log_type, $logaction); $logEntry->setTarget(Title::makeTitle(NS_USER, $target)); $logEntry->setComment($data['Reason'][0]); $logEntry->setPerformer($performer); $logEntry->setParameters($logParams); # Relate log ID to block IDs (bug 25763) $blockIds = array_merge([$status['id']], $status['autoIds']); $logEntry->setRelations(['ipb_id' => $blockIds]); $logId = $logEntry->insert(); $logEntry->publish($logId); # Report to the user return true; }
function doSubmit() { global $wgOut, $wgUser, $wgSysopUserBans, $wgSysopRangeBans; $userId = 0; $this->BlockAddress = trim($this->BlockAddress); $rxIP = '\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}'; # Check for invalid specifications if (!preg_match("/^{$rxIP}\$/", $this->BlockAddress)) { if (preg_match("/^({$rxIP})\\/(\\d{1,2})\$/", $this->BlockAddress, $matches)) { if ($wgSysopRangeBans) { if ($matches[2] > 31 || $matches[2] < 16) { $this->showForm(wfMsg('ip_range_invalid')); return; } $this->BlockAddress = Block::normaliseRange($this->BlockAddress); } else { # Range block illegal $this->showForm(wfMsg('range_block_disabled')); return; } } else { # Username block if ($wgSysopUserBans) { $user = User::newFromName($this->BlockAddress); if (!is_null($user) && $user->getID()) { # Use canonical name $this->BlockAddress = $user->getName(); $userId = $user->getID(); } else { $this->showForm(wfMsg('nosuchusershort', htmlspecialchars($this->BlockAddress))); return; } } else { $this->showForm(wfMsg('badipaddress')); return; } } } $expirestr = $this->BlockExpiry; if ($expirestr == 'other') { $expirestr = $this->BlockOther; } if (strlen($expirestr) == 0) { $this->showForm(wfMsg('ipb_expiry_invalid')); return; } if ($expirestr == 'infinite' || $expirestr == 'indefinite') { $expiry = Block::infinity(); } else { # Convert GNU-style date, on error returns -1 for PHP <5.1 and false for PHP >=5.1 $expiry = strtotime($expirestr); if ($expiry < 0 || $expiry === false) { $this->showForm(wfMsg('ipb_expiry_invalid')); return; } $expiry = wfTimestamp(TS_MW, $expiry); } # Create block # Note: for a user block, ipb_address is only for display purposes $block = new Block($this->BlockAddress, $userId, $wgUser->getID(), $this->BlockReason, wfTimestampNow(), 0, $expiry, $this->BlockAnonOnly, $this->BlockCreateAccount); if (wfRunHooks('BlockIp', array(&$block, &$wgUser))) { if (!$block->insert()) { $this->showForm(wfMsg('ipb_already_blocked', htmlspecialchars($this->BlockAddress))); return; } wfRunHooks('BlockIpComplete', array($block, $wgUser)); # Make log entry $log = new LogPage('block'); $log->addEntry('block', Title::makeTitle(NS_USER, $this->BlockAddress), $this->BlockReason, $expirestr); # Report to the user $titleObj = Title::makeTitle(NS_SPECIAL, 'Blockip'); $wgOut->redirect($titleObj->getFullURL('action=success&ip=' . urlencode($this->BlockAddress))); } }
/** * Called from the themes page to create a new block instace * * @param mixed $handler_vars */ public function ajax_add_block($handler_vars) { Utils::check_request_method(array('POST')); $this->setup_admin_theme(''); $title = $_POST['title']; $type = $_POST['type']; if (!isset($_POST['title'])) { $this->theme->blocks = Plugins::filter('block_list', array()); $this->theme->block_instances = DB::get_results('SELECT b.* FROM {blocks} b ORDER BY b.title ASC', array(), 'Block'); $this->theme->active_theme = Themes::get_active_data(true); $this->display('block_instances'); } elseif ($title == '') { $this->theme->blocks = Plugins::filter('block_list', array()); $this->theme->block_instances = DB::get_results('SELECT b.* FROM {blocks} b ORDER BY b.title ASC', array(), 'Block'); $this->theme->active_theme = Themes::get_active_data(true); $this->display('block_instances'); $msg = json_encode(_t('A new block must first have a name.')); echo '<script type="text/javascript"> alert(' . $msg . '); </script>'; } else { $block = new Block(array('title' => $title, 'type' => $type)); $block->insert(); $this->prepare_block_list(); $this->theme->active_theme = Themes::get_active_data(true); $this->display('block_instances'); $msg = json_encode(_t('Added new block "%1s" of type "%2s".', array($title, $type))); echo '<script type="text/javascript"> human_msg.display_msg(' . $msg . '); spinner.stop(); </script>'; } }