* Allow blocks on anonymous users only.
* Allow or disallow account creation from blocked IP addressess on a per-block basis. * Prevent duplicate blocks. * Fixed the problem of expiry and unblocking erroneously affecting multiple blocks. * Fixed confusing lack of error message when a blocked user attempts to create an account. * Fixed inefficiency of Special:Ipblocklist in the presence of large numbers of blocks; added indexes and implemented an indexed pager.
This commit is contained in:
parent
e67cbd5a94
commit
1d9922db64
11 changed files with 549 additions and 226 deletions
|
|
@ -25,9 +25,7 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
|
|||
|
||||
== Major new features ==
|
||||
|
||||
* None!
|
||||
|
||||
|
||||
* (bug 550) Allow blocks on anonymous users only.
|
||||
|
||||
== Changes since 1.7 ==
|
||||
|
||||
|
|
@ -36,6 +34,13 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
|
|||
* (bug 6586) Regression in "unblocked" subtitle
|
||||
* Don't put empty-page message into view-source when page text is blank
|
||||
* (bug 6587) Remove redundant "allnonarticles" message
|
||||
* Block improvements: Allow blocks on anonymous users only. Optionally allow
|
||||
or disallow account creation from blocked IP addresses. Prevent duplicate
|
||||
blocks. Fixed the problem of expiry and unblocking erroneously affecting
|
||||
multiple blocks. Fixed confusing lack of error message when a blocked user
|
||||
attempts to create an account. Fixed inefficiency of Special:Ipblocklist in
|
||||
the presence of large numbers of blocks; added indexes and implemented an
|
||||
indexed pager.
|
||||
|
||||
== Languages updated ==
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
* All the functions in this class assume the object is either explicitly
|
||||
* loaded or filled. It is not load-on-demand. There are no accessors.
|
||||
*
|
||||
* To use delete(), you only need to fill $mAddress
|
||||
* Globals used: $wgAutoblockExpiry, $wgAntiLockFlags
|
||||
*
|
||||
* @todo This could be used everywhere, but it isn't.
|
||||
|
|
@ -18,7 +17,7 @@
|
|||
class Block
|
||||
{
|
||||
/* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry,
|
||||
$mRangeStart, $mRangeEnd;
|
||||
$mRangeStart, $mRangeEnd, $mAnonOnly;
|
||||
/* private */ var $mNetworkBits, $mIntegerAddr, $mForUpdate, $mFromMaster, $mByName;
|
||||
|
||||
const EB_KEEP_EXPIRED = 1;
|
||||
|
|
@ -26,19 +25,18 @@ class Block
|
|||
const EB_RANGE_ONLY = 4;
|
||||
|
||||
function Block( $address = '', $user = '', $by = 0, $reason = '',
|
||||
$timestamp = '' , $auto = 0, $expiry = '' )
|
||||
$timestamp = '' , $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0 )
|
||||
{
|
||||
$this->mId = 0;
|
||||
$this->mAddress = $address;
|
||||
$this->mUser = $user;
|
||||
$this->mBy = $by;
|
||||
$this->mReason = $reason;
|
||||
$this->mTimestamp = wfTimestamp(TS_MW,$timestamp);
|
||||
$this->mAuto = $auto;
|
||||
if( empty( $expiry ) ) {
|
||||
$this->mExpiry = $expiry;
|
||||
} else {
|
||||
$this->mExpiry = wfTimestamp( TS_MW, $expiry );
|
||||
}
|
||||
$this->mAnonOnly = $anonOnly;
|
||||
$this->mCreateAccount = $createAccount;
|
||||
$this->mExpiry = self::decodeExpiry( $expiry );
|
||||
|
||||
$this->mForUpdate = false;
|
||||
$this->mFromMaster = false;
|
||||
|
|
@ -46,19 +44,36 @@ class Block
|
|||
$this->initialiseRange();
|
||||
}
|
||||
|
||||
/*static*/ function newFromDB( $address, $user = 0, $killExpired = true )
|
||||
static function newFromDB( $address, $user = 0, $killExpired = true )
|
||||
{
|
||||
$ban = new Block();
|
||||
$ban->load( $address, $user, $killExpired );
|
||||
return $ban;
|
||||
$block = new Block();
|
||||
$block->load( $address, $user, $killExpired );
|
||||
if ( $block->isValid() ) {
|
||||
return $block;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static function newFromID( $id )
|
||||
{
|
||||
$dbr =& wfGetDB( DB_SLAVE );
|
||||
$res = $dbr->resultObject( $dbr->select( 'ipblocks', '*',
|
||||
array( 'ipb_id' => $id ), __METHOD__ ) );
|
||||
$block = new Block;
|
||||
if ( $block->loadFromResult( $res ) ) {
|
||||
return $block;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function clear()
|
||||
{
|
||||
$this->mAddress = $this->mReason = $this->mTimestamp = '';
|
||||
$this->mUser = $this->mBy = 0;
|
||||
$this->mId = $this->mAnonOnly = $this->mCreateAccount =
|
||||
$this->mAuto = $this->mUser = $this->mBy = 0;
|
||||
$this->mByName = false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -70,56 +85,80 @@ class Block
|
|||
if ( $this->mForUpdate || $this->mFromMaster ) {
|
||||
$db =& wfGetDB( DB_MASTER );
|
||||
if ( !$this->mForUpdate || ($wgAntiLockFlags & ALF_NO_BLOCK_LOCK) ) {
|
||||
$options = '';
|
||||
$options = array();
|
||||
} else {
|
||||
$options = 'FOR UPDATE';
|
||||
$options = array( 'FOR UPDATE' );
|
||||
}
|
||||
} else {
|
||||
$db =& wfGetDB( DB_SLAVE );
|
||||
$options = '';
|
||||
$options = array();
|
||||
}
|
||||
return $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a ban from the DB, with either the given address or the given username
|
||||
*
|
||||
* @param string $address The IP address of the user, or blank to skip IP blocks
|
||||
* @param integer $user The user ID, or zero for anonymous users
|
||||
* @param bool $killExpired Whether to delete expired rows while loading
|
||||
*
|
||||
*/
|
||||
function load( $address = '', $user = 0, $killExpired = true )
|
||||
{
|
||||
$fname = 'Block::load';
|
||||
wfDebug( "Block::load: '$address', '$user', $killExpired\n" );
|
||||
|
||||
$options = '';
|
||||
$options = array();
|
||||
$db =& $this->getDBOptions( $options );
|
||||
|
||||
$ret = false;
|
||||
$killed = false;
|
||||
$ipblocks = $db->tableName( 'ipblocks' );
|
||||
|
||||
if ( 0 == $user && $address == '' ) {
|
||||
# Invalid user specification, not blocked
|
||||
$this->clear();
|
||||
return false;
|
||||
} elseif ( $address == '' ) {
|
||||
$sql = "SELECT * FROM $ipblocks WHERE ipb_user={$user} $options";
|
||||
} elseif ( $user == '' ) {
|
||||
$sql = "SELECT * FROM $ipblocks WHERE ipb_address=" . $db->addQuotes( $address ) . " $options";
|
||||
} elseif ( $options == '' ) {
|
||||
# If there are no options (e.g. FOR UPDATE), use a UNION
|
||||
# so that the query can make efficient use of indices
|
||||
$sql = "SELECT * FROM $ipblocks WHERE ipb_address='" . $db->strencode( $address ) .
|
||||
"' UNION SELECT * FROM $ipblocks WHERE ipb_user={$user}";
|
||||
} else {
|
||||
# If there are options, a UNION can not be used, use one
|
||||
# SELECT instead. Will do a full table scan.
|
||||
$sql = "SELECT * FROM $ipblocks WHERE (ipb_address='" . $db->strencode( $address ) .
|
||||
"' OR ipb_user={$user}) $options";
|
||||
}
|
||||
|
||||
$res = $db->query( $sql, $fname );
|
||||
if ( 0 != $db->numRows( $res ) ) {
|
||||
# Try user block
|
||||
if ( $user ) {
|
||||
$res = $db->resultObject( $db->select( 'ipblocks', '*', array( 'ipb_user' => $user ),
|
||||
__METHOD__, $options ) );
|
||||
if ( $this->loadFromResult( $res, $killExpired ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
# Try IP block
|
||||
if ( $address ) {
|
||||
$conds = array( 'ipb_address' => $address );
|
||||
if ( $user ) {
|
||||
$conds['ipb_anon_only'] = 0;
|
||||
}
|
||||
$res = $db->resultObject( $db->select( 'ipblocks', '*', $conds, __METHOD__, $options ) );
|
||||
if ( $this->loadFromResult( $res, $killExpired ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
# Try range block
|
||||
if ( $this->loadRange( $address, $killExpired, $user == 0 ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
# Give up
|
||||
$this->clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in member variables from a result wrapper
|
||||
*/
|
||||
function loadFromResult( ResultWrapper $res, $killExpired = true ) {
|
||||
$ret = false;
|
||||
if ( 0 != $res->numRows() ) {
|
||||
# Get first block
|
||||
$row = $db->fetchObject( $res );
|
||||
$row = $res->fetchObject();
|
||||
$this->initFromRow( $row );
|
||||
|
||||
if ( $killExpired ) {
|
||||
|
|
@ -127,7 +166,7 @@ class Block
|
|||
do {
|
||||
$killed = $this->deleteIfExpired();
|
||||
if ( $killed ) {
|
||||
$row = $db->fetchObject( $res );
|
||||
$row = $res->fetchObject();
|
||||
if ( $row ) {
|
||||
$this->initFromRow( $row );
|
||||
}
|
||||
|
|
@ -135,26 +174,14 @@ class Block
|
|||
} while ( $killed && $row );
|
||||
|
||||
# If there were any left after the killing finished, return true
|
||||
if ( !$row ) {
|
||||
$ret = false;
|
||||
$this->clear();
|
||||
} else {
|
||||
if ( $row ) {
|
||||
$ret = true;
|
||||
}
|
||||
} else {
|
||||
$ret = true;
|
||||
}
|
||||
}
|
||||
$db->freeResult( $res );
|
||||
|
||||
# No blocks found yet? Try looking for range blocks
|
||||
if ( !$ret && $address != '' ) {
|
||||
$ret = $this->loadRange( $address, $killExpired );
|
||||
}
|
||||
if ( !$ret ) {
|
||||
$this->clear();
|
||||
}
|
||||
|
||||
$res->free();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
|
@ -162,10 +189,8 @@ class Block
|
|||
* Search the database for any range blocks matching the given address, and
|
||||
* load the row if one is found.
|
||||
*/
|
||||
function loadRange( $address, $killExpired = true )
|
||||
function loadRange( $address, $killExpired = true, $isAnon = true )
|
||||
{
|
||||
$fname = 'Block::loadRange';
|
||||
|
||||
$iaddr = wfIP2Hex( $address );
|
||||
if ( $iaddr === false ) {
|
||||
# Invalid address
|
||||
|
|
@ -176,27 +201,19 @@ class Block
|
|||
# Blocks should not cross a /16 boundary.
|
||||
$range = substr( $iaddr, 0, 4 );
|
||||
|
||||
$options = '';
|
||||
$options = array();
|
||||
$db =& $this->getDBOptions( $options );
|
||||
$ipblocks = $db->tableName( 'ipblocks' );
|
||||
$sql = "SELECT * FROM $ipblocks WHERE ipb_range_start LIKE '$range%' ".
|
||||
"AND ipb_range_start <= '$iaddr' AND ipb_range_end >= '$iaddr' $options";
|
||||
$res = $db->query( $sql, $fname );
|
||||
$row = $db->fetchObject( $res );
|
||||
|
||||
$success = false;
|
||||
if ( $row ) {
|
||||
# Found a row, initialise this object
|
||||
$this->initFromRow( $row );
|
||||
|
||||
# Is it expired?
|
||||
if ( !$killExpired || !$this->deleteIfExpired() ) {
|
||||
# No, return true
|
||||
$success = true;
|
||||
}
|
||||
$conds = array(
|
||||
"ipb_range_start LIKE '$range%'",
|
||||
"ipb_range_start <= '$iaddr'",
|
||||
"ipb_range_end >= '$iaddr'"
|
||||
);
|
||||
if ( !$isAnon ) {
|
||||
$conds['ipb_anon_only'] = 0;
|
||||
}
|
||||
|
||||
$db->freeResult( $res );
|
||||
$res = $db->resultObject( $db->select( 'ipblocks', '*', $conds, __METHOD__, $options ) );
|
||||
$success = $this->loadFromResult( $res, $killExpired );
|
||||
return $success;
|
||||
}
|
||||
|
||||
|
|
@ -220,10 +237,10 @@ class Block
|
|||
$this->mUser = $row->ipb_user;
|
||||
$this->mBy = $row->ipb_by;
|
||||
$this->mAuto = $row->ipb_auto;
|
||||
$this->mAnonOnly = $row->ipb_anon_only;
|
||||
$this->mCreateAccount = $row->ipb_create_account;
|
||||
$this->mId = $row->ipb_id;
|
||||
$this->mExpiry = $row->ipb_expiry ?
|
||||
wfTimestamp(TS_MW,$row->ipb_expiry) :
|
||||
$row->ipb_expiry;
|
||||
$this->mExpiry = self::decodeExpiry( $row->ipb_expiry );
|
||||
if ( isset( $row->user_name ) ) {
|
||||
$this->mByName = $row->user_name;
|
||||
} else {
|
||||
|
|
@ -304,24 +321,27 @@ class Block
|
|||
|
||||
function delete()
|
||||
{
|
||||
$fname = 'Block::delete';
|
||||
if (wfReadOnly()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if ( !$this->mId ) {
|
||||
throw new MWException( "Block::delete() now requires that the mId member be filled\n" );
|
||||
}
|
||||
$dbw =& wfGetDB( DB_MASTER );
|
||||
|
||||
if ( $this->mAddress == '' ) {
|
||||
$condition = array( 'ipb_id' => $this->mId );
|
||||
} else {
|
||||
$condition = array( 'ipb_address' => $this->mAddress );
|
||||
}
|
||||
return( $dbw->delete( 'ipblocks', $condition, $fname ) > 0 ? true : false );
|
||||
$dbw =& wfGetDB( DB_MASTER );
|
||||
$dbw->delete( 'ipblocks', array( 'ipb_id' => $this->mId ), __METHOD__ );
|
||||
return $dbw->affectedRows() > 0;
|
||||
}
|
||||
|
||||
function insert()
|
||||
{
|
||||
wfDebug( "Block::insert; timestamp {$this->mTimestamp}\n" );
|
||||
$dbw =& wfGetDB( DB_MASTER );
|
||||
$dbw->begin();
|
||||
|
||||
# Don't collide with expired blocks
|
||||
Block::purgeExpired();
|
||||
|
||||
$ipb_id = $dbw->nextSequenceValue('ipblocks_ipb_id_val');
|
||||
$dbw->insert( 'ipblocks',
|
||||
array(
|
||||
|
|
@ -332,13 +352,16 @@ class Block
|
|||
'ipb_reason' => $this->mReason,
|
||||
'ipb_timestamp' => $dbw->timestamp($this->mTimestamp),
|
||||
'ipb_auto' => $this->mAuto,
|
||||
'ipb_expiry' => $this->mExpiry ?
|
||||
$dbw->timestamp($this->mExpiry) :
|
||||
$this->mExpiry,
|
||||
'ipb_anon_only' => $this->mAnonOnly,
|
||||
'ipb_create_account' => $this->mCreateAccount,
|
||||
'ipb_expiry' => self::encodeExpiry( $this->mExpiry, $dbw ),
|
||||
'ipb_range_start' => $this->mRangeStart,
|
||||
'ipb_range_end' => $this->mRangeEnd,
|
||||
), 'Block::insert'
|
||||
), 'Block::insert', array( 'IGNORE' )
|
||||
);
|
||||
$affected = $dbw->affectedRows();
|
||||
$dbw->commit();
|
||||
return $affected;
|
||||
}
|
||||
|
||||
function deleteIfExpired()
|
||||
|
|
@ -417,13 +440,43 @@ class Block
|
|||
return wfSetVar( $this->mFromMaster, $x );
|
||||
}
|
||||
|
||||
/* static */ function getAutoblockExpiry( $timestamp )
|
||||
function getRedactedName() {
|
||||
if ( $this->mAuto ) {
|
||||
return '#' . $this->mId;
|
||||
} else {
|
||||
return $this->mAddress;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode expiry for DB
|
||||
*/
|
||||
static function encodeExpiry( $expiry, $db ) {
|
||||
if ( $expiry == '' || $expiry == Block::infinity() ) {
|
||||
return Block::infinity();
|
||||
} else {
|
||||
return $db->timestamp( $expiry );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode expiry which has come from the DB
|
||||
*/
|
||||
static function decodeExpiry( $expiry ) {
|
||||
if ( $expiry == '' || $expiry == Block::infinity() ) {
|
||||
return Block::infinity();
|
||||
} else {
|
||||
return wfTimestamp( TS_MW, $expiry );
|
||||
}
|
||||
}
|
||||
|
||||
static function getAutoblockExpiry( $timestamp )
|
||||
{
|
||||
global $wgAutoblockExpiry;
|
||||
return wfTimestamp( TS_MW, wfTimestamp( TS_UNIX, $timestamp ) + $wgAutoblockExpiry );
|
||||
}
|
||||
|
||||
/* static */ function normaliseRange( $range )
|
||||
static function normaliseRange( $range )
|
||||
{
|
||||
$parts = explode( '/', $range );
|
||||
if ( count( $parts ) == 2 ) {
|
||||
|
|
@ -436,5 +489,28 @@ class Block
|
|||
return $range;
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge expired blocks from the ipblocks table
|
||||
*/
|
||||
static function purgeExpired() {
|
||||
$dbw =& wfGetDB( DB_MASTER );
|
||||
$dbw->delete( 'ipblocks', array( 'ipb_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ), __METHOD__ );
|
||||
}
|
||||
|
||||
static function infinity() {
|
||||
# This is a special keyword for timestamps in PostgreSQL, and
|
||||
# works with CHAR(14) as well because "i" sorts after all numbers.
|
||||
return 'infinity';
|
||||
|
||||
/*
|
||||
static $infinity;
|
||||
if ( !isset( $infinity ) ) {
|
||||
$dbr =& wfGetDB( DB_SLAVE );
|
||||
$infinity = $dbr->bigTimestamp();
|
||||
}
|
||||
return $infinity;
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -46,6 +46,15 @@ class IPBlockForm {
|
|||
$this->BlockReason = $wgRequest->getText( 'wpBlockReason' );
|
||||
$this->BlockExpiry = $wgRequest->getVal( 'wpBlockExpiry', wfMsg('ipbotheroption') );
|
||||
$this->BlockOther = $wgRequest->getVal( 'wpBlockOther', '' );
|
||||
$this->BlockAnonOnly = $wgRequest->getBool( 'wpAnonOnly' );
|
||||
|
||||
# Unchecked checkboxes are not included in the form data at all, so having one
|
||||
# that is true by default is a bit tricky
|
||||
if ( $wgRequest->wasPosted() ) {
|
||||
$this->BlockCreateAccount = $wgRequest->getBool( 'wpCreateAccount', false );
|
||||
} else {
|
||||
$this->BlockCreateAccount = $wgRequest->getBool( 'wpCreateAccount', true );
|
||||
}
|
||||
}
|
||||
|
||||
function showForm( $err ) {
|
||||
|
|
@ -64,6 +73,8 @@ class IPBlockForm {
|
|||
$mIpbothertime = wfMsgHtml( 'ipbotheroption' );
|
||||
$mIpbreason = wfMsgHtml( 'ipbreason' );
|
||||
$mIpbsubmit = wfMsgHtml( 'ipbsubmit' );
|
||||
$mIpbanononly = wfMsgHtml( 'ipbanononly' );
|
||||
$mIpbcreateaccount = wfMsgHtml( 'ipbcreateaccount' );
|
||||
$titleObj = Title::makeTitle( NS_SPECIAL, 'Blockip' );
|
||||
$action = $titleObj->escapeLocalURL( "action=submit" );
|
||||
|
||||
|
|
@ -77,6 +88,8 @@ class IPBlockForm {
|
|||
$scBlockReason = htmlspecialchars( $this->BlockReason );
|
||||
$scBlockOtherTime = htmlspecialchars( $this->BlockOther );
|
||||
$scBlockExpiryOptions = htmlspecialchars( wfMsgForContent( 'ipboptions' ) );
|
||||
$anonOnlyChecked = $this->BlockAnonOnly ? 'checked' : '';
|
||||
$createAccountChecked = $this->BlockCreateAccount ? 'checked' : '';
|
||||
|
||||
$showblockoptions = $scBlockExpiryOptions != '-';
|
||||
if (!$showblockoptions)
|
||||
|
|
@ -102,7 +115,7 @@ class IPBlockForm {
|
|||
<tr>
|
||||
<td align=\"right\">{$mIpaddress}:</td>
|
||||
<td align=\"left\">
|
||||
<input tabindex='1' type='text' size='20' name=\"wpBlockAddress\" value=\"{$scBlockAddress}\" />
|
||||
<input tabindex='1' type='text' size='40' name=\"wpBlockAddress\" value=\"{$scBlockAddress}\" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>");
|
||||
|
|
@ -133,6 +146,24 @@ class IPBlockForm {
|
|||
<tr>
|
||||
<td> </td>
|
||||
<td align=\"left\">
|
||||
<label>
|
||||
<input type='checkbox' name='wpAnonOnly' value='1' $anonOnlyChecked />
|
||||
{$mIpbanononly}
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td align=\"left\">
|
||||
<label>
|
||||
<input type='checkbox' name='wpCreateAccount' value='1' $createAccountChecked />
|
||||
{$mIpbcreateaccount}
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style='padding-top: 1em'> </td>
|
||||
<td style='padding-top: 1em' align=\"left\">
|
||||
<input tabindex='4' type='submit' name=\"wpBlock\" value=\"{$mIpbsubmit}\" />
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -188,7 +219,7 @@ class IPBlockForm {
|
|||
}
|
||||
|
||||
if ( $expirestr == 'infinite' || $expirestr == 'indefinite' ) {
|
||||
$expiry = '';
|
||||
$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 );
|
||||
|
|
@ -199,20 +230,24 @@ class IPBlockForm {
|
|||
}
|
||||
|
||||
$expiry = wfTimestamp( TS_MW, $expiry );
|
||||
|
||||
}
|
||||
|
||||
# Create block
|
||||
# Note: for a user block, ipb_address is only for display purposes
|
||||
|
||||
$ban = new Block( $this->BlockAddress, $userId, $wgUser->getID(),
|
||||
$this->BlockReason, wfTimestampNow(), 0, $expiry );
|
||||
$block = new Block( $this->BlockAddress, $userId, $wgUser->getID(),
|
||||
$this->BlockReason, wfTimestampNow(), 0, $expiry, $this->BlockAnonOnly,
|
||||
$this->BlockCreateAccount );
|
||||
|
||||
if (wfRunHooks('BlockIp', array(&$ban, &$wgUser))) {
|
||||
if (wfRunHooks('BlockIp', array(&$block, &$wgUser))) {
|
||||
|
||||
$ban->insert();
|
||||
if ( !$block->insert() ) {
|
||||
$this->showForm( wfMsg( 'ipb_already_blocked',
|
||||
htmlspecialchars( $this->BlockAddress ) ) );
|
||||
return;
|
||||
}
|
||||
|
||||
wfRunHooks('BlockIpComplete', array($ban, $wgUser));
|
||||
wfRunHooks('BlockIpComplete', array($block, $wgUser));
|
||||
|
||||
# Make log entry
|
||||
$log = new LogPage( 'block' );
|
||||
|
|
|
|||
|
|
@ -12,13 +12,15 @@ function wfSpecialIpblocklist() {
|
|||
global $wgUser, $wgOut, $wgRequest;
|
||||
|
||||
$ip = $wgRequest->getVal( 'wpUnblockAddress', $wgRequest->getVal( 'ip' ) );
|
||||
$id = $wgRequest->getVal( 'id' );
|
||||
$reason = $wgRequest->getText( 'wpUnblockReason' );
|
||||
$action = $wgRequest->getText( 'action' );
|
||||
$successip = $wgRequest->getVal( 'successip' );
|
||||
|
||||
$ipu = new IPUnblockForm( $ip, $reason );
|
||||
$ipu = new IPUnblockForm( $ip, $id, $reason );
|
||||
|
||||
if ( "success" == $action ) {
|
||||
$ipu->showList( $wgOut->parse( wfMsg( 'unblocked', $ip ) ) );
|
||||
$ipu->showList( $wgOut->parse( wfMsg( 'unblocked', $successip ) ) );
|
||||
} else if ( "submit" == $action && $wgRequest->wasPosted() &&
|
||||
$wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) {
|
||||
if ( ! $wgUser->isAllowed('block') ) {
|
||||
|
|
@ -39,10 +41,11 @@ function wfSpecialIpblocklist() {
|
|||
* @subpackage SpecialPage
|
||||
*/
|
||||
class IPUnblockForm {
|
||||
var $ip, $reason;
|
||||
var $ip, $reason, $id;
|
||||
|
||||
function IPUnblockForm( $ip, $reason ) {
|
||||
function IPUnblockForm( $ip, $id, $reason ) {
|
||||
$this->ip = $ip;
|
||||
$this->id = $id;
|
||||
$this->reason = $reason;
|
||||
}
|
||||
|
||||
|
|
@ -64,13 +67,27 @@ class IPUnblockForm {
|
|||
}
|
||||
$token = htmlspecialchars( $wgUser->editToken() );
|
||||
|
||||
$addressPart = false;
|
||||
if ( $this->id ) {
|
||||
$block = Block::newFromID( $this->id );
|
||||
if ( $block ) {
|
||||
$encName = htmlspecialchars( $block->getRedactedName() );
|
||||
$encId = htmlspecialchars( $this->id );
|
||||
$addressPart = $encName . "<input type='hidden' name=\"id\" value=\"$encId\" />";
|
||||
}
|
||||
}
|
||||
if ( !$addressPart ) {
|
||||
$addressPart = "<input tabindex='1' type='text' size='20' " .
|
||||
"name=\"wpUnblockAddress\" value=\"" . htmlspecialchars( $this->ip ) . "\" />";
|
||||
}
|
||||
|
||||
$wgOut->addHTML( "
|
||||
<form id=\"unblockip\" method=\"post\" action=\"{$action}\">
|
||||
<table border='0'>
|
||||
<tr>
|
||||
<td align='right'>{$ipa}:</td>
|
||||
<td align='left'>
|
||||
<input tabindex='1' type='text' size='20' name=\"wpUnblockAddress\" value=\"" . htmlspecialchars( $this->ip ) . "\" />
|
||||
{$addressPart}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -94,27 +111,46 @@ class IPUnblockForm {
|
|||
function doSubmit() {
|
||||
global $wgOut;
|
||||
|
||||
$block = new Block();
|
||||
$this->ip = trim( $this->ip );
|
||||
|
||||
if ( $this->ip{0} == "#" ) {
|
||||
$block->mId = substr( $this->ip, 1 );
|
||||
if ( $this->id ) {
|
||||
$block = Block::newFromID( $this->id );
|
||||
if ( $block ) {
|
||||
$this->ip = $block->getRedactedName();
|
||||
}
|
||||
} else {
|
||||
$block->mAddress = $this->ip;
|
||||
$block = new Block();
|
||||
$this->ip = trim( $this->ip );
|
||||
if ( substr( $this->ip, 0, 1 ) == "#" ) {
|
||||
$id = substr( $this->ip, 1 );
|
||||
$block = Block::newFromID( $id );
|
||||
} else {
|
||||
$block = Block::newFromDB( $this->ip );
|
||||
if ( !$block ) {
|
||||
$block = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
$success = false;
|
||||
if ( $block ) {
|
||||
# Delete block
|
||||
if ( $block->delete() ) {
|
||||
# Make log entry
|
||||
$log = new LogPage( 'block' );
|
||||
$log->addEntry( 'unblock', Title::makeTitle( NS_USER, $this->ip ), $this->reason );
|
||||
$success = true;
|
||||
}
|
||||
}
|
||||
|
||||
# Delete block (if it exists)
|
||||
# We should probably check for errors rather than just declaring success
|
||||
$block->delete();
|
||||
|
||||
# Make log entry
|
||||
$log = new LogPage( 'block' );
|
||||
$log->addEntry( 'unblock', Title::makeTitle( NS_USER, $this->ip ), $this->reason );
|
||||
|
||||
# Report to the user
|
||||
$titleObj = Title::makeTitle( NS_SPECIAL, "Ipblocklist" );
|
||||
$success = $titleObj->getFullURL( "action=success&ip=" . urlencode( $this->ip ) );
|
||||
$wgOut->redirect( $success );
|
||||
if ( $success ) {
|
||||
# Report to the user
|
||||
$titleObj = Title::makeTitle( NS_SPECIAL, "Ipblocklist" );
|
||||
$success = $titleObj->getFullURL( "action=success&successip=" . urlencode( $this->ip ) );
|
||||
$wgOut->redirect( $success );
|
||||
} else {
|
||||
if ( !$this->ip && $this->id ) {
|
||||
$this->ip = '#' . $this->id;
|
||||
}
|
||||
$this->showForm( wfMsg( 'ipb_cant_unblock', htmlspecialchars( $this->id ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
function showList( $msg ) {
|
||||
|
|
@ -124,29 +160,43 @@ class IPUnblockForm {
|
|||
if ( "" != $msg ) {
|
||||
$wgOut->setSubtitle( $msg );
|
||||
}
|
||||
global $wgRequest;
|
||||
list( $this->limit, $this->offset ) = $wgRequest->getLimitOffset();
|
||||
$this->counter = 0;
|
||||
|
||||
$paging = '<p>' . wfViewPrevNext( $this->offset, $this->limit,
|
||||
Title::makeTitle( NS_SPECIAL, 'Ipblocklist' ),
|
||||
'ip=' . urlencode( $this->ip ) ) . "</p>\n";
|
||||
$wgOut->addHTML( $paging );
|
||||
|
||||
$search = $this->searchForm();
|
||||
$wgOut->addHTML( $search );
|
||||
|
||||
$wgOut->addHTML( "<ul>" );
|
||||
if( !Block::enumBlocks( array( &$this, "addRow" ), 0 ) ) {
|
||||
// FIXME hack to solve #bug 1487
|
||||
$wgOut->addHTML( '<li>'.wfMsgHtml( 'ipblocklistempty' ).'</li>' );
|
||||
// Purge expired entries on one in every 10 queries
|
||||
if ( !mt_rand( 0, 10 ) ) {
|
||||
Block::purgeExpired();
|
||||
}
|
||||
$wgOut->addHTML( "</ul>\n" );
|
||||
$wgOut->addHTML( $paging );
|
||||
|
||||
$conds = array();
|
||||
if ( $this->ip == '' ) {
|
||||
// No extra conditions
|
||||
} elseif ( substr( $this->ip, 0, 1 ) == '#' ) {
|
||||
$conds['ipb_id'] = substr( $this->ip, 1 );
|
||||
} elseif ( wfIP2Unsigned( $this->ip ) !== false ) {
|
||||
$conds['ipb_address'] = $this->ip;
|
||||
$conds['ipb_auto'] = 0;
|
||||
} else {
|
||||
$user = User::newFromName( $this->ip );
|
||||
if ( ( $id = $user->getID() ) != 0 ) {
|
||||
$conds['ipb_user'] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
$pager = new IPBlocklistPager( $this, $conds );
|
||||
$s = $pager->getNavigationBar() .
|
||||
$this->searchForm();
|
||||
if ( $pager->getNumRows() ) {
|
||||
$s .= "<ul>" .
|
||||
$pager->getBody() .
|
||||
"</ul>";
|
||||
} else {
|
||||
$s .= '<p>' . wfMsgHTML( 'ipblocklistempty' ) . '</p>';
|
||||
}
|
||||
$s .= $pager->getNavigationBar();
|
||||
$wgOut->addHTML( $s );
|
||||
}
|
||||
|
||||
function searchForm() {
|
||||
global $wgTitle;
|
||||
global $wgTitle, $wgRequest;
|
||||
return
|
||||
wfElement( 'form', array(
|
||||
'action' => $wgTitle->getLocalUrl() ),
|
||||
|
|
@ -158,7 +208,7 @@ class IPUnblockForm {
|
|||
wfElement( 'input', array(
|
||||
'type' => 'hidden',
|
||||
'name' => 'limit',
|
||||
'value' => $this->limit ) ).
|
||||
'value' => $wgRequest->getText( 'limit' ) ) ) .
|
||||
wfElement( 'input', array(
|
||||
'name' => 'ip',
|
||||
'value' => $this->ip ) ) .
|
||||
|
|
@ -171,33 +221,10 @@ class IPUnblockForm {
|
|||
/**
|
||||
* Callback function to output a block
|
||||
*/
|
||||
function addRow( $block, $tag ) {
|
||||
global $wgOut, $wgUser, $wgLang;
|
||||
function formatRow( $block ) {
|
||||
global $wgUser, $wgLang;
|
||||
|
||||
if( $this->ip != '' ) {
|
||||
if( $block->mAuto ) {
|
||||
if( stristr( $block->mId, $this->ip ) == false ) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if( stristr( $block->mAddress, $this->ip ) == false ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loading blocks is fast; displaying them is slow.
|
||||
// Quick hack for paging.
|
||||
$this->counter++;
|
||||
if( $this->counter <= $this->offset ) {
|
||||
return;
|
||||
}
|
||||
if( $this->counter - $this->offset > $this->limit ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$fname = 'IPUnblockForm-addRow';
|
||||
wfProfileIn( $fname );
|
||||
wfProfileIn( __METHOD__ );
|
||||
|
||||
static $sk=null, $msg=null;
|
||||
|
||||
|
|
@ -205,14 +232,15 @@ class IPUnblockForm {
|
|||
$sk = $wgUser->getSkin();
|
||||
if( is_null( $msg ) ) {
|
||||
$msg = array();
|
||||
foreach( array( 'infiniteblock', 'expiringblock', 'contribslink', 'unblocklink' ) as $key ) {
|
||||
$keys = array( 'infiniteblock', 'expiringblock', 'contribslink', 'unblocklink',
|
||||
'anononlyblock', 'createaccountblock' );
|
||||
foreach( $keys as $key ) {
|
||||
$msg[$key] = wfMsgHtml( $key );
|
||||
}
|
||||
$msg['blocklistline'] = wfMsg( 'blocklistline' );
|
||||
$msg['contribslink'] = wfMsg( 'contribslink' );
|
||||
}
|
||||
|
||||
|
||||
# Prepare links to the blocker's user and talk pages
|
||||
$blocker_name = $block->getByName();
|
||||
$blocker = $sk->MakeLinkObj( Title::makeTitle( NS_USER, $blocker_name ), $blocker_name );
|
||||
|
|
@ -220,35 +248,101 @@ class IPUnblockForm {
|
|||
|
||||
# Prepare links to the block target's user and contribs. pages (as applicable, don't do it for autoblocks)
|
||||
if( $block->mAuto ) {
|
||||
$target = '#' . $block->mId; # Hide the IP addresses of auto-blocks; privacy
|
||||
$target = $block->getRedactedName(); # Hide the IP addresses of auto-blocks; privacy
|
||||
} else {
|
||||
$target = $sk->makeLinkObj( Title::makeTitle( NS_USER, $block->mAddress ), $block->mAddress );
|
||||
$target .= ' (' . $sk->makeKnownLinkObj( Title::makeTitle( NS_SPECIAL, 'Contributions' ), $msg['contribslink'], 'target=' . urlencode( $block->mAddress ) ) . ')';
|
||||
}
|
||||
|
||||
# Prep the address for the unblock link, masking autoblocks as before
|
||||
$addr = $block->mAuto ? '#' . $block->mId : $block->mAddress;
|
||||
|
||||
$formattedTime = $wgLang->timeanddate( $block->mTimestamp, true );
|
||||
|
||||
if ( $block->mExpiry === "" ) {
|
||||
$formattedExpiry = $msg['infiniteblock'];
|
||||
$properties = array();
|
||||
if ( $block->mExpiry === "" || $block->mExpiry === Block::infinity() ) {
|
||||
$properties[] = $msg['infiniteblock'];
|
||||
} else {
|
||||
$formattedExpiry = wfMsgReplaceArgs( $msg['expiringblock'],
|
||||
$properties[] = wfMsgReplaceArgs( $msg['expiringblock'],
|
||||
array( $wgLang->timeanddate( $block->mExpiry, true ) ) );
|
||||
}
|
||||
if ( $block->mAnonOnly ) {
|
||||
$properties[] = $msg['anononlyblock'];
|
||||
}
|
||||
if ( $block->mCreateAccount ) {
|
||||
$properties[] = $msg['createaccountblock'];
|
||||
}
|
||||
$properties = implode( ', ', $properties );
|
||||
|
||||
$line = wfMsgReplaceArgs( $msg['blocklistline'], array( $formattedTime, $blocker, $target, $formattedExpiry ) );
|
||||
$line = wfMsgReplaceArgs( $msg['blocklistline'], array( $formattedTime, $blocker, $target, $properties ) );
|
||||
|
||||
$wgOut->addHTML( "<li>{$line}" );
|
||||
$s = "<li>{$line}";
|
||||
|
||||
if ( $wgUser->isAllowed('block') ) {
|
||||
$titleObj = Title::makeTitle( NS_SPECIAL, "Ipblocklist" );
|
||||
$wgOut->addHTML( ' (' . $sk->makeKnownLinkObj($titleObj, $msg['unblocklink'], 'action=unblock&ip=' . urlencode( $addr ) ) . ')' );
|
||||
$s .= ' (' . $sk->makeKnownLinkObj($titleObj, $msg['unblocklink'], 'action=unblock&id=' . urlencode( $block->mId ) ) . ')';
|
||||
}
|
||||
$wgOut->addHTML( $sk->commentBlock( $block->mReason ) );
|
||||
$wgOut->addHTML( "</li>\n" );
|
||||
wfProfileOut( $fname );
|
||||
$s .= $sk->commentBlock( $block->mReason );
|
||||
$s .= "</li>\n";
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $s;
|
||||
}
|
||||
}
|
||||
|
||||
class IPBlocklistPager extends ReverseChronologicalPager {
|
||||
public $mForm, $mConds;
|
||||
|
||||
function __construct( $form, $conds = array() ) {
|
||||
$this->mForm = $form;
|
||||
$this->mConds = $conds;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
function getStartBody() {
|
||||
wfProfileIn( __METHOD__ );
|
||||
# Do a link batch query
|
||||
$this->mResult->seek( 0 );
|
||||
$lb = new LinkBatch;
|
||||
|
||||
/*
|
||||
while ( $row = $this->mResult->fetchObject() ) {
|
||||
$lb->addObj( Title::makeTitleSafe( NS_USER, $row->user_name ) );
|
||||
$lb->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->user_name ) );
|
||||
$lb->addObj( Title::makeTitleSafe( NS_USER, $row->ipb_address ) );
|
||||
$lb->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->ipb_address ) );
|
||||
}*/
|
||||
# Faster way
|
||||
# Usernames and titles are in fact related by a simple substitution of space -> underscore
|
||||
# The last few lines of Title::secureAndSplit() tell the story.
|
||||
while ( $row = $this->mResult->fetchObject() ) {
|
||||
$name = str_replace( ' ', '_', $row->user_name );
|
||||
$lb->add( NS_USER, $name );
|
||||
$lb->add( NS_USER_TALK, $name );
|
||||
$name = str_replace( ' ', '_', $row->ipb_address );
|
||||
$lb->add( NS_USER, $name );
|
||||
$lb->add( NS_USER_TALK, $name );
|
||||
}
|
||||
$lb->execute();
|
||||
wfProfileOut( __METHOD__ );
|
||||
return '';
|
||||
}
|
||||
|
||||
function formatRow( $row ) {
|
||||
$block = new Block;
|
||||
$block->initFromRow( $row );
|
||||
return $this->mForm->formatRow( $block );
|
||||
}
|
||||
|
||||
function getQueryInfo() {
|
||||
$conds = $this->mConds;
|
||||
$conds[] = 'ipb_expiry>' . $this->mDb->addQuotes( $this->mDb->timestamp() );
|
||||
$conds[] = 'ipb_by=user_id';
|
||||
return array(
|
||||
'tables' => array( 'ipblocks', 'user' ),
|
||||
'fields' => 'ipblocks.*,user_name',
|
||||
'conds' => $conds,
|
||||
);
|
||||
}
|
||||
|
||||
function getIndexField() {
|
||||
return 'ipb_timestamp';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -470,6 +470,27 @@ class LoginForm {
|
|||
$wgOut->returnToMain( false );
|
||||
}
|
||||
|
||||
/** */
|
||||
function userBlockedMessage() {
|
||||
global $wgOut;
|
||||
|
||||
# Let's be nice about this, it's likely that this feature will be used
|
||||
# for blocking large numbers of innocent people, e.g. range blocks on
|
||||
# schools. Don't blame it on the user. There's a small chance that it
|
||||
# really is the user's fault, i.e. the username is blocked and they
|
||||
# haven't bothered to log out before trying to create an account to
|
||||
# evade it, but we'll leave that to their guilty conscience to figure
|
||||
# out.
|
||||
|
||||
$wgOut->setPageTitle( wfMsg( 'cantcreateaccounttitle' ) );
|
||||
$wgOut->setRobotpolicy( 'noindex,nofollow' );
|
||||
$wgOut->setArticleRelated( false );
|
||||
|
||||
$ip = wfGetIP();
|
||||
$wgOut->addWikiText( wfMsg( 'cantcreateaccounttext', $ip ) );
|
||||
$wgOut->returnToMain( false );
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
|
|
@ -477,9 +498,14 @@ class LoginForm {
|
|||
global $wgUser, $wgOut, $wgAllowRealName, $wgEnableEmail;
|
||||
global $wgCookiePrefix, $wgAuth, $wgLoginLanguageSelector;
|
||||
|
||||
if ( $this->mType == 'signup' && !$wgUser->isAllowedToCreateAccount() ) {
|
||||
$this->userNotPrivilegedMessage();
|
||||
return;
|
||||
if ( $this->mType == 'signup' ) {
|
||||
if ( !$wgUser->isAllowed( 'createaccount' ) ) {
|
||||
$this->userNotPrivilegedMessage();
|
||||
return;
|
||||
} elseif ( $wgUser->isBlockedFromCreateAccount() ) {
|
||||
$this->userBlockedMessage();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( '' == $this->mName ) {
|
||||
|
|
@ -570,7 +596,7 @@ class LoginForm {
|
|||
function showCreateOrLoginLink( &$user ) {
|
||||
if( $this->mType == 'signup' ) {
|
||||
return( true );
|
||||
} elseif( $user->isAllowedToCreateAccount() ) {
|
||||
} elseif( $user->isAllowed( 'createaccount' ) ) {
|
||||
return( true );
|
||||
} else {
|
||||
return( false );
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class User {
|
|||
*/
|
||||
var $mBlockedby; //!<
|
||||
var $mBlockreason; //!<
|
||||
var $mBlock; //!<
|
||||
var $mDataLoaded; //!<
|
||||
var $mEmail; //!<
|
||||
var $mEmailAuthenticated; //!<
|
||||
|
|
@ -114,8 +115,6 @@ class User {
|
|||
*/
|
||||
function __sleep() {
|
||||
return array(
|
||||
'mBlockedby',
|
||||
'mBlockreason',
|
||||
'mDataLoaded',
|
||||
'mEmail',
|
||||
'mEmailAuthenticated',
|
||||
|
|
@ -436,16 +435,17 @@ class User {
|
|||
$ip = wfGetIP();
|
||||
|
||||
# User/IP blocking
|
||||
$block = new Block();
|
||||
$block->fromMaster( !$bFromSlave );
|
||||
if ( $block->load( $ip , $this->mId ) ) {
|
||||
$this->mBlock = new Block();
|
||||
$this->mBlock->fromMaster( !$bFromSlave );
|
||||
if ( $this->mBlock->load( $ip , $this->mId ) ) {
|
||||
wfDebug( "$fname: Found block.\n" );
|
||||
$this->mBlockedby = $block->mBy;
|
||||
$this->mBlockreason = $block->mReason;
|
||||
$this->mBlockedby = $this->mBlock->mBy;
|
||||
$this->mBlockreason = $this->mBlock->mReason;
|
||||
if ( $this->isLoggedIn() ) {
|
||||
$this->spreadBlock();
|
||||
}
|
||||
} else {
|
||||
$this->mBlock = null;
|
||||
wfDebug( "$fname: No block.\n" );
|
||||
}
|
||||
|
||||
|
|
@ -694,6 +694,8 @@ class User {
|
|||
$user->loadFromDatabase();
|
||||
} else {
|
||||
wfDebug( "User::loadFromSession() got from cache!\n" );
|
||||
# Set block status to unloaded, that should be loaded every time
|
||||
$user->mBlockedby = -1;
|
||||
}
|
||||
|
||||
if ( isset( $_SESSION['wsToken'] ) ) {
|
||||
|
|
@ -1532,13 +1534,13 @@ class User {
|
|||
}
|
||||
|
||||
$userblock = Block::newFromDB( '', $this->mId );
|
||||
if ( !$userblock->isValid() ) {
|
||||
if ( !$userblock ) {
|
||||
return;
|
||||
}
|
||||
|
||||
# Check if this IP address is already blocked
|
||||
$ipblock = Block::newFromDB( wfGetIP() );
|
||||
if ( $ipblock->isValid() ) {
|
||||
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
|
||||
|
|
@ -1612,8 +1614,13 @@ class User {
|
|||
return $confstr;
|
||||
}
|
||||
|
||||
function isBlockedFromCreateAccount() {
|
||||
$this->getBlockedStatus();
|
||||
return $this->mBlock && $this->mBlock->mCreateAccount;
|
||||
}
|
||||
|
||||
function isAllowedToCreateAccount() {
|
||||
return $this->isAllowed( 'createaccount' ) && !$this->isBlocked();
|
||||
return $this->isAllowed( 'createaccount' ) && !$this->isBlockedFromCreateAccount();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -555,6 +555,10 @@ the text into a text file and save it for later.</strong>',
|
|||
'nocreatetitle' => 'Page creation limited',
|
||||
'nocreatetext' => 'This site has restricted the ability to create new pages.
|
||||
You can go back and edit an existing page, or [[Special:Userlogin|log in or create an account]].',
|
||||
'cantcreateaccounttitle' => 'Can\'t create account',
|
||||
'cantcreateaccounttext' => 'Account creation from this IP address (<b>$1</b>) has been blocked.
|
||||
This is probably due to persistent vandalism from your school or Internet service
|
||||
provider. ',
|
||||
|
||||
# History pages
|
||||
#
|
||||
|
|
@ -1271,6 +1275,8 @@ pages that were vandalized).",
|
|||
'ipadressorusername' => 'IP Address or username',
|
||||
'ipbexpiry' => 'Expiry',
|
||||
'ipbreason' => 'Reason',
|
||||
'ipbanononly' => 'Block anonymous users only',
|
||||
'ipbcreateaccount' => 'Prevent account creation',
|
||||
'ipbsubmit' => 'Block this user',
|
||||
'ipbother' => 'Other time',
|
||||
'ipboptions' => '2 hours:2 hours,1 day:1 day,3 days:3 days,1 week:1 week,2 weeks:2 weeks,1 month:1 month,3 months:3 months,6 months:6 months,1 year:1 year,infinite:infinite',
|
||||
|
|
@ -1288,6 +1294,8 @@ to a previously blocked IP address or username.',
|
|||
'blocklistline' => "$1, $2 blocked $3 ($4)",
|
||||
'infiniteblock' => 'infinite',
|
||||
'expiringblock' => 'expires $1',
|
||||
'anononlyblock' => 'anon. only',
|
||||
'createaccountblock' => 'account creation blocked',
|
||||
'ipblocklistempty' => 'The blocklist is empty.',
|
||||
'blocklink' => 'block',
|
||||
'unblocklink' => 'unblock',
|
||||
|
|
@ -1301,8 +1309,10 @@ the list of currently operational bans and blocks.',
|
|||
'unblocklogentry' => 'unblocked $1',
|
||||
'range_block_disabled' => 'The sysop ability to create range blocks is disabled.',
|
||||
'ipb_expiry_invalid' => 'Expiry time invalid.',
|
||||
'ipb_already_blocked' => '"$1" is already blocked',
|
||||
'ip_range_invalid' => 'Invalid IP range.',
|
||||
'proxyblocker' => 'Proxy blocker',
|
||||
'ipb_cant_unblock' => 'Error: Block ID $1 not found. It may have been unblocked already.',
|
||||
'proxyblockreason' => 'Your IP address has been blocked because it is an open proxy. Please contact your Internet service provider or tech support and inform them of this serious security problem.',
|
||||
'proxyblocksuccess' => 'Done.',
|
||||
'sorbs' => 'SORBS DNSBL',
|
||||
|
|
|
|||
43
maintenance/archives/patch-ipb_anon_only.sql
Normal file
43
maintenance/archives/patch-ipb_anon_only.sql
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
-- Add extra option fields to the ipblocks table, add some extra indexes,
|
||||
-- convert infinity values in ipb_expiry to something that sorts better,
|
||||
-- extend ipb_address and range fields, add a unique index for block conflict
|
||||
-- detection.
|
||||
|
||||
-- Conflicts in the new unique index can be handled by creating a new
|
||||
-- table and inserting into it instead of doing an ALTER TABLE.
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS /*$wgDBprefix*/ipblocks_newunique;
|
||||
|
||||
CREATE TABLE /*$wgDBprefix*/ipblocks_newunique (
|
||||
ipb_id int(8) NOT NULL auto_increment,
|
||||
ipb_address tinyblob NOT NULL default '',
|
||||
ipb_user int(8) unsigned NOT NULL default '0',
|
||||
ipb_by int(8) unsigned NOT NULL default '0',
|
||||
ipb_reason tinyblob NOT NULL default '',
|
||||
ipb_timestamp char(14) binary NOT NULL default '',
|
||||
ipb_auto boolean NOT NULL default 0,
|
||||
ipb_anon_only boolean NOT NULL default 0,
|
||||
ipb_create_account boolean NOT NULL default 1,
|
||||
ipb_expiry char(14) binary NOT NULL default '',
|
||||
ipb_range_start tinyblob NOT NULL default '',
|
||||
ipb_range_end tinyblob NOT NULL default '',
|
||||
|
||||
PRIMARY KEY ipb_id (ipb_id),
|
||||
UNIQUE INDEX ipb_address_unique (ipb_address(255), ipb_user, ipb_auto),
|
||||
INDEX ipb_user (ipb_user),
|
||||
INDEX ipb_range (ipb_range_start(8), ipb_range_end(8)),
|
||||
INDEX ipb_timestamp (ipb_timestamp),
|
||||
INDEX ipb_expiry (ipb_expiry)
|
||||
|
||||
) TYPE=InnoDB;
|
||||
|
||||
INSERT IGNORE INTO /*$wgDBprefix*/ipblocks_newunique
|
||||
(ipb_id, ipb_address, ipb_user, ipb_by, ipb_reason, ipb_timestamp, ipb_auto, ipb_expiry, ipb_range_start, ipb_range_end)
|
||||
SELECT ipb_id, ipb_address, ipb_user, ipb_by, ipb_reason, ipb_timestamp, ipb_auto, ipb_expiry, ipb_range_start, ipb_range_end
|
||||
FROM /*$wgDBprefix*/ipblocks;
|
||||
|
||||
DROP TABLE IF EXISTS /*$wgDBprefix*/ipblocks_old;
|
||||
RENAME TABLE /*$wgDBprefix*/ipblocks TO /*$wgDBprefix*/ipblocks_old;
|
||||
RENAME TABLE /*$wgDBprefix*/ipblocks_newunique TO /*$wgDBprefix*/ipblocks;
|
||||
|
||||
|
|
@ -583,8 +583,14 @@ CREATE TABLE /*$wgDBprefix*/ipblocks (
|
|||
-- Indicates that the IP address was banned because a banned
|
||||
-- user accessed a page through it. If this is 1, ipb_address
|
||||
-- will be hidden, and the block identified by block ID number.
|
||||
ipb_auto tinyint(1) NOT NULL default '0',
|
||||
ipb_auto boolean NOT NULL default '0',
|
||||
|
||||
-- If set to 1, block applies only to logged-out users
|
||||
ipb_anon_only boolean NOT NULL default 0,
|
||||
|
||||
-- Block prevents account creation from matching IP addresses
|
||||
ipb_create_account boolean NOT NULL default 1,
|
||||
|
||||
-- Time at which the block will expire.
|
||||
ipb_expiry char(14) binary NOT NULL default '',
|
||||
|
||||
|
|
@ -594,9 +600,15 @@ CREATE TABLE /*$wgDBprefix*/ipblocks (
|
|||
ipb_range_end varchar(32) NOT NULL default '',
|
||||
|
||||
PRIMARY KEY ipb_id (ipb_id),
|
||||
INDEX ipb_address (ipb_address),
|
||||
|
||||
-- Unique index to support "user already blocked" messages
|
||||
-- Any new options which prevent collisions should be included
|
||||
UNIQUE INDEX ipb_address (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only),
|
||||
|
||||
INDEX ipb_user (ipb_user),
|
||||
INDEX ipb_range (ipb_range_start(8), ipb_range_end(8))
|
||||
INDEX ipb_range (ipb_range_start(8), ipb_range_end(8)),
|
||||
INDEX ipb_timestamp (ipb_timestamp),
|
||||
INDEX ipb_expiry (ipb_expiry)
|
||||
|
||||
) TYPE=InnoDB, DEFAULT CHARSET=utf8;
|
||||
|
||||
|
|
@ -1006,4 +1018,4 @@ CREATE TABLE /*$wgDBprefix*/querycache_info (
|
|||
|
||||
UNIQUE KEY ( qci_type )
|
||||
|
||||
) TYPE=InnoDB;
|
||||
) TYPE=InnoDB;
|
||||
|
|
|
|||
|
|
@ -552,7 +552,7 @@ CREATE TABLE /*$wgDBprefix*/ipblocks (
|
|||
ipb_id int(8) NOT NULL auto_increment,
|
||||
|
||||
-- Blocked IP address in dotted-quad form or user name.
|
||||
ipb_address varchar(40) binary NOT NULL default '',
|
||||
ipb_address tinyblob NOT NULL default '',
|
||||
|
||||
-- Blocked user ID or 0 for IP blocks.
|
||||
ipb_user int(8) unsigned NOT NULL default '0',
|
||||
|
|
@ -570,20 +570,32 @@ CREATE TABLE /*$wgDBprefix*/ipblocks (
|
|||
-- Indicates that the IP address was banned because a banned
|
||||
-- user accessed a page through it. If this is 1, ipb_address
|
||||
-- will be hidden, and the block identified by block ID number.
|
||||
ipb_auto tinyint(1) NOT NULL default '0',
|
||||
ipb_auto boolean NOT NULL default 0,
|
||||
|
||||
-- If set to 1, block applies only to logged-out users
|
||||
ipb_anon_only boolean NOT NULL default 0,
|
||||
|
||||
-- Block prevents account creation from matching IP addresses
|
||||
ipb_create_account boolean NOT NULL default 1,
|
||||
|
||||
-- Time at which the block will expire.
|
||||
ipb_expiry char(14) binary NOT NULL default '',
|
||||
|
||||
-- Start and end of an address range, in hexadecimal
|
||||
-- Size chosen to allow IPv6
|
||||
ipb_range_start varchar(32) NOT NULL default '',
|
||||
ipb_range_end varchar(32) NOT NULL default '',
|
||||
ipb_range_start tinyblob NOT NULL default '',
|
||||
ipb_range_end tinyblob NOT NULL default '',
|
||||
|
||||
PRIMARY KEY ipb_id (ipb_id),
|
||||
INDEX ipb_address (ipb_address),
|
||||
|
||||
-- Unique index to support "user already blocked" messages
|
||||
-- Any new options which prevent collisions should be included
|
||||
UNIQUE INDEX ipb_address (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only),
|
||||
|
||||
INDEX ipb_user (ipb_user),
|
||||
INDEX ipb_range (ipb_range_start(8), ipb_range_end(8))
|
||||
INDEX ipb_range (ipb_range_start(8), ipb_range_end(8)),
|
||||
INDEX ipb_timestamp (ipb_timestamp),
|
||||
INDEX ipb_expiry (ipb_expiry)
|
||||
|
||||
) TYPE=InnoDB;
|
||||
|
||||
|
|
@ -913,10 +925,10 @@ CREATE TABLE /*$wgDBprefix*/objectcache (
|
|||
-- Cache of interwiki transclusion
|
||||
--
|
||||
CREATE TABLE /*$wgDBprefix*/transcache (
|
||||
tc_url VARCHAR(255) NOT NULL,
|
||||
tc_contents TEXT,
|
||||
tc_time INT NOT NULL,
|
||||
UNIQUE INDEX tc_url_idx(tc_url)
|
||||
tc_url VARCHAR(255) NOT NULL,
|
||||
tc_contents TEXT,
|
||||
tc_time INT NOT NULL,
|
||||
UNIQUE INDEX tc_url_idx(tc_url)
|
||||
) TYPE=InnoDB;
|
||||
|
||||
CREATE TABLE /*$wgDBprefix*/logging (
|
||||
|
|
@ -951,14 +963,14 @@ CREATE TABLE /*$wgDBprefix*/logging (
|
|||
) TYPE=InnoDB;
|
||||
|
||||
CREATE TABLE /*$wgDBprefix*/trackbacks (
|
||||
tb_id integer AUTO_INCREMENT PRIMARY KEY,
|
||||
tb_page integer REFERENCES page(page_id) ON DELETE CASCADE,
|
||||
tb_title varchar(255) NOT NULL,
|
||||
tb_url varchar(255) NOT NULL,
|
||||
tb_ex text,
|
||||
tb_name varchar(255),
|
||||
tb_id integer AUTO_INCREMENT PRIMARY KEY,
|
||||
tb_page integer REFERENCES page(page_id) ON DELETE CASCADE,
|
||||
tb_title varchar(255) NOT NULL,
|
||||
tb_url varchar(255) NOT NULL,
|
||||
tb_ex text,
|
||||
tb_name varchar(255),
|
||||
|
||||
INDEX (tb_page)
|
||||
INDEX (tb_page)
|
||||
) TYPE=InnoDB;
|
||||
|
||||
|
||||
|
|
@ -986,13 +998,15 @@ CREATE TABLE /*$wgDBprefix*/job (
|
|||
-- Details of updates to cached special pages
|
||||
CREATE TABLE /*$wgDBprefix*/querycache_info (
|
||||
|
||||
-- Special page name
|
||||
-- Corresponds to a qc_type value
|
||||
qci_type varchar(32) NOT NULL default '',
|
||||
-- Special page name
|
||||
-- Corresponds to a qc_type value
|
||||
qci_type varchar(32) NOT NULL default '',
|
||||
|
||||
-- Timestamp of last update
|
||||
qci_timestamp char(14) NOT NULL default '19700101000000',
|
||||
-- Timestamp of last update
|
||||
qci_timestamp char(14) NOT NULL default '19700101000000',
|
||||
|
||||
UNIQUE KEY ( qci_type )
|
||||
UNIQUE KEY ( qci_type )
|
||||
|
||||
) TYPE=InnoDB;
|
||||
|
||||
-- vim: sw=2 sts=2 et
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ $wgNewFields = array(
|
|||
array( 'interwiki', 'iw_trans', 'patch-interwiki-trans.sql' ),
|
||||
array( 'ipblocks', 'ipb_range_start', 'patch-ipb_range_start.sql' ),
|
||||
array( 'site_stats', 'ss_images', 'patch-ss_images.sql' ),
|
||||
array( 'ipblocks', 'ipb_anon_only', 'patch-ipb_anon_only.sql' ),
|
||||
);
|
||||
|
||||
function rename_table( $from, $to, $patch ) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue