2004-02-18 02:15:00 +00:00
|
|
|
<?php
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @file
|
2004-09-02 23:28:24 +00:00
|
|
|
* Blocks and bans object
|
|
|
|
|
*/
|
2004-02-14 12:37:25 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
|
|
|
|
* The block class
|
2005-08-02 13:35:19 +00:00
|
|
|
* All the functions in this class assume the object is either explicitly
|
2004-09-02 23:28:24 +00:00
|
|
|
* loaded or filled. It is not load-on-demand. There are no accessors.
|
2005-08-02 13:35:19 +00:00
|
|
|
*
|
2005-12-01 10:37:47 +00:00
|
|
|
* Globals used: $wgAutoblockExpiry, $wgAntiLockFlags
|
2004-09-03 23:00:01 +00:00
|
|
|
*
|
2004-09-02 23:28:24 +00:00
|
|
|
* @todo This could be used everywhere, but it isn't.
|
2011-03-12 21:54:35 +00:00
|
|
|
* FIXME: this whole class is a cesspit, needs a complete rewrite
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2008-09-22 04:52:51 +00:00
|
|
|
class Block {
|
2011-03-21 19:12:41 +00:00
|
|
|
/* public*/ var $mUser, $mReason, $mTimestamp, $mAuto, $mExpiry,
|
|
|
|
|
$mHideName,
|
|
|
|
|
$mAngryAutoblock;
|
2011-03-20 17:43:17 +00:00
|
|
|
protected
|
2011-03-21 19:12:41 +00:00
|
|
|
$mAddress,
|
|
|
|
|
$mId,
|
|
|
|
|
$mBy,
|
|
|
|
|
$mByName,
|
2011-03-19 23:47:08 +00:00
|
|
|
$mFromMaster,
|
|
|
|
|
$mRangeStart,
|
|
|
|
|
$mRangeEnd,
|
|
|
|
|
$mAnonOnly,
|
2011-03-21 19:12:41 +00:00
|
|
|
$mEnableAutoblock,
|
2011-03-19 23:47:08 +00:00
|
|
|
$mBlockEmail,
|
|
|
|
|
$mAllowUsertalk,
|
|
|
|
|
$mCreateAccount;
|
|
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
/// @var User|String
|
|
|
|
|
protected $target;
|
|
|
|
|
|
|
|
|
|
/// @var Block::TYPE_ constant. Can only be USER, IP or RANGE internally
|
|
|
|
|
protected $type;
|
|
|
|
|
|
|
|
|
|
/// @var User
|
|
|
|
|
protected $blocker;
|
|
|
|
|
|
2011-03-20 17:43:17 +00:00
|
|
|
# TYPE constants
|
2011-03-12 21:54:35 +00:00
|
|
|
const TYPE_USER = 1;
|
|
|
|
|
const TYPE_IP = 2;
|
|
|
|
|
const TYPE_RANGE = 3;
|
2011-03-13 14:47:34 +00:00
|
|
|
const TYPE_AUTO = 4;
|
|
|
|
|
const TYPE_ID = 5;
|
2011-03-12 21:54:35 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
/**
|
|
|
|
|
* Constructor
|
|
|
|
|
* FIXME: Don't know what the best format to have for this constructor is, but fourteen
|
|
|
|
|
* optional parameters certainly isn't it.
|
|
|
|
|
*/
|
2007-01-20 13:34:31 +00:00
|
|
|
function __construct( $address = '', $user = 0, $by = 0, $reason = '',
|
2010-12-26 04:38:41 +00:00
|
|
|
$timestamp = 0, $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0,
|
2010-04-17 21:06:21 +00:00
|
|
|
$hideName = 0, $blockEmail = 0, $allowUsertalk = 0, $byName = false )
|
2003-09-01 13:13:56 +00:00
|
|
|
{
|
2011-03-21 19:12:41 +00:00
|
|
|
if( $timestamp === 0 ){
|
|
|
|
|
$timestamp = wfTimestampNow();
|
|
|
|
|
}
|
|
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
$this->mId = 0;
|
2007-03-12 19:31:30 +00:00
|
|
|
# Expand valid IPv6 addresses
|
2007-03-12 21:37:46 +00:00
|
|
|
$address = IP::sanitizeIP( $address );
|
2003-09-01 13:13:56 +00:00
|
|
|
$this->mAddress = $address;
|
|
|
|
|
$this->mUser = $user;
|
|
|
|
|
$this->mBy = $by;
|
|
|
|
|
$this->mReason = $reason;
|
2010-02-14 22:07:30 +00:00
|
|
|
$this->mTimestamp = wfTimestamp( TS_MW, $timestamp );
|
2003-09-07 13:56:25 +00:00
|
|
|
$this->mAuto = $auto;
|
2006-07-10 06:30:03 +00:00
|
|
|
$this->mAnonOnly = $anonOnly;
|
|
|
|
|
$this->mCreateAccount = $createAccount;
|
2011-03-18 19:15:56 +00:00
|
|
|
$this->mExpiry = $expiry;
|
2006-11-01 21:57:18 +00:00
|
|
|
$this->mEnableAutoblock = $enableAutoblock;
|
2007-03-14 05:24:06 +00:00
|
|
|
$this->mHideName = $hideName;
|
2007-06-07 17:31:08 +00:00
|
|
|
$this->mBlockEmail = $blockEmail;
|
2008-09-25 11:45:26 +00:00
|
|
|
$this->mAllowUsertalk = $allowUsertalk;
|
2005-12-01 10:37:47 +00:00
|
|
|
$this->mFromMaster = false;
|
2010-04-17 21:06:21 +00:00
|
|
|
$this->mByName = $byName;
|
2008-06-27 06:24:42 +00:00
|
|
|
$this->mAngryAutoblock = false;
|
2004-02-14 12:37:25 +00:00
|
|
|
$this->initialiseRange();
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Load a block from the database, using either the IP address or
|
2008-09-22 04:52:51 +00:00
|
|
|
* user ID. Tries the user ID first, and if that doesn't work, tries
|
|
|
|
|
* the address.
|
2010-02-14 22:07:30 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $address String: IP address of user/anon
|
|
|
|
|
* @param $user Integer: user id of user
|
|
|
|
|
* @param $killExpired Boolean: delete expired blocks on load
|
2008-09-21 14:22:23 +00:00
|
|
|
* @return Block Object
|
|
|
|
|
*/
|
2008-11-23 09:52:29 +00:00
|
|
|
public static function newFromDB( $address, $user = 0, $killExpired = true ) {
|
2008-09-24 08:46:18 +00:00
|
|
|
$block = new Block;
|
2006-07-10 06:30:03 +00:00
|
|
|
$block->load( $address, $user, $killExpired );
|
|
|
|
|
if ( $block->isValid() ) {
|
|
|
|
|
return $block;
|
|
|
|
|
} else {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Load a blocked user from their block id.
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $id Integer: Block id to search for
|
2008-09-21 14:22:23 +00:00
|
|
|
* @return Block object
|
|
|
|
|
*/
|
2008-11-23 09:52:29 +00:00
|
|
|
public static function newFromID( $id ) {
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2008-04-14 07:45:50 +00:00
|
|
|
$res = $dbr->resultObject( $dbr->select( 'ipblocks', '*',
|
2006-07-10 06:30:03 +00:00
|
|
|
array( 'ipb_id' => $id ), __METHOD__ ) );
|
2008-09-24 08:46:18 +00:00
|
|
|
$block = new Block;
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
if ( $block->loadFromResult( $res ) ) {
|
|
|
|
|
return $block;
|
|
|
|
|
} else {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2008-11-23 09:52:29 +00:00
|
|
|
/**
|
|
|
|
|
* Check if two blocks are effectively equal
|
|
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Boolean
|
2008-11-23 09:52:29 +00:00
|
|
|
*/
|
|
|
|
|
public function equals( Block $block ) {
|
2009-10-19 11:15:51 +00:00
|
|
|
return (
|
2008-11-23 09:52:29 +00:00
|
|
|
$this->mAddress == $block->mAddress
|
|
|
|
|
&& $this->mUser == $block->mUser
|
|
|
|
|
&& $this->mAuto == $block->mAuto
|
|
|
|
|
&& $this->mAnonOnly == $block->mAnonOnly
|
|
|
|
|
&& $this->mCreateAccount == $block->mCreateAccount
|
|
|
|
|
&& $this->mExpiry == $block->mExpiry
|
|
|
|
|
&& $this->mEnableAutoblock == $block->mEnableAutoblock
|
|
|
|
|
&& $this->mHideName == $block->mHideName
|
|
|
|
|
&& $this->mBlockEmail == $block->mBlockEmail
|
|
|
|
|
&& $this->mAllowUsertalk == $block->mAllowUsertalk
|
2009-02-21 10:15:10 +00:00
|
|
|
&& $this->mReason == $block->mReason
|
2008-11-23 09:52:29 +00:00
|
|
|
);
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Clear all member variables in the current object. Does not clear
|
|
|
|
|
* the block from the DB.
|
|
|
|
|
*/
|
2008-11-23 09:52:29 +00:00
|
|
|
public function clear() {
|
2005-08-23 16:52:42 +00:00
|
|
|
$this->mAddress = $this->mReason = $this->mTimestamp = '';
|
2008-04-14 07:45:50 +00:00
|
|
|
$this->mId = $this->mAnonOnly = $this->mCreateAccount =
|
|
|
|
|
$this->mEnableAutoblock = $this->mAuto = $this->mUser =
|
2008-09-25 11:45:26 +00:00
|
|
|
$this->mBy = $this->mHideName = $this->mBlockEmail = $this->mAllowUsertalk = 0;
|
2005-08-23 16:52:42 +00:00
|
|
|
$this->mByName = false;
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
2005-12-01 10:37:47 +00:00
|
|
|
/**
|
2008-09-22 04:52:51 +00:00
|
|
|
* Get a block from the DB, with either the given address or the given username
|
2006-07-10 06:30:03 +00:00
|
|
|
*
|
2008-09-21 14:22:23 +00:00
|
|
|
* @param $address string The IP address of the user, or blank to skip IP blocks
|
|
|
|
|
* @param $user int The user ID, or zero for anonymous users
|
|
|
|
|
* @param $killExpired bool Whether to delete expired rows while loading
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Boolean: the user is blocked from editing
|
2011-03-21 19:12:41 +00:00
|
|
|
* @deprecated since 1.18
|
2005-12-01 10:37:47 +00:00
|
|
|
*/
|
2008-11-23 09:52:29 +00:00
|
|
|
public function load( $address = '', $user = 0, $killExpired = true ) {
|
2011-03-21 19:12:41 +00:00
|
|
|
wfDeprecated( __METHOD__ );
|
|
|
|
|
if( $user ){
|
|
|
|
|
$username = User::whoIs( $user );
|
|
|
|
|
$block = self::newFromTarget( $username, $address );
|
|
|
|
|
} else {
|
|
|
|
|
$block = self::newFromTarget( null, $address );
|
|
|
|
|
}
|
2005-12-01 10:37:47 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
if( $block instanceof Block ){
|
|
|
|
|
# This is mildly evil, but hey, it's B/C :D
|
|
|
|
|
foreach( $block as $variable => $value ){
|
|
|
|
|
$this->$variable = $value;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-12-01 10:37:47 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
/**
|
|
|
|
|
* Load a block from the database which affects the already-set $this->target:
|
|
|
|
|
* 1) A block directly on the given user or IP
|
|
|
|
|
* 2) A rangeblock encompasing the given IP (smallest first)
|
|
|
|
|
* 3) An autoblock on the given IP
|
|
|
|
|
* @param $vagueTarget User|String also search for blocks affecting this target. Doesn't
|
|
|
|
|
* make any sense to use TYPE_AUTO / TYPE_ID here
|
|
|
|
|
* @return Bool whether a relevant block was found
|
|
|
|
|
*/
|
|
|
|
|
protected function newLoad( $vagueTarget = null ) {
|
|
|
|
|
$db = wfGetDB( $this->mFromMaster ? DB_MASTER : DB_SLAVE );
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
if( $this->type !== null ){
|
|
|
|
|
$conds = array(
|
|
|
|
|
'ipb_address' => array( (string)$this->target ),
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
$conds = array( 'ipb_address' => array() );
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
if( $vagueTarget !== null ){
|
|
|
|
|
list( $target, $type ) = self::parseTarget( $vagueTarget );
|
|
|
|
|
switch( $type ) {
|
|
|
|
|
case self::TYPE_USER:
|
|
|
|
|
# Slightly wierd, but who are we to argue?
|
|
|
|
|
$conds['ipb_address'][] = (string)$target;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case self::TYPE_IP:
|
|
|
|
|
$conds['ipb_address'][] = (string)$target;
|
|
|
|
|
$conds[] = self::getRangeCond( IP::toHex( $target ) );
|
|
|
|
|
$conds = $db->makeList( $conds, LIST_OR );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case self::TYPE_RANGE:
|
|
|
|
|
list( $start, $end ) = IP::parseRange( $target );
|
|
|
|
|
$conds['ipb_address'][] = (string)$target;
|
|
|
|
|
$conds[] = self::getRangeCond( $start, $end );
|
|
|
|
|
$conds = $db->makeList( $conds, LIST_OR );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
throw new MWException( "Tried to load block with invalid type" );
|
2006-07-10 06:30:03 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
$res = $db->select( 'ipblocks', '*', $conds, __METHOD__ );
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
# This result could contain a block on the user, a block on the IP, and a russian-doll
|
|
|
|
|
# set of rangeblocks. We want to choose the most specific one, so keep a leader board.
|
|
|
|
|
$bestRow = null;
|
2006-07-10 06:30:03 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
# Lower will be better
|
|
|
|
|
$bestBlockScore = 100;
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
# This is begging for $this = $bestBlock, but that's not allowed in PHP :(
|
|
|
|
|
$bestBlockPreventsEdit = null;
|
2006-07-10 06:30:03 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
foreach( $res as $row ){
|
|
|
|
|
$block = Block::newFromRow( $row );
|
2010-02-14 22:07:30 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
# Don't use expired blocks
|
|
|
|
|
if( $block->deleteIfExpired() ){
|
|
|
|
|
continue;
|
2006-07-11 05:30:35 +00:00
|
|
|
}
|
2010-02-14 22:07:30 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
# Don't use anon only blocks on users
|
|
|
|
|
if( $this->type == self::TYPE_USER && !$block->isHardblock() ){
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2010-02-14 22:07:30 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
if( $block->getType() == self::TYPE_RANGE ){
|
|
|
|
|
# This is the number of bits that are allowed to vary in the block, give
|
|
|
|
|
# or take some floating point errors
|
|
|
|
|
$end = wfBaseconvert( $block->getRangeEnd(), 16, 10 );
|
|
|
|
|
$start = wfBaseconvert( $block->getRangeStart(), 16, 10 );
|
|
|
|
|
$size = log( $end - $start + 1, 2 );
|
|
|
|
|
|
|
|
|
|
# This has the nice property that a /32 block is ranked equally with a
|
|
|
|
|
# single-IP block, which is exactly what it is...
|
|
|
|
|
$score = self::TYPE_RANGE - 1 + ( $size / 128 );
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
$score = $block->getType();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( $score < $bestBlockScore ){
|
|
|
|
|
$bestBlockScore = $score;
|
|
|
|
|
$bestRow = $row;
|
|
|
|
|
$bestBlockPreventsEdit = $block->prevents( 'edit' );
|
2006-07-11 05:30:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
if( $bestRow !== null ){
|
|
|
|
|
$this->initFromRow( $bestRow );
|
|
|
|
|
$this->prevents( 'edit', $bestBlockPreventsEdit );
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2006-07-10 06:30:03 +00:00
|
|
|
}
|
|
|
|
|
|
2011-03-19 23:47:08 +00:00
|
|
|
/**
|
|
|
|
|
* Get a set of SQL conditions which will select rangeblocks encompasing a given range
|
|
|
|
|
* @param $start String Hexadecimal IP representation
|
|
|
|
|
* @param $end String Hexadecimal IP represenation, or null to use $start = $end
|
|
|
|
|
* @return String
|
|
|
|
|
*/
|
2011-03-20 17:43:17 +00:00
|
|
|
public static function getRangeCond( $start, $end = null ) {
|
|
|
|
|
if ( $end === null ) {
|
2011-03-19 23:47:08 +00:00
|
|
|
$end = $start;
|
|
|
|
|
}
|
|
|
|
|
# Per bug 14634, we want to include relevant active rangeblocks; for
|
|
|
|
|
# rangeblocks, we want to include larger ranges which enclose the given
|
|
|
|
|
# range. We know that all blocks must be smaller than $wgBlockCIDRLimit,
|
|
|
|
|
# so we can improve performance by filtering on a LIKE clause
|
|
|
|
|
$chunk = self::getIpFragment( $start );
|
|
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
|
|
|
|
$like = $dbr->buildLike( $chunk, $dbr->anyString() );
|
|
|
|
|
|
|
|
|
|
# Fairly hard to make a malicious SQL statement out of hex characters,
|
|
|
|
|
# but stranger things have happened...
|
|
|
|
|
$safeStart = $dbr->addQuotes( $start );
|
|
|
|
|
$safeEnd = $dbr->addQuotes( $end );
|
|
|
|
|
|
|
|
|
|
return $dbr->makeList(
|
|
|
|
|
array(
|
|
|
|
|
"ipb_range_start $like",
|
|
|
|
|
"ipb_range_start <= $safeStart",
|
|
|
|
|
"ipb_range_end >= $safeEnd",
|
|
|
|
|
),
|
|
|
|
|
LIST_AND
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the component of an IP address which is certain to be the same between an IP
|
|
|
|
|
* address and a rangeblock containing that IP address.
|
|
|
|
|
* @param $hex String Hexadecimal IP representation
|
|
|
|
|
* @return String
|
|
|
|
|
*/
|
2011-03-20 17:43:17 +00:00
|
|
|
protected static function getIpFragment( $hex ) {
|
2011-03-19 23:47:08 +00:00
|
|
|
global $wgBlockCIDRLimit;
|
2011-03-20 17:43:17 +00:00
|
|
|
if ( substr( $hex, 0, 3 ) == 'v6-' ) {
|
2011-03-19 23:47:08 +00:00
|
|
|
return 'v6-' . substr( substr( $hex, 3 ), 0, floor( $wgBlockCIDRLimit['IPv6'] / 4 ) );
|
|
|
|
|
} else {
|
|
|
|
|
return substr( $hex, 0, floor( $wgBlockCIDRLimit['IPv4'] / 4 ) );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
/**
|
|
|
|
|
* Fill in member variables from a result wrapper
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $res ResultWrapper: row from the ipblocks table
|
|
|
|
|
* @param $killExpired Boolean: whether to delete expired rows while loading
|
|
|
|
|
* @return Boolean
|
2006-07-10 06:30:03 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
protected function loadFromResult( ResultWrapper $res, $killExpired = true ) {
|
2006-07-10 06:30:03 +00:00
|
|
|
$ret = false;
|
2010-02-14 22:07:30 +00:00
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
if ( 0 != $res->numRows() ) {
|
2003-09-01 13:13:56 +00:00
|
|
|
# Get first block
|
2006-07-10 06:30:03 +00:00
|
|
|
$row = $res->fetchObject();
|
2003-09-01 13:13:56 +00:00
|
|
|
$this->initFromRow( $row );
|
|
|
|
|
|
|
|
|
|
if ( $killExpired ) {
|
|
|
|
|
# If requested, delete expired rows
|
|
|
|
|
do {
|
|
|
|
|
$killed = $this->deleteIfExpired();
|
2003-09-07 13:56:25 +00:00
|
|
|
if ( $killed ) {
|
2006-07-10 06:30:03 +00:00
|
|
|
$row = $res->fetchObject();
|
2003-09-07 13:56:25 +00:00
|
|
|
if ( $row ) {
|
|
|
|
|
$this->initFromRow( $row );
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-09-01 13:13:56 +00:00
|
|
|
} while ( $killed && $row );
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2003-09-01 13:13:56 +00:00
|
|
|
# If there were any left after the killing finished, return true
|
2006-07-10 06:30:03 +00:00
|
|
|
if ( $row ) {
|
2003-09-01 13:13:56 +00:00
|
|
|
$ret = true;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$ret = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-07-10 06:30:03 +00:00
|
|
|
$res->free();
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2003-09-01 13:13:56 +00:00
|
|
|
return $ret;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-12-01 10:37:47 +00:00
|
|
|
/**
|
2006-01-07 13:09:30 +00:00
|
|
|
* Search the database for any range blocks matching the given address, and
|
2005-12-01 10:37:47 +00:00
|
|
|
* load the row if one is found.
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $address String: IP address range
|
|
|
|
|
* @param $killExpired Boolean: whether to delete expired rows while loading
|
2010-06-15 20:09:19 +00:00
|
|
|
* @param $user Integer: if not 0, then sets ipb_anon_only
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Boolean
|
2005-12-01 10:37:47 +00:00
|
|
|
*/
|
2011-03-19 17:44:01 +00:00
|
|
|
protected function loadRange( $address, $killExpired = true, $user = 0 ) {
|
2006-07-14 17:02:49 +00:00
|
|
|
$iaddr = IP::toHex( $address );
|
2010-02-14 22:07:30 +00:00
|
|
|
|
2005-12-01 10:37:47 +00:00
|
|
|
if ( $iaddr === false ) {
|
|
|
|
|
# Invalid address
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Only scan ranges which start in this /16, this improves search speed
|
|
|
|
|
# Blocks should not cross a /16 boundary.
|
|
|
|
|
$range = substr( $iaddr, 0, 4 );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2011-03-19 17:32:59 +00:00
|
|
|
$db = wfGetDB( $this->mFromMaster ? DB_MASTER : DB_SLAVE );
|
2006-07-10 06:30:03 +00:00
|
|
|
$conds = array(
|
2009-10-21 19:53:03 +00:00
|
|
|
'ipb_range_start' . $db->buildLike( $range, $db->anyString() ),
|
2006-07-10 06:30:03 +00:00
|
|
|
"ipb_range_start <= '$iaddr'",
|
|
|
|
|
"ipb_range_end >= '$iaddr'"
|
|
|
|
|
);
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2007-03-12 21:56:31 +00:00
|
|
|
if ( $user ) {
|
|
|
|
|
$conds['ipb_anon_only'] = 0;
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2011-03-19 17:32:59 +00:00
|
|
|
$res = $db->resultObject( $db->select( 'ipblocks', '*', $conds, __METHOD__ ) );
|
2006-07-10 06:30:03 +00:00
|
|
|
$success = $this->loadFromResult( $res, $killExpired );
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2005-12-01 10:37:47 +00:00
|
|
|
return $success;
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Given a database row from the ipblocks table, initialize
|
|
|
|
|
* member variables
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $row ResultWrapper: a row from the ipblocks table
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2011-03-19 17:44:01 +00:00
|
|
|
protected function initFromRow( $row ) {
|
2011-03-21 19:12:41 +00:00
|
|
|
list( $this->target, $this->type ) = self::parseTarget( $row->ipb_address );
|
|
|
|
|
|
|
|
|
|
$this->setTarget( $row->ipb_address );
|
|
|
|
|
$this->setBlocker( User::newFromId( $row->ipb_by ) );
|
|
|
|
|
|
2003-09-01 13:13:56 +00:00
|
|
|
$this->mReason = $row->ipb_reason;
|
2010-02-14 22:07:30 +00:00
|
|
|
$this->mTimestamp = wfTimestamp( TS_MW, $row->ipb_timestamp );
|
2003-09-07 13:56:25 +00:00
|
|
|
$this->mAuto = $row->ipb_auto;
|
2006-07-10 06:30:03 +00:00
|
|
|
$this->mAnonOnly = $row->ipb_anon_only;
|
|
|
|
|
$this->mCreateAccount = $row->ipb_create_account;
|
2006-11-01 21:57:18 +00:00
|
|
|
$this->mEnableAutoblock = $row->ipb_enable_autoblock;
|
2007-06-07 17:31:08 +00:00
|
|
|
$this->mBlockEmail = $row->ipb_block_email;
|
2008-09-25 11:45:26 +00:00
|
|
|
$this->mAllowUsertalk = $row->ipb_allow_usertalk;
|
2007-03-14 05:24:06 +00:00
|
|
|
$this->mHideName = $row->ipb_deleted;
|
2003-09-07 13:56:25 +00:00
|
|
|
$this->mId = $row->ipb_id;
|
2011-03-18 19:15:56 +00:00
|
|
|
$this->mExpiry = $row->ipb_expiry;
|
2005-12-01 10:37:47 +00:00
|
|
|
$this->mRangeStart = $row->ipb_range_start;
|
|
|
|
|
$this->mRangeEnd = $row->ipb_range_end;
|
2005-08-02 13:35:19 +00:00
|
|
|
}
|
2003-09-01 13:13:56 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
/**
|
|
|
|
|
* Create a new Block object from a database row
|
|
|
|
|
* @param $row ResultWrapper row from the ipblocks table
|
|
|
|
|
* @return Block
|
|
|
|
|
*/
|
|
|
|
|
public static function newFromRow( $row ){
|
|
|
|
|
$block = new Block;
|
|
|
|
|
$block->initFromRow( $row );
|
|
|
|
|
return $block;
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
2010-02-14 22:07:30 +00:00
|
|
|
* Once $mAddress has been set, get the range they came from.
|
2008-09-21 14:22:23 +00:00
|
|
|
* Wrapper for IP::parseRange
|
|
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
protected function initialiseRange() {
|
2005-12-01 10:37:47 +00:00
|
|
|
$this->mRangeStart = '';
|
|
|
|
|
$this->mRangeEnd = '';
|
2006-11-22 11:51:49 +00:00
|
|
|
|
2004-02-14 12:37:25 +00:00
|
|
|
if ( $this->mUser == 0 ) {
|
2006-11-25 17:32:41 +00:00
|
|
|
list( $this->mRangeStart, $this->mRangeEnd ) = IP::parseRange( $this->mAddress );
|
2006-01-07 13:31:29 +00:00
|
|
|
}
|
2004-02-14 12:37:25 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Delete the row from the IP blocks table.
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Boolean
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function delete() {
|
|
|
|
|
if ( wfReadOnly() ) {
|
2006-07-10 06:30:03 +00:00
|
|
|
return false;
|
2005-03-08 02:45:25 +00:00
|
|
|
}
|
2010-02-14 22:07:30 +00:00
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
if ( !$this->mId ) {
|
|
|
|
|
throw new MWException( "Block::delete() now requires that the mId member be filled\n" );
|
2003-09-07 13:56:25 +00:00
|
|
|
}
|
2006-07-10 06:30:03 +00:00
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2006-07-10 06:30:03 +00:00
|
|
|
$dbw->delete( 'ipblocks', array( 'ipb_id' => $this->mId ), __METHOD__ );
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
return $dbw->affectedRows() > 0;
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
2006-11-08 09:54:06 +00:00
|
|
|
/**
|
2008-09-22 04:52:51 +00:00
|
|
|
* Insert a block into the block table. Will fail if there is a conflicting
|
|
|
|
|
* block (same name and options) already in the database.
|
|
|
|
|
*
|
2011-03-22 11:22:15 +00:00
|
|
|
* @return mixed: false on failure, assoc array on success:
|
|
|
|
|
* ('id' => block ID, 'autoId' => autoblock ID or false)
|
2008-09-22 04:52:51 +00:00
|
|
|
*/
|
2010-04-17 21:16:06 +00:00
|
|
|
public function insert( $dbw = null ) {
|
2005-01-11 09:29:29 +00:00
|
|
|
wfDebug( "Block::insert; timestamp {$this->mTimestamp}\n" );
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2010-04-17 21:16:06 +00:00
|
|
|
if ( $dbw === null )
|
2010-04-17 20:59:05 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2006-07-10 06:30:03 +00:00
|
|
|
|
2008-09-21 15:16:32 +00:00
|
|
|
$this->validateBlockParams();
|
2008-12-15 12:10:41 +00:00
|
|
|
$this->initialiseRange();
|
2008-02-18 12:16:23 +00:00
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
# Don't collide with expired blocks
|
|
|
|
|
Block::purgeExpired();
|
2006-11-22 11:51:49 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
$ipb_id = $dbw->nextSequenceValue( 'ipblocks_ipb_id_seq' );
|
|
|
|
|
$dbw->insert(
|
|
|
|
|
'ipblocks',
|
2004-07-10 03:09:26 +00:00
|
|
|
array(
|
2005-08-02 13:35:19 +00:00
|
|
|
'ipb_id' => $ipb_id,
|
2004-07-10 03:09:26 +00:00
|
|
|
'ipb_address' => $this->mAddress,
|
|
|
|
|
'ipb_user' => $this->mUser,
|
|
|
|
|
'ipb_by' => $this->mBy,
|
2008-02-18 12:16:23 +00:00
|
|
|
'ipb_by_text' => $this->mByName,
|
2004-07-10 03:09:26 +00:00
|
|
|
'ipb_reason' => $this->mReason,
|
2010-02-14 22:07:30 +00:00
|
|
|
'ipb_timestamp' => $dbw->timestamp( $this->mTimestamp ),
|
2004-07-10 03:09:26 +00:00
|
|
|
'ipb_auto' => $this->mAuto,
|
2006-07-10 06:30:03 +00:00
|
|
|
'ipb_anon_only' => $this->mAnonOnly,
|
|
|
|
|
'ipb_create_account' => $this->mCreateAccount,
|
2006-11-01 21:57:18 +00:00
|
|
|
'ipb_enable_autoblock' => $this->mEnableAutoblock,
|
2011-03-18 19:15:56 +00:00
|
|
|
'ipb_expiry' => $dbw->encodeExpiry( $this->mExpiry ),
|
2005-12-01 10:37:47 +00:00
|
|
|
'ipb_range_start' => $this->mRangeStart,
|
|
|
|
|
'ipb_range_end' => $this->mRangeEnd,
|
2010-03-12 19:18:14 +00:00
|
|
|
'ipb_deleted' => intval( $this->mHideName ), // typecast required for SQLite
|
2008-09-25 11:45:26 +00:00
|
|
|
'ipb_block_email' => $this->mBlockEmail,
|
|
|
|
|
'ipb_allow_usertalk' => $this->mAllowUsertalk
|
2010-02-14 22:07:30 +00:00
|
|
|
),
|
|
|
|
|
'Block::insert',
|
|
|
|
|
array( 'IGNORE' )
|
2004-07-10 03:09:26 +00:00
|
|
|
);
|
2006-07-10 06:30:03 +00:00
|
|
|
$affected = $dbw->affectedRows();
|
2006-11-08 09:54:06 +00:00
|
|
|
|
2011-03-22 11:22:15 +00:00
|
|
|
if ( $affected ) {
|
|
|
|
|
$auto_ipd_id = $this->doRetroactiveAutoblock();
|
|
|
|
|
return array( 'id' => $ipb_id, 'autoId' => $auto_ipd_id );
|
|
|
|
|
}
|
2006-11-08 09:54:06 +00:00
|
|
|
|
2011-03-22 11:22:15 +00:00
|
|
|
return false;
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
2008-09-21 15:16:32 +00:00
|
|
|
/**
|
2008-09-22 04:52:51 +00:00
|
|
|
* Update a block in the DB with new parameters.
|
|
|
|
|
* The ID field needs to be loaded first.
|
2008-09-21 15:16:32 +00:00
|
|
|
*/
|
|
|
|
|
public function update() {
|
|
|
|
|
wfDebug( "Block::update; timestamp {$this->mTimestamp}\n" );
|
|
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
|
|
|
|
|
|
|
|
|
$this->validateBlockParams();
|
|
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
$dbw->update(
|
|
|
|
|
'ipblocks',
|
2008-09-21 15:16:32 +00:00
|
|
|
array(
|
|
|
|
|
'ipb_user' => $this->mUser,
|
|
|
|
|
'ipb_by' => $this->mBy,
|
|
|
|
|
'ipb_by_text' => $this->mByName,
|
|
|
|
|
'ipb_reason' => $this->mReason,
|
2010-02-14 22:07:30 +00:00
|
|
|
'ipb_timestamp' => $dbw->timestamp( $this->mTimestamp ),
|
2008-09-21 15:16:32 +00:00
|
|
|
'ipb_auto' => $this->mAuto,
|
|
|
|
|
'ipb_anon_only' => $this->mAnonOnly,
|
|
|
|
|
'ipb_create_account' => $this->mCreateAccount,
|
|
|
|
|
'ipb_enable_autoblock' => $this->mEnableAutoblock,
|
2011-03-18 19:15:56 +00:00
|
|
|
'ipb_expiry' => $dbw->encodeExpiry( $this->mExpiry ),
|
2008-09-21 15:16:32 +00:00
|
|
|
'ipb_range_start' => $this->mRangeStart,
|
|
|
|
|
'ipb_range_end' => $this->mRangeEnd,
|
|
|
|
|
'ipb_deleted' => $this->mHideName,
|
2008-09-25 11:45:26 +00:00
|
|
|
'ipb_block_email' => $this->mBlockEmail,
|
2010-02-14 22:07:30 +00:00
|
|
|
'ipb_allow_usertalk' => $this->mAllowUsertalk
|
|
|
|
|
),
|
2008-09-21 15:16:32 +00:00
|
|
|
array( 'ipb_id' => $this->mId ),
|
2010-02-14 22:07:30 +00:00
|
|
|
'Block::update'
|
|
|
|
|
);
|
2008-09-21 15:16:32 +00:00
|
|
|
|
|
|
|
|
return $dbw->affectedRows();
|
|
|
|
|
}
|
2010-02-14 22:07:30 +00:00
|
|
|
|
2008-09-21 15:16:32 +00:00
|
|
|
/**
|
|
|
|
|
* Make sure all the proper members are set to sane values
|
|
|
|
|
* before adding/updating a block
|
|
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
protected function validateBlockParams() {
|
2008-09-21 15:16:32 +00:00
|
|
|
# Unset ipb_anon_only for user blocks, makes no sense
|
|
|
|
|
if ( $this->mUser ) {
|
|
|
|
|
$this->mAnonOnly = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Unset ipb_enable_autoblock for IP blocks, makes no sense
|
|
|
|
|
if ( !$this->mUser ) {
|
|
|
|
|
$this->mEnableAutoblock = 0;
|
2009-05-21 20:32:28 +00:00
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2009-05-21 20:32:28 +00:00
|
|
|
# bug 18860: non-anon-only IP blocks should be allowed to block email
|
|
|
|
|
if ( !$this->mUser && $this->mAnonOnly ) {
|
|
|
|
|
$this->mBlockEmail = 0;
|
2008-09-21 15:16:32 +00:00
|
|
|
}
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( !$this->mByName ) {
|
|
|
|
|
if ( $this->mBy ) {
|
2008-09-21 15:16:32 +00:00
|
|
|
$this->mByName = User::whoIs( $this->mBy );
|
|
|
|
|
} else {
|
|
|
|
|
global $wgUser;
|
|
|
|
|
$this->mByName = $wgUser->getName();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2006-11-08 09:54:06 +00:00
|
|
|
/**
|
2009-10-19 11:15:51 +00:00
|
|
|
* Retroactively autoblocks the last IP used by the user (if it is a user)
|
|
|
|
|
* blocked by this Block.
|
|
|
|
|
*
|
2011-03-22 11:22:15 +00:00
|
|
|
* @return mixed: block ID if a retroactive autoblock was made, false if not.
|
2009-10-19 11:15:51 +00:00
|
|
|
*/
|
2011-03-19 17:44:01 +00:00
|
|
|
protected function doRetroactiveAutoblock() {
|
2006-11-25 16:24:44 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2009-10-19 11:15:51 +00:00
|
|
|
# If autoblock is enabled, autoblock the LAST IP used
|
2006-11-08 09:54:06 +00:00
|
|
|
# - stolen shamelessly from CheckUser_body.php
|
|
|
|
|
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( $this->mEnableAutoblock && $this->mUser ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( "Doing retroactive autoblocks for " . $this->mAddress . "\n" );
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2008-06-27 06:24:42 +00:00
|
|
|
$options = array( 'ORDER BY' => 'rc_timestamp DESC' );
|
|
|
|
|
$conds = array( 'rc_user_text' => $this->mAddress );
|
2009-10-19 11:15:51 +00:00
|
|
|
|
|
|
|
|
if ( $this->mAngryAutoblock ) {
|
2008-06-27 06:24:42 +00:00
|
|
|
// Block any IP used in the last 7 days. Up to five IPs.
|
2009-10-19 11:15:51 +00:00
|
|
|
$conds[] = 'rc_timestamp < ' . $dbr->addQuotes( $dbr->timestamp( time() - ( 7 * 86400 ) ) );
|
2008-06-27 06:24:42 +00:00
|
|
|
$options['LIMIT'] = 5;
|
|
|
|
|
} else {
|
|
|
|
|
// Just the last IP used.
|
|
|
|
|
$options['LIMIT'] = 1;
|
|
|
|
|
}
|
2006-11-08 09:54:06 +00:00
|
|
|
|
2008-06-27 06:24:42 +00:00
|
|
|
$res = $dbr->select( 'recentchanges', array( 'rc_ip' ), $conds,
|
2009-10-19 11:15:51 +00:00
|
|
|
__METHOD__ , $options );
|
2006-11-08 09:54:06 +00:00
|
|
|
|
2008-06-27 06:24:42 +00:00
|
|
|
if ( !$dbr->numRows( $res ) ) {
|
2009-10-19 11:15:51 +00:00
|
|
|
# No results, don't autoblock anything
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( "No IP found to retroactively autoblock\n" );
|
2006-11-08 09:54:06 +00:00
|
|
|
} else {
|
2010-10-13 23:11:40 +00:00
|
|
|
foreach ( $res as $row ) {
|
2010-05-30 14:48:30 +00:00
|
|
|
if ( $row->rc_ip ) {
|
2011-03-22 11:22:15 +00:00
|
|
|
return $this->doAutoblock( $row->rc_ip );
|
2010-05-30 14:48:30 +00:00
|
|
|
}
|
2008-06-27 06:24:42 +00:00
|
|
|
}
|
2006-11-08 09:54:06 +00:00
|
|
|
}
|
|
|
|
|
}
|
2011-03-22 11:22:15 +00:00
|
|
|
return false;
|
2006-11-08 09:54:06 +00:00
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2006-11-08 09:54:06 +00:00
|
|
|
/**
|
2008-08-08 05:56:43 +00:00
|
|
|
* Checks whether a given IP is on the autoblock whitelist.
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $ip String: The IP to check
|
|
|
|
|
* @return Boolean
|
2008-08-08 05:56:43 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function isWhitelistedFromAutoblocks( $ip ) {
|
2008-09-21 14:22:23 +00:00
|
|
|
global $wgMemc;
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
// Try to get the autoblock_whitelist from the cache, as it's faster
|
|
|
|
|
// than getting the msg raw and explode()'ing it.
|
2008-09-21 20:25:21 +00:00
|
|
|
$key = wfMemcKey( 'ipb', 'autoblock', 'whitelist' );
|
2008-09-21 14:22:23 +00:00
|
|
|
$lines = $wgMemc->get( $key );
|
|
|
|
|
if ( !$lines ) {
|
|
|
|
|
$lines = explode( "\n", wfMsgForContentNoTrans( 'autoblock_whitelist' ) );
|
2008-09-21 14:25:46 +00:00
|
|
|
$wgMemc->set( $key, $lines, 3600 * 24 );
|
2008-09-21 14:22:23 +00:00
|
|
|
}
|
2006-11-22 23:42:39 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( "Checking the autoblock whitelist..\n" );
|
2006-11-22 23:42:39 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
foreach ( $lines as $line ) {
|
2006-11-22 23:42:39 +00:00
|
|
|
# List items only
|
|
|
|
|
if ( substr( $line, 0, 1 ) !== '*' ) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-19 11:15:51 +00:00
|
|
|
$wlEntry = substr( $line, 1 );
|
|
|
|
|
$wlEntry = trim( $wlEntry );
|
2006-11-22 23:42:39 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( "Checking $ip against $wlEntry..." );
|
2006-11-22 23:42:39 +00:00
|
|
|
|
|
|
|
|
# Is the IP in this range?
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( IP::isInRange( $ip, $wlEntry ) ) {
|
2010-02-14 22:07:30 +00:00
|
|
|
wfDebug( " IP $ip matches $wlEntry, not autoblocking\n" );
|
2008-08-08 05:56:43 +00:00
|
|
|
return true;
|
2006-12-08 10:30:50 +00:00
|
|
|
} else {
|
|
|
|
|
wfDebug( " No match\n" );
|
2006-11-22 23:42:39 +00:00
|
|
|
}
|
2006-11-22 11:51:49 +00:00
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2008-08-08 05:56:43 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2008-09-22 04:52:51 +00:00
|
|
|
* Autoblocks the given IP, referring to this Block.
|
|
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $autoblockIP String: the IP to autoblock.
|
2011-03-22 11:22:15 +00:00
|
|
|
* @param $justInserted Boolean: the main block was just inserted.
|
|
|
|
|
* @return mixed: block ID if an autoblock was inserted, false if not.
|
2008-09-22 04:52:51 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function doAutoblock( $autoblockIP, $justInserted = false ) {
|
2008-08-08 05:56:43 +00:00
|
|
|
# If autoblocks are disabled, go away.
|
|
|
|
|
if ( !$this->mEnableAutoblock ) {
|
2011-03-22 11:22:15 +00:00
|
|
|
return false;
|
2008-08-08 05:56:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Check for presence on the autoblock whitelist
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( Block::isWhitelistedFromAutoblocks( $autoblockIP ) ) {
|
2011-03-22 11:22:15 +00:00
|
|
|
return false;
|
2008-08-08 05:56:43 +00:00
|
|
|
}
|
2010-02-14 22:07:30 +00:00
|
|
|
|
|
|
|
|
# # Allow hooks to cancel the autoblock.
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( !wfRunHooks( 'AbortAutoblock', array( $autoblockIP, &$this ) ) ) {
|
2009-01-13 20:28:54 +00:00
|
|
|
wfDebug( "Autoblock aborted by hook.\n" );
|
2008-05-23 10:34:11 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2006-11-22 11:51:49 +00:00
|
|
|
|
|
|
|
|
# It's okay to autoblock. Go ahead and create/insert the block.
|
|
|
|
|
|
2011-03-21 23:03:11 +00:00
|
|
|
$ipblock = Block::newFromTarget( $autoblockIP );
|
2006-11-08 09:54:06 +00:00
|
|
|
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
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( $this->mExpiry &&
|
2010-05-30 14:48:30 +00:00
|
|
|
( $this->mExpiry < Block::getAutoblockExpiry( $ipblock->mTimestamp ) )
|
|
|
|
|
) {
|
2011-03-22 11:22:15 +00:00
|
|
|
return false;
|
2006-11-08 09:54:06 +00:00
|
|
|
}
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2006-11-08 09:54:06 +00:00
|
|
|
# Just update the timestamp
|
2007-03-31 17:23:10 +00:00
|
|
|
if ( !$justInserted ) {
|
|
|
|
|
$ipblock->updateTimestamp();
|
|
|
|
|
}
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2011-03-22 11:22:15 +00:00
|
|
|
return false;
|
2006-11-08 09:54:06 +00:00
|
|
|
} else {
|
|
|
|
|
$ipblock = new Block;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Make a new block object with the desired properties
|
2008-09-22 04:52:51 +00:00
|
|
|
wfDebug( "Autoblocking {$this->mAddress}@" . $autoblockIP . "\n" );
|
|
|
|
|
$ipblock->mAddress = $autoblockIP;
|
2006-11-08 09:54:06 +00:00
|
|
|
$ipblock->mUser = 0;
|
|
|
|
|
$ipblock->mBy = $this->mBy;
|
2008-06-27 09:22:12 +00:00
|
|
|
$ipblock->mByName = $this->mByName;
|
2006-11-08 09:54:06 +00:00
|
|
|
$ipblock->mReason = wfMsgForContent( 'autoblocker', $this->mAddress, $this->mReason );
|
|
|
|
|
$ipblock->mTimestamp = wfTimestampNow();
|
|
|
|
|
$ipblock->mAuto = 1;
|
2006-11-13 06:44:37 +00:00
|
|
|
$ipblock->mCreateAccount = $this->mCreateAccount;
|
2007-03-14 05:24:06 +00:00
|
|
|
# Continue suppressing the name if needed
|
|
|
|
|
$ipblock->mHideName = $this->mHideName;
|
2008-09-30 19:57:00 +00:00
|
|
|
$ipblock->mAllowUsertalk = $this->mAllowUsertalk;
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2006-11-08 09:54:06 +00:00
|
|
|
# If the user is already blocked with an expiry date, we don't
|
|
|
|
|
# want to pile on top of that!
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( $this->mExpiry ) {
|
2009-10-19 11:15:51 +00:00
|
|
|
$ipblock->mExpiry = min( $this->mExpiry, Block::getAutoblockExpiry( $this->mTimestamp ) );
|
2006-11-08 09:54:06 +00:00
|
|
|
} else {
|
|
|
|
|
$ipblock->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
|
|
|
|
|
}
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2006-11-08 09:54:06 +00:00
|
|
|
# Insert it
|
2011-03-22 11:22:15 +00:00
|
|
|
$status = $ipblock->insert();
|
|
|
|
|
return $status ? $status['id'] : false;
|
2006-11-08 09:54:06 +00:00
|
|
|
}
|
|
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Check if a block has expired. Delete it if it is.
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Boolean
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function deleteIfExpired() {
|
2009-10-19 11:15:51 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2003-09-01 13:13:56 +00:00
|
|
|
if ( $this->isExpired() ) {
|
2005-01-11 08:05:22 +00:00
|
|
|
wfDebug( "Block::deleteIfExpired() -- deleting\n" );
|
2003-09-01 13:13:56 +00:00
|
|
|
$this->delete();
|
2005-10-22 20:52:30 +00:00
|
|
|
$retVal = true;
|
2003-09-01 13:13:56 +00:00
|
|
|
} else {
|
2005-01-11 08:05:22 +00:00
|
|
|
wfDebug( "Block::deleteIfExpired() -- not expired\n" );
|
2005-10-22 20:52:30 +00:00
|
|
|
$retVal = false;
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2009-10-19 11:15:51 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2005-10-22 20:52:30 +00:00
|
|
|
return $retVal;
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Has the block expired?
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Boolean
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function isExpired() {
|
2005-01-11 08:05:22 +00:00
|
|
|
wfDebug( "Block::isExpired() checking current " . wfTimestampNow() . " vs $this->mExpiry\n" );
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2004-02-16 00:05:25 +00:00
|
|
|
if ( !$this->mExpiry ) {
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
2005-01-11 08:05:22 +00:00
|
|
|
return wfTimestampNow() > $this->mExpiry;
|
2004-02-16 00:05:25 +00:00
|
|
|
}
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Is the block address valid (i.e. not a null string?)
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Boolean
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function isValid() {
|
2004-06-08 23:56:09 +00:00
|
|
|
return $this->mAddress != '';
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
2010-02-14 22:07:30 +00:00
|
|
|
* Update the timestamp on autoblocks.
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function updateTimestamp() {
|
2004-02-27 08:25:56 +00:00
|
|
|
if ( $this->mAuto ) {
|
2004-09-07 06:20:51 +00:00
|
|
|
$this->mTimestamp = wfTimestamp();
|
2004-02-27 08:25:56 +00:00
|
|
|
$this->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
|
|
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2005-08-02 13:35:19 +00:00
|
|
|
$dbw->update( 'ipblocks',
|
|
|
|
|
array( /* SET */
|
2009-10-19 11:15:51 +00:00
|
|
|
'ipb_timestamp' => $dbw->timestamp( $this->mTimestamp ),
|
|
|
|
|
'ipb_expiry' => $dbw->timestamp( $this->mExpiry ),
|
2004-07-10 03:09:26 +00:00
|
|
|
), array( /* WHERE */
|
|
|
|
|
'ipb_address' => $this->mAddress
|
2005-08-02 13:35:19 +00:00
|
|
|
), 'Block::updateTimestamp'
|
2004-07-10 03:09:26 +00:00
|
|
|
);
|
2004-02-14 12:37:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2011-03-19 23:47:08 +00:00
|
|
|
/**
|
|
|
|
|
* Get the IP address at the start of the range in Hex form
|
|
|
|
|
* @return String IP in Hex form
|
|
|
|
|
*/
|
2011-03-20 17:43:17 +00:00
|
|
|
public function getRangeStart() {
|
|
|
|
|
switch( $this->type ) {
|
2011-03-19 23:47:08 +00:00
|
|
|
case self::TYPE_USER:
|
|
|
|
|
return null;
|
|
|
|
|
case self::TYPE_IP:
|
|
|
|
|
return IP::toHex( $this->target );
|
|
|
|
|
case self::TYPE_RANGE:
|
|
|
|
|
return $this->mRangeStart;
|
|
|
|
|
default: throw new MWException( "Block with invalid type" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the IP address at the start of the range in Hex form
|
|
|
|
|
* @return String IP in Hex form
|
|
|
|
|
*/
|
2011-03-20 17:43:17 +00:00
|
|
|
public function getRangeEnd() {
|
|
|
|
|
switch( $this->type ) {
|
2011-03-19 23:47:08 +00:00
|
|
|
case self::TYPE_USER:
|
|
|
|
|
return null;
|
|
|
|
|
case self::TYPE_IP:
|
|
|
|
|
return IP::toHex( $this->target );
|
|
|
|
|
case self::TYPE_RANGE:
|
|
|
|
|
return $this->mRangeEnd;
|
|
|
|
|
default: throw new MWException( "Block with invalid type" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-11-21 18:26:55 +00:00
|
|
|
/**
|
2008-09-21 14:22:23 +00:00
|
|
|
* Get the user id of the blocking sysop
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Integer
|
2006-11-21 18:26:55 +00:00
|
|
|
*/
|
|
|
|
|
public function getBy() {
|
|
|
|
|
return $this->mBy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2008-09-21 14:22:23 +00:00
|
|
|
* Get the username of the blocking sysop
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return String
|
2006-11-21 18:26:55 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function getByName() {
|
2005-08-23 16:52:42 +00:00
|
|
|
return $this->mByName;
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
/**
|
|
|
|
|
* Get the block ID
|
|
|
|
|
* @return int
|
|
|
|
|
*/
|
|
|
|
|
public function getId() {
|
|
|
|
|
return $this->mId;
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-22 04:52:51 +00:00
|
|
|
/**
|
|
|
|
|
* Get/set the SELECT ... FOR UPDATE flag
|
2011-03-19 17:32:59 +00:00
|
|
|
* @deprecated since 1.18
|
2008-09-22 04:52:51 +00:00
|
|
|
*/
|
2009-10-19 11:15:51 +00:00
|
|
|
public function forUpdate( $x = null ) {
|
2011-03-19 17:32:59 +00:00
|
|
|
# noop
|
2004-08-15 07:23:39 +00:00
|
|
|
}
|
|
|
|
|
|
2008-09-22 04:52:51 +00:00
|
|
|
/**
|
|
|
|
|
* Get/set a flag determining whether the master is used for reads
|
|
|
|
|
*/
|
2009-10-19 11:15:51 +00:00
|
|
|
public function fromMaster( $x = null ) {
|
2005-12-01 10:37:47 +00:00
|
|
|
return wfSetVar( $this->mFromMaster, $x );
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-19 23:47:08 +00:00
|
|
|
/**
|
|
|
|
|
* Get/set whether the Block is a hardblock (affects logged-in users on a given IP/range
|
|
|
|
|
* @param $x Bool
|
|
|
|
|
* @return Bool
|
|
|
|
|
*/
|
2011-03-20 17:43:17 +00:00
|
|
|
public function isHardblock( $x = null ) {
|
2011-03-19 23:47:08 +00:00
|
|
|
$y = $this->mAnonOnly;
|
2011-03-20 17:43:17 +00:00
|
|
|
if ( $x !== null ) {
|
2011-03-19 23:47:08 +00:00
|
|
|
$this->mAnonOnly = !$x;
|
|
|
|
|
}
|
|
|
|
|
return !$y;
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
public function isAutoblocking( $x = null ) {
|
|
|
|
|
return wfSetVar( $this->mEnableAutoblock, $x );
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-19 23:47:08 +00:00
|
|
|
/**
|
|
|
|
|
* Get/set whether the Block prevents a given action
|
|
|
|
|
* @param $action String
|
|
|
|
|
* @param $x Bool
|
|
|
|
|
* @return Bool
|
|
|
|
|
*/
|
2011-03-20 17:43:17 +00:00
|
|
|
public function prevents( $action, $x = null ) {
|
|
|
|
|
switch( $action ) {
|
2011-03-19 23:47:08 +00:00
|
|
|
case 'edit':
|
2011-03-21 19:12:41 +00:00
|
|
|
# For now... <evil laugh>
|
2011-03-19 23:47:08 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
case 'createaccount':
|
|
|
|
|
return wfSetVar( $this->mCreateAccount, $x );
|
|
|
|
|
|
|
|
|
|
case 'sendemail':
|
|
|
|
|
return wfSetVar( $this->mBlockEmail, $x );
|
|
|
|
|
|
2011-03-20 17:43:17 +00:00
|
|
|
case 'editownusertalk':
|
2011-03-19 23:47:08 +00:00
|
|
|
$y = $this->mAllowUsertalk;
|
2011-03-20 17:43:17 +00:00
|
|
|
if ( $x !== null ) {
|
2011-03-19 23:47:08 +00:00
|
|
|
$this->mAllowUsertalk = !$x;
|
|
|
|
|
}
|
|
|
|
|
return !$y;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-22 04:52:51 +00:00
|
|
|
/**
|
|
|
|
|
* Get the block name, but with autoblocked IPs hidden as per standard privacy policy
|
2011-03-13 15:14:33 +00:00
|
|
|
* @return String, text is escaped
|
2008-09-22 04:52:51 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function getRedactedName() {
|
2006-07-10 06:30:03 +00:00
|
|
|
if ( $this->mAuto ) {
|
2011-03-13 15:14:33 +00:00
|
|
|
return HTML::rawElement(
|
|
|
|
|
'span',
|
|
|
|
|
array( 'class' => 'mw-autoblockid' ),
|
|
|
|
|
wfMessage( 'autoblockid', $this->mId )
|
|
|
|
|
);
|
2006-07-10 06:30:03 +00:00
|
|
|
} else {
|
2011-03-13 15:14:33 +00:00
|
|
|
return htmlspecialchars( $this->mAddress );
|
2006-07-10 06:30:03 +00:00
|
|
|
}
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
/**
|
|
|
|
|
* Encode expiry for DB
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2010-02-14 22:07:30 +00:00
|
|
|
* @param $expiry String: timestamp for expiry, or
|
2008-09-21 14:22:23 +00:00
|
|
|
* @param $db Database object
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return String
|
2011-03-18 19:15:56 +00:00
|
|
|
* @deprecated since 1.18; use $dbw->encodeExpiry() instead
|
2006-07-10 06:30:03 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function encodeExpiry( $expiry, $db ) {
|
2011-03-18 22:28:39 +00:00
|
|
|
return $db->encodeExpiry( $expiry );
|
2006-07-10 06:30:03 +00:00
|
|
|
}
|
|
|
|
|
|
2008-04-14 07:45:50 +00:00
|
|
|
/**
|
2006-07-10 06:30:03 +00:00
|
|
|
* Decode expiry which has come from the DB
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $expiry String: Database expiry format
|
2008-09-21 14:22:23 +00:00
|
|
|
* @param $timestampType Requested timestamp format
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return String
|
2011-03-18 19:15:56 +00:00
|
|
|
* @deprecated since 1.18; use $wgLang->decodeExpiry() instead
|
2006-07-10 06:30:03 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function decodeExpiry( $expiry, $timestampType = TS_MW ) {
|
2011-03-18 19:15:56 +00:00
|
|
|
global $wgContLang;
|
|
|
|
|
return $wgContLang->formatExpiry( $expiry, $timestampType );
|
2006-07-10 06:30:03 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Get a timestamp of the expiry for autoblocks
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return String
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function getAutoblockExpiry( $timestamp ) {
|
2004-02-14 12:37:25 +00:00
|
|
|
global $wgAutoblockExpiry;
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2004-09-07 06:26:15 +00:00
|
|
|
return wfTimestamp( TS_MW, wfTimestamp( TS_UNIX, $timestamp ) + $wgAutoblockExpiry );
|
2004-02-14 12:37:25 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
|
|
|
|
/**
|
2007-03-28 05:39:06 +00:00
|
|
|
* Gets rid of uneeded numbers in quad-dotted/octet IP strings
|
2007-03-14 05:24:06 +00:00
|
|
|
* For example, 127.111.113.151/24 -> 127.111.113.0/24
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $range String: IP address to normalize
|
2008-09-21 14:22:23 +00:00
|
|
|
* @return string
|
2011-03-18 23:28:23 +00:00
|
|
|
* @deprecated since 1.18, call IP::sanitizeRange() directly
|
2007-03-14 05:24:06 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function normaliseRange( $range ) {
|
2011-03-18 23:28:23 +00:00
|
|
|
return IP::sanitizeRange( $range );
|
2007-03-12 07:01:27 +00:00
|
|
|
}
|
2003-09-07 13:56:25 +00:00
|
|
|
|
2008-04-14 07:45:50 +00:00
|
|
|
/**
|
2006-07-10 06:30:03 +00:00
|
|
|
* Purge expired blocks from the ipblocks table
|
|
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function purgeExpired() {
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2006-07-10 06:30:03 +00:00
|
|
|
$dbw->delete( 'ipblocks', array( 'ipb_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ), __METHOD__ );
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
2008-09-22 04:52:51 +00:00
|
|
|
* Get a value to insert into expiry field of the database when infinite expiry
|
2011-01-05 13:43:13 +00:00
|
|
|
* is desired
|
2011-03-18 22:28:39 +00:00
|
|
|
* @deprecated since 1.18, call $dbr->getInfinity() directly
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return String
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function infinity() {
|
2011-01-05 13:43:13 +00:00
|
|
|
return wfGetDB( DB_SLAVE )->getInfinity();
|
2006-07-10 06:30:03 +00:00
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2008-05-23 10:34:11 +00:00
|
|
|
/**
|
|
|
|
|
* Convert a DB-encoded expiry into a real string that humans can read.
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $encoded_expiry String: Database encoded expiry time
|
2009-05-22 09:35:48 +00:00
|
|
|
* @return Html-escaped String
|
2011-03-18 19:15:56 +00:00
|
|
|
* @deprecated since 1.18; use $wgLang->formatExpiry() instead
|
2008-05-23 10:34:11 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function formatExpiry( $encoded_expiry ) {
|
2011-03-18 19:15:56 +00:00
|
|
|
global $wgContLang;
|
2008-05-23 10:34:11 +00:00
|
|
|
static $msg = null;
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
if ( is_null( $msg ) ) {
|
2008-05-23 10:34:11 +00:00
|
|
|
$msg = array();
|
|
|
|
|
$keys = array( 'infiniteblock', 'expiringblock' );
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2010-02-14 22:07:30 +00:00
|
|
|
foreach ( $keys as $key ) {
|
2008-05-23 10:34:11 +00:00
|
|
|
$msg[$key] = wfMsgHtml( $key );
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2011-03-18 19:15:56 +00:00
|
|
|
$expiry = $wgContLang->formatExpiry( $encoded_expiry, TS_MW );
|
2011-03-18 22:28:39 +00:00
|
|
|
if ( $expiry == wfGetDB( DB_SLAVE )->getInfinity() ) {
|
2008-05-23 10:34:11 +00:00
|
|
|
$expirystr = $msg['infiniteblock'];
|
|
|
|
|
} else {
|
|
|
|
|
global $wgLang;
|
2009-10-19 11:15:51 +00:00
|
|
|
$expiredatestr = htmlspecialchars( $wgLang->date( $expiry, true ) );
|
|
|
|
|
$expiretimestr = htmlspecialchars( $wgLang->time( $expiry, true ) );
|
2009-05-25 18:02:58 +00:00
|
|
|
$expirystr = wfMsgReplaceArgs( $msg['expiringblock'], array( $expiredatestr, $expiretimestr ) );
|
2008-05-23 10:34:11 +00:00
|
|
|
}
|
2010-05-30 14:48:30 +00:00
|
|
|
|
2008-05-23 10:34:11 +00:00
|
|
|
return $expirystr;
|
|
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2011-03-18 16:35:22 +00:00
|
|
|
# FIXME: everything above here is a mess, needs much cleaning up
|
|
|
|
|
|
2008-05-23 10:34:11 +00:00
|
|
|
/**
|
2011-03-18 16:35:22 +00:00
|
|
|
* Convert a submitted expiry time, which may be relative ("2 weeks", etc) or absolute
|
|
|
|
|
* ("24 May 2034"), into an absolute timestamp we can put into the database.
|
|
|
|
|
* @param $expiry String: whatever was typed into the form
|
|
|
|
|
* @return String: timestamp or "infinity" string for th DB implementation
|
|
|
|
|
* @deprecated since 1.18 moved to SpecialBlock::parseExpiryInput()
|
2008-05-23 10:34:11 +00:00
|
|
|
*/
|
2011-03-18 16:35:22 +00:00
|
|
|
public static function parseExpiryInput( $expiry ) {
|
|
|
|
|
wfDeprecated( __METHOD__ );
|
|
|
|
|
return SpecialBlock::parseExpiryInput( $expiry );
|
2008-05-23 10:34:11 +00:00
|
|
|
}
|
2011-03-13 14:47:34 +00:00
|
|
|
|
|
|
|
|
/**
|
2011-03-13 21:33:52 +00:00
|
|
|
* Given a target and the target's type, get an existing Block object if possible.
|
2011-03-21 19:12:41 +00:00
|
|
|
* @param $specificTarget String|User|Int a block target, which may be one of several types:
|
2011-03-13 14:47:34 +00:00
|
|
|
* * 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
|
2011-03-21 19:12:41 +00:00
|
|
|
* * 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 $vagueTarget String|User|Int 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)
|
|
|
|
|
* @param $fromMaster Bool 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!
|
2011-03-13 14:47:34 +00:00
|
|
|
*/
|
2011-03-21 19:12:41 +00:00
|
|
|
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 );
|
2011-03-13 14:47:34 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
} elseif( in_array( $type, array( Block::TYPE_USER, Block::TYPE_IP, Block::TYPE_RANGE, null ) ) ) {
|
|
|
|
|
$block = new Block();
|
|
|
|
|
$block->fromMaster( $fromMaster );
|
2011-03-13 14:47:34 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
if( $type !== null ){
|
|
|
|
|
$block->setTarget( $target );
|
|
|
|
|
}
|
2011-03-13 14:47:34 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
if( $block->newLoad( $vagueTarget ) ){
|
|
|
|
|
return $block;
|
|
|
|
|
} else {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2011-03-13 14:47:34 +00:00
|
|
|
} else {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* From an existing Block, get the target and the type of target. Note that it is
|
|
|
|
|
* always safe to treat the target as a string; for User objects this will return
|
|
|
|
|
* User::__toString() which in turn gives User::getName().
|
|
|
|
|
* @return array( User|String, Block::TYPE_ constant )
|
|
|
|
|
*/
|
2011-03-20 17:43:17 +00:00
|
|
|
public static function parseTarget( $target ) {
|
2011-03-13 14:47:34 +00:00
|
|
|
$target = trim( $target );
|
|
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
# We may have been through this before
|
|
|
|
|
if( $target instanceof User ){
|
|
|
|
|
if( IP::isValid( $target->getName() ) ){
|
|
|
|
|
return self::TYPE_IP;
|
|
|
|
|
} else {
|
|
|
|
|
return self::TYPE_USER;
|
|
|
|
|
}
|
|
|
|
|
} elseif( $target === null ){
|
|
|
|
|
return array( null, null );
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-13 14:47:34 +00:00
|
|
|
$userObj = User::newFromName( $target );
|
2011-03-20 17:43:17 +00:00
|
|
|
if ( $userObj instanceof User ) {
|
2011-03-19 16:50:21 +00:00
|
|
|
# Note that since numbers are valid usernames, a $target of "12345" will be
|
|
|
|
|
# considered a User. If you want to pass a block ID, prepend a hash "#12345",
|
|
|
|
|
# since hash characters are not valid in usernames or titles generally.
|
2011-03-13 14:47:34 +00:00
|
|
|
return array( $userObj, Block::TYPE_USER );
|
|
|
|
|
|
2011-03-20 17:43:17 +00:00
|
|
|
} elseif ( IP::isValid( $target ) ) {
|
2011-03-13 14:47:34 +00:00
|
|
|
# We can still create a User if it's an IP address, but we need to turn
|
|
|
|
|
# off validation checking (which would exclude IP addresses)
|
|
|
|
|
return array(
|
|
|
|
|
User::newFromName( IP::sanitizeIP( $target ), false ),
|
|
|
|
|
Block::TYPE_IP
|
|
|
|
|
);
|
|
|
|
|
|
2011-03-20 17:43:17 +00:00
|
|
|
} elseif ( IP::isValidBlock( $target ) ) {
|
2011-03-13 14:47:34 +00:00
|
|
|
# Can't create a User from an IP range
|
2011-03-20 17:43:17 +00:00
|
|
|
return array( IP::sanitizeRange( $target ), Block::TYPE_RANGE );
|
2011-03-13 14:47:34 +00:00
|
|
|
|
2011-03-20 17:43:17 +00:00
|
|
|
} elseif ( preg_match( '/^#\d+$/', $target ) ) {
|
2011-03-13 14:47:34 +00:00
|
|
|
# Autoblock reference in the form "#12345"
|
|
|
|
|
return array( substr( $target, 1 ), Block::TYPE_AUTO );
|
|
|
|
|
|
2011-03-19 16:50:21 +00:00
|
|
|
} else {
|
|
|
|
|
# WTF?
|
|
|
|
|
return array( null, null );
|
2011-03-13 14:47:34 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2011-03-21 19:12:41 +00:00
|
|
|
* Get the type of target for this particular block
|
|
|
|
|
* @return Block::TYPE_ constant, will never be TYPE_ID
|
|
|
|
|
*/
|
|
|
|
|
public function getType() {
|
|
|
|
|
return $this->mAuto
|
|
|
|
|
? self::TYPE_AUTO
|
|
|
|
|
: $this->type;
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-21 23:27:08 +00:00
|
|
|
/**
|
|
|
|
|
* Get the target and target type for this particular Block. Note that for autoblocks,
|
|
|
|
|
* this returns the unredacted name; frontend functions need to call $block->getRedactedName()
|
|
|
|
|
* in this situation.
|
|
|
|
|
* @return array( User|String, Block::TYPE_ constant )
|
|
|
|
|
* FIXME: this should be an integral part of the Block member variables
|
|
|
|
|
*/
|
|
|
|
|
public function getTargetAndType() {
|
|
|
|
|
return array( $this->getTarget(), $this->getType() );
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
/**
|
|
|
|
|
* Get the target for this particular Block. Note that for autoblocks,
|
2011-03-13 15:14:33 +00:00
|
|
|
* this returns the unredacted name; frontend functions need to call $block->getRedactedName()
|
|
|
|
|
* in this situation.
|
2011-03-21 19:12:41 +00:00
|
|
|
* @return User|String
|
2011-03-13 14:47:34 +00:00
|
|
|
*/
|
2011-03-21 19:12:41 +00:00
|
|
|
public function getTarget() {
|
|
|
|
|
return $this->target;
|
|
|
|
|
}
|
2011-03-13 15:14:33 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
/**
|
|
|
|
|
* Set the target for this block, and update $this->type accordingly
|
|
|
|
|
* @param $target Mixed
|
|
|
|
|
*/
|
|
|
|
|
public function setTarget( $target ){
|
|
|
|
|
list( $this->target, $this->type ) = self::parseTarget( $target );
|
|
|
|
|
|
|
|
|
|
$this->mAddress = (string)$this->target;
|
|
|
|
|
if( $this->type == self::TYPE_USER ){
|
|
|
|
|
if( $this->target instanceof User ){
|
|
|
|
|
# Cheat
|
|
|
|
|
$this->mUser = $this->target->getID();
|
|
|
|
|
} else {
|
|
|
|
|
$this->mUser = User::idFromName( $this->target );
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$this->mUser = 0;
|
2011-03-13 15:14:33 +00:00
|
|
|
}
|
2011-03-13 14:47:34 +00:00
|
|
|
}
|
2011-03-13 21:33:52 +00:00
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
/**
|
|
|
|
|
* Get the user who implemented this block
|
|
|
|
|
* @return User
|
|
|
|
|
*/
|
|
|
|
|
public function getBlocker(){
|
|
|
|
|
return $this->blocker;
|
2011-03-13 21:33:52 +00:00
|
|
|
}
|
|
|
|
|
|
2011-03-21 19:12:41 +00:00
|
|
|
/**
|
|
|
|
|
* Set the user who implemented (or will implement) this block
|
|
|
|
|
* @param $user User
|
|
|
|
|
*/
|
|
|
|
|
public function setBlocker( User $user ){
|
|
|
|
|
$this->blocker = $user;
|
|
|
|
|
|
|
|
|
|
$this->mBy = $user->getID();
|
|
|
|
|
$this->mByName = $user->getName();
|
2011-03-13 21:33:52 +00:00
|
|
|
}
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|