'createtalk',
'delete',
'deletedhistory',
+ 'deleterevision',
'edit',
'editinterface',
'editusercssjs',
+ 'hideuser',
'import',
'importupload',
'ipblock-exempt',
'markbotedits',
'minoredit',
'move',
+ 'movefile',
+ 'move-rootuserpages',
+ 'move-subpages',
'nominornewtalk',
'noratelimit',
'patrol',
'proxyunbannable',
'purge',
'read',
+ 'reset-passwords',
'reupload',
'reupload-shared',
'rollback',
'siteadmin',
+ 'suppressionlog',
'suppressredirect',
+ 'suppressrevision',
'trackback',
'undelete',
'unwatchedpages',
'upload',
'upload_by_url',
'userrights',
+ 'userrights-interwiki',
+ 'writeapi',
);
/**
* \string Cached results of getAllRights()
/**
* Get database id given a user name
* @param $name \string Username
- * @return \2types{\int,\null} The corresponding user's ID, or null if user is nonexistent
- * @static
+ * @return \types{\int,\null} The corresponding user's ID, or null if user is nonexistent
*/
static function idFromName( $name ) {
- $nt = Title::newFromText( $name );
+ $nt = Title::makeTitleSafe( NS_USER, $name );
if( is_null( $nt ) ) {
# Illegal name
return null;
* Given unvalidated user input, return a canonical username, or false if
* the username is invalid.
* @param $name \string User input
- * @param $validate \2types{\string,\bool} Type of validation to use:
+ * @param $validate \types{\string,\bool} Type of validation to use:
* - false No validation
* - 'valid' Valid for batch processes
* - 'usable' Valid for batch processes and login
$dbr = wfGetDB( DB_MASTER );
$s = $dbr->selectRow( 'user', '*', array( 'user_id' => $this->mId ), __METHOD__ );
+ wfRunHooks( 'UserLoadFromDatabase', array( $this, &$s ) );
+
if ( $s !== false ) {
# Initialise user table data
$this->loadFromRow( $s );
$this->mDataLoaded = true;
if ( isset( $row->user_id ) ) {
- $this->mId = $row->user_id;
+ $this->mId = intval( $row->user_id );
}
$this->mName = $row->user_name;
$this->mRealName = $row->user_real_name;
* @return \type{\arrayof{\string}} Array of user toggle names
*/
static function getToggles() {
- global $wgContLang;
+ global $wgContLang, $wgUseRCPatrol;
$extraToggles = array();
wfRunHooks( 'UserToggles', array( &$extraToggles ) );
+ if( $wgUseRCPatrol ) {
+ $extraToggles[] = 'hidepatrolled';
+ $extraToggles[] = 'newpageshidepatrolled';
+ $extraToggles[] = 'watchlisthidepatrolled';
+ }
return array_merge( self::$mToggles, $extraToggles, $wgContLang->getExtraUserToggles() );
}
*/
public function isPingLimitable() {
global $wgRateLimitsExcludedGroups;
+ global $wgRateLimitsExcludedIPs;
if( array_intersect( $this->getEffectiveGroups(), $wgRateLimitsExcludedGroups ) ) {
// Deprecated, but kept for backwards-compatibility config
return false;
}
+ if( in_array( wfGetIP(), $wgRateLimitsExcludedIPs ) ) {
+ // No other good way currently to disable rate limits
+ // for specific IPs. :P
+ // But this is a crappy hack and should die.
+ return false;
+ }
return !$this->isAllowed('noratelimit');
}
return $this->mBlockreason;
}
+ /**
+ * If user is blocked, return the ID for the block
+ * @return \int Block ID
+ */
+ function getBlockId() {
+ $this->getBlockedStatus();
+ return ($this->mBlock ? $this->mBlock->mId : false);
+ }
+
/**
* Check if user is blocked on all wikis.
* Do not use for actual edit permission checks!
*
* @see getNewtalk()
* @param $field \string 'user_ip' for anonymous users, 'user_id' otherwise
- * @param $id \2types{\string,\int} User's IP address for anonymous users, User ID otherwise
+ * @param $id \types{\string,\int} User's IP address for anonymous users, User ID otherwise
* @param $fromMaster \bool true to fetch from the master, false for a slave
* @return \bool True if the user has new messages
* @private
/**
* Add or update the new messages flag
* @param $field \string 'user_ip' for anonymous users, 'user_id' otherwise
- * @param $id \2types{\string,\int} User's IP address for anonymous users, User ID otherwise
+ * @param $id \types{\string,\int} User's IP address for anonymous users, User ID otherwise
* @return \bool True if successful, false otherwise
* @private
*/
/**
* Clear the new messages flag for the given user
* @param $field \string 'user_ip' for anonymous users, 'user_id' otherwise
- * @param $id \2types{\string,\int} User's IP address for anonymous users, User ID otherwise
+ * @param $id \types{\string,\int} User's IP address for anonymous users, User ID otherwise
* @return \bool True if successful, false otherwise
* @private
*/
}
$this->mOptions[$oname] = $val;
}
+
+ /**
+ * Reset all options to the site defaults
+ */
+ function restoreOptions() {
+ $this->mOptions = User::getDefaultOptions();
+ }
/**
* Get the user's preferred date format.
* @return \int User'e edit count
*/
function getEditCount() {
- if ($this->mId) {
+ if ($this->getId()) {
if ( !isset( $this->mEditCount ) ) {
/* Populate the count, if it has not been populated yet */
$this->mEditCount = User::edits($this->mId);
* @param $action \string action to be checked
* @return \bool True if action is allowed, else false
*/
- function isAllowed($action='') {
+ function isAllowed( $action = '' ) {
if ( $action === '' )
- // In the spirit of DWIM
- return true;
-
+ return true; // In the spirit of DWIM
+ # Patrolling may not be enabled
+ if( $action === 'patrol' || $action === 'autopatrol' ) {
+ global $wgUseRCPatrol, $wgUseNPPatrol;
+ if( !$wgUseRCPatrol && !$wgUseNPPatrol )
+ return false;
+ }
# Use strict parameter to avoid matching numeric 0 accidentally inserted
# by misconfiguration: 0 == 'foo'
return in_array( $action, $this->getRights(), true );
* Set a cookie on the user's client. Wrapper for
* WebResponse::setCookie
* @param $name \string Name of the cookie to set
- * @param $name \string Value to set
- * @param $name \int Expiration time, as a UNIX time value;
+ * @param $value \string Value to set
+ * @param $exp \int Expiration time, as a UNIX time value;
* if 0 or not specified, use the default $wgCookieExpiration
*/
protected function setCookie( $name, $value, $exp=0 ) {
wfRunHooks( 'UserSetCookies', array( $this, &$session, &$cookies ) );
#check for null, since the hook could cause a null value
- if ( !is_null( $session ) && !is_null( $_SESSION ) ){
+ if ( !is_null( $session ) && isset( $_SESSION ) ){
$_SESSION = $session + $_SESSION;
}
foreach ( $cookies as $name => $value ) {
* @return \bool True if matches, false otherwise
*/
function checkTemporaryPassword( $plaintext ) {
- return self::comparePasswords( $this->mNewpassword, $plaintext, $this->getId() );
+ global $wgNewPasswordExpiry;
+ if( self::comparePasswords( $this->mNewpassword, $plaintext, $this->getId() ) ) {
+ $this->load();
+ $expiry = wfTimestamp( TS_UNIX, $this->mNewpassTime ) + $wgNewPasswordExpiry;
+ return ( time() < $expiry );
+ } else {
+ return false;
+ }
}
/**
* login credentials aren't being hijacked with a foreign form
* submission.
*
- * @param $salt \2types{\string,\arrayof{\string}} Optional function-specific data for hashing
+ * @param $salt \types{\string,\arrayof{\string}} Optional function-specific data for hashing
* @return \string The new edit token
*/
function editToken( $salt = '' ) {
* Generate a new e-mail confirmation token and send a confirmation/invalidation
* mail to the user's given address.
*
- * @return \2types{\bool,\type{WikiError}} True on success, a WikiError object on failure.
+ * @return \types{\bool,\type{WikiError}} True on success, a WikiError object on failure.
*/
function sendConfirmationMail() {
global $wgLang;
* @param $body \string Message body
* @param $from \string Optional From address; if unspecified, default $wgPasswordSender will be used
* @param $replyto \string Reply-To address
- * @return \2types{\bool,\type{WikiError}} True on success, a WikiError object on failure
+ * @return \types{\bool,\type{WikiError}} True on success, a WikiError object on failure
*/
function sendMail( $subject, $body, $from = null, $replyto = null ) {
if( is_null( $from ) ) {
/**
* Get the timestamp of account creation.
*
- * @return \2types{\string,\bool} string Timestamp of account creation, or false for
+ * @return \types{\string,\bool} string Timestamp of account creation, or false for
* non-existent/anonymous user accounts.
*/
public function getRegistration() {
- return $this->mId > 0
+ return $this->getId() > 0
? $this->mRegistration
: false;
}
+
+ /**
+ * Get the timestamp of the first edit
+ *
+ * @return \types{\string,\bool} string Timestamp of first edit, or false for
+ * non-existent/anonymous user accounts.
+ */
+ public function getFirstEditTimestamp() {
+ if( $this->getId() == 0 ) return false; // anons
+ $dbr = wfGetDB( DB_SLAVE );
+ $time = $dbr->selectField( 'revision', 'rev_timestamp',
+ array( 'rev_user' => $this->getId() ),
+ __METHOD__,
+ array( 'ORDER BY' => 'rev_timestamp ASC' )
+ );
+ if( !$time ) return false; // no edits
+ return wfTimestamp( TS_MW, $time );
+ }
/**
* Get the permissions associated with a given list of groups
* Get the title of a page describing a particular group
*
* @param $group \string Internal group name
- * @return \2types{\type{Title},\bool} Title of the page if it exists, false otherwise
+ * @return \types{\type{Title},\bool} Title of the page if it exists, false otherwise
*/
static function getGroupPage( $group ) {
global $wgMessageCache;
static function crypt( $password, $salt = false ) {
global $wgPasswordSalt;
- if($wgPasswordSalt) {
+ $hash = '';
+ if( !wfRunHooks( 'UserCryptPassword', array( &$password, &$salt, &$wgPasswordSalt, &$hash ) ) ) {
+ return $hash;
+ }
+
+ if( $wgPasswordSalt ) {
if ( $salt === false ) {
$salt = substr( wfGenerateToken(), 0, 8 );
}
return ':B:' . $salt . ':' . md5( $salt . '-' . md5( $password ) );
} else {
- return ':A:' . md5( $password);
+ return ':A:' . md5( $password );
}
}
static function comparePasswords( $hash, $password, $userId = false ) {
$m = false;
$type = substr( $hash, 0, 3 );
+
+ $result = false;
+ if( !wfRunHooks( 'UserComparePasswords', array( &$hash, &$password, &$userId, &$result ) ) ) {
+ return $result;
+ }
+
if ( $type == ':A:' ) {
# Unsalted
return md5( $password ) === substr( $hash, 3 );
/**
* Add a newuser log entry for this user
- * @param bool $byEmail, account made by email?
+ * @param $byEmail Boolean: account made by email?
*/
public function addNewUserLogEntry( $byEmail = false ) {
global $wgUser, $wgContLang, $wgNewUserLog;