N°4095 - Provisions for future implementation of users password

expiration.
This commit is contained in:
denis.flaven@combodo.com
2021-08-09 17:12:34 +02:00
parent 5926e9d110
commit 99d0c05c1c
6 changed files with 46 additions and 12 deletions

View File

@@ -1094,9 +1094,13 @@ class LoginWebPage extends NiceWebPage
if (isset($_SESSION['auth_user']))
{
$sAuthUser = $_SESSION['auth_user'];
$sIssue = $_SESSION['pwd_issue'] ?? null;
unset($_SESSION['pwd_issue']);
$bFailedLogin = ($sIssue != null); // Force the "failed login" flag to display the "issue" message
UserRights::Login($sAuthUser); // Set the user's language
$oPage = self::NewLoginWebPage();
$oPage->DisplayChangePwdForm();
$oPage->DisplayChangePwdForm($bFailedLogin, $sIssue);
$oPage->output();
exit;
}

View File

@@ -604,7 +604,7 @@ abstract class User extends cmdbAbstractObject
* @throws \OQLException
* @since 3.0.0
*/
private function IsCurrentUser(): bool
protected function IsCurrentUser(): bool
{
if (is_null(UserRights::GetUserId())) {
return false;

View File

@@ -36,6 +36,8 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:UserLocal/Attribute:expiration/Value:never_expire+' => '',
'Class:UserLocal/Attribute:expiration/Value:force_expire' => 'abgelaufen',
'Class:UserLocal/Attribute:expiration/Value:force_expire+' => '',
'Class:UserLocal/Attribute:expiration/Value:otp_expire' => 'einmaliges Passwort',
'Class:UserLocal/Attribute:expiration/Value:otp_expire+' => '',
'Class:UserLocal/Attribute:password_renewed_date' => 'Letzte Passworterneuerung',
'Class:UserLocal/Attribute:password_renewed_date+' => 'Letztes Änderungsdatum',

View File

@@ -49,10 +49,13 @@ Dict::Add('EN US', 'English', 'English', array(
'Class:UserLocal/Attribute:expiration/Value:never_expire+' => '',
'Class:UserLocal/Attribute:expiration/Value:force_expire' => 'Expired',
'Class:UserLocal/Attribute:expiration/Value:force_expire+' => '',
'Class:UserLocal/Attribute:password_renewed_date' => 'Password renewal',
'Class:UserLocal/Attribute:expiration/Value:otp_expire' => 'One-time Password',
'Class:UserLocal/Attribute:expiration/Value:otp_expire+' => 'Password cannot be changed by the user.',
'Class:UserLocal/Attribute:password_renewed_date' => 'Password renewed on',
'Class:UserLocal/Attribute:password_renewed_date+' => 'When the password was last changed',
'Error:UserLocalPasswordValidator:UserPasswordPolicyRegex:ValidationFailed' => 'Password must be at least 8 characters and include uppercase, lowercase, numeric and special characters.',
'UserLocal:password:expiration' => 'The fields below require an extension'
'UserLocal:password:expiration' => 'The fields below require an extension',
'Class:UserLocal/Error:OneTimePasswordChangeIsNotAllowed' => 'Setting password expiration to "One-time password" is not allowed for your own User',
));

View File

@@ -27,16 +27,19 @@ Dict::Add('FR FR', 'French', 'Français', array(
'Class:UserLocal/Attribute:expiration' => 'Validité du mot de passe',
'Class:UserLocal/Attribute:expiration+' => 'Statut du mot de passe (nécessite une extension pour avoir un effet)',
'Class:UserLocal/Attribute:expiration/Value:can_expire' => 'à durée limitée',
'Class:UserLocal/Attribute:expiration/Value:can_expire' => 'Durée limitée',
'Class:UserLocal/Attribute:expiration/Value:can_expire+' => '',
'Class:UserLocal/Attribute:expiration/Value:never_expire' => 'à validité permanente',
'Class:UserLocal/Attribute:expiration/Value:never_expire' => 'Permanente',
'Class:UserLocal/Attribute:expiration/Value:never_expire+' => '',
'Class:UserLocal/Attribute:expiration/Value:force_expire' => 'à changer',
'Class:UserLocal/Attribute:expiration/Value:force_expire' => 'A changer à la prochaine connexion',
'Class:UserLocal/Attribute:expiration/Value:force_expire+' => '',
'Class:UserLocal/Attribute:expiration/Value:otp_expire' => 'Usage unique',
'Class:UserLocal/Attribute:expiration/Value:otp_expire+' => '',
'Class:UserLocal/Attribute:password_renewed_date' => 'Mot de passe changé le',
'Class:UserLocal/Attribute:password_renewed_date+' => 'Dernière date à laquelle le mot de passe a été changé',
'Error:UserLocalPasswordValidator:UserPasswordPolicyRegex:ValidationFailed' => 'Le mot de passe doit contenir au moins 8 caractères, avec minuscule, majuscule, nombre et caractère spécial.',
'UserLocal:password:expiration' => 'Les champs ci-dessous nécessitent une extension'
'UserLocal:password:expiration' => 'Les champs ci-dessous nécessitent une extension',
'Class:UserLocal/Error:OneTimePasswordChangeIsNotAllowed' => 'Impossible de mettre "Usage unique" comme validité du mot de passe pour son propre utilisateur.',
));

View File

@@ -68,7 +68,8 @@ class UserLocal extends UserInternal
const EXPIRE_CAN = 'can_expire';
const EXPIRE_NEVER = 'never_expire';
const EXPIRE_FORCE = 'force_expire';
const EXPIRE_ONE_TIME_PWD = 'otp_expire';
/** @var UserLocalPasswordValidity|null */
protected $m_oPasswordValidity = null;
@@ -90,8 +91,8 @@ class UserLocal extends UserInternal
MetaModel::Init_AddAttribute(new AttributeOneWayPassword("password", array("allowed_values"=>null, "sql"=>"pwd", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
$sExpireEnum = implode(',', array(self::EXPIRE_CAN, self::EXPIRE_NEVER, self::EXPIRE_FORCE));
MetaModel::Init_AddAttribute(new AttributeEnum("expiration", array("allowed_values"=>new ValueSetEnum($sExpireEnum), "sql"=>"expiration", "default_value"=>'never_expire', "is_null_allowed"=>false, "depends_on"=>array())));
$sExpireEnum = implode(',', array(self::EXPIRE_CAN, self::EXPIRE_NEVER, self::EXPIRE_FORCE, self::EXPIRE_ONE_TIME_PWD));
MetaModel::Init_AddAttribute(new AttributeEnum("expiration", array("allowed_values"=>new ValueSetEnum($sExpireEnum), "sql"=>"expiration", "default_value"=>self::EXPIRE_NEVER, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDate("password_renewed_date", array("allowed_values"=>null, "sql"=>"password_renewed_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
// Display lists
@@ -136,6 +137,10 @@ class UserLocal extends UserInternal
{
return false;
}
if($this->Get('expiration') == self::EXPIRE_ONE_TIME_PWD)
{
return false;
}
return true;
}
@@ -184,6 +189,8 @@ class UserLocal extends UserInternal
protected function OnInsert()
{
parent::OnInsert();
$sToday = date(\AttributeDate::GetInternalFormat());
$this->Set('password_renewed_date', $sToday);
$this->OnWrite();
}
@@ -202,6 +209,15 @@ class UserLocal extends UserInternal
$sNow = date(\AttributeDate::GetInternalFormat());
$this->Set('password_renewed_date', $sNow);
// Reset the "force" expiration flag when the user updates her/his own password!
if ($this->IsCurrentUser())
{
if (($this->Get('expiration') == self::EXPIRE_FORCE))
{
$this->Set('expiration', self::EXPIRE_CAN);
}
}
}
public function IsPasswordValid()
@@ -278,7 +294,13 @@ class UserLocal extends UserInternal
{
$this->m_aCheckIssues[] = $this->m_oPasswordValidity->getPasswordValidityMessage();
}
// A User cannot force a one-time password on herself/himself
if ($this->IsCurrentUser()) {
if (array_key_exists('expiration', $this->ListChanges()) && ($this->Get('expiration') == self::EXPIRE_ONE_TIME_PWD)) {
$this->m_aCheckIssues[] = Dict::S('Class:UserLocal/Error:OneTimePasswordChangeIsNotAllowed');
}
}
parent::DoCheckToWrite();
}