@ -107,6 +107,7 @@ public class DefaultSystemSecurityService implements SystemSecurityService {
securitySettings = new SecuritySettings ( ) ;
securitySettings = new SecuritySettings ( ) ;
securitySettings . setPasswordPolicy ( new UserPasswordPolicy ( ) ) ;
securitySettings . setPasswordPolicy ( new UserPasswordPolicy ( ) ) ;
securitySettings . getPasswordPolicy ( ) . setMinimumLength ( 6 ) ;
securitySettings . getPasswordPolicy ( ) . setMinimumLength ( 6 ) ;
securitySettings . getPasswordPolicy ( ) . setMaximumLength ( 72 ) ;
}
}
return securitySettings ;
return securitySettings ;
}
}
@ -131,9 +132,18 @@ public class DefaultSystemSecurityService implements SystemSecurityService {
@Override
@Override
public void validateUserCredentials ( TenantId tenantId , UserCredentials userCredentials , String username , String password ) throws AuthenticationException {
public void validateUserCredentials ( TenantId tenantId , UserCredentials userCredentials , String username , String password ) throws AuthenticationException {
SecuritySettings securitySettings = self . getSecuritySettings ( tenantId ) ;
UserPasswordPolicy passwordPolicy = securitySettings . getPasswordPolicy ( ) ;
if ( passwordPolicy . getForceUserToResetPasswordIfNotValid ( ) ) {
try {
validatePasswordByPolicy ( password , passwordPolicy ) ;
} catch ( DataValidationException e ) {
throw new BadCredentialsException ( "Password does not pass validation. Please try again or reset password to valid one." ) ;
}
}
if ( ! encoder . matches ( password , userCredentials . getPassword ( ) ) ) {
if ( ! encoder . matches ( password , userCredentials . getPassword ( ) ) ) {
int failedLoginAttempts = userService . increaseFailedLoginAttempts ( tenantId , userCredentials . getUserId ( ) ) ;
int failedLoginAttempts = userService . increaseFailedLoginAttempts ( tenantId , userCredentials . getUserId ( ) ) ;
SecuritySettings securitySettings = self . getSecuritySettings ( tenantId ) ;
if ( securitySettings . getMaxFailedLoginAttempts ( ) ! = null & & securitySettings . getMaxFailedLoginAttempts ( ) > 0 ) {
if ( securitySettings . getMaxFailedLoginAttempts ( ) ! = null & & securitySettings . getMaxFailedLoginAttempts ( ) > 0 ) {
if ( failedLoginAttempts > securitySettings . getMaxFailedLoginAttempts ( ) & & userCredentials . isEnabled ( ) ) {
if ( failedLoginAttempts > securitySettings . getMaxFailedLoginAttempts ( ) & & userCredentials . isEnabled ( ) ) {
lockAccount ( userCredentials . getUserId ( ) , username , securitySettings . getUserLockoutNotificationEmail ( ) , securitySettings . getMaxFailedLoginAttempts ( ) ) ;
lockAccount ( userCredentials . getUserId ( ) , username , securitySettings . getUserLockoutNotificationEmail ( ) , securitySettings . getMaxFailedLoginAttempts ( ) ) ;
@ -149,7 +159,6 @@ public class DefaultSystemSecurityService implements SystemSecurityService {
userService . resetFailedLoginAttempts ( tenantId , userCredentials . getUserId ( ) ) ;
userService . resetFailedLoginAttempts ( tenantId , userCredentials . getUserId ( ) ) ;
SecuritySettings securitySettings = self . getSecuritySettings ( tenantId ) ;
if ( isPositiveInteger ( securitySettings . getPasswordPolicy ( ) . getPasswordExpirationPeriodDays ( ) ) ) {
if ( isPositiveInteger ( securitySettings . getPasswordPolicy ( ) . getPasswordExpirationPeriodDays ( ) ) ) {
if ( ( userCredentials . getCreatedTime ( )
if ( ( userCredentials . getCreatedTime ( )
+ TimeUnit . DAYS . toMillis ( securitySettings . getPasswordPolicy ( ) . getPasswordExpirationPeriodDays ( ) ) )
+ TimeUnit . DAYS . toMillis ( securitySettings . getPasswordPolicy ( ) . getPasswordExpirationPeriodDays ( ) ) )
@ -199,8 +208,26 @@ public class DefaultSystemSecurityService implements SystemSecurityService {
SecuritySettings securitySettings = self . getSecuritySettings ( tenantId ) ;
SecuritySettings securitySettings = self . getSecuritySettings ( tenantId ) ;
UserPasswordPolicy passwordPolicy = securitySettings . getPasswordPolicy ( ) ;
UserPasswordPolicy passwordPolicy = securitySettings . getPasswordPolicy ( ) ;
validatePasswordByPolicy ( password , passwordPolicy ) ;
if ( userCredentials ! = null & & isPositiveInteger ( passwordPolicy . getPasswordReuseFrequencyDays ( ) ) ) {
long passwordReuseFrequencyTs = System . currentTimeMillis ( ) - TimeUnit . DAYS . toMillis ( passwordPolicy . getPasswordReuseFrequencyDays ( ) ) ;
JsonNode additionalInfo = userCredentials . getAdditionalInfo ( ) ;
if ( additionalInfo instanceof ObjectNode & & additionalInfo . has ( UserServiceImpl . USER_PASSWORD_HISTORY ) ) {
JsonNode userPasswordHistoryJson = additionalInfo . get ( UserServiceImpl . USER_PASSWORD_HISTORY ) ;
Map < String , String > userPasswordHistoryMap = JacksonUtil . convertValue ( userPasswordHistoryJson , new TypeReference < > ( ) { } ) ;
for ( Map . Entry < String , String > entry : userPasswordHistoryMap . entrySet ( ) ) {
if ( encoder . matches ( password , entry . getValue ( ) ) & & Long . parseLong ( entry . getKey ( ) ) > passwordReuseFrequencyTs ) {
throw new DataValidationException ( "Password was already used for the last " + passwordPolicy . getPasswordReuseFrequencyDays ( ) + " days" ) ;
}
}
}
}
}
private void validatePasswordByPolicy ( String password , UserPasswordPolicy passwordPolicy ) {
List < Rule > passwordRules = new ArrayList < > ( ) ;
List < Rule > passwordRules = new ArrayList < > ( ) ;
passwordRules . add ( new LengthRule ( passwordPolicy . getMinimumLength ( ) , Integer . MAX_VALUE ) ) ;
passwordRules . add ( new LengthRule ( passwordPolicy . getMinimumLength ( ) , passwordPolicy . getMaximumLength ( ) ) ) ;
if ( isPositiveInteger ( passwordPolicy . getMinimumUppercaseLetters ( ) ) ) {
if ( isPositiveInteger ( passwordPolicy . getMinimumUppercaseLetters ( ) ) ) {
passwordRules . add ( new CharacterRule ( EnglishCharacterData . UpperCase , passwordPolicy . getMinimumUppercaseLetters ( ) ) ) ;
passwordRules . add ( new CharacterRule ( EnglishCharacterData . UpperCase , passwordPolicy . getMinimumUppercaseLetters ( ) ) ) ;
}
}
@ -223,21 +250,6 @@ public class DefaultSystemSecurityService implements SystemSecurityService {
String message = String . join ( "\n" , validator . getMessages ( result ) ) ;
String message = String . join ( "\n" , validator . getMessages ( result ) ) ;
throw new DataValidationException ( message ) ;
throw new DataValidationException ( message ) ;
}
}
if ( userCredentials ! = null & & isPositiveInteger ( passwordPolicy . getPasswordReuseFrequencyDays ( ) ) ) {
long passwordReuseFrequencyTs = System . currentTimeMillis ( ) - TimeUnit . DAYS . toMillis ( passwordPolicy . getPasswordReuseFrequencyDays ( ) ) ;
JsonNode additionalInfo = userCredentials . getAdditionalInfo ( ) ;
if ( additionalInfo instanceof ObjectNode & & additionalInfo . has ( UserServiceImpl . USER_PASSWORD_HISTORY ) ) {
JsonNode userPasswordHistoryJson = additionalInfo . get ( UserServiceImpl . USER_PASSWORD_HISTORY ) ;
Map < String , String > userPasswordHistoryMap = JacksonUtil . convertValue ( userPasswordHistoryJson , new TypeReference < > ( ) { } ) ;
for ( Map . Entry < String , String > entry : userPasswordHistoryMap . entrySet ( ) ) {
if ( encoder . matches ( password , entry . getValue ( ) ) & & Long . parseLong ( entry . getKey ( ) ) > passwordReuseFrequencyTs ) {
throw new DataValidationException ( "Password was already used for the last " + passwordPolicy . getPasswordReuseFrequencyDays ( ) + " days" ) ;
}
}
}
}
}
}
@Override
@Override