|| strlen( $name ) > $wgMaxNameChars
|| $name != $wgContLang->ucfirst( $name ) )
return false;
-
+
// Ensure that the name can't be misresolved as a different title,
// such as with extra namespace keys at the start.
$parsed = Title::newFromText( $name );
|| $parsed->getNamespace()
|| strcmp( $name, $parsed->getPrefixedText() ) )
return false;
- else
- return true;
+
+ // Check an additional blacklist of troublemaker characters.
+ // Should these be merged into the title char list?
+ $unicodeBlacklist = '/[' .
+ '\x{0080}-\x{009f}' . # iso-8859-1 control chars
+ '\x{00a0}' . # non-breaking space
+ '\x{2000}-\x{200f}' . # various whitespace
+ '\x{2028}-\x{202f}' . # breaks and control chars
+ '\x{3000}' . # ideographic space
+ '\x{e000}-\x{f8ff}' . # private use
+ ']/u';
+ if( preg_match( $unicodeBlacklist, $name ) ) {
+ return false;
+ }
+
+ return true;
}
/**
$fname = 'User::loadDefaults' . $n;
wfProfileIn( $fname );
- global $wgContLang, $wgDBname;
+ global $wgCookiePrefix;
global $wgNamespacesToBeSearchedDefault;
$this->mId = 0;
$this->setToken(); # Random
$this->mHash = false;
- if ( isset( $_COOKIE[$wgDBname.'LoggedOut'] ) ) {
- $this->mTouched = wfTimestamp( TS_MW, $_COOKIE[$wgDBname.'LoggedOut'] );
+ if ( isset( $_COOKIE[$wgCookiePrefix.'LoggedOut'] ) ) {
+ $this->mTouched = wfTimestamp( TS_MW, $_COOKIE[$wgCookiePrefix.'LoggedOut'] );
}
else {
$this->mTouched = '0'; # Allow any pages to be cached
}
$this->mRegistration = wfTimestamp( TS_MW );
-
+
wfProfileOut( $fname );
}
* @static
*/
function loadFromSession() {
- global $wgMemc, $wgDBname;
+ global $wgMemc, $wgDBname, $wgCookiePrefix;
if ( isset( $_SESSION['wsUserID'] ) ) {
if ( 0 != $_SESSION['wsUserID'] ) {
} else {
return new User();
}
- } else if ( isset( $_COOKIE["{$wgDBname}UserID"] ) ) {
- $sId = intval( $_COOKIE["{$wgDBname}UserID"] );
+ } else if ( isset( $_COOKIE["{$wgCookiePrefix}UserID"] ) ) {
+ $sId = intval( $_COOKIE["{$wgCookiePrefix}UserID"] );
$_SESSION['wsUserID'] = $sId;
} else {
return new User();
}
if ( isset( $_SESSION['wsUserName'] ) ) {
$sName = $_SESSION['wsUserName'];
- } else if ( isset( $_COOKIE["{$wgDBname}UserName"] ) ) {
- $sName = $_COOKIE["{$wgDBname}UserName"];
+ } else if ( isset( $_COOKIE["{$wgCookiePrefix}UserName"] ) ) {
+ $sName = $_COOKIE["{$wgCookiePrefix}UserName"];
$_SESSION['wsUserName'] = $sName;
} else {
return new User();
} else {
wfDebug( "User::loadFromSession() got from cache!\n" );
}
-
+
if ( isset( $_SESSION['wsToken'] ) ) {
$passwordCorrect = $_SESSION['wsToken'] == $user->mToken;
- } else if ( isset( $_COOKIE["{$wgDBname}Token"] ) ) {
- $passwordCorrect = $user->mToken == $_COOKIE["{$wgDBname}Token"];
+ } else if ( isset( $_COOKIE["{$wgCookiePrefix}Token"] ) ) {
+ $passwordCorrect = $user->mToken == $_COOKIE["{$wgCookiePrefix}Token"];
} else {
return new User(); # Can't log in from session
}
$this->mGroups[] = $row->ug_group;
}
$implicitGroups = array( '*', 'user' );
-
+
global $wgAutoConfirmAge;
$accountAge = time() - wfTimestampOrNull( TS_UNIX, $this->mRegistration );
if( $accountAge >= $wgAutoConfirmAge ) {
$implicitGroups[] = 'autoconfirmed';
}
-
+
$effectiveGroups = array_merge( $implicitGroups, $this->mGroups );
$this->mRights = $this->getGroupPermissions( $effectiveGroups );
}
return (bool)$this->mNewtalk;
}
+ /**
+ * Return the talk page(s) this user has new messages on.
+ */
+ function getNewMessageLinks() {
+ global $wgDBname;
+ $talks = array();
+ if (!wfRunHooks('UserRetrieveNewTalks', array(&$this, &$talks)))
+ return $talks;
+
+ if (!$this->getNewtalk())
+ return array();
+ $up = $this->getUserPage();
+ $utp = $up->getTalkPage();
+ return array(array("wiki" => $wgDBname, "link" => $utp->getLocalURL()));
+ }
+
+
/**
* Perform a user_newtalk check on current slaves; if the memcached data
* is funky we don't want newtalk state to get stuck on save, as that's
array( $field => $id ), $fname );
return $ok !== false;
}
-
+
/**
- * Add or update the
+ * Add or update the
* @param string $field
* @param mixed $id
* @access private
wfDebug( "$fname: set on ($field, $id)\n" );
return true;
}
-
+
/**
+ * Clear the new messages flag for the given user
* @param string $field
* @param mixed $id
* @access private
wfDebug( "$fname: killed on ($field, $id)\n" );
return true;
}
-
+
/**
* Update the 'You have new messages!' status.
* @param bool $val
if( wfReadOnly() ) {
return;
}
-
+
$this->loadFromDatabase();
$this->mNewtalk = $val;
$fname = 'User::setNewtalk';
-
+
if( $this->isAnon() ) {
$field = 'user_ip';
$id = $this->getName();
$field = 'user_id';
$id = $this->getId();
}
-
+
if( $val ) {
$changed = $this->updateNewtalk( $field, $id );
} else {
$changed = $this->deleteNewtalk( $field, $id );
}
-
+
if( $changed ) {
if( $this->isAnon() ) {
// Anons have a separate memcached space, since
// user records aren't kept for them.
global $wgDBname, $wgMemc;
- $key = "$wgDBname:newtalk:ip:$value";
+ $key = "$wgDBname:newtalk:ip:$val";
$wgMemc->set( $key, $val ? 1 : 0 );
} else {
if( $val ) {
$this->mRealName = $str;
}
+ /**
+ * @param string $oname The option to check
+ * @return string
+ */
function getOption( $oname ) {
$this->loadFromDatabase();
if ( array_key_exists( $oname, $this->mOptions ) ) {
}
}
+ /**
+ * @param string $oname The option to check
+ * @return bool False if the option is not selected, true if it is
+ */
+ function getBoolOption( $oname ) {
+ return (bool)$this->getOption( $oname );
+ }
+
function setOption( $oname, $val ) {
$this->loadFromDatabase();
if ( $oname == 'skin' ) {
}
/**
- * Remove the user from the given group.
+ * Add the user to the given group.
* This takes immediate effect.
* @string $group
*/
$fname = 'User::getSkin';
wfProfileIn( $fname );
- # get all skin names available
- $skinNames = Skin::getSkinNames();
-
# get the user skin
$userSkin = $this->getOption( 'skin' );
$userSkin = $wgRequest->getVal('useskin', $userSkin);
-
+
$this->mSkin =& Skin::newFromKey( $userSkin );
wfProfileOut( $fname );
}
function clearNotification( &$title ) {
global $wgUser, $wgUseEnotif;
+
if ($title->getNamespace() == NS_USER_TALK &&
$title->getText() == $this->getName() ) {
+ if (!wfRunHooks('UserClearNewTalkNotification', array(&$this)))
+ return;
$this->setNewtalk( false );
}
-
+
if( !$wgUseEnotif ) {
return;
}
}
function setCookies() {
- global $wgCookieExpiration, $wgCookiePath, $wgCookieDomain, $wgDBname;
+ global $wgCookieExpiration, $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookiePrefix;
if ( 0 == $this->mId ) return;
$this->loadFromDatabase();
$exp = time() + $wgCookieExpiration;
$_SESSION['wsUserID'] = $this->mId;
- setcookie( $wgDBname.'UserID', $this->mId, $exp, $wgCookiePath, $wgCookieDomain );
+ setcookie( $wgCookiePrefix.'UserID', $this->mId, $exp, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
$_SESSION['wsUserName'] = $this->getName();
- setcookie( $wgDBname.'UserName', $this->getName(), $exp, $wgCookiePath, $wgCookieDomain );
+ setcookie( $wgCookiePrefix.'UserName', $this->getName(), $exp, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
$_SESSION['wsToken'] = $this->mToken;
if ( 1 == $this->getOption( 'rememberpassword' ) ) {
- setcookie( $wgDBname.'Token', $this->mToken, $exp, $wgCookiePath, $wgCookieDomain );
+ setcookie( $wgCookiePrefix.'Token', $this->mToken, $exp, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
} else {
- setcookie( $wgDBname.'Token', '', time() - 3600 );
+ setcookie( $wgCookiePrefix.'Token', '', time() - 3600 );
}
}
* It will clean the session cookie
*/
function logout() {
- global $wgCookiePath, $wgCookieDomain, $wgDBname;
+ global $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookiePrefix;
$this->loadDefaults();
$this->setLoaded( true );
$_SESSION['wsUserID'] = 0;
- setcookie( $wgDBname.'UserID', '', time() - 3600, $wgCookiePath, $wgCookieDomain );
- setcookie( $wgDBname.'Token', '', time() - 3600, $wgCookiePath, $wgCookieDomain );
+ setcookie( $wgCookiePrefix.'UserID', '', time() - 3600, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
+ setcookie( $wgCookiePrefix.'Token', '', time() - 3600, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
# Remember when user logged out, to prevent seeing cached pages
- setcookie( $wgDBname.'LoggedOut', wfTimestampNow(), time() + 86400, $wgCookiePath, $wgCookieDomain );
+ setcookie( $wgCookiePrefix.'LoggedOut', wfTimestampNow(), time() + 86400, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
}
/**
* Save object settings into database
*/
function saveSettings() {
- global $wgMemc, $wgDBname, $wgUseEnotif;
+ global $wgMemc, $wgDBname;
$fname = 'User::saveSettings';
if ( wfReadOnly() ) { return; }
// add in language specific options, if any
$extra = $wgContLang->getExtraHashOptions();
$confstr .= $extra;
-
+
// Give a chance for extensions to modify the hash, if they have
// extra options or other effects on the parser cache.
wfRunHooks( 'PageRenderingHash', array( &$confstr ) );
*/
function matchEditToken( $val, $salt = '' ) {
global $wgMemc;
-
-/*
- if ( !isset( $_SESSION['wsEditToken'] ) ) {
+ $sessionToken = $this->editToken( $salt );
+ if ( $val != $sessionToken ) {
$logfile = '/home/wikipedia/logs/session_debug/session.log';
$mckey = memsess_key( session_id() );
$uname = @posix_uname();
- $msg = "wsEditToken not set!\n" .
+ $msg = date('r') . "\nEdit token mismatch, expected $sessionToken got $val\n" .
'apache server=' . $uname['nodename'] . "\n" .
'session_id = ' . session_id() . "\n" .
'$_SESSION=' . var_export( $_SESSION, true ) . "\n" .
@error_log( $msg, 3, $logfile );
}
-*/
- return ( $val == $this->editToken( $salt ) );
+ return $val == $sessionToken;
}
/**
array_keys( $wgGroupPermissions ),
array( '*', 'user', 'autoconfirmed' ) );
}
-
}
?>