* @file
*/
+use Wikimedia\Assert\Assert;
+
/**
* Represents a password hash for use in authentication
*
* @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.
*
* @return bool True if needs update, false otherwise
*/
- public function needsUpdate() {
- }
+ abstract public function needsUpdate();
/**
* Compare one Password object to this object
* 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
*