Index: trunk/phase3/includes/User.php |
— | — | @@ -1157,7 +1157,7 @@ |
1158 | 1158 | $this->mBlockedby = $this->mBlock->mByName; |
1159 | 1159 | $this->mBlockreason = $this->mBlock->mReason; |
1160 | 1160 | $this->mHideName = $this->mBlock->mHideName; |
1161 | | - $this->mAllowUsertalk = $this->mBlock->mAllowUsertalk; |
| 1161 | + $this->mAllowUsertalk = !$this->mBlock->prevents( 'editusertalk' ); |
1162 | 1162 | if ( $this->isLoggedIn() && $wgUser->getID() == $this->getID() ) { |
1163 | 1163 | $this->spreadBlock(); |
1164 | 1164 | } |
— | — | @@ -2801,7 +2801,7 @@ |
2802 | 2802 | */ |
2803 | 2803 | function isBlockedFromCreateAccount() { |
2804 | 2804 | $this->getBlockedStatus(); |
2805 | | - return $this->mBlock && $this->mBlock->mCreateAccount; |
| 2805 | + return $this->mBlock && $this->mBlock->prevents( 'createaccount' ); |
2806 | 2806 | } |
2807 | 2807 | |
2808 | 2808 | /** |
— | — | @@ -2810,7 +2810,7 @@ |
2811 | 2811 | */ |
2812 | 2812 | function isBlockedFromEmailuser() { |
2813 | 2813 | $this->getBlockedStatus(); |
2814 | | - return $this->mBlock && $this->mBlock->mBlockEmail; |
| 2814 | + return $this->mBlock && $this->mBlock->prevents( 'sendemail' ); |
2815 | 2815 | } |
2816 | 2816 | |
2817 | 2817 | /** |
Index: trunk/phase3/includes/specials/SpecialBlockList.php |
— | — | @@ -90,26 +90,6 @@ |
91 | 91 | $this->showList(); |
92 | 92 | } |
93 | 93 | |
94 | | - /** |
95 | | - * Get the component of an IP address which is certain to be the same between an IP |
96 | | - * address and a rangeblock containing that IP address. |
97 | | - * @todo: should be in IP.php?? |
98 | | - * @param $ip String |
99 | | - * @return String |
100 | | - */ |
101 | | - protected static function getIpFragment( $ip ){ |
102 | | - global $wgBlockCIDRLimit; |
103 | | - if( IP::isIPv4( $ip ) ){ |
104 | | - $hexAddress = IP::toHex( $ip ); |
105 | | - return substr( $hexAddress, 0, wfBaseconvert( $wgBlockCIDRLimit['IPv4'], 10, 16 ) ); |
106 | | - } elseif( IP::isIPv6( $ip ) ) { |
107 | | - $hexAddress = substr( IP::toHex( $ip ), 2 ); |
108 | | - return 'v6-' . substr( $hexAddress, 0, wfBaseconvert( $wgBlockCIDRLimit['IPv6'], 10, 16 ) ); |
109 | | - } else { |
110 | | - return null; |
111 | | - } |
112 | | - } |
113 | | - |
114 | 94 | function showList() { |
115 | 95 | global $wgOut, $wgUser; |
116 | 96 | |
— | — | @@ -133,25 +113,16 @@ |
134 | 114 | break; |
135 | 115 | |
136 | 116 | case Block::TYPE_IP: |
137 | | - case BLock::TYPE_RANGE: |
| 117 | + case Block::TYPE_RANGE: |
138 | 118 | list( $start, $end ) = IP::parseRange( $target ); |
139 | | - # Per bug 14634, we want to include relevant active rangeblocks; for |
140 | | - # rangeblocks, we want to include larger ranges which enclose the given |
141 | | - # range. We know that all blocks must be smaller than $wgBlockCIDRLimit, |
142 | | - # so we can improve performance by filtering on a LIKE clause |
143 | | - $chunk = self::getIpFragment( $start ); |
144 | 119 | $dbr = wfGetDB( DB_SLAVE ); |
145 | | - $like = $dbr->buildLike( $chunk, $dbr->anyString() ); |
146 | | - |
147 | | - # Fairly hard to make a malicious SQL statement out of hex characters, |
148 | | - # but stranger things have happened... |
149 | | - $safeStart = $dbr->addQuotes( IP::toHex( $start ) ); |
150 | | - $safeEnd = $dbr->addQuotes( IP::toHex( $end ) ); |
151 | | - $safeTarget = $dbr->addQuotes( IP::toHex( $target ) ); |
152 | | - |
153 | | - # TODO: abstract this away |
154 | | - $conds[] = "(ipb_address = $safeTarget) OR |
155 | | - (ipb_range_start $like AND ipb_range_start <= $safeStart AND ipb_range_end >= $safeEnd)"; |
| 120 | + $conds[] = $dbr->makeList( |
| 121 | + array( |
| 122 | + 'ipb_address' => $target, |
| 123 | + Block::getRangeCond( $start, $end ) |
| 124 | + ), |
| 125 | + LIST_OR |
| 126 | + ); |
156 | 127 | $conds['ipb_auto'] = 0; |
157 | 128 | break; |
158 | 129 | |
Index: trunk/phase3/includes/specials/SpecialBlock.php |
— | — | @@ -208,17 +208,17 @@ |
209 | 209 | || $block->mAddress == $this->target ) # or if it is, the range is what we're about to block |
210 | 210 | ) |
211 | 211 | { |
212 | | - $fields['HardBlock']['default'] = !$block->mAnonOnly; |
213 | | - $fields['CreateAccount']['default'] = $block->mCreateAccount; |
| 212 | + $fields['HardBlock']['default'] = $block->isHardblock(); |
| 213 | + $fields['CreateAccount']['default'] = $block->prevents( 'createaccount' ); |
214 | 214 | $fields['AutoBlock']['default'] = $block->mEnableAutoblock; |
215 | 215 | if( isset( $fields['DisableEmail'] ) ){ |
216 | | - $fields['DisableEmail']['default'] = $block->mBlockEmail; |
| 216 | + $fields['DisableEmail']['default'] = $block->prevents( 'sendemail' ); |
217 | 217 | } |
218 | 218 | if( isset( $fields['HideUser'] ) ){ |
219 | 219 | $fields['HideUser']['default'] = $block->mHideName; |
220 | 220 | } |
221 | 221 | if( isset( $fields['DisableUTEdit'] ) ){ |
222 | | - $fields['DisableUTEdit']['default'] = !$block->mAllowUsertalk; |
| 222 | + $fields['DisableUTEdit']['default'] = $block->prevents( 'editusertalk' ); |
223 | 223 | } |
224 | 224 | $fields['Reason']['default'] = $block->mReason; |
225 | 225 | $fields['AlreadyBlocked']['default'] = true; |
— | — | @@ -502,10 +502,6 @@ |
503 | 503 | return array( 'ipb_expiry_invalid' ); |
504 | 504 | } |
505 | 505 | |
506 | | - if( !$wgBlockAllowsUTEdit ){ |
507 | | - $data['DisableUTEdit'] = true; |
508 | | - } |
509 | | - |
510 | 506 | # If the user has done the form 'properly', they won't even have been given the |
511 | 507 | # option to suppress-block unless they have the 'hideuser' permission |
512 | 508 | if( !isset( $data['HideUser'] ) ){ |
— | — | @@ -548,10 +544,11 @@ |
549 | 545 | !$data['HardBlock'], # Block anon only |
550 | 546 | $data['CreateAccount'], |
551 | 547 | $data['AutoBlock'], |
552 | | - $data['HideUser'], |
553 | | - $data['DisableEmail'], |
554 | | - !$data['DisableUTEdit'] # *Allow* UTEdit |
| 548 | + $data['HideUser'] |
555 | 549 | ); |
| 550 | + |
| 551 | + $block->prevents( 'editusertalk', ( !$wgBlockAllowsUTEdit || $data['DisableUTEdit'] ) ); |
| 552 | + $block->prevents( 'sendemail', $data['DisableEmail'] ); |
556 | 553 | |
557 | 554 | if( !wfRunHooks( 'BlockIp', array( &$block, &$wgUser ) ) ) { |
558 | 555 | return array( 'hookaborted' ); |
— | — | @@ -569,7 +566,7 @@ |
570 | 567 | |
571 | 568 | # This returns direct blocks before autoblocks/rangeblocks, since we should |
572 | 569 | # be sure the user is blocked by now it should work for our purposes |
573 | | - $currentBlock = Block::newFromDB( $target, $userId ); |
| 570 | + $currentBlock = Block::newFromTargetAndType( $target, $type ); |
574 | 571 | |
575 | 572 | if( $block->equals( $currentBlock ) ) { |
576 | 573 | return array( 'ipb_already_blocked' ); |
— | — | @@ -613,7 +610,7 @@ |
614 | 611 | } |
615 | 612 | |
616 | 613 | # Block constructor sanitizes certain block options on insert |
617 | | - $data['BlockEmail'] = $block->mBlockEmail; |
| 614 | + $data['BlockEmail'] = $block->prevents( 'sendemail' ); |
618 | 615 | $data['AutoBlock'] = $block->mEnableAutoblock; |
619 | 616 | |
620 | 617 | # Prepare log parameters |
Index: trunk/phase3/includes/Block.php |
— | — | @@ -16,10 +16,18 @@ |
17 | 17 | */ |
18 | 18 | class Block { |
19 | 19 | /* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry, |
20 | | - $mRangeStart, $mRangeEnd, $mAnonOnly, $mEnableAutoblock, $mHideName, |
21 | | - $mBlockEmail, $mByName, $mAngryAutoblock, $mAllowUsertalk; |
22 | | - private $mFromMaster; |
| 20 | + $mEnableAutoblock, $mHideName, |
| 21 | + $mByName, $mAngryAutoblock; |
| 22 | + private |
| 23 | + $mFromMaster, |
| 24 | + $mRangeStart, |
| 25 | + $mRangeEnd, |
| 26 | + $mAnonOnly, |
| 27 | + $mBlockEmail, |
| 28 | + $mAllowUsertalk, |
| 29 | + $mCreateAccount; |
23 | 30 | |
| 31 | + /// TYPE constants |
24 | 32 | const TYPE_USER = 1; |
25 | 33 | const TYPE_IP = 2; |
26 | 34 | const TYPE_RANGE = 3; |
— | — | @@ -227,6 +235,54 @@ |
228 | 236 | } |
229 | 237 | |
230 | 238 | /** |
| 239 | + * Get a set of SQL conditions which will select rangeblocks encompasing a given range |
| 240 | + * @param $start String Hexadecimal IP representation |
| 241 | + * @param $end String Hexadecimal IP represenation, or null to use $start = $end |
| 242 | + * @return String |
| 243 | + */ |
| 244 | + public static function getRangeCond( $start, $end = null ){ |
| 245 | + if( $end === null ){ |
| 246 | + $end = $start; |
| 247 | + } |
| 248 | + # Per bug 14634, we want to include relevant active rangeblocks; for |
| 249 | + # rangeblocks, we want to include larger ranges which enclose the given |
| 250 | + # range. We know that all blocks must be smaller than $wgBlockCIDRLimit, |
| 251 | + # so we can improve performance by filtering on a LIKE clause |
| 252 | + $chunk = self::getIpFragment( $start ); |
| 253 | + $dbr = wfGetDB( DB_SLAVE ); |
| 254 | + $like = $dbr->buildLike( $chunk, $dbr->anyString() ); |
| 255 | + |
| 256 | + # Fairly hard to make a malicious SQL statement out of hex characters, |
| 257 | + # but stranger things have happened... |
| 258 | + $safeStart = $dbr->addQuotes( $start ); |
| 259 | + $safeEnd = $dbr->addQuotes( $end ); |
| 260 | + |
| 261 | + return $dbr->makeList( |
| 262 | + array( |
| 263 | + "ipb_range_start $like", |
| 264 | + "ipb_range_start <= $safeStart", |
| 265 | + "ipb_range_end >= $safeEnd", |
| 266 | + ), |
| 267 | + LIST_AND |
| 268 | + ); |
| 269 | + } |
| 270 | + |
| 271 | + /** |
| 272 | + * Get the component of an IP address which is certain to be the same between an IP |
| 273 | + * address and a rangeblock containing that IP address. |
| 274 | + * @param $hex String Hexadecimal IP representation |
| 275 | + * @return String |
| 276 | + */ |
| 277 | + protected static function getIpFragment( $hex ){ |
| 278 | + global $wgBlockCIDRLimit; |
| 279 | + if( substr( $hex, 0, 3 ) == 'v6-' ){ |
| 280 | + return 'v6-' . substr( substr( $hex, 3 ), 0, floor( $wgBlockCIDRLimit['IPv6'] / 4 ) ); |
| 281 | + } else { |
| 282 | + return substr( $hex, 0, floor( $wgBlockCIDRLimit['IPv4'] / 4 ) ); |
| 283 | + } |
| 284 | + } |
| 285 | + |
| 286 | + /** |
231 | 287 | * Fill in member variables from a result wrapper |
232 | 288 | * |
233 | 289 | * @param $res ResultWrapper: row from the ipblocks table |
— | — | @@ -707,6 +763,38 @@ |
708 | 764 | } |
709 | 765 | |
710 | 766 | /** |
| 767 | + * Get the IP address at the start of the range in Hex form |
| 768 | + * @return String IP in Hex form |
| 769 | + */ |
| 770 | + public function getRangeStart(){ |
| 771 | + switch( $this->type ){ |
| 772 | + case self::TYPE_USER: |
| 773 | + return null; |
| 774 | + case self::TYPE_IP: |
| 775 | + return IP::toHex( $this->target ); |
| 776 | + case self::TYPE_RANGE: |
| 777 | + return $this->mRangeStart; |
| 778 | + default: throw new MWException( "Block with invalid type" ); |
| 779 | + } |
| 780 | + } |
| 781 | + |
| 782 | + /** |
| 783 | + * Get the IP address at the start of the range in Hex form |
| 784 | + * @return String IP in Hex form |
| 785 | + */ |
| 786 | + public function getRangeEnd(){ |
| 787 | + switch( $this->type ){ |
| 788 | + case self::TYPE_USER: |
| 789 | + return null; |
| 790 | + case self::TYPE_IP: |
| 791 | + return IP::toHex( $this->target ); |
| 792 | + case self::TYPE_RANGE: |
| 793 | + return $this->mRangeEnd; |
| 794 | + default: throw new MWException( "Block with invalid type" ); |
| 795 | + } |
| 796 | + } |
| 797 | + |
| 798 | + /** |
711 | 799 | * Get the user id of the blocking sysop |
712 | 800 | * |
713 | 801 | * @return Integer |
— | — | @@ -740,6 +828,49 @@ |
741 | 829 | } |
742 | 830 | |
743 | 831 | /** |
| 832 | + * Get/set whether the Block is a hardblock (affects logged-in users on a given IP/range |
| 833 | + * @param $x Bool |
| 834 | + * @return Bool |
| 835 | + */ |
| 836 | + public function isHardblock( $x = null ){ |
| 837 | + $y = $this->mAnonOnly; |
| 838 | + if( $x !== null){ |
| 839 | + $this->mAnonOnly = !$x; |
| 840 | + } |
| 841 | + return !$y; |
| 842 | + } |
| 843 | + |
| 844 | + /** |
| 845 | + * Get/set whether the Block prevents a given action |
| 846 | + * @param $action String |
| 847 | + * @param $x Bool |
| 848 | + * @return Bool |
| 849 | + */ |
| 850 | + public function prevents( $action, $x = null ){ |
| 851 | + switch( $action ){ |
| 852 | + case 'edit': |
| 853 | + # TODO Not actually quite this simple (bug 13611 etc) |
| 854 | + return true; |
| 855 | + |
| 856 | + case 'createaccount': |
| 857 | + return wfSetVar( $this->mCreateAccount, $x ); |
| 858 | + |
| 859 | + case 'sendemail': |
| 860 | + return wfSetVar( $this->mBlockEmail, $x ); |
| 861 | + |
| 862 | + case 'editusertalk': |
| 863 | + $y = $this->mAllowUsertalk; |
| 864 | + if( $x !== null){ |
| 865 | + $this->mAllowUsertalk = !$x; |
| 866 | + } |
| 867 | + return !$y; |
| 868 | + |
| 869 | + default: |
| 870 | + return null; |
| 871 | + } |
| 872 | + } |
| 873 | + |
| 874 | + /** |
744 | 875 | * Get the block name, but with autoblocked IPs hidden as per standard privacy policy |
745 | 876 | * @return String, text is escaped |
746 | 877 | */ |
Index: trunk/extensions/AbuseFilter/Views/AbuseFilterViewRevert.php |
— | — | @@ -188,7 +188,7 @@ |
189 | 189 | function revertAction( $action, $result ) { |
190 | 190 | switch( $action ) { |
191 | 191 | case 'block': |
192 | | - $block = Block::newFromDB( '', $result['userid'], false ); |
| 192 | + $block = Block::newFromTarget( User::whoIs( $result['userid'] ) ); |
193 | 193 | if ( !$block || $block->getBy() != AbuseFilter::getFilterUser()->getId() ) { |
194 | 194 | return false; // Not blocked by abuse filter. |
195 | 195 | } |
Index: trunk/extensions/AbuseFilter/AbuseFilter.class.php |
— | — | @@ -1013,8 +1013,8 @@ |
1014 | 1014 | $block->mByName = $filterUser->getName(); |
1015 | 1015 | $block->mReason = wfMsgForContent( 'abusefilter-blockreason', $rule_desc ); |
1016 | 1016 | $block->mTimestamp = wfTimestampNow(); |
1017 | | - $block->mAnonOnly = 1; |
1018 | | - $block->mCreateAccount = 1; |
| 1017 | + $block->isHardblock( false ); |
| 1018 | + $block->prevents( 'createaccount', true ); |
1019 | 1019 | $block->mExpiry = SpecialBlock::parseExpiryInput( $wgAbuseFilterBlockDuration ); |
1020 | 1020 | |
1021 | 1021 | $block->insert(); |
— | — | @@ -1042,11 +1042,7 @@ |
1043 | 1043 | case 'rangeblock': |
1044 | 1044 | $filterUser = AbuseFilter::getFilterUser(); |
1045 | 1045 | |
1046 | | - $range = IP::toHex( wfGetIP() ); |
1047 | | - $range = substr( $range, 0, 4 ) . '0000'; |
1048 | | - $range = long2ip( hexdec( $range ) ); |
1049 | | - $range .= '/16'; |
1050 | | - $range = Block::normaliseRange( $range ); |
| 1046 | + $range = IP::sanitizeRange( wfGetIP() . '/16' ); |
1051 | 1047 | |
1052 | 1048 | // Create a block. |
1053 | 1049 | $block = new Block; |
— | — | @@ -1056,8 +1052,8 @@ |
1057 | 1053 | $block->mByName = $filterUser->getName(); |
1058 | 1054 | $block->mReason = wfMsgForContent( 'abusefilter-blockreason', $rule_desc ); |
1059 | 1055 | $block->mTimestamp = wfTimestampNow(); |
1060 | | - $block->mAnonOnly = 0; |
1061 | | - $block->mCreateAccount = 1; |
| 1056 | + $block->isHardblock( false ); |
| 1057 | + $block->prevents( 'createaccount', true ); |
1062 | 1058 | $block->mExpiry = SpecialBlock::parseExpiryInput( '1 week' ); |
1063 | 1059 | |
1064 | 1060 | $block->insert(); |
Index: trunk/extensions/regexBlock/regexBlockCore.php |
— | — | @@ -573,7 +573,7 @@ |
574 | 574 | /* account creation check goes through the same hook... */ |
575 | 575 | if ( $valid['create'] == 1 ) { |
576 | 576 | if ( $user->mBlock ) { |
577 | | - $user->mBlock->mCreateAccount = 1; |
| 577 | + $user->mBlock->prevents( 'createaccount', true ); |
578 | 578 | } |
579 | 579 | } |
580 | 580 | /* set expiry information */ |