* to be fulfilled:
* * If Password::toString() is called on an object, and the result is passed back in
* to PasswordFactory::newFromCiphertext(), the result will be identical to the original.
- * * The string representations of two Password objects are equal only if
- * the original plaintext passwords match. In other words, if the toString() result of
- * two objects match, the passwords are the same, and the user will be logged in.
- * Since the string representation of a hash includes its type name (@see Password::toString),
- * this property is preserved across all classes that inherit Password.
- * If a hashing scheme does not fulfill this expectation, it must make sure to override the
- * Password::equals() function and use custom comparison logic. However, this is not
- * recommended unless absolutely required by the hashing mechanism.
* With these two points in mind, when creating a new Password sub-class, there are some functions
* you have to override (because they are abstract) and others that you may want to override.
*
* * Password::toString(), which can be useful if the hash was changed in the constructor and
* needs to be re-assembled before being returned as a string. This function is expected to add
* the type back on to the hash, so make sure to do that if you override the function.
- * * Password::equals() - This function compares two Password objects to see if they are equal.
- * The default is to just do a timing-safe string comparison on the $this->hash values.
+ * * Password::verify() - This function checks if $this->hash was generated with the given
+ * password. The default is to just hash the password and do a timing-safe string comparison with
+ * $this->hash.
*
* After creating a new password hash type, it can be registered using the static
* Password::register() method. The default type is set using the Password::setDefaultType() type.
* @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;
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.
* custom comparison, but it is not recommended unless necessary.
*
* @deprecated since 1.33, use verify()
+ * @codeCoverageIgnore
*
* @param Password|string $other The other password
* @return bool True if equal, false otherwise
*/
public function equals( $other ) {
+ wfDeprecated( __METHOD__, '1.33' );
+
if ( is_string( $other ) ) {
return $this->verify( $other );
}
* @return bool
*/
public function verify( $password ) {
- Assert::parameter( is_string( $password ),
- '$password', 'must be string, actual: ' . gettype( $password )
- );
+ Assert::parameterType( 'string', $password, '$password' );
// No need to use the factory because we're definitely making
// an object of the same type.