Index: trunk/phase3/includes/User.php |
— | — | @@ -183,7 +183,7 @@ |
184 | 184 | /** |
185 | 185 | * \type{\bool} Whether the cache variables have been loaded. |
186 | 186 | */ |
187 | | - var $mDataLoaded; |
| 187 | + var $mDataLoaded, $mAuthLoaded; |
188 | 188 | |
189 | 189 | /** |
190 | 190 | * \type{\string} Initialization data source if mDataLoaded==false. May be one of: |
— | — | @@ -199,7 +199,8 @@ |
200 | 200 | /** @name Lazy-initialized variables, invalidated with clearInstanceCache */ |
201 | 201 | //@{ |
202 | 202 | var $mNewtalk, $mDatePreference, $mBlockedby, $mHash, $mSkin, $mRights, |
203 | | - $mBlockreason, $mBlock, $mEffectiveGroups; |
| 203 | + $mBlockreason, $mBlock, $mEffectiveGroups, $mBlockedGlobally, |
| 204 | + $mLocked, $mHideName; |
204 | 205 | //@} |
205 | 206 | |
206 | 207 | /** |
— | — | @@ -252,6 +253,23 @@ |
253 | 254 | } |
254 | 255 | wfProfileOut( __METHOD__ ); |
255 | 256 | } |
| 257 | + |
| 258 | + protected function callAuthPlugin( $fname /* $args */ ) { |
| 259 | + $args = func_get_args(); |
| 260 | + array_shift( $args ); |
| 261 | + // Load auth plugin conterpart functions for User functions |
| 262 | + if( !$this->mAuthLoaded ) { |
| 263 | + global $wgAuth; |
| 264 | + $this->mAuthCallbacks = array(); |
| 265 | + $wgAuth->setUserCallbacks( $this, $this->mAuthCallbacks ); |
| 266 | + $this->mAuthLoaded = true; |
| 267 | + } |
| 268 | + // Try to call the auth plugin version of this function |
| 269 | + if( isset($this->mAuthCallbacks[$fname]) && is_callable($this->mAuthCallbacks[$fname]) ) { |
| 270 | + return call_user_func_array( $this->mAuthCallbacks[$fname], $args ); |
| 271 | + } |
| 272 | + return NULL; |
| 273 | + } |
256 | 274 | |
257 | 275 | /** |
258 | 276 | * Load user table data, given mId has already been set. |
— | — | @@ -1295,6 +1313,59 @@ |
1296 | 1314 | $this->getBlockedStatus(); |
1297 | 1315 | return $this->mBlockreason; |
1298 | 1316 | } |
| 1317 | + |
| 1318 | + /** |
| 1319 | + * Check if user is blocked on all wikis. |
| 1320 | + * Do not use for actual edit permission checks! |
| 1321 | + * This is intented for quick UI checks. |
| 1322 | + * |
| 1323 | + * @param $ip \type{\string} IP address, uses current client if none given |
| 1324 | + * @return \type{\bool} True if blocked, false otherwise |
| 1325 | + */ |
| 1326 | + function isBlockedGlobally( $ip = '' ) { |
| 1327 | + if( $this->mBlockedGlobally !== null ) { |
| 1328 | + return $this->mBlockedGlobally; |
| 1329 | + } |
| 1330 | + // User is already an IP? |
| 1331 | + if( IP::isIPAddress( $this->getName() ) ) { |
| 1332 | + $ip = $this->getName(); |
| 1333 | + } else if( !$ip ) { |
| 1334 | + $ip = wfGetIP(); |
| 1335 | + } |
| 1336 | + $blocked = false; |
| 1337 | + wfRunHooks( 'UserIsBlockedGlobally', array( &$this, $ip, &$blocked ) ); |
| 1338 | + $this->mBlockedGlobally = (bool)$blocked; |
| 1339 | + return $this->mBlockedGlobally; |
| 1340 | + } |
| 1341 | + |
| 1342 | + /** |
| 1343 | + * Check if user account is locked |
| 1344 | + * |
| 1345 | + * @return \type{\bool} True if locked, false otherwise |
| 1346 | + */ |
| 1347 | + function isLocked() { |
| 1348 | + if( $this->mLocked !== null ) { |
| 1349 | + return $this->mLocked; |
| 1350 | + } |
| 1351 | + $this->mLocked = (bool)$this->callAuthPlugin( __FUNCTION__ ); |
| 1352 | + return $this->mLocked; |
| 1353 | + } |
| 1354 | + |
| 1355 | + /** |
| 1356 | + * Check if user account is hidden |
| 1357 | + * |
| 1358 | + * @return \type{\bool} True if hidden, false otherwise |
| 1359 | + */ |
| 1360 | + function isHidden() { |
| 1361 | + if( $this->mHideName !== null ) { |
| 1362 | + return $this->mHideName; |
| 1363 | + } |
| 1364 | + $this->getBlockedStatus(); |
| 1365 | + if( !$this->mHideName ) { |
| 1366 | + $this->mHideName = (bool)$this->callAuthPlugin( __FUNCTION__ ); |
| 1367 | + } |
| 1368 | + return $this->mHideName; |
| 1369 | + } |
1299 | 1370 | |
1300 | 1371 | /** |
1301 | 1372 | * Get the user's ID. |
Index: trunk/phase3/includes/AuthPlugin.php |
— | — | @@ -241,4 +241,11 @@ |
242 | 242 | function getCanonicalName( $username ) { |
243 | 243 | return $username; |
244 | 244 | } |
| 245 | + |
| 246 | + /** |
| 247 | + * Adds any functionality to a User object in context of the auth system |
| 248 | + */ |
| 249 | + function setUserCallbacks( $user, &$callbacks ) { |
| 250 | + return true; |
| 251 | + } |
245 | 252 | } |
Index: trunk/extensions/GlobalBlocking/GlobalBlocking.php |
— | — | @@ -27,6 +27,7 @@ |
28 | 28 | $wgExtensionMessagesFiles['GlobalBlocking'] = "$dir/GlobalBlocking.i18n.php"; |
29 | 29 | $wgExtensionAliasesFiles['GlobalBlocking'] = "$dir/GlobalBlocking.alias.php"; |
30 | 30 | $wgHooks['getUserPermissionsErrorsExpensive'][] = 'GlobalBlocking::getUserPermissionsErrors'; |
| 31 | +$wgHooks['UserIsBlockedGlobally'][] = 'GlobalBlocking::isBlockedGlobally'; |
31 | 32 | |
32 | 33 | $wgAutoloadClasses['SpecialGlobalBlock'] = "$dir/SpecialGlobalBlock.php"; |
33 | 34 | $wgSpecialPages['GlobalBlock'] = 'SpecialGlobalBlock'; |
— | — | @@ -77,20 +78,38 @@ |
78 | 79 | if ($action == 'read' || !$wgApplyGlobalBlocks) { |
79 | 80 | return true; |
80 | 81 | } |
| 82 | + $ip = wfGetIp(); |
| 83 | + $blockError = self::getUserBlockErrors( $user, $ip ); |
| 84 | + if( !empty($blockError) ) { |
| 85 | + $result[] = $blockError; |
| 86 | + return false; |
| 87 | + } |
| 88 | + return true; |
| 89 | + } |
| 90 | + |
| 91 | + static function isBlockedGlobally( &$user, $ip, &$blocked ) { |
| 92 | + $blockError = self::getUserBlockErrors( $user, $ip ); |
| 93 | + if( $blockError ) { |
| 94 | + $blocked = true; |
| 95 | + return false; |
| 96 | + } |
| 97 | + return true; |
| 98 | + } |
81 | 99 | |
| 100 | + static function getUserBlockErrors( $user, $ip ) { |
82 | 101 | $dbr = GlobalBlocking::getGlobalBlockingSlave(); |
83 | | - $ip = wfGetIp(); |
84 | 102 | |
85 | 103 | $hex_ip = IP::toHex( $ip ); |
86 | | - |
87 | 104 | $ip_pattern = substr( $hex_ip, 0, 4 ) . '%'; // Don't bother checking blocks out of this /16. |
88 | 105 | |
89 | | - $conds = array( 'gb_range_end>='.$dbr->addQuotes($hex_ip), // This block in the given range. |
90 | | - 'gb_range_start<='.$dbr->addQuotes($hex_ip), |
91 | | - 'gb_range_start like ' . $dbr->addQuotes( $ip_pattern ), |
92 | | - 'gb_expiry>'.$dbr->addQuotes($dbr->timestamp(wfTimestampNow())) ); |
| 106 | + $conds = array( |
| 107 | + 'gb_range_end>='.$dbr->addQuotes($hex_ip), // This block in the given range. |
| 108 | + 'gb_range_start<='.$dbr->addQuotes($hex_ip), |
| 109 | + 'gb_range_start like ' . $dbr->addQuotes( $ip_pattern ), |
| 110 | + 'gb_expiry>'.$dbr->addQuotes($dbr->timestamp(wfTimestampNow())) |
| 111 | + ); |
93 | 112 | |
94 | | - if (!$user->isAnon()) |
| 113 | + if ( !$user->isAnon() ) |
95 | 114 | $conds['gb_anon_only'] = 0; |
96 | 115 | |
97 | 116 | // Get the block |
— | — | @@ -99,12 +118,12 @@ |
100 | 119 | // Check for local whitelisting |
101 | 120 | if (GlobalBlocking::getWhitelistInfo( $block->gb_id ) ) { |
102 | 121 | // Block has been whitelisted. |
103 | | - return true; |
| 122 | + return array(); |
104 | 123 | } |
105 | 124 | |
106 | 125 | if ( $user->isAllowed( 'ipblock-exempt' ) ) { |
107 | 126 | // User is exempt from IP blocks. |
108 | | - return true; |
| 127 | + return array(); |
109 | 128 | } |
110 | 129 | |
111 | 130 | $expiry = Block::formatExpiry( $block->gb_expiry ); |
— | — | @@ -114,11 +133,9 @@ |
115 | 134 | $display_wiki = self::getWikiName( $block->gb_by_wiki ); |
116 | 135 | $user_display = self::maybeLinkUserpage( $block->gb_by_wiki, $block->gb_by ); |
117 | 136 | |
118 | | - $result[] = array('globalblocking-blocked', $user_display, $display_wiki, $block->gb_reason, $expiry); |
119 | | - return false; |
| 137 | + return array('globalblocking-blocked', $user_display, $display_wiki, $block->gb_reason, $expiry); |
120 | 138 | } |
121 | | - |
122 | | - return true; |
| 139 | + return array(); |
123 | 140 | } |
124 | 141 | |
125 | 142 | static function getGlobalBlockingMaster() { |
Index: trunk/extensions/CentralAuth/CentralAuthPlugin.php |
— | — | @@ -244,4 +244,10 @@ |
245 | 245 | } |
246 | 246 | } |
247 | 247 | } |
| 248 | + |
| 249 | + function setUserCallbacks( $user, &$callbacks ) { |
| 250 | + $central = CentralAuthUser::getInstance( $user ); |
| 251 | + $callbacks['isLocked'] = array( $central, 'isLocked' ); |
| 252 | + $callbacks['isHidden'] = array( $central, 'isHidden' ); |
| 253 | + } |
248 | 254 | } |
Index: trunk/extensions/CheckUser/CheckUser_body.php |
— | — | @@ -787,12 +787,16 @@ |
788 | 788 | $block->fromMaster( false ); // use slaves |
789 | 789 | $ip = IP::isIPAddress( $name ) ? // If an account, get last IP |
790 | 790 | $name : $users_infosets[$name][count($users_infosets[$name])-1][0]; |
| 791 | + # Load user object |
| 792 | + $user = User::newFromName( $name ); |
791 | 793 | if( $block->load( $ip, $users_ids[$name] ) ) { |
| 794 | + // Range blocked? |
792 | 795 | if( IP::isIPAddress($block->mAddress) && strpos($block->mAddress,'/') ) { |
793 | 796 | $userpage = Title::makeTitle( NS_USER, $block->mAddress ); |
794 | 797 | $blocklog = $this->sk->makeKnownLinkObj( $logs, wfMsgHtml('checkuser-blocked'), |
795 | 798 | 'type=block&page=' . urlencode( $userpage->getPrefixedText() ) ); |
796 | 799 | $flags[] = '<strong>(' . $blocklog . ' - ' . $block->mAddress . ')</strong>'; |
| 800 | + // Auto blocked? |
797 | 801 | } else if( $block->mAuto ) { |
798 | 802 | $blocklog = $this->sk->makeKnownLinkObj( $blocklist, |
799 | 803 | wfMsgHtml('checkuser-blocked'), 'ip=' . urlencode( "#$block->mId" ) ); |
— | — | @@ -803,23 +807,21 @@ |
804 | 808 | 'type=block&page=' . urlencode( $userpage->getPrefixedText() ) ); |
805 | 809 | $flags[] = '<strong>(' . $blocklog . ')</strong>'; |
806 | 810 | } |
| 811 | + // Blocked on all wikis? |
| 812 | + } else if( $user->isBlockedGlobally( $ip ) ) { |
| 813 | + $flags[] = '<strong>(' . wfMsgHtml('checkuser-gblocked') . ')</strong>'; |
807 | 814 | } else if( self::userWasBlocked( $name ) ) { |
808 | 815 | $userpage = Title::makeTitle( NS_USER, $name ); |
809 | 816 | $blocklog = $this->sk->makeKnownLinkObj( $logs, wfMsgHtml('checkuser-wasblocked'), |
810 | 817 | 'type=block&page=' . urlencode( $userpage->getPrefixedText() ) ); |
811 | 818 | $flags[] = '<strong>(' . $blocklog . ')</strong>'; |
812 | 819 | } |
813 | | - # Check how many accounts the user made recently? |
814 | | - if( $ip ) { |
815 | | - $key = wfMemcKey( 'acctcreate', 'ip', $ip ); |
816 | | - $count = intval( $wgMemc->get( $key ) ); |
817 | | - if( $count ) { |
818 | | - $flags[] = '<strong>[' . wfMsgExt('checkuser-accounts',array('parsemag'),$count) . ']</strong>'; |
819 | | - } |
820 | | - } |
821 | 820 | # Check for extra user rights... |
822 | 821 | if( $users_ids[$name] ) { |
823 | 822 | $user = User::newFromId( $users_ids[$name] ); |
| 823 | + if( $user->isLocked() ) { |
| 824 | + $flags[] = '<b>(' . wfMsgHtml('checkuser-locked') . ')</b>'; |
| 825 | + } |
824 | 826 | $list = array(); |
825 | 827 | foreach( $user->getGroups() as $group ) { |
826 | 828 | $list[] = self::buildGroupLink( $group ); |
— | — | @@ -829,6 +831,14 @@ |
830 | 832 | $flags[] = '<i>(' . $groups . ')</i>'; |
831 | 833 | } |
832 | 834 | } |
| 835 | + # Check how many accounts the user made recently? |
| 836 | + if( $ip ) { |
| 837 | + $key = wfMemcKey( 'acctcreate', 'ip', $ip ); |
| 838 | + $count = intval( $wgMemc->get( $key ) ); |
| 839 | + if( $count ) { |
| 840 | + $flags[] = '<strong>[' . wfMsgExt('checkuser-accounts',array('parsemag'),$count) . ']</strong>'; |
| 841 | + } |
| 842 | + } |
833 | 843 | $s .= implode(' ',$flags); |
834 | 844 | $s .= '<ol>'; |
835 | 845 | # List out each IP/XFF combo for this username |
Index: trunk/extensions/CheckUser/CheckUser.i18n.php |
— | — | @@ -41,6 +41,8 @@ |
42 | 42 | 'checkuser-log-fail' => 'Unable to add log entry', |
43 | 43 | 'checkuser-nolog' => 'No log file found.', |
44 | 44 | 'checkuser-blocked' => 'Blocked', |
| 45 | + 'checkuser-gblocked' => 'Blocked globally', |
| 46 | + 'checkuser-locked' => 'Locked', |
45 | 47 | 'checkuser-wasblocked' => 'Previously blocked', |
46 | 48 | 'checkuser-massblock' => 'Block selected users', |
47 | 49 | 'checkuser-massblock-text' => 'Selected accounts will be blocked indefinitely, with autoblocking enabled and account creation disabled. |