MediaWiki  master
Password.php
Go to the documentation of this file.
1 <?php
23 declare( strict_types = 1 );
24 
61 abstract class Password {
65  protected $factory;
66 
71  protected $hash;
72 
77  protected $config;
78 
82  private const MAX_HASH_SIZE = 255;
83 
96  final public function __construct( PasswordFactory $factory, array $config, string $hash = null ) {
97  if ( !$this->isSupported() ) {
98  throw new Exception( 'PHP support not found for ' . get_class( $this ) );
99  }
100  if ( !isset( $config['type'] ) ) {
101  throw new Exception( 'Password configuration must contain a type name.' );
102  }
103  $this->config = $config;
104  $this->factory = $factory;
105 
106  if ( $hash !== null && strlen( $hash ) >= 3 ) {
107  // Strip the type from the hash for parsing
108  $hash = substr( $hash, strpos( $hash, ':', 1 ) + 1 );
109  }
110 
111  $this->hash = $hash;
112  $this->parseHash( $hash );
113  }
114 
120  final public function getType() : string {
121  return $this->config['type'];
122  }
123 
129  protected function isSupported() : bool {
130  return true;
131  }
132 
140  protected function parseHash( ?string $hash ) : void {
141  }
142 
148  abstract public function needsUpdate() : bool;
149 
156  public function verify( string $password ) : bool {
157  // No need to use the factory because we're definitely making
158  // an object of the same type.
159  $obj = clone $this;
160  $obj->crypt( $password );
161 
162  return hash_equals( $this->toString(), $obj->toString() );
163  }
164 
177  public function toString() : string {
178  $result = ':' . $this->config['type'] . ':' . $this->hash;
179  $this->assertIsSafeSize( $result );
180  return $result;
181  }
182 
193  final protected function assertIsSafeSize( string $hash ) : void {
194  if ( strlen( $hash ) > self::MAX_HASH_SIZE ) {
195  throw new PasswordError( "Password hash is too big" );
196  }
197  }
198 
208  abstract public function crypt( string $password ) : void;
209 }
Password\assertIsSafeSize
assertIsSafeSize(string $hash)
Assert that hash will fit in a tinyblob field.
Definition: Password.php:193
PasswordError
Show an error when any operation involving passwords fails to run.
Definition: PasswordError.php:28
Password\crypt
crypt(string $password)
Hash a password and store the result in this object.
Password\$config
array $config
Array of configuration variables injected from the constructor.
Definition: Password.php:77
Password\verify
verify(string $password)
Checks whether the given password matches the hash stored in this object.
Definition: Password.php:156
Password\isSupported
isSupported()
Whether current password type is supported on this system.
Definition: Password.php:129
Password\MAX_HASH_SIZE
const MAX_HASH_SIZE
Hash must fit in user_password, which is a tinyblob.
Definition: Password.php:82
Password\getType
getType()
Get the type name of the password.
Definition: Password.php:120
Password\toString
toString()
Convert this hash to a string that can be stored in the database.
Definition: Password.php:177
Password\__construct
__construct(PasswordFactory $factory, array $config, string $hash=null)
Construct the Password object using a string hash.
Definition: Password.php:96
Password\parseHash
parseHash(?string $hash)
Perform any parsing necessary on the hash to see if the hash is valid and/or to perform logic for see...
Definition: Password.php:140
Password\$hash
string null $hash
String representation of the hash without the type.
Definition: Password.php:71
Password\needsUpdate
needsUpdate()
Determine if the hash needs to be updated.
Password\$factory
PasswordFactory $factory
Factory that created the object.
Definition: Password.php:65
PasswordFactory
Factory class for creating and checking Password objects.
Definition: PasswordFactory.php:30
Password
Represents a password hash for use in authentication.
Definition: Password.php:61