Merge "Fix HeaderCallback failing on headers without a colon"
[lhc/web/wiklou.git] / includes / password / Password.php
index 13d1e6d..8f6cb3e 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use Wikimedia\Assert\Assert;
+
 /**
  * Represents a password hash for use in authentication
  *
@@ -99,8 +101,11 @@ abstract class Password {
         * @param string|null $hash The raw hash, including the type
         */
        final public function __construct( PasswordFactory $factory, array $config, $hash = null ) {
+               if ( !$this->isSupported() ) {
+                       throw new Exception( 'PHP support not found for ' . get_class( $this ) );
+               }
                if ( !isset( $config['type'] ) ) {
-                       throw new MWException( 'Password configuration must contain a type name.' );
+                       throw new Exception( 'Password configuration must contain a type name.' );
                }
                $this->config = $config;
                $this->factory = $factory;
@@ -123,6 +128,15 @@ abstract class Password {
                return $this->config['type'];
        }
 
+       /**
+        * Whether current password type is supported on this system.
+        *
+        * @return bool
+        */
+       protected function isSupported() {
+               return true;
+       }
+
        /**
         * Perform any parsing necessary on the hash to see if the hash is valid
         * and/or to perform logic for seeing if the hash needs updating.
@@ -138,8 +152,7 @@ abstract class Password {
         *
         * @return bool True if needs update, false otherwise
         */
-       public function needsUpdate() {
-       }
+       abstract public function needsUpdate();
 
        /**
         * Compare one Password object to this object
@@ -148,21 +161,36 @@ abstract class Password {
         * Password::toString() for each object. This can be overridden to do
         * custom comparison, but it is not recommended unless necessary.
         *
+        * @deprecated since 1.33, use verify()
+        *
         * @param Password|string $other The other password
         * @return bool True if equal, false otherwise
         */
        public function equals( $other ) {
-               if ( !$other instanceof self ) {
-                       // No need to use the factory because we're definitely making
-                       // an object of the same type.
-                       $obj = clone $this;
-                       $obj->crypt( $other );
-                       $other = $obj;
+               if ( is_string( $other ) ) {
+                       return $this->verify( $other );
                }
 
                return hash_equals( $this->toString(), $other->toString() );
        }
 
+       /**
+        * Checks whether the given password matches the hash stored in this object.
+        *
+        * @param string $password Password to check
+        * @return bool
+        */
+       public function verify( $password ) {
+               Assert::parameterType( 'string', $password, '$password' );
+
+               // No need to use the factory because we're definitely making
+               // an object of the same type.
+               $obj = clone $this;
+               $obj->crypt( $password );
+
+               return hash_equals( $this->toString(), $obj->toString() );
+       }
+
        /**
         * Convert this hash to a string that can be stored in the database
         *