(bug 13453) Fix rebuildrecentchanges for DB's with FK constraints
[lhc/web/wiklou.git] / includes / User.php
index 29b8184..8435414 100644 (file)
@@ -354,8 +354,10 @@ class User {
                        $validate = 'valid';
                }
                $name = self::getCanonicalName( $name, $validate );
-               if ( $name === false ) {
-                       return null;
+               if ( WikiError::isError( $name ) ) {
+                       return $name;
+               } elseif ( $name === false ) {
+                       return false;
                } else {
                        # Create unloaded user object
                        $u = new User;
@@ -619,21 +621,43 @@ class User {
         * Is the input a valid password for this user?
         *
         * @param $password String Desired password
-        * @return mixed: true on success, string of error message on failure
+        * @return bool True or false
         */
        function isValidPassword( $password ) {
-               global $wgMinimalPasswordLength, $wgContLang;
+               //simple boolean wrapper for getPasswordValidity
+               return $this->getPasswordValidity( $password ) === true;
+       }
 
+       /**
+        * Given unvalidated password input, return error message on failure.
+        *
+        * @param $password String Desired password
+        * @return mixed: true on success, string of error message on failure
+        */
+       function getPasswordValidity( $password ) {
+               global $wgMinimalPasswordLength, $wgContLang;
+               
+               $result = false; //init $result to false for the internal checks
+               
                if( !wfRunHooks( 'isValidPassword', array( $password, &$result, $this ) ) )
                        return $result;
-
-               // Password needs to be long enough
-               if( strlen( $password ) < $wgMinimalPasswordLength ) {
-                       return 'passwordtooshort';
-               } elseif( $wgContLang->lc( $password ) == $wgContLang->lc( $this->mName ) ) {
-                       return 'password-name-match';
-               } else {
+               
+               if ( $result === false ) {
+                       if( strlen( $password ) < $wgMinimalPasswordLength ) {
+                               return 'passwordtooshort';
+                       } elseif ( $wgContLang->lc( $password ) == $wgContLang->lc( $this->mName ) ) {
+                               return 'password-name-match';
+                       } 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
+                               //doesn't modify $result, then we will likely get down into this if with
+                               //a valid password.
+                               return true;
+                       }
+               } elseif( $result === true ) {
                        return true;
+               } else {
+                       return $result; //the isValidPassword hook set a string $result and returned true
                }
        }
 
@@ -676,7 +700,7 @@ class User {
                # with title normalisation, but then it's too late to
                # check elsewhere
                if( strpos( $name, '#' ) !== false )
-                       return false;
+                       return new WikiError( 'usernamehasherror' );
 
                # Clean up name according to title rules
                $t = ( $validate === 'valid' ) ?
@@ -1166,27 +1190,33 @@ class User {
         * Whether the given IP is in a given DNS blacklist.
         *
         * @param $ip \string IP to check
-        * @param $base \string URL of the DNS blacklist
+        * @param $bases \string or Array of Strings: URL of the DNS blacklist
         * @return \bool True if blacklisted.
         */
-       function inDnsBlacklist( $ip, $base ) {
+       function inDnsBlacklist( $ip, $bases ) {
                wfProfileIn( __METHOD__ );
 
                $found = false;
                $host = '';
                // FIXME: IPv6 ???  (http://bugs.php.net/bug.php?id=33170)
                if( IP::isIPv4( $ip ) ) {
-                       # Make hostname
-                       $host = "$ip.$base";
+                       # Reverse IP, bug 21255
+                       $ipReversed = implode( '.', array_reverse( explode( '.', $ip ) ) );
 
-                       # Send query
-                       $ipList = gethostbynamel( $host );
+                       foreach( (array)$bases as $base ) {
+                               # Make hostname
+                               $host = "$ipReversed.$base";
 
-                       if( $ipList ) {
-                               wfDebug( "Hostname $host is {$ipList[0]}, it's a proxy says $base!\n" );
-                               $found = true;
-                       } else {
-                               wfDebug( "Requested $host, not found in $base.\n" );
+                               # Send query
+                               $ipList = gethostbynamel( $host );
+
+                               if( $ipList ) {
+                                       wfDebug( "Hostname $host is {$ipList[0]}, it's a proxy says $base!\n" );
+                                       $found = true;
+                                       break;
+                               } else {
+                                       wfDebug( "Requested $host, not found in $base.\n" );
+                               }
                        }
                }
 
@@ -1201,11 +1231,18 @@ class User {
         */
        public function isPingLimitable() {
                global $wgRateLimitsExcludedGroups;
+               global $wgRateLimitsExcludedIPs;
                if( array_intersect( $this->getEffectiveGroups(), $wgRateLimitsExcludedGroups ) ) {
                        // Deprecated, but kept for backwards-compatibility config
                        return false;
                }
-               return !$this->isAllowed( 'noratelimit' );
+               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');
        }
 
        /**
@@ -1735,13 +1772,13 @@ class User {
                        if( !$wgAuth->allowPasswordChange() ) {
                                throw new PasswordError( wfMsg( 'password-change-forbidden' ) );
                        }
-
-                       $valid = $this->isValidPassword( $str );
-                       if( $valid !== true ) {
-                               global $wgMinimalPasswordLength;
+                       if( !$this->isValidPassword( $str ) ) {
+                               global $wgMinimalPasswordLength;
+                               $valid = $this->getPasswordValidity( $str );
                                throw new PasswordError( wfMsgExt( $valid, array( 'parsemag' ),
                                        $wgMinimalPasswordLength ) );
-                       }
+                       }
                }
 
                if( !$wgAuth->setPassword( $this, $str ) ) {
@@ -2029,6 +2066,7 @@ class User {
         */
        function getEffectiveGroups( $recache = false ) {
                if ( $recache || is_null( $this->mEffectiveGroups ) ) {
+                       wfProfileIn( __METHOD__ );
                        $this->mEffectiveGroups = $this->getGroups();
                        $this->mEffectiveGroups[] = '*';
                        if( $this->getId() ) {
@@ -2042,6 +2080,7 @@ class User {
                                # Hook for additional groups
                                wfRunHooks( 'UserEffectiveGroups', array( &$this, &$this->mEffectiveGroups ) );
                        }
+                       wfProfileOut( __METHOD__ );
                }
                return $this->mEffectiveGroups;
        }
@@ -2587,7 +2626,7 @@ class User {
         * Generate a string which will be different for any combination of
         * user options which would produce different parser output.
         * This will be used as part of the hash key for the parser cache,
-        * so users will the same options can share the same cached data
+        * so users with the same options can share the same cached data
         * safely.
         *
         * Extensions which require it should install 'PageRenderingHash' hook,
@@ -2720,7 +2759,7 @@ class User {
                // 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).
-               if( $this->isValidPassword( $password ) !== true ) {
+               if( !$this->isValidPassword( $password ) ) {
                        return false;
                }