use of eu.bcvsolutions.idm.core.api.dto.IdmPasswordDto in project CzechIdMng by bcvsolutions.
the class DefaultPasswordFilterManagerIntegrationTest method testValidateWithMinPasswordAgeUnderAdmin.
@Test
public void testValidateWithMinPasswordAgeUnderAdmin() {
SysSystemDto system = createSystem(false);
IdmPasswordPolicyDto policy = new IdmPasswordPolicyDto();
policy.setName(getHelper().createName());
policy.setType(IdmPasswordPolicyType.VALIDATE);
policy.setMinPasswordAge(1);
policy = passwordPolicyService.save(policy);
system.setPasswordPolicyValidate(policy.getId());
system = systemService.save(system);
IdmIdentityDto identity = createIdentity(system);
setPasswordFilter(system, true);
assignSystem(createUniformDefinition(true), system);
cleanProvivisioning(identity, system);
checkChangeInIdm(identity, 0);
String password = getHelper().createName();
PasswordRequest request = prepareRequest(identity.getUsername(), system.getCode(), password);
IdmPasswordDto idmPassword = passwordService.findOneByIdentity(identity.getId());
Assert.assertNull(idmPassword);
checkEmptyProvisioning(identity, system);
checkEcho(identity, system, EchoCheck.DOESNT_EXIST);
checkChangeInIdm(identity, 0);
processValidate(request, true);
checkEcho(identity, system, EchoCheck.VALIDATE);
checkChangeInIdm(identity, 0);
checkEmptyProvisioning(identity, system);
processChange(request, true);
checkEcho(identity, system, EchoCheck.VALIDATE_AND_CHANGE);
checkChangeInIdm(identity, 1);
checkEmptyProvisioning(identity, system);
idmPassword = passwordService.findOneByIdentity(identity.getId());
Assert.assertNotNull(idmPassword);
// under different user, but set
Assert.assertNotNull(idmPassword.getValidFrom());
// success => admin can change password
try {
request.setPassword(getHelper().createName());
getHelper().loginAdmin();
//
AccPasswordFilterRequestDto passwordFilterRequest = new AccPasswordFilterRequestDto();
passwordFilterRequest.setUsername(identity.getUsername());
// different password => new validate without cache
passwordFilterRequest.setPassword(new GuardedString(getHelper().createName()));
passwordFilterRequest.setResource(system.getCode());
//
passwordFilterManager.validate(passwordFilterRequest);
} finally {
getHelper().logout();
}
}
use of eu.bcvsolutions.idm.core.api.dto.IdmPasswordDto in project CzechIdMng by bcvsolutions.
the class DefaultPasswordFilterManagerIntegrationTest method testValidateWithMinPasswordAgeFailed.
@Test(expected = PasswordChangeException.class)
public void testValidateWithMinPasswordAgeFailed() {
SysSystemDto system = createSystem(false);
IdmPasswordPolicyDto policy = new IdmPasswordPolicyDto();
policy.setName(getHelper().createName());
policy.setType(IdmPasswordPolicyType.VALIDATE);
policy.setMinPasswordAge(1);
policy = passwordPolicyService.save(policy);
system.setPasswordPolicyValidate(policy.getId());
system = systemService.save(system);
IdmIdentityDto identity = createIdentity(system);
setPasswordFilter(system, true);
assignSystem(createUniformDefinition(true), system);
cleanProvivisioning(identity, system);
checkChangeInIdm(identity, 0);
String password = getHelper().createName();
PasswordRequest request = prepareRequest(identity.getUsername(), system.getCode(), password);
IdmPasswordDto idmPassword = passwordService.findOneByIdentity(identity.getId());
Assert.assertNull(idmPassword);
checkEmptyProvisioning(identity, system);
checkEcho(identity, system, EchoCheck.DOESNT_EXIST);
checkChangeInIdm(identity, 0);
processValidate(request, true);
checkEcho(identity, system, EchoCheck.VALIDATE);
checkChangeInIdm(identity, 0);
checkEmptyProvisioning(identity, system);
processChange(request, true);
checkEcho(identity, system, EchoCheck.VALIDATE_AND_CHANGE);
checkChangeInIdm(identity, 1);
checkEmptyProvisioning(identity, system);
idmPassword = passwordService.findOneByIdentity(identity.getId());
Assert.assertNotNull(idmPassword);
// under different user, but set
Assert.assertNotNull(idmPassword.getValidFrom());
// fail => cannot be changed again by policy
try {
request.setPassword(getHelper().createName());
IdmIdentityDto manager = getHelper().createIdentity();
getHelper().login(manager);
//
AccPasswordFilterRequestDto passwordFilterRequest = new AccPasswordFilterRequestDto();
passwordFilterRequest.setUsername(identity.getUsername());
// different password => new validate without cache
passwordFilterRequest.setPassword(new GuardedString(getHelper().createName()));
passwordFilterRequest.setResource(system.getCode());
//
passwordFilterManager.validate(passwordFilterRequest);
} finally {
getHelper().logout();
}
}
use of eu.bcvsolutions.idm.core.api.dto.IdmPasswordDto in project CzechIdMng by bcvsolutions.
the class DefaultPasswordFilterManagerIntegrationTest method testCheckPasswordValidityNull.
@Test
public void testCheckPasswordValidityNull() {
IdmPasswordPolicyDto passwordPolicy = createPasswordPolicy(null, null, null, null, null, true);
passwordPolicy.setMaxPasswordAge(null);
passwordPolicy = passwordPolicyService.save(passwordPolicy);
SysSystemDto system = createSystem(false);
IdmIdentityDto identity = createIdentity(system);
assignSystem(createUniformDefinition(true), system);
setPasswordFilter(system, true);
String password = getHelper().createName();
PasswordChangeDto passwordChangeDto = new PasswordChangeDto();
passwordChangeDto.setAll(true);
passwordChangeDto.setNewPassword(new GuardedString(password));
List<OperationResult> results = identityService.passwordChange(identity, passwordChangeDto);
assertEquals(2, results.size());
checkEcho(identity, system, EchoCheck.VALIDATE_AND_CHANGE);
checkPassword(prepareUid(identity, system), password, true);
checkActivePasswordOperation(identity, system, 0, password);
loginToIdm(identity, password, true);
IdmPasswordDto passwordDto = passwordService.findOneByIdentity(identity.getId());
assertNotNull(passwordDto);
assertNull(passwordDto.getValidTill());
Assert.assertNull(passwordDto.getValidFrom());
}
use of eu.bcvsolutions.idm.core.api.dto.IdmPasswordDto in project CzechIdMng by bcvsolutions.
the class DefaultIdmPasswordService method save.
@Override
@Transactional
public IdmPasswordDto save(IdmIdentityDto identity, PasswordChangeDto passwordChangeDto) {
Assert.notNull(identity, "Identity is required.");
Assert.notNull(passwordChangeDto, "Password change dto is required.");
Assert.notNull(passwordChangeDto.getNewPassword(), "New password is required.");
GuardedString newPassword = passwordChangeDto.getNewPassword();
//
IdmPasswordDto password = getPasswordByIdentity(identity.getId());
//
if (password == null) {
// identity has no password yet
password = new IdmPasswordDto();
password.setIdentity(identity.getId());
}
//
if (passwordChangeDto.getMaxPasswordAge() != null) {
password.setValidTill(passwordChangeDto.getMaxPasswordAge().toLocalDate());
} else {
password.setValidTill(null);
}
//
UUID ownerId = password.getIdentity();
UUID currentId = securityService.getCurrentId();
// resolve password valid from, if password is saved by other logged identity
if (// currentId can be null => system
!Objects.equals(currentId, password.getIdentity()) && !passwordChangeDto.isSkipResetValidFrom()) {
password.setValidFrom(null);
LOG.debug("Password owner [{}] is different than logged identity [{}], " + "password will not be checked for minimum days, when password is changed next time by password owner", ownerId, currentId);
} else {
// set new password validity ~ creation date
LocalDate now = LocalDate.now();
password.setValidFrom(now);
LOG.trace("Password (for password owner [{}]) valid from [{}] set.", ownerId, now);
}
//
password.setPassword(this.generateHash(newPassword, getSalt()));
//
// set must change password to false
password.setMustChange(false);
//
// reset unsuccessful attempts, after password is changed
password.resetUnsuccessfulAttempts();
//
// Clear block loging date
password.setBlockLoginDate(null);
//
// create new password history with currently changed password
createPasswordHistory(password);
//
return save(password);
}
use of eu.bcvsolutions.idm.core.api.dto.IdmPasswordDto in project CzechIdMng by bcvsolutions.
the class DefaultIdmPasswordPolicyService method validate.
private void validate(IdmPasswordValidationDto passwordValidationDto, List<IdmPasswordPolicyDto> passwordPolicies, boolean prevalidation) {
Assert.notNull(passwordPolicies, "Password policies are required.");
Assert.notNull(passwordValidationDto, "Password validation dto is required.");
IdmIdentityDto identity = passwordValidationDto.getIdentity();
// default password policy is used when list of password policies is empty, or for get maximum equals password
IdmPasswordPolicyDto defaultPolicy = this.getDefaultPasswordPolicy(IdmPasswordPolicyType.VALIDATE);
// if list is empty, get default password policy
if (passwordPolicies.isEmpty() && !prevalidation) {
if (defaultPolicy != null) {
passwordPolicies.add(defaultPolicy);
}
}
// if list with password policies is empty, validate is always true
if (passwordPolicies.isEmpty()) {
// this state means that system IdM hasn't default password policy
return;
}
IdmPasswordDto oldPassword = null;
// For checking with old password identity must has ID (for create doesn't exists ID)
if (identity != null && identity.getId() != null) {
oldPassword = passwordService.findOneByIdentity(identity.getId());
}
String password = passwordValidationDto.getPassword().asString();
ZonedDateTime now = ZonedDateTime.now();
Map<String, Object> errors = new HashMap<>();
Set<Character> prohibitedChar = new HashSet<>();
String prohibitedBeginChar = null;
String prohibitedEndChar = null;
List<String> policyNames = new ArrayList<String>();
Map<String, Object> specialCharBase = new HashMap<>();
Map<String, Object> forbiddenCharBase = new HashMap<>();
Map<String, Object> forbiddenBeginCharBase = new HashMap<>();
Map<String, Object> forbiddenEndCharBase = new HashMap<>();
for (IdmPasswordPolicyDto passwordPolicy : passwordPolicies) {
if (passwordPolicy.isDisabled()) {
continue;
}
boolean validateNotSuccess = false;
// check if can change password for minimal age for change
Integer minPasswordAge = passwordPolicy.getMinPasswordAge();
boolean enforceMinPasswordAgeValidation = passwordValidationDto.isEnforceMinPasswordAgeValidation();
if (minPasswordAge != null && oldPassword != null && !oldPassword.isMustChange() && !prevalidation && !securityService.isAdmin() && (// force => checked even when owner and logged user is different
enforceMinPasswordAgeValidation || Objects.equals(securityService.getCurrentId(), oldPassword.getIdentity()))) {
LocalDate passwordValidFrom = oldPassword.getValidFrom();
if (// check can be disabled (by previous change attempt)
passwordValidFrom != null && passwordValidFrom.plusDays(minPasswordAge).compareTo(now.toLocalDate()) > 0) {
throw new PasswordChangeException(passwordValidFrom.plusDays(minPasswordAge));
}
}
// minimum rules to fulfill
Map<String, Object> notPassRules = new HashMap<>();
int minRulesToFulfill = passwordPolicy.getMinRulesToFulfill() == null ? 0 : passwordPolicy.getMinRulesToFulfill().intValue();
// check to max password length
if (!isNull(passwordPolicy.getMaxPasswordLength()) && (password.length() > passwordPolicy.getMaxPasswordLength() || prevalidation)) {
if (!passwordPolicy.isPasswordLengthRequired() && passwordPolicy.isEnchancedControl()) {
notPassRules.put(MAX_LENGTH, Math.min(convertToInt(errors.get(MAX_LENGTH)), passwordPolicy.getMaxPasswordLength()));
} else if (!(errors.containsKey(MAX_LENGTH) && compareInt(passwordPolicy.getMaxPasswordLength(), errors.get(MAX_LENGTH)))) {
errors.put(MAX_LENGTH, passwordPolicy.getMaxPasswordLength());
}
validateNotSuccess = true;
}
// check to minimal password length
if (!isNullOrZeroValue(passwordPolicy.getMinPasswordLength()) && password.length() < passwordPolicy.getMinPasswordLength()) {
if (!passwordPolicy.isPasswordLengthRequired() && passwordPolicy.isEnchancedControl()) {
notPassRules.put(MIN_LENGTH, Math.max(convertToInt(errors.get(MIN_LENGTH)), passwordPolicy.getMinPasswordLength()));
} else if (!(errors.containsKey(MIN_LENGTH) && compareInt(errors.get(MIN_LENGTH), passwordPolicy.getMinPasswordLength()))) {
errors.put(MIN_LENGTH, passwordPolicy.getMinPasswordLength());
}
validateNotSuccess = true;
}
// check to prohibited characters
if (!Strings.isNullOrEmpty(passwordPolicy.getProhibitedCharacters()) && !password.matches("[^" + Pattern.quote(passwordPolicy.getProhibitedCharacters()) + "]*")) {
for (char character : passwordPolicy.getProhibitedCharacters().toCharArray()) {
if (password.indexOf(character) >= 0) {
prohibitedChar.add(character);
}
}
validateNotSuccess = true;
}
// check character at the beginning
prohibitedBeginChar = checkInitialFinalCharForbidden(password, passwordPolicy.getProhibitedBeginCharacters(), true);
// check character at the end
prohibitedEndChar = checkInitialFinalCharForbidden(password, passwordPolicy.getProhibitedEndCharacters(), false);
// check to minimal numbers
if (!isNullOrZeroValue(passwordPolicy.getMinNumber()) && !password.matches("(.*[" + Pattern.quote(passwordPolicy.getNumberBase()) + "].*){" + passwordPolicy.getMinNumber() + ",}")) {
if (!passwordPolicy.isNumberRequired() && passwordPolicy.isEnchancedControl()) {
notPassRules.put(MIN_NUMBER, Math.max(convertToInt(errors.get(MIN_NUMBER)), passwordPolicy.getMinNumber()));
} else if (!(errors.containsKey(MIN_NUMBER) && compareInt(errors.get(MIN_NUMBER), passwordPolicy.getMinNumber()))) {
errors.put(MIN_NUMBER, passwordPolicy.getMinNumber());
}
validateNotSuccess = true;
}
// check to minimal lower characters
if (!isNullOrZeroValue(passwordPolicy.getMinLowerChar()) && !password.matches("(.*[" + Pattern.quote(passwordPolicy.getLowerCharBase()) + "].*){" + passwordPolicy.getMinLowerChar() + ",}")) {
if (!passwordPolicy.isLowerCharRequired() && passwordPolicy.isEnchancedControl()) {
notPassRules.put(MIN_LOWER_CHAR, Math.max(convertToInt(errors.get(MIN_LOWER_CHAR)), passwordPolicy.getMinLowerChar()));
} else if (!(errors.containsKey(MIN_LOWER_CHAR) && compareInt(errors.get(MIN_LOWER_CHAR), passwordPolicy.getMinLowerChar()))) {
errors.put(MIN_LOWER_CHAR, passwordPolicy.getMinLowerChar());
}
validateNotSuccess = true;
}
// check to minimal upper character
if (!isNullOrZeroValue(passwordPolicy.getMinUpperChar()) && !password.matches("(.*[" + Pattern.quote(passwordPolicy.getUpperCharBase()) + "].*){" + passwordPolicy.getMinUpperChar() + ",}")) {
if (!passwordPolicy.isUpperCharRequired() && passwordPolicy.isEnchancedControl()) {
notPassRules.put(MIN_UPPER_CHAR, Math.max(convertToInt(errors.get(MIN_UPPER_CHAR)), passwordPolicy.getMinUpperChar()));
} else if (!(errors.containsKey(MIN_UPPER_CHAR) && compareInt(errors.get(MIN_UPPER_CHAR), passwordPolicy.getMinUpperChar()))) {
errors.put(MIN_UPPER_CHAR, passwordPolicy.getMinUpperChar());
}
validateNotSuccess = true;
}
// check to minimal special character and add special character base
if (!isNullOrZeroValue(passwordPolicy.getMinSpecialChar()) && !password.matches("(.*[" + Pattern.quote(passwordPolicy.getSpecialCharBase()) + "].*){" + passwordPolicy.getMinSpecialChar() + ",}")) {
if (!passwordPolicy.isSpecialCharRequired() && passwordPolicy.isEnchancedControl()) {
notPassRules.put(MIN_SPECIAL_CHAR, Math.max(convertToInt(errors.get(MIN_SPECIAL_CHAR)), passwordPolicy.getMinSpecialChar()));
specialCharBase.put(passwordPolicy.getName(), passwordPolicy.getSpecialCharBase());
} else if (!(errors.containsKey(MIN_SPECIAL_CHAR) && compareInt(errors.get(MIN_SPECIAL_CHAR), passwordPolicy.getMinSpecialChar()))) {
errors.put(MIN_SPECIAL_CHAR, passwordPolicy.getMinSpecialChar());
specialCharBase.put(passwordPolicy.getName(), passwordPolicy.getSpecialCharBase());
}
validateNotSuccess = true;
}
// building of character bases of forbidden characters in passwords for password hints
if (passwordPolicy.getProhibitedCharacters() != null) {
forbiddenCharBase.put(passwordPolicy.getName(), passwordPolicy.getProhibitedCharacters());
}
if (!Strings.isNullOrEmpty(passwordPolicy.getProhibitedBeginCharacters())) {
forbiddenBeginCharBase.put(passwordPolicy.getName(), passwordPolicy.getProhibitedBeginCharacters());
}
if (!Strings.isNullOrEmpty(passwordPolicy.getProhibitedEndCharacters())) {
forbiddenEndCharBase.put(passwordPolicy.getName(), passwordPolicy.getProhibitedEndCharacters());
}
if (!notPassRules.isEmpty() && passwordPolicy.isEnchancedControl()) {
int notRequiredRules = passwordPolicy.getNotRequiredRules();
int missingRules = notRequiredRules - notPassRules.size();
if (missingRules - minRulesToFulfill < 0) {
errors.put(MIN_RULES_TO_FULFILL_COUNT, minRulesToFulfill - missingRules);
errors.put(MIN_RULES_TO_FULFILL, notPassRules);
}
}
// if not success we want password policy name
if (validateNotSuccess && !errors.isEmpty() && !prevalidation) {
policyNames.add(passwordPolicy.getName());
}
// check to similar identity attributes, enhanced control
if (prevalidation) {
enhancedControlForSimilar(passwordPolicy, prevalidation, errors);
} else {
enhancedControlForSimilar(passwordPolicy, passwordValidationDto, errors);
}
// TODO: weak words
}
if (!specialCharBase.isEmpty() && prevalidation) {
errors.put(SPECIAL_CHARACTER_BASE, specialCharBase);
}
if (!forbiddenCharBase.isEmpty() && prevalidation) {
errors.put(FORBIDDEN_CHARACTER_BASE, forbiddenCharBase);
}
if (!forbiddenBeginCharBase.isEmpty() && prevalidation) {
errors.put(FORBIDDEN_BEGIN_CHARACTER_BASE, forbiddenBeginCharBase);
}
if (!forbiddenEndCharBase.isEmpty() && prevalidation) {
errors.put(FORBIDDEN_END_CHARACTER_BASE, forbiddenEndCharBase);
}
if (!policyNames.isEmpty() && !prevalidation) {
String name = prevalidation ? POLICY_NAME_PREVALIDATION : POLICY_NAME;
errors.put(name, String.join(", ", policyNames));
}
if (!prohibitedChar.isEmpty()) {
errors.put(COINTAIN_PROHIBITED, prohibitedChar.toString());
}
if (!Strings.isNullOrEmpty(prohibitedBeginChar)) {
errors.put(BEGIN_PROHIBITED, prohibitedBeginChar);
}
if (!Strings.isNullOrEmpty(prohibitedEndChar)) {
errors.put(END_PROHIBITED, prohibitedEndChar);
}
// in some case (tests) are save identity in one transaction and id doesn't exist
if (!prevalidation && defaultPolicy != null) {
Integer maxHistorySimilar = defaultPolicy.getMaxHistorySimilar();
if (maxHistorySimilar != null && identity != null && identity.getId() != null) {
boolean checkHistory = passwordHistoryService.checkHistory(passwordValidationDto.getIdentity().getId(), maxHistorySimilar, passwordValidationDto.getPassword());
if (checkHistory) {
errors.put(MAX_HISTORY_SIMILAR, maxHistorySimilar);
}
}
}
if (!errors.isEmpty()) {
// TODO: password policy audit
if (prevalidation) {
throw new ResultCodeException(CoreResultCode.PASSWORD_PREVALIDATION, errors);
}
throw new ResultCodeException(CoreResultCode.PASSWORD_DOES_NOT_MEET_POLICY, errors);
}
}
Aggregations