use of eu.bcvsolutions.idm.acc.dto.AccUniformPasswordDto in project CzechIdMng by bcvsolutions.
the class DefaultUniformPasswordManagerIntegrationTest method testUniformPassword.
@Test
public void testUniformPassword() {
try {
// Turn on an async execution.
getHelper().setConfigurationValue(EventConfiguration.PROPERTY_EVENT_ASYNCHRONOUS_ENABLED, true);
getHelper().setConfigurationValue(SchedulerConfiguration.PROPERTY_TASK_ASYNCHRONOUS_ENABLED, true);
SysSystemDto contractSystem = initData();
Assert.assertNotNull(contractSystem);
IdmTreeTypeDto treeType = helper.createTreeType();
AbstractSysSyncConfigDto config = doCreateSyncConfig(contractSystem, treeType);
Assert.assertTrue(config instanceof SysSyncContractConfigDto);
SysSystemDto targetSystemOne = helper.createTestResourceSystem(true);
// Create system two with account suffix "_targetSystemTwo".
String targetSystemTwoSuffix = "_targetSystemTwo";
SysSystemDto targetSystemTwo = helper.createTestResourceSystem(true);
// Create uniform password definition.
AccUniformPasswordDto uniformPasswordDef = createUniformPasswordDef(targetSystemOne, targetSystemTwo);
SysSystemMappingDto provisioningMapping = systemMappingService.findProvisioningMapping(targetSystemTwo.getId(), SystemEntityType.IDENTITY);
List<SysSystemAttributeMappingDto> attributeMappingDtos = schemaAttributeMappingService.findBySystemMapping(provisioningMapping);
SysSystemAttributeMappingDto uidAttribute = schemaAttributeMappingService.getUidAttribute(attributeMappingDtos, targetSystemTwo);
uidAttribute.setTransformToResourceScript("return attributeValue + \"" + targetSystemTwoSuffix + "\"");
schemaAttributeMappingService.save(uidAttribute);
IdmRoleDto automaticRoleTreeOne = helper.createRole();
helper.createRoleSystem(automaticRoleTreeOne, targetSystemOne);
IdmTreeNodeDto treeNodeOne = helper.createTreeNode(treeType, null);
helper.createAutomaticRole(automaticRoleTreeOne, treeNodeOne);
IdmRoleDto automaticRoleTreeTwo = helper.createRole();
helper.createRoleSystem(automaticRoleTreeTwo, targetSystemTwo);
IdmTreeNodeDto treeNodeTwo = helper.createTreeNode(treeType, null);
helper.createAutomaticRole(automaticRoleTreeTwo, treeNodeTwo);
IdmIdentityDto ownerOne = helper.createIdentityOnly();
List<TestContractResource> contractResources = Lists.newArrayList(this.createContract("1", ownerOne.getUsername(), null, "true", treeNodeOne.getCode(), null, null, null), this.createContract("2", ownerOne.getUsername(), null, "false", treeNodeTwo.getCode(), null, null, null));
this.getBean().initContractData(contractResources);
IdmIdentityContractFilter contractFilter = new IdmIdentityContractFilter();
contractFilter.setIdentity(ownerOne.getId());
contractService.find(contractFilter, null).getContent().forEach(contract -> contractService.delete(contract));
Assert.assertEquals(0, contractService.find(contractFilter, null).getTotalElements());
IdmIdentityFilter identityFilter = new IdmIdentityFilter();
identityFilter.setAddPasswordMetadata(true);
ownerOne = identityService.get(ownerOne.getId(), identityFilter);
// Identities should be in the CREATED state.
Assert.assertEquals(IdentityState.CREATED, ownerOne.getState());
Assert.assertNull(ownerOne.getPassword());
Assert.assertNull(ownerOne.getPasswordMetadata());
SynchronizationSchedulableTaskExecutor lrt = new SynchronizationSchedulableTaskExecutor(config.getId());
LongRunningFutureTask<Boolean> longRunningFutureTask = longRunningTaskManager.execute(lrt);
UUID transactionIdLrt = longRunningTaskService.get(longRunningFutureTask.getExecutor().getLongRunningTaskId()).getTransactionId();
// Waiting for the LRT will be running.
getHelper().waitForResult(res -> {
return !longRunningTaskService.get(longRunningFutureTask.getExecutor().getLongRunningTaskId()).isRunning();
}, 50, 40);
// Waiting for the LRT will be EXECUTED.
getHelper().waitForResult(res -> {
return longRunningTaskService.get(longRunningFutureTask.getExecutor().getLongRunningTaskId()).getResultState() != OperationState.EXECUTED;
}, 250, 100);
Assert.assertEquals(longRunningTaskService.get(longRunningFutureTask.getExecutor().getLongRunningTaskId()).getResultState(), OperationState.EXECUTED);
SysSyncLogDto log = helper.checkSyncLog(config, SynchronizationActionType.CREATE_ENTITY, 2, OperationResultType.SUCCESS);
Assert.assertFalse(log.isRunning());
Assert.assertFalse(log.isContainsError());
UUID transactionId = log.getTransactionId();
Assert.assertNotNull(transactionId);
Assert.assertEquals(transactionIdLrt, transactionId);
contractFilter.setIdentity(ownerOne.getId());
Assert.assertEquals(2, contractService.count(contractFilter));
ownerOne = identityService.get(ownerOne.getId());
// Identities should have a valid state.
Assert.assertEquals(IdentityState.VALID, ownerOne.getState());
// Waiting for removing entity state.
IdmIdentityDto finalOwnerOne = ownerOne;
getHelper().waitForResult(res -> {
return uniformPasswordManager.getEntityState(finalOwnerOne.getId(), IdmIdentityDto.class, transactionId) != null;
}, 50, 100);
// LRT ended, entityStates must be removed.
IdmEntityStateDto entityStateDtoOwnerOne = uniformPasswordManager.getEntityState(ownerOne.getId(), IdmIdentityDto.class, transactionId);
Assert.assertNull(entityStateDtoOwnerOne);
TestResource resourceOwnerOne = helper.findResource(ownerOne.getUsername());
Assert.assertNotNull(resourceOwnerOne);
TestResource resourceOwnerTwo = helper.findResource(ownerOne.getUsername() + targetSystemTwoSuffix);
Assert.assertNotNull(resourceOwnerTwo);
String passwordOwnerOne = resourceOwnerOne.getPassword();
String passwordOwnerTwo = resourceOwnerTwo.getPassword();
Assert.assertNotNull(passwordOwnerOne);
Assert.assertNotNull(passwordOwnerTwo);
Assert.assertEquals(passwordOwnerOne, passwordOwnerTwo);
// Change in the IdM is disabled.
ownerOne = identityService.get(ownerOne.getId(), identityFilter);
Assert.assertNull(ownerOne.getPassword());
Assert.assertNull(ownerOne.getPasswordMetadata());
// One uniform password notification was send.
IdmNotificationFilter notificationFilter = new IdmNotificationFilter();
notificationFilter.setRecipient(ownerOne.getUsername());
notificationFilter.setNotificationType(IdmEmailLog.class);
notificationFilter.setTopic(CoreModule.TOPIC_UNIFORM_PASSWORD_SET);
List<IdmNotificationLogDto> notificationLogDtos = notificationLogService.find(notificationFilter, null).getContent();
Assert.assertEquals(1, notificationLogDtos.size());
// Check if notification contains code of uniform password group.
IdmNotificationLogDto uniformPasswordSetNotification = notificationLogDtos.get(0);
String notificationBody = uniformPasswordSetNotification.getMessage().getHtmlMessage();
Assert.assertTrue(notificationBody.contains(uniformPasswordDef.getCode()));
// None a new password notification was send.
notificationFilter.setTopic(AccModuleDescriptor.TOPIC_NEW_PASSWORD);
notificationLogDtos = notificationLogService.find(notificationFilter, null).getContent();
Assert.assertEquals(0, notificationLogDtos.size());
// None password set notification was send.
notificationFilter.setTopic(CoreModule.TOPIC_PASSWORD_SET);
notificationLogDtos = notificationLogService.find(notificationFilter, null).getContent();
Assert.assertEquals(0, notificationLogDtos.size());
// None password change notification was send.
notificationFilter.setTopic(CoreModule.TOPIC_PASSWORD_CHANGED);
notificationLogDtos = notificationLogService.find(notificationFilter, null).getContent();
Assert.assertEquals(0, notificationLogDtos.size());
// Delete log
syncLogService.delete(log);
// Delete identities.
identityService.delete(ownerOne);
// Delete uniform password def.
uniformPasswordService.delete(uniformPasswordDef);
} finally {
// Turn off an async execution.
getHelper().setConfigurationValue(EventConfiguration.PROPERTY_EVENT_ASYNCHRONOUS_ENABLED, false);
getHelper().setConfigurationValue(SchedulerConfiguration.PROPERTY_TASK_ASYNCHRONOUS_ENABLED, false);
}
}
use of eu.bcvsolutions.idm.acc.dto.AccUniformPasswordDto in project CzechIdMng by bcvsolutions.
the class DefaultUniformPasswordManagerIntegrationTest method testDisableUniformPassword.
@Test
public void testDisableUniformPassword() {
try {
// Turn on an async execution.
getHelper().enableAsynchronousProcessing();
// Create password generate policy if missing.
createGeneratePolicy();
SysSystemDto contractSystem = initData();
Assert.assertNotNull(contractSystem);
IdmTreeTypeDto treeType = helper.createTreeType();
AbstractSysSyncConfigDto config = doCreateSyncConfig(contractSystem, treeType);
Assert.assertTrue(config instanceof SysSyncContractConfigDto);
SysSystemDto targetSystemOne = helper.createTestResourceSystem(true);
// Create system two with account suffix "_targetSystemTwo".
String targetSystemTwoSuffix = "_targetSystemTwo";
SysSystemDto targetSystemTwo = helper.createTestResourceSystem(true);
// Create uniform password definition.
AccUniformPasswordDto uniformPasswordDef = createUniformPasswordDef(targetSystemOne, targetSystemTwo);
// Disable an uniform password definition.
uniformPasswordDef.setDisabled(true);
uniformPasswordDef = uniformPasswordService.save(uniformPasswordDef);
SysSystemMappingDto provisioningMapping = systemMappingService.findProvisioningMapping(targetSystemTwo.getId(), SystemEntityType.IDENTITY);
List<SysSystemAttributeMappingDto> attributeMappingDtos = schemaAttributeMappingService.findBySystemMapping(provisioningMapping);
SysSystemAttributeMappingDto uidAttribute = schemaAttributeMappingService.getUidAttribute(attributeMappingDtos, targetSystemTwo);
uidAttribute.setTransformToResourceScript("return attributeValue + \"" + targetSystemTwoSuffix + "\"");
schemaAttributeMappingService.save(uidAttribute);
IdmRoleDto automaticRoleTreeOne = helper.createRole();
helper.createRoleSystem(automaticRoleTreeOne, targetSystemOne);
IdmTreeNodeDto treeNodeOne = helper.createTreeNode(treeType, null);
helper.createAutomaticRole(automaticRoleTreeOne, treeNodeOne);
IdmRoleDto automaticRoleTreeTwo = helper.createRole();
helper.createRoleSystem(automaticRoleTreeTwo, targetSystemTwo);
IdmTreeNodeDto treeNodeTwo = helper.createTreeNode(treeType, null);
helper.createAutomaticRole(automaticRoleTreeTwo, treeNodeTwo);
IdmIdentityDto ownerOne = helper.createIdentityOnly();
List<TestContractResource> contractResources = Lists.newArrayList(this.createContract("1", ownerOne.getUsername(), null, "true", treeNodeOne.getCode(), null, null, null), this.createContract("2", ownerOne.getUsername(), null, "false", treeNodeTwo.getCode(), null, null, null));
this.getBean().initContractData(contractResources);
IdmIdentityContractFilter contractFilter = new IdmIdentityContractFilter();
contractFilter.setIdentity(ownerOne.getId());
contractService.find(contractFilter, null).getContent().forEach(contract -> contractService.delete(contract));
Assert.assertEquals(0, contractService.find(contractFilter, null).getTotalElements());
ownerOne = identityService.get(ownerOne.getId());
// Identities should be in the CREATED state.
Assert.assertEquals(IdentityState.CREATED, ownerOne.getState());
SynchronizationSchedulableTaskExecutor lrt = new SynchronizationSchedulableTaskExecutor(config.getId());
LongRunningFutureTask<Boolean> longRunningFutureTask = longRunningTaskManager.execute(lrt);
UUID transactionIdLrt = longRunningTaskService.get(longRunningFutureTask.getExecutor().getLongRunningTaskId()).getTransactionId();
// Waiting for the LRT will be running.
getHelper().waitForResult(res -> {
return !longRunningTaskService.get(longRunningFutureTask.getExecutor().getLongRunningTaskId()).isRunning();
}, 50, 40);
// Waiting for the LRT will be EXECUTED.
getHelper().waitForResult(res -> {
return longRunningTaskService.get(longRunningFutureTask.getExecutor().getLongRunningTaskId()).getResultState() != OperationState.EXECUTED;
}, 250, 100);
Assert.assertEquals(OperationState.EXECUTED, longRunningTaskService.get(longRunningFutureTask.getExecutor().getLongRunningTaskId()).getResultState());
SysSyncLogDto log = helper.checkSyncLog(config, SynchronizationActionType.CREATE_ENTITY, 2, OperationResultType.SUCCESS);
Assert.assertFalse(log.isRunning());
Assert.assertFalse(log.isContainsError());
UUID transactionId = log.getTransactionId();
Assert.assertNotNull(transactionId);
Assert.assertEquals(transactionIdLrt, transactionId);
contractFilter.setIdentity(ownerOne.getId());
Assert.assertEquals(2, contractService.count(contractFilter));
ownerOne = identityService.get(ownerOne.getId());
// Identities should have a valid state.
Assert.assertEquals(IdentityState.VALID, ownerOne.getState());
// Uniform password feature is disabled -> password could be not same.
IdmEntityStateDto entityStateDtoOwnerOne = uniformPasswordManager.getEntityState(ownerOne.getId(), IdmIdentityDto.class, transactionId);
Assert.assertNull(entityStateDtoOwnerOne);
TestResource resourceOwnerOne = helper.findResource(ownerOne.getUsername());
Assert.assertNotNull(resourceOwnerOne);
TestResource resourceOwnerTwo = helper.findResource(ownerOne.getUsername() + targetSystemTwoSuffix);
Assert.assertNotNull(resourceOwnerTwo);
String passwordOwnerOne = resourceOwnerOne.getPassword();
String passwordOwnerTwo = resourceOwnerTwo.getPassword();
Assert.assertNotNull(passwordOwnerOne);
Assert.assertNotNull(passwordOwnerTwo);
// Uniform password feature is disabled -> password cannot be not same.
Assert.assertNotEquals(passwordOwnerOne, passwordOwnerTwo);
// None a uniform password notification was send.
IdmNotificationFilter notificationFilter = new IdmNotificationFilter();
notificationFilter.setRecipient(ownerOne.getUsername());
notificationFilter.setNotificationType(IdmEmailLog.class);
notificationFilter.setTopic(CoreModule.TOPIC_UNIFORM_PASSWORD_SET);
List<IdmNotificationLogDto> notificationLogDtos = notificationLogService.find(notificationFilter, null).getContent();
Assert.assertEquals(0, notificationLogDtos.size());
// None a new password notification was send.
notificationFilter.setTopic(AccModuleDescriptor.TOPIC_NEW_PASSWORD);
notificationLogDtos = notificationLogService.find(notificationFilter, null).getContent();
Assert.assertEquals(2, notificationLogDtos.size());
// None a password change notification was send.
notificationFilter.setTopic(CoreModule.TOPIC_PASSWORD_SET);
notificationLogDtos = notificationLogService.find(notificationFilter, null).getContent();
Assert.assertEquals(0, notificationLogDtos.size());
// Delete log
syncLogService.delete(log);
// Delete identities.
identityService.delete(ownerOne);
// Delete uniform password def.
uniformPasswordService.delete(uniformPasswordDef);
} finally {
// Turn off an async execution.
getHelper().disableAsynchronousProcessing();
}
}
use of eu.bcvsolutions.idm.acc.dto.AccUniformPasswordDto in project CzechIdMng by bcvsolutions.
the class UniformPasswordDeleteProcessor method process.
@Override
public EventResult<AccUniformPasswordDto> process(EntityEvent<AccUniformPasswordDto> event) {
AccUniformPasswordDto uniformPasswordFilter = event.getContent();
Assert.notNull(uniformPasswordFilter, "Uniform password cannot be null!");
Assert.notNull(uniformPasswordFilter.getId(), "ID for uniform password must exists!");
// Delete all connections with systems
AccUniformPasswordSystemFilter uniformPasswordSystemFilter = new AccUniformPasswordSystemFilter();
uniformPasswordSystemFilter.setUniformPasswordId(uniformPasswordFilter.getId());
uniformPasswordSystemService.find(uniformPasswordSystemFilter, null).forEach(uniformPasswordSystem -> {
uniformPasswordSystemService.delete(uniformPasswordSystem);
});
uniformPasswordService.deleteInternal(uniformPasswordFilter);
return new DefaultEventResult<>(event, this);
}
use of eu.bcvsolutions.idm.acc.dto.AccUniformPasswordDto in project CzechIdMng by bcvsolutions.
the class DefaultPasswordFilterManager method change.
@Override
public void change(AccPasswordFilterRequestDto request) {
LOG.info("Change request from resource [{}] for identity identifier [{}] starting. {}", request.getResource(), request.getUsername(), request.getLogMetadata());
SysSystemDto system = getSystem(request.getResource());
SysSystemAttributeMappingDto passwordFilterAttribute = getAttributeMappingForPasswordFilter(system);
IdmIdentityDto identity = evaluateUsernameToIdentity(system, request, passwordFilterAttribute);
List<AccUniformPasswordDto> passwordDefinitions = getActiveUniformPasswordDefinitions(system);
final GuardedString password = request.getPassword();
final long timeout = passwordFilterAttribute.getEchoTimeout();
final boolean changeInIdm = changeInIdm(passwordDefinitions);
// Accounts with password filter support.
List<AccAccountDto> managedAccounts = null;
// Accounts only for password changed without echo and password filter system.
List<AccAccountDto> notManagedAccounts = null;
// System doesn't exists in password uniform feature.
if (CollectionUtils.isEmpty(passwordDefinitions)) {
LOG.debug("System [{}] isn't exist in uniform password definition. Password will be changed only trough the given system.");
// Try find one account for given system with supported passwod filter
managedAccounts = getAccountForSystemWithPasswordFilter(system, identity);
notManagedAccounts = Lists.newArrayList();
} else {
UUID identityId = identity.getId();
managedAccounts = getAccountsForPasswordChange(passwordDefinitions, identityId, Boolean.TRUE);
notManagedAccounts = getAccountsForPasswordChange(passwordDefinitions, identityId, Boolean.FALSE);
}
if (managedAccounts.isEmpty()) {
LOG.warn("Password will not be changed! For identifier [{}] (identity username: [{}]) and resource [{}] wasn't found any managed account. {}", request.getUsername(), identity.getUsername(), request.getResource(), request.getLogMetadata());
return;
}
// Accounts for current system only.
List<AccAccountDto> accounts = managedAccounts.stream().filter(account -> {
return account.getSystem().equals(system.getId());
}).collect(Collectors.toList());
for (AccAccountDto account : accounts) {
AccPasswordFilterEchoItemDto echo = getEcho(account.getId());
if (echo == null) {
// Echo doesn't exist yet validation must be executed first!
LOG.error("Echo record for validation doesn't exist! For account uid [{}] and system code [{}]. Execute validation first! {}", account.getUid(), system.getCode(), request.getLogMetadata());
throw new ResultCodeException(AccResultCode.PASSWORD_FILTER_NOT_VALID_CHANGE_REQUEST, ImmutableMap.of("identifier", identity.getId()));
}
boolean echoValid = echo.isEchoValid(timeout);
boolean passwordEqual = isPasswordEqual(echo, password);
if (!passwordEqual) {
// Password doesn't match with checked password - security problem.
LOG.error("Password doesn't match with validated password! For account uid [{}] and system code [{}]. {}", account.getUid(), system.getCode(), request.getLogMetadata());
throw new ResultCodeException(AccResultCode.PASSWORD_FILTER_NOT_VALID_CHANGE_REQUEST, ImmutableMap.of("identifier", identity.getId()));
}
if (BooleanUtils.isFalse(echo.isValidityChecked())) {
// Validation wasn't successfully executed yet - validation must pass.
LOG.error("Password wasn't successfully validated! For account id [{}] and system id [{}]. Validation must pass! {}", account.getId(), system.getId(), request.getLogMetadata());
throw new ResultCodeException(AccResultCode.PASSWORD_FILTER_NOT_VALID_CHANGE_REQUEST, ImmutableMap.of("identifier", identity.getId()));
}
if (echoValid && echo.isChanged()) {
// Classic valid echo that was already changed, for this echo will not be changed again - FOR ALL ANOTHER SYSTEMS.
LOG.info("Echo record found! For account uid [{}] and system code [{}]. Password will not be changed. {}", account.getUid(), system.getCode(), request.getLogMetadata());
// For one valid echo just skip password change
return;
}
}
// Create final account list for password change and check duplicate.
List<AccAccountDto> finalAccounts = Lists.newArrayList(managedAccounts);
notManagedAccounts.forEach(account -> {
if (!finalAccounts.contains(account)) {
finalAccounts.add(account);
}
});
// Remove account for original resource - is possible that account can be empty.
List<UUID> accountsForResource = Lists.newArrayList();
finalAccounts.removeIf(account -> {
if (account.getSystem().equals(system.getId())) {
accountsForResource.add(account.getId());
return true;
}
return false;
});
// When account is empty and uniform password doesn't required password change trough IdM skip password change process.
if (finalAccounts.isEmpty() && changeInIdm == false) {
LOG.info("Request for resource indetifier [{}] (identity username [{}]) and system code [{}] will not be processed! No suitable account found (including IdM). {}", request.getUsername(), identity.getUsername(), system.getCode(), request.getLogMetadata());
// Set echos for accounts by the given system, because there is password changed by the system.
accounts.forEach(account -> {
setEchoForChange(account.getId(), password);
});
return;
}
// Prepare account ids
List<String> accountsIds = Lists.newArrayList();
finalAccounts.forEach(account -> {
accountsIds.add(account.getId().toString());
});
if (finalAccounts.isEmpty()) {
LOG.info("Password change will be processed only trough IdM. For identity [{}] and system [{}]. {}", identity.getUsername(), system.getCode(), request.getLogMetadata());
} else {
LOG.info("Password change will be processed. For identity [{}] and system [{}] was found these accounts for change [{}]. {}", identity.getUsername(), system.getCode(), Strings.join(accountsIds, ','), request.getLogMetadata());
}
// Setup echo for resource from that was executed from event password.
accountsForResource.forEach(accountId -> {
setEchoForChange(accountId, password);
});
// Prepare request for password change.
PasswordChangeDto passwordChangeDto = new PasswordChangeDto();
// Not for all, but only for chosen
passwordChangeDto.setAll(false);
passwordChangeDto.setIdm(changeInIdm);
passwordChangeDto.setAccounts(accountsIds);
passwordChangeDto.setNewPassword(password);
passwordChangeDto.setSkipResetValidFrom(true);
//
IdentityEvent identityEvent = new IdentityEvent(IdentityEventType.PASSWORD, identity, ImmutableMap.of(IdentityPasswordProcessor.PROPERTY_PASSWORD_CHANGE_DTO, passwordChangeDto, // Managed accounts in event is for performance speedup in processor IdentityPasswordProvisioningProcessor and set echos
MANAGED_ACCOUNTS, Lists.newArrayList(managedAccounts.stream().map(AccAccountDto::getId).collect(Collectors.toList())), // Exclude all accounts for given system
EXCLUDED_SYSTEM, system.getId(), // Skip whole validation just change password - password was validate before
IdentityProcessor.SKIP_PASSWORD_VALIDATION, Boolean.TRUE));
// Classic password change event
identityService.passwordChange(identityEvent);
LOG.info("Password change was finished! For identity username [{}] and system code [{}]. {}", identity.getUsername(), system.getCode(), request.getLogMetadata());
}
use of eu.bcvsolutions.idm.acc.dto.AccUniformPasswordDto in project CzechIdMng by bcvsolutions.
the class DefaultPasswordFilterManager method validate.
@Override
public void validate(AccPasswordFilterRequestDto request) {
LOG.info("Validation request from resource [{}] for identity identifier [{}] starting. {}", request.getResource(), request.getUsername(), request.getLogMetadata());
SysSystemDto system = getSystem(request.getResource());
SysSystemAttributeMappingDto passwordFilterAttribute = getAttributeMappingForPasswordFilter(system);
IdmIdentityDto identity = evaluateUsernameToIdentity(system, request, passwordFilterAttribute);
List<AccUniformPasswordDto> passwordDefinitions = getActiveUniformPasswordDefinitions(system);
final GuardedString password = request.getPassword();
final long timeout = passwordFilterAttribute.getEchoTimeout();
final boolean changeInIdm = changeInIdm(passwordDefinitions);
// Accounts with password filter support
List<AccAccountDto> managedAccounts = null;
// Accounts only for password changed without echo and password filter system
List<AccAccountDto> notManagedAccounts = null;
// System doesn't exists in password uniform feature
if (CollectionUtils.isEmpty(passwordDefinitions)) {
LOG.debug("System [{}] isn't exist in uniform password definition. Password will be check only trough the given system.");
// Try find one account for given system with supported password filter
managedAccounts = getAccountForSystemWithPasswordFilter(system, identity);
notManagedAccounts = Lists.newArrayList();
} else {
UUID identityId = identity.getId();
managedAccounts = getAccountsForPasswordChange(passwordDefinitions, identityId, Boolean.TRUE);
notManagedAccounts = getAccountsForPasswordChange(passwordDefinitions, identityId, Boolean.FALSE);
}
if (managedAccounts.isEmpty()) {
LOG.warn("For identifier [{}] (identity: [{}]) and resource [{}] wasn't found any managed account, validation will not be processed. {}", request.getUsername(), identity.getUsername(), request.getResource(), request.getLogMetadata());
return;
}
// Accounts for current system only
List<AccAccountDto> accounts = managedAccounts.stream().filter(account -> {
return account.getSystem().equals(system.getId());
}).collect(Collectors.toList());
for (AccAccountDto account : accounts) {
AccPasswordFilterEchoItemDto echo = getEcho(account.getId());
if (echo == null) {
// Echo doesn't exist yet we can continue for validation
LOG.debug("Echo for account id [{}] and system identifier [{}] doesn't exist. {}", account.getId(), request.getUsername(), request.getLogMetadata());
continue;
}
boolean echoValid = echo.isEchoValid(timeout);
boolean passwordEqual = isPasswordEqual(echo, password);
if (echoValid && passwordEqual && echo.isChanged()) {
// Classic valid echo that was already changed, for this echo will not validate again
LOG.info("Echo record found! Account uid [{}] and system code [{}]. Validation will be skipped. {}", account.getUid(), system.getCode(), request.getLogMetadata());
// For one valid echo just skip password validate for all another password from uniform password
return;
}
if (echo.isValidityChecked()) {
// Validation was successfully executed, now is second run
// TODO: can we skip this validation?
LOG.debug("For account [{}] and system [{}] exist only echo for validation. {}", account.getUid(), system.getCode(), request.getLogMetadata());
}
}
// Unite system from managed and not managed accounts
List<SysSystemDto> systems = getSystemForAccounts(managedAccounts);
systems.addAll(getSystemForAccounts(notManagedAccounts));
// Get password policies from managed systems
List<IdmPasswordPolicyDto> policies = getPasswordPolicy(systems);
// Default password policy must be also added when is setup change trough IdM
if (changeInIdm) {
IdmPasswordPolicyDto defaultPasswordPolicy = policyService.getDefaultPasswordPolicy(IdmPasswordPolicyType.VALIDATE);
// Password policy can be added by some system check for duplicate
if (defaultPasswordPolicy != null && !policies.contains(defaultPasswordPolicy)) {
policies.add(defaultPasswordPolicy);
}
}
// For empty policies is not required process validation
if (policies.isEmpty()) {
LOG.info("Any applicable password policy found! For identifier [{}] (identity: [{}]) and resource [{}]. {}", request.getUsername(), identity.getUsername(), request.getResource(), request.getLogMetadata());
} else {
// Compose validation request for IdM
IdmPasswordValidationDto passwordValidationDto = new IdmPasswordValidationDto();
passwordValidationDto.setPassword(password);
passwordValidationDto.setIdentity(identity);
// password is changed on different logged identity, but change by password filter is originally executed as target identity
passwordValidationDto.setEnforceMinPasswordAgeValidation(true);
try {
policyService.validate(passwordValidationDto, policies);
} catch (Exception e) {
// Just log the message and send error next
LOG.error("Validation didn't pass! For identity username [{}] and system code [{}]. Error message: [{}]. {}", identity.getUsername(), system.getCode(), StringUtils.defaultString(e.getMessage()), request.getLogMetadata());
// Set echod with not information about not valid password
managedAccounts.forEach(account -> {
createEchoForValidation(account.getId(), password, false);
});
// Throw error to caller
throw e;
}
}
// Set validate echos only for managed accounts
managedAccounts.forEach(account -> {
createEchoForValidation(account.getId(), password, true);
});
// Password valid
LOG.info("Validation request pass! For identity [{}] and system code [{}]. {}", identity.getUsername(), system.getCode(), request.getLogMetadata());
}
Aggregations