Added minimum password requirements

This commit is contained in:
MatteoF96
2022-01-10 12:34:57 +01:00
parent 504e18c855
commit 43fd2fdc34
5 changed files with 52 additions and 11 deletions

View File

@ -220,5 +220,17 @@ Set to `true` to restrict user assignments to roles only.
If `true` registration and last login IPs are not logged into users table, instead a dummy 127.0.0.1 is used
#### minPasswordRequirements (type: `array`, default: `['lower' => 1, 'digit' => 1, 'upper' => 1]`)
Minimum requirements when a new password is automatically generated.
Array structure: `"requirement" => minimum_number_characters`.
Possible array keys:
- lower: minimum number of lowercase characters;
- upper: minimum number of uppercase characters;
- digit: minimum number of digits;
- special: minimum number of special characters;
- min: minimum number of characters (= minimum length).
© [2amigos](http://www.2amigos.us/) 2013-2019

View File

@ -13,6 +13,7 @@ namespace Da\User\Helper;
use yii\base\Exception;
use yii\base\Security;
use yii\base\InvalidConfigException;
class SecurityHelper
{
@ -60,25 +61,36 @@ class SecurityHelper
return $this->security->validatePassword($password, $hash);
}
public function generatePassword($length)
public function generatePassword($length, $minPasswordRequirements)
{
$sets = [
'abcdefghjkmnpqrstuvwxyz',
'ABCDEFGHJKMNPQRSTUVWXYZ',
'23456789',
'lower' => 'abcdefghjkmnpqrstuvwxyz',
'upper' => 'ABCDEFGHJKMNPQRSTUVWXYZ',
'digit' => '123456789',
'special' => '!#$%&()*+,-./:;<=>?@[\]^_{|}~'
];
$all = '';
$password = '';
foreach ($sets as $set) {
$password .= $set[array_rand(str_split($set))];
if (isset($minPasswordRequirements['min']) && $length < $minPasswordRequirements['min']) {
$length = $minPasswordRequirements['min'];
}
foreach ($sets as $setKey => $set) {
if (isset($minPasswordRequirements[$setKey])) {
for ($i = 0; $i < $minPasswordRequirements[$setKey]; $i++) {
$password .= $set[array_rand(str_split($set))];
}
}
$all .= $set;
}
$passwordLength = strlen($password);
if ($passwordLength > $length) {
throw new InvalidConfigException('The minimum length is incompatible with other minimum requirements.');
}
$all = str_split($all);
for ($i = 0; $i < $length - count($sets); ++$i) {
for ($i = 0; $i < $length - $passwordLength; ++$i) {
$password .= $all[array_rand($all)];
}
$password = str_shuffle($password);
return $password;

View File

@ -211,6 +211,23 @@ class Module extends BaseModule
*/
public $disableIpLogging = false;
/**
* @var array Minimum requirements when a new password is automatically generated.
* Array structure: `requirement => minimum number characters`.
*
* Possible array keys:
* - lower: minimum number of lowercase characters;
* - upper: minimum number of uppercase characters;
* - digit: minimum number of digits;
* - special: minimum number of special characters;
* - min: minimum number of characters (= minimum length).
*/
public $minPasswordRequirements = [
'lower' => 1,
'digit' => 1,
'upper' => 1,
];
/**
* @return string with the hit to be used with the give consent checkbox
*/

View File

@ -57,7 +57,7 @@ class UserCreateService implements ServiceInterface
$model->confirmed_at = time();
$model->password = !empty($model->password)
? $model->password
: $this->securityHelper->generatePassword(8);
: $this->securityHelper->generatePassword(8, $this->getModule('user')->minPasswordRequirements);
/** @var UserEvent $event */
$event = $this->make(UserEvent::class, [$model]);

View File

@ -51,7 +51,7 @@ class UserRegisterService implements ServiceInterface
try {
$model->confirmed_at = $this->getModule()->enableEmailConfirmation ? null : time();
$model->password = $this->getModule()->generatePasswords
? $this->securityHelper->generatePassword(8)
? $this->securityHelper->generatePassword(8, $this->getModule('user')->minPasswordRequirements)
: $model->password;
$event = $this->make(UserEvent::class, [$model]);