MediaWiki  master
PasswordFactory.php
Go to the documentation of this file.
1 <?php
23 declare( strict_types = 1 );
24 
30 final class PasswordFactory {
37  private $default = '';
38 
46  private $types = [
47  '' => [ 'type' => '', 'class' => InvalidPassword::class ],
48  ];
49 
58  public function __construct( array $config = [], string $default = '' ) {
59  foreach ( $config as $type => $options ) {
60  $this->register( $type, $options );
61  }
62 
63  if ( $default !== '' ) {
64  $this->setDefaultType( $default );
65  }
66  }
67 
76  public function register( string $type, array $config ) : void {
77  $config['type'] = $type;
78  $this->types[$type] = $config;
79  }
80 
90  public function setDefaultType( string $type ) : void {
91  if ( !isset( $this->types[$type] ) ) {
92  throw new InvalidArgumentException( "Invalid password type $type." );
93  }
94  $this->default = $type;
95  }
96 
102  public function getDefaultType() : string {
103  return $this->default;
104  }
105 
113  public function init( Config $config ) : void {
114  foreach ( $config->get( 'PasswordConfig' ) as $type => $options ) {
115  $this->register( $type, $options );
116  }
117 
118  $this->setDefaultType( $config->get( 'PasswordDefault' ) );
119  }
120 
126  public function getTypes() : array {
127  return $this->types;
128  }
129 
141  public function newFromCiphertext( ?string $hash ) : Password {
142  if ( $hash === null || $hash === '' ) {
143  return new InvalidPassword( $this, [ 'type' => '' ], null );
144  } elseif ( $hash[0] !== ':' ) {
145  throw new PasswordError( 'Invalid hash given' );
146  }
147 
148  $type = substr( $hash, 1, strpos( $hash, ':', 1 ) - 1 );
149  if ( !isset( $this->types[$type] ) ) {
150  throw new PasswordError( "Unrecognized password hash type $type." );
151  }
152 
153  $config = $this->types[$type];
154 
155  return new $config['class']( $this, $config, $hash );
156  }
157 
165  public function newFromType( string $type ) : Password {
166  if ( !isset( $this->types[$type] ) ) {
167  throw new PasswordError( "Unrecognized password hash type $type." );
168  }
169 
170  $config = $this->types[$type];
171 
172  return new $config['class']( $this, $config );
173  }
174 
185  public function newFromPlaintext( ?string $password, Password $existing = null ) : Password {
186  if ( $password === null ) {
187  return new InvalidPassword( $this, [ 'type' => '' ], null );
188  }
189 
190  if ( $existing === null ) {
191  $config = $this->types[$this->default];
192  $obj = new $config['class']( $this, $config );
193  } else {
194  $obj = clone $existing;
195  }
196 
197  $obj->crypt( $password );
198 
199  return $obj;
200  }
201 
212  public function needsUpdate( Password $password ) : bool {
213  if ( $password->getType() !== $this->default ) {
214  return true;
215  } else {
216  return $password->needsUpdate();
217  }
218  }
219 
226  public static function generateRandomPasswordString( int $minLength = 10 ) : string {
227  // Decide the final password length based on our min password length,
228  // stopping at a minimum of 10 chars.
229  $length = max( 10, $minLength );
230  // Multiply by 1.25 to get the number of hex characters we need
231  // Generate random hex chars
232  $hex = MWCryptRand::generateHex( ceil( $length * 1.25 ) );
233  // Convert from base 16 to base 32 to get a proper password like string
234  return substr( Wikimedia\base_convert( $hex, 16, 32, $length ), -$length );
235  }
236 
242  public static function newInvalidPassword() : InvalidPassword {
243  static $password = null;
244 
245  if ( $password === null ) {
246  $factory = new self();
247  $password = new InvalidPassword( $factory, [ 'type' => '' ], null );
248  }
249 
250  return $password;
251  }
252 }
PasswordFactory\getDefaultType
getDefaultType()
Get the default password type.
Definition: PasswordFactory.php:102
PasswordFactory\$default
string $default
The default PasswordHash type.
Definition: PasswordFactory.php:37
PasswordFactory\setDefaultType
setDefaultType(string $type)
Set the default password type.
Definition: PasswordFactory.php:90
PasswordFactory\newFromType
newFromType(string $type)
Make a new default password of the given type.
Definition: PasswordFactory.php:165
PasswordError
Show an error when any operation involving passwords fails to run.
Definition: PasswordError.php:29
InvalidPassword
Represents an invalid password hash.
Definition: InvalidPassword.php:34
PasswordFactory\needsUpdate
needsUpdate(Password $password)
Determine whether a password object needs updating.
Definition: PasswordFactory.php:212
Config
Interface for configuration instances.
Definition: Config.php:30
PasswordFactory\__construct
__construct(array $config=[], string $default='')
Most of the time you'll want to use MediaWikiServices::getInstance()->getPasswordFactory instead.
Definition: PasswordFactory.php:58
Config\get
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
PasswordFactory\newFromCiphertext
newFromCiphertext(?string $hash)
Create a new Hash object from an existing string hash.
Definition: PasswordFactory.php:141
Password\getType
getType()
Get the type name of the password.
Definition: Password.php:120
PasswordFactory\generateRandomPasswordString
static generateRandomPasswordString(int $minLength=10)
Generate a random string suitable for a password.
Definition: PasswordFactory.php:226
PasswordFactory\getTypes
getTypes()
Get the list of types of passwords.
Definition: PasswordFactory.php:126
MWCryptRand\generateHex
static generateHex( $chars)
Generate a run of cryptographically random data and return it in hexadecimal string format.
Definition: MWCryptRand.php:36
PasswordFactory\newInvalidPassword
static newInvalidPassword()
Create an InvalidPassword.
Definition: PasswordFactory.php:242
PasswordFactory\init
init(Config $config)
Definition: PasswordFactory.php:113
Password\needsUpdate
needsUpdate()
Determine if the hash needs to be updated.
Wikimedia
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Ge...
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
PasswordFactory\newFromPlaintext
newFromPlaintext(?string $password, Password $existing=null)
Create a new Hash object from a plaintext password.
Definition: PasswordFactory.php:185
PasswordFactory\$types
array $types
Mapping of password types to classes.
Definition: PasswordFactory.php:46
$type
$type
Definition: testCompression.php:52