* Create a new user object using data from session or cookies. If the
* login credentials are invalid, the result is an anonymous user.
*
- * @param $request WebRequest object to use; $wgRequest will be used if
- * ommited.
+ * @param $request WebRequest object to use; $wgRequest will be used if omitted.
* @return User object
*/
public static function newFromSession( WebRequest $request = null ) {
* Is the input a valid username?
*
* Checks if the input is a valid username, we don't want an empty string,
- * an IP address, anything that containins slashes (would mess up subpages),
+ * an IP address, anything that contains slashes (would mess up subpages),
* is longer than the maximum allowed username size or doesn't begin with
* a capital letter.
*
return 'passwordtooshort';
} elseif ( $wgContLang->lc( $password ) == $wgContLang->lc( $this->mName ) ) {
return 'password-name-match';
- } elseif ( isset( $blockedLogins[ $this->getName() ] ) && $password == $blockedLogins[ $this->getName() ] ) {
+ } elseif ( isset( $blockedLogins[$this->getName()] ) && $password == $blockedLogins[$this->getName()] ) {
return 'password-login-forbidden';
} else {
//it seems weird returning true here, but this is because of the
* @return Bool True if the user is logged in, false otherwise.
*/
private function loadFromSession() {
- global $wgExternalAuthType, $wgAutocreatePolicy;
-
$result = null;
wfRunHooks( 'UserLoadFromSession', array( $this, &$result ) );
if ( $result !== null ) {
return $result;
}
- if ( $wgExternalAuthType && $wgAutocreatePolicy == 'view' ) {
- $extUser = ExternalUser::newFromCookie();
- if ( $extUser ) {
- # TODO: Automatically create the user here (or probably a bit
- # lower down, in fact)
- }
- }
-
$request = $this->getRequest();
$cookieId = $request->getCookie( 'UserID' );
* done against master.
*/
private function getBlockedStatus( $bFromSlave = true ) {
- global $wgProxyWhitelist, $wgUser;
+ global $wgProxyWhitelist, $wgUser, $wgApplyIpBlocksToXff;
if ( -1 != $this->mBlockedby ) {
return;
}
}
+ # (bug 23343) Apply IP blocks to the contents of XFF headers, if enabled
+ if ( !$block instanceof Block
+ && $wgApplyIpBlocksToXff
+ && $ip !== null
+ && !$this->isAllowed( 'proxyunbannable' )
+ && !in_array( $ip, $wgProxyWhitelist )
+ ) {
+ $xff = $this->getRequest()->getHeader( 'X-Forwarded-For' );
+ $xff = array_map( 'trim', explode( ',', $xff ) );
+ $xff = array_diff( $xff, array( $ip ) );
+ $xffblocks = Block::getBlocksForIPList( $xff, $this->isAnon(), !$bFromSlave );
+ $block = Block::chooseBlock( $xffblocks, $xff );
+ if ( $block instanceof Block ) {
+ # Mangle the reason to alert the user that the block
+ # originated from matching the X-Forwarded-For header.
+ $block->mReason = wfMessage( 'xffblockreason', $block->mReason )->text();
+ }
+ }
+
if ( $block instanceof Block ) {
wfDebug( __METHOD__ . ": Found block.\n" );
$this->mBlock = $block;
$this->mAllowUsertalk = false;
}
- # Extensions
+ // Extensions
wfRunHooks( 'GetBlockedStatus', array( &$this ) );
wfProfileOut( __METHOD__ );
// Set the user limit key
if ( $userLimit !== false ) {
wfDebug( __METHOD__ . ": effective user limit: $userLimit\n" );
- $keys[ wfMemcKey( 'limiter', $action, 'user', $id ) ] = $userLimit;
+ $keys[wfMemcKey( 'limiter', $action, 'user', $id )] = $userLimit;
}
$triggered = false;
/**
* Check if user is blocked on all wikis.
* Do not use for actual edit permission checks!
- * This is intented for quick UI checks.
+ * This is intended for quick UI checks.
*
* @param string $ip IP address, uses current client if none given
* @return Bool True if blocked, false otherwise
* address for an anonymous user to something other than the current
* remote IP.
*
- * @note User::newFromName() has rougly the same function, when the named user
+ * @note User::newFromName() has roughly the same function, when the named user
* does not exist.
* @param string $str New user name to set
*/
* for reload on the next hit.
*/
public function invalidateCache() {
- if( wfReadOnly() ) {
+ if ( wfReadOnly() ) {
return;
}
$this->load();
- if( $this->mId ) {
+ if ( $this->mId ) {
$this->mTouched = self::newTouchedTimestamp();
$dbw = wfGetDB( DB_MASTER );
-
- // Prevent contention slams by checking user_touched first
- $now = $dbw->timestamp( $this->mTouched );
- $needsPurge = $dbw->selectField( 'user', '1',
- array( 'user_id' => $this->mId, 'user_touched < ' . $dbw->addQuotes( $now ) )
- );
- if ( $needsPurge ) {
- $dbw->update( 'user',
- array( 'user_touched' => $now ),
- array( 'user_id' => $this->mId, 'user_touched < ' . $dbw->addQuotes( $now ) ),
- __METHOD__
- );
- }
-
+ $userid = $this->mId;
+ $touched = $this->mTouched;
+ $dbw->onTransactionIdle( function() use ( $dbw, $userid, $touched ) {
+ // Prevent contention slams by checking user_touched first
+ $encTouched = $dbw->addQuotes( $dbw->timestamp( $touched ) );
+ $needsPurge = $dbw->selectField( 'user', '1',
+ array( 'user_id' => $userid, 'user_touched < ' . $encTouched ) );
+ if ( $needsPurge ) {
+ $dbw->update( 'user',
+ array( 'user_touched' => $dbw->timestamp( $touched ) ),
+ array( 'user_id' => $userid, 'user_touched < ' . $encTouched ),
+ __METHOD__
+ );
+ }
+ } );
$this->clearSharedCache();
}
}
* Generate a looking random token for various uses.
*
* @return String The new random token
- * @deprecated since 1.20; Use MWCryptRand for secure purposes or wfRandomString for pesudo-randomness
+ * @deprecated since 1.20; Use MWCryptRand for secure purposes or wfRandomString for pseudo-randomness
*/
public static function generateToken() {
return MWCryptRand::generateHex( 32 );
protected function getTokenUrl( $page, $token ) {
// Hack to bypass localization of 'Special:'
$title = Title::makeTitle( NS_MAIN, "Special:$page/$token" );
- return $title->getCanonicalUrl();
+ return $title->getCanonicalURL();
}
/**
* @return bool
*/
public function confirmEmail() {
- $this->setEmailAuthenticationTimestamp( wfTimestampNow() );
- wfRunHooks( 'ConfirmEmailComplete', array( $this ) );
+ // Check if it's already confirmed, so we don't touch the database
+ // and fire the ConfirmEmailComplete hook on redundant confirmations.
+ if ( !$this->isEmailConfirmed() ) {
+ $this->setEmailAuthenticationTimestamp( wfTimestampNow() );
+ wfRunHooks( 'ConfirmEmailComplete', array( $this ) );
+ }
return true;
}
}
// Re-map numeric keys of AddToSelf/RemoveFromSelf to the 'user' key for backwards compatibility
- if( empty( $wgGroupsAddToSelf['user']) || $wgGroupsAddToSelf['user'] !== true ) {
+ if( empty( $wgGroupsAddToSelf['user'] ) || $wgGroupsAddToSelf['user'] !== true ) {
foreach( $wgGroupsAddToSelf as $key => $value ) {
if( is_int( $key ) ) {
$wgGroupsAddToSelf['user'][] = $value;
}
}
- if( empty( $wgGroupsRemoveFromSelf['user']) || $wgGroupsRemoveFromSelf['user'] !== true ) {
+ if( empty( $wgGroupsRemoveFromSelf['user'] ) || $wgGroupsRemoveFromSelf['user'] !== true ) {
foreach( $wgGroupsRemoveFromSelf as $key => $value ) {
if( is_int( $key ) ) {
$wgGroupsRemoveFromSelf['user'][] = $value;
* @todo document
*/
protected function saveOptions() {
- global $wgAllowPrefChange;
-
$this->loadOptions();
// Not using getOptions(), to keep hidden preferences in database
return;
}
- $extuser = ExternalUser::newFromUser( $this );
$userId = $this->getId();
$insert_rows = array();
foreach( $saveOptions as $key => $value ) {
'up_value' => $value,
);
}
- if ( $extuser && isset( $wgAllowPrefChange[$key] ) ) {
- switch ( $wgAllowPrefChange[$key] ) {
- case 'local':
- case 'message':
- break;
- case 'semiglobal':
- case 'global':
- $extuser->setPref( $key, $value );
- }
- }
}
$dbw = wfGetDB( DB_MASTER );