X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FUser.php;h=bafa5410cd7701a0d973743f75eab077518f9296;hb=b7ff4b8b88c8106d6da06e823f6d30ed5da7f527;hp=a3f6cddbe28598d9d67d11198e3ef5249d08f130;hpb=7dcc7872aad0ac9e0d9494e0942dbd64c4f08e11;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/User.php b/includes/User.php index a3f6cddbe2..bafa5410cd 100644 --- a/includes/User.php +++ b/includes/User.php @@ -99,6 +99,7 @@ class User { 'deletedhistory', 'deletedtext', 'deleterevision', + 'disableaccount', 'edit', 'editinterface', 'editusercssjs', @@ -248,7 +249,7 @@ class User { } if ( !$data ) { - wfDebug( "Cache miss for user {$this->mId}\n" ); + wfDebug( "User: cache miss for user {$this->mId}\n" ); # Load from DB if ( !$this->loadFromDatabase() ) { # Can't load from ID, user is anonymous @@ -256,7 +257,7 @@ class User { } $this->saveToCache(); } else { - wfDebug( "Got user {$this->mId} from cache\n" ); + wfDebug( "User: got user {$this->mId} from cache\n" ); # Restore from cache foreach ( self::$mCacheVars as $name ) { $this->$name = $data[$name]; @@ -301,7 +302,7 @@ class User { * User::getCanonicalName(), except that true is accepted as an alias * for 'valid', for BC. * - * @return \type{User} The User object, or false if the username is invalid + * @return User The User object, or false if the username is invalid * (e.g. if it contains illegal characters or is an IP address). If the * username is not present in the database, the result will be a user object * with a name, zero user ID and default settings. @@ -556,7 +557,7 @@ class User { * either by batch processes or by user accounts which have * already been created. * - * Additional blacklisting may be added here rather than in + * Additional blacklisting may be added here rather than in * isValidUserName() to avoid disrupting existing accounts. * * @param $name \string String to match @@ -602,6 +603,11 @@ class User { */ function getPasswordValidity( $password ) { global $wgMinimalPasswordLength, $wgContLang; + + static $blockedLogins = array( + 'Useruser' => 'Passpass', 'Useruser1' => 'Passpass1', # r75589 + 'Apitestsysop' => 'testpass', 'Apitestuser' => 'testpass' # r75605 + ); $result = false; //init $result to false for the internal checks @@ -613,6 +619,8 @@ class User { return 'passwordtooshort'; } elseif ( $wgContLang->lc( $password ) == $wgContLang->lc( $this->mName ) ) { return 'password-name-match'; + } 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 //initialization of $result to false above. If the hook is never run or it @@ -644,8 +652,19 @@ class User { if( !wfRunHooks( 'isValidEmailAddr', array( $addr, &$result ) ) ) { return $result; } + $rfc5322_atext = "a-z0-9!#$%&'*+-\/=?^_`{|}—~" ; + $rfc1034_ldh_str = "a-z0-9-" ; + + $HTML5_email_regexp = "/ + ^ # start of string + [$rfc5322_atext\\.]+ # user part which is liberal :p + @ # 'apostrophe' + [$rfc1034_ldh_str]+ # First domain part + (\\.[$rfc1034_ldh_str]+)+ # Following part prefixed with a dot + $ # End of string + /ix" ; // case Insensitive, eXtended - return strpos( $addr, '@' ) !== false; + return (bool) preg_match( $HTML5_email_regexp, $addr ); } /** @@ -678,7 +697,6 @@ class User { } # Reject various classes of invalid names - $name = $t->getText(); global $wgAuth; $name = $wgAuth->getCanonicalName( $t->getText() ); @@ -863,7 +881,6 @@ class User { return false; } - $passwordCorrect = FALSE; $this->mId = $sId; if ( !$this->loadFromId() ) { # Not a valid ID, loadFromId has switched the object to anon for us @@ -891,11 +908,11 @@ class User { if ( ( $sName == $this->mName ) && $passwordCorrect ) { $_SESSION['wsToken'] = $this->mToken; - wfDebug( "Logged in from $from\n" ); + wfDebug( "User: logged in from $from\n" ); return true; } else { # Invalid credentials - wfDebug( "Can't log in from $from, invalid credentials\n" ); + wfDebug( "User: can't log in from $from, invalid credentials\n" ); $this->loadDefaults(); return false; } @@ -976,7 +993,7 @@ class User { array( 'ug_user' => $this->mId ), __METHOD__ ); $this->mGroups = array(); - while( $row = $dbr->fetchObject( $res ) ) { + foreach ( $res as $row ) { $this->mGroups[] = $row->ug_group; } } @@ -1021,7 +1038,7 @@ class User { /** * default language setting */ - $variant = $wgContLang->getPreferredVariant( false ); + $variant = $wgContLang->getDefaultVariant(); $defOpt['variant'] = $variant; $defOpt['language'] = $variant; foreach( SearchEngine::searchableNamespaces() as $nsnum => $nsname ) { @@ -1060,7 +1077,6 @@ class User { global $wgProxyWhitelist, $wgUser; if ( -1 != $this->mBlockedby ) { - wfDebug( "User::getBlockedStatus: already loaded.\n" ); return; } @@ -1173,7 +1189,6 @@ class User { wfProfileIn( __METHOD__ ); $found = false; - $host = ''; // FIXME: IPv6 ??? (http://bugs.php.net/bug.php?id=33170) if( IP::isIPv4( $ip ) ) { # Reverse IP, bug 21255 @@ -1212,34 +1227,10 @@ class User { // Deprecated, but kept for backwards-compatibility config return false; } - - wfDebug( "Checking the list of IP addresses excluded from rate limit..\n" ); - - // Read list of IP addresses from MediaWiki namespace - $message = wfMsgForContentNoTrans( 'ratelimit-excluded-ips' ); - $lines = explode( "\n", $message ); - foreach( $lines as $line ) { - // Remove comment lines - $comment = substr( trim( $line ), 0, 1 ); - if ( $comment == '#' || $comment == '' ) { - continue; - } - // Remove additional comments after an IP address - $comment = strpos( $line, '#' ); - if ( $comment > 0 ) { - $line = trim( substr( $line, 0, $comment-1 ) ); - if ( IP::isValid( $line ) ) { - $wgRateLimitsExcludedIPs[] = IP::sanitizeIP( $line ); - } - } - } - - $ip = IP::sanitizeIP( wfGetIP() ); - if( in_array( $ip, $wgRateLimitsExcludedIPs ) ) { + 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. - wfDebug( "IP $ip matches the list of rate limit excluded IPs\n" ); return false; } return !$this->isAllowed('noratelimit'); @@ -1349,7 +1340,6 @@ class User { * @return \bool True if blocked, false otherwise */ function isBlocked( $bFromSlave = true ) { // hacked from false due to horrible probs on site - wfDebug( "User::isBlocked: enter\n" ); $this->getBlockedStatus( $bFromSlave ); return $this->mBlockedby !== 0; } @@ -1364,9 +1354,7 @@ class User { function isBlockedFrom( $title, $bFromSlave = false ) { global $wgBlockAllowsUTEdit; wfProfileIn( __METHOD__ ); - wfDebug( __METHOD__ . ": enter\n" ); - wfDebug( __METHOD__ . ": asking isBlocked()\n" ); $blocked = $this->isBlocked( $bFromSlave ); $allowUsertalk = ( $wgBlockAllowsUTEdit ? $this->mAllowUsertalk : false ); # If a user's name is suppressed, they cannot make edits anywhere @@ -1468,7 +1456,7 @@ class User { /** * Get the user's ID. - * @return \int The user's ID; 0 if the user is anonymous or nonexistent + * @return Integer The user's ID; 0 if the user is anonymous or nonexistent */ function getId() { if( $this->mId === null and $this->mName !== null @@ -1774,11 +1762,11 @@ class User { } if( !$this->isValidPassword( $str ) ) { - global $wgMinimalPasswordLength; + global $wgMinimalPasswordLength; $valid = $this->getPasswordValidity( $str ); throw new PasswordError( wfMsgExt( $valid, array( 'parsemag' ), $wgMinimalPasswordLength ) ); - } + } } if( !$wgAuth->setPassword( $this, $str ) ) { @@ -2050,7 +2038,7 @@ class User { global $wgMaxArticleSize; # Maximum article size, in Kb $threshold = intval( $this->getOption( 'stubthreshold' ) ); if ( $threshold > $wgMaxArticleSize * 1024 ) { - # If they have set an impossible value, disable the preference + # If they have set an impossible value, disable the preference # so we can use the parser cache again. $threshold = 0; } @@ -2200,11 +2188,12 @@ class User { /** * Check if user is allowed to access a feature / make an action * @param $action \string action to be checked - * @return \bool True if action is allowed, else false + * @return Boolean: True if action is allowed, else false */ function isAllowed( $action = '' ) { - if ( $action === '' ) + if ( $action === '' ) { return true; // In the spirit of DWIM + } # Patrolling may not be enabled if( $action === 'patrol' || $action === 'autopatrol' ) { global $wgUseRCPatrol, $wgUseNPPatrol; @@ -2218,7 +2207,7 @@ class User { /** * Check whether to enable recent changes patrol features for this user - * @return \bool True or false + * @return Boolean: True or false */ public function useRCPatrol() { global $wgUseRCPatrol; @@ -2246,28 +2235,28 @@ class User { $skin->setTitle( $t ); return $skin; } else { - if ( ! $this->mSkin ) { + if ( !$this->mSkin ) { $this->mSkin = $this->createSkinObject(); } - - if ( ! $this->mSkin->getTitle() ) { + + if ( !$this->mSkin->getTitle() ) { global $wgOut; $t = $wgOut->getTitle(); $this->mSkin->setTitle($t); } - + return $this->mSkin; } } - + // Creates a Skin object, for getSkin() private function createSkinObject() { wfProfileIn( __METHOD__ ); global $wgHiddenPrefs; if( !in_array( 'skin', $wgHiddenPrefs ) ) { - # get the user skin global $wgRequest; + # get the user skin $userSkin = $this->getOption( 'skin' ); $userSkin = $wgRequest->getVal( 'useskin', $userSkin ); } else { @@ -2278,7 +2267,7 @@ class User { $skin = Skin::newFromKey( $userSkin ); wfProfileOut( __METHOD__ ); - + return $skin; } @@ -2413,7 +2402,7 @@ class User { // If an option is not set in $str, use the default value $this->mOptions = self::getDefaultOptions(); - + $a = explode( "\n", $str ); foreach ( $a as $s ) { $m = array(); @@ -2525,8 +2514,8 @@ class User { 'user_newpassword' => $this->mNewpassword, 'user_newpass_time' => $dbw->timestampOrNull( $this->mNewpassTime ), 'user_real_name' => $this->mRealName, - 'user_email' => $this->mEmail, - 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ), + 'user_email' => $this->mEmail, + 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ), 'user_options' => '', 'user_touched' => $dbw->timestamp( $this->mTouched ), 'user_token' => $this->mToken, @@ -2584,12 +2573,13 @@ class User { } $dbw = wfGetDB( DB_MASTER ); $seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' ); + $fields = array( 'user_id' => $seqVal, 'user_name' => $name, 'user_password' => $user->mPassword, 'user_newpassword' => $user->mNewpassword, - 'user_newpass_time' => $dbw->timestamp( $user->mNewpassTime ), + 'user_newpass_time' => $dbw->timestampOrNull( $user->mNewpassTime ), 'user_email' => $user->mEmail, 'user_email_authenticated' => $dbw->timestampOrNull( $user->mEmailAuthenticated ), 'user_real_name' => $user->mRealName, @@ -2623,7 +2613,7 @@ class User { 'user_name' => $this->mName, 'user_password' => $this->mPassword, 'user_newpassword' => $this->mNewpassword, - 'user_newpass_time' => $dbw->timestamp( $this->mNewpassTime ), + 'user_newpass_time' => $dbw->timestampOrNull( $this->mNewpassTime ), 'user_email' => $this->mEmail, 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ), 'user_real_name' => $this->mRealName, @@ -2671,6 +2661,7 @@ class User { * which will give them a chance to modify this key based on their own * settings. * + * @deprecated use the ParserOptions object to get the relevant options * @return \string Page rendering hash */ function getPageRenderingHash() { @@ -2678,9 +2669,10 @@ class User { if( $this->mHash ){ return $this->mHash; } + wfDeprecated( __METHOD__ ); // stubthreshold is only included below for completeness, - // since it disables the parser cache, its value will always + // since it disables the parser cache, its value will always // be 0 when this function is called by parsercache. $confstr = $this->getOption( 'math' ); @@ -2721,7 +2713,7 @@ class User { /** * Get whether the user is blocked from using Special:Emailuser. - * @return \bool True if blocked + * @return Boolean: True if blocked */ function isBlockedFromEmailuser() { $this->getBlockedStatus(); @@ -2730,7 +2722,7 @@ class User { /** * Get whether the user is allowed to create an account. - * @return \bool True if allowed + * @return Boolean: True if allowed */ function isAllowedToCreateAccount() { return $this->isAllowed( 'createaccount' ) && !$this->isBlockedFromCreateAccount(); @@ -2739,7 +2731,7 @@ class User { /** * Get this user's personal page title. * - * @return \type{Title} User's personal page title + * @return Title: User's personal page title */ function getUserPage() { return Title::makeTitle( NS_USER, $this->getName() ); @@ -2748,7 +2740,7 @@ class User { /** * Get this user's talk page title. * - * @return \type{Title} User's talk page title + * @return Title: User's talk page title */ function getTalkPage() { $title = $this->getUserPage(); @@ -2757,7 +2749,7 @@ class User { /** * Get the maximum valid user ID. - * @return \int User ID + * @return Integer: User ID * @static */ function getMaxID() { @@ -2774,7 +2766,7 @@ class User { /** * Determine whether the user is a newbie. Newbies are either * anonymous IPs, or the most recently created accounts. - * @return \bool True if the user is a newbie + * @return Boolean: True if the user is a newbie */ function isNewbie() { return !$this->isAllowed( 'autoconfirmed' ); @@ -2782,8 +2774,8 @@ class User { /** * Check to see if the given clear-text password is one of the accepted passwords - * @param $password \string user password. - * @return \bool True if the given password is correct, otherwise False. + * @param $password String: user password. + * @return Boolean: True if the given password is correct, otherwise False. */ function checkPassword( $password ) { global $wgAuth; @@ -2793,7 +2785,7 @@ class User { // are shorter than this, doesn't mean people wont be able // to. Certain authentication plugins do NOT want to save // domain passwords in a mysql database, so we should - // check this (incase $wgAuth->strict() is false). + // check this (in case $wgAuth->strict() is false). if( !$this->isValidPassword( $password ) ) { return false; } @@ -2823,12 +2815,14 @@ class User { /** * Check if the given clear-text password matches the temporary password * sent by e-mail for password reset operations. - * @return \bool True if matches, false otherwise + * @return Boolean: True if matches, false otherwise */ function checkTemporaryPassword( $plaintext ) { global $wgNewPasswordExpiry; if( self::comparePasswords( $this->mNewpassword, $plaintext, $this->getId() ) ) { - $this->load(); + if ( is_null( $this->mNewpassTime ) ) { + return true; + } $expiry = wfTimestamp( TS_UNIX, $this->mNewpassTime ) + $wgNewPasswordExpiry; return ( time() < $expiry ); } else { @@ -2881,7 +2875,7 @@ class User { * * @param $val \string Input value to compare * @param $salt \string Optional function-specific data for hashing - * @return \bool Whether the token matches + * @return Boolean: Whether the token matches */ function matchEditToken( $val, $salt = '' ) { $sessionToken = $this->editToken( $salt ); @@ -2897,7 +2891,7 @@ class User { * * @param $val \string Input value to compare * @param $salt \string Optional function-specific data for hashing - * @return \bool Whether the token matches + * @return Boolean: Whether the token matches */ function matchEditTokenNoSuffix( $val, $salt = '' ) { $sessionToken = $this->editToken( $salt ); @@ -2909,7 +2903,7 @@ class User { * mail to the user's given address. * * @param $changed Boolean: whether the adress changed - * @return \types{\bool,\type{WikiError}} True on success, a WikiError object on failure. + * @return Status object */ function sendConfirmationMail( $changed = false ) { global $wgLang; @@ -2939,16 +2933,17 @@ class User { * @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 \types{\bool,\type{WikiError}} True on success, a WikiError object on failure + * @return Status object */ function sendMail( $subject, $body, $from = null, $replyto = null ) { if( is_null( $from ) ) { - global $wgPasswordSender; - $from = $wgPasswordSender; + global $wgPasswordSender, $wgPasswordSenderName; + $sender = new MailAddress( $wgPasswordSender, $wgPasswordSenderName ); + } else { + $sender = new MailAddress( $from ); } $to = new MailAddress( $this ); - $sender = new MailAddress( $from ); return UserMailer::send( $to, $sender, $subject, $body, $replyto ); } @@ -3057,7 +3052,7 @@ class User { /** * Is this user allowed to send e-mails within limits of current * site configuration? - * @return \bool True if allowed + * @return Boolean: True if allowed */ function canSendEmail() { global $wgEnableEmail, $wgEnableUserEmail; @@ -3072,7 +3067,7 @@ class User { /** * Is this user allowed to receive e-mails within limits of current * site configuration? - * @return \bool True if allowed + * @return Boolean: True if allowed */ function canReceiveEmail() { return $this->isEmailConfirmed() && !$this->getOption( 'disablemail' ); @@ -3086,7 +3081,7 @@ class User { * confirmed their address by returning a code or using a password * sent to the address from the wiki. * - * @return \bool True if confirmed + * @return Boolean: True if confirmed */ function isEmailConfirmed() { global $wgEmailAuthentication; @@ -3107,7 +3102,7 @@ class User { /** * Check whether there is an outstanding request for e-mail confirmation. - * @return \bool True if pending + * @return Boolean: True if pending */ function isEmailConfirmationPending() { global $wgEmailAuthentication; @@ -3136,14 +3131,18 @@ class User { * non-existent/anonymous user accounts. */ public function getFirstEditTimestamp() { - if( $this->getId() == 0 ) return false; // anons + 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 + if( !$time ) { + return false; // no edits + } return wfTimestamp( TS_MW, $time ); } @@ -3223,7 +3222,7 @@ class User { * Return the set of defined explicit groups. * The implicit groups (by default *, 'user' and 'autoconfirmed') * are not included, as they are defined automatically, not in the database. - * @return \type{\arrayof{\string}} Array of internal group names + * @return Array of internal group names */ static function getAllGroups() { global $wgGroupPermissions, $wgRevokePermissions; @@ -3235,7 +3234,7 @@ class User { /** * Get a list of all available permissions. - * @return \type{\arrayof{\string}} Array of permission names + * @return Array of permission names */ static function getAllRights() { if ( self::$mAllRights === false ) { @@ -3536,7 +3535,7 @@ class User { * @param $hash \string Password hash * @param $password \string Plain-text password to compare * @param $userId \string User ID for old-style password salt - * @return \bool + * @return Boolean: */ static function comparePasswords( $hash, $password, $userId = false ) { $type = substr( $hash, 0, 3 ); @@ -3617,12 +3616,12 @@ class User { // Maybe load from the object if ( !is_null( $this->mOptionOverrides ) ) { - wfDebug( "Loading options for user " . $this->getId() . " from override cache.\n" ); + wfDebug( "User: loading options for user " . $this->getId() . " from override cache.\n" ); foreach( $this->mOptionOverrides as $key => $value ) { $this->mOptions[$key] = $value; } } else { - wfDebug( "Loading options for user " . $this->getId() . " from database.\n" ); + wfDebug( "User: loading options for user " . $this->getId() . " from database.\n" ); // Load from database $dbr = wfGetDB( DB_SLAVE ); @@ -3633,7 +3632,7 @@ class User { __METHOD__ ); - while( $row = $dbr->fetchObject( $res ) ) { + foreach ( $res as $row ) { $this->mOptionOverrides[$row->up_property] = $row->up_value; $this->mOptions[$row->up_property] = $row->up_value; }