use of eu.bcvsolutions.idm.acc.dto.AccPasswordFilterEchoItemDto in project CzechIdMng by bcvsolutions.
the class DefaultPasswordFilterManager method createEcho.
@Override
public void createEcho(UUID accountId, GuardedString password) {
AccPasswordFilterEchoItemDto echo = new AccPasswordFilterEchoItemDto(hashPassword(password), accountId);
ZonedDateTime now = ZonedDateTime.now();
echo.setValidityChecked(true);
echo.setChanged(true);
echo.setChangeDate(now);
echo.setValidateDate(now);
LOG.info("For account [{}] will be created new standard echo with validity and changed record.", accountId);
idmCacheManager.cacheValue(ECHO_CACHE_NAME, accountId, echo);
}
use of eu.bcvsolutions.idm.acc.dto.AccPasswordFilterEchoItemDto in project CzechIdMng by bcvsolutions.
the class DefaultPasswordFilterManager method getEcho.
@Override
public AccPasswordFilterEchoItemDto getEcho(UUID accountId) {
ValueWrapper value = idmCacheManager.getValue(ECHO_CACHE_NAME, accountId);
if (value == null) {
return null;
}
Object echoAsObject = value.get();
if (echoAsObject == null) {
return null;
}
return (AccPasswordFilterEchoItemDto) echoAsObject;
}
use of eu.bcvsolutions.idm.acc.dto.AccPasswordFilterEchoItemDto in project CzechIdMng by bcvsolutions.
the class DefaultPasswordFilterManager method setEchoForChange.
@Override
public void setEchoForChange(UUID accountId, GuardedString password) {
AccPasswordFilterEchoItemDto echo = getEcho(accountId);
if (echo == null) {
// Echo record for the item missing! This isn't possible
LOG.info("For account id [{}] cannot be find echo record. Validation wasn't called first.", accountId);
echo = new AccPasswordFilterEchoItemDto();
echo.setAccountId(accountId);
echo.setValidityChecked(true);
}
ZonedDateTime now = ZonedDateTime.now();
LOG.info("For account [{}] will be updated echo record with changed [true]. Echo's date of validation [{}], changed date [{}]", accountId, echo.getValidateDate(), now);
echo.setChanged(true);
echo.setChangeDate(now);
// Password given
if (password != null) {
echo.setPassword(hashPassword(password));
}
idmCacheManager.cacheValue(ECHO_CACHE_NAME, accountId, echo);
}
use of eu.bcvsolutions.idm.acc.dto.AccPasswordFilterEchoItemDto in project CzechIdMng by bcvsolutions.
the class AbstractPasswordFilterIntegrationTest method checkEcho.
protected void checkEcho(IdmIdentityDto identity, SysSystemDto system, EchoCheck echoCheck) {
AccAccountDto account = getAccount(identity, system);
if (account == null && echoCheck == EchoCheck.DOESNT_EXIST) {
return;
}
AccPasswordFilterEchoItemDto echo = (AccPasswordFilterEchoItemDto) account.getEmbedded().get(AccAccountDto.PROPERTY_ECHO);
if (echoCheck == EchoCheck.DOESNT_EXIST) {
assertNull(echo);
return;
}
assertNotNull(echo);
if (echoCheck == EchoCheck.VALIDATE) {
assertTrue(echo.isValidityChecked());
assertNotNull(echo.getValidateDate());
} else if (echoCheck == EchoCheck.CHANGE) {
assertTrue(echo.isChanged());
assertNotNull(echo.getChangeDate());
} else if (echoCheck == EchoCheck.VALIDATE_AND_CHANGE) {
assertTrue(echo.isValidityChecked());
assertTrue(echo.isChanged());
assertNotNull(echo.getChangeDate());
} else if (echoCheck == EchoCheck.VALIDATE_FAILED) {
assertFalse(echo.isValidityChecked());
assertNotNull(echo.getValidateDate());
} else if (echoCheck == EchoCheck.CREATE) {
assertTrue(echo.isValidityChecked());
assertNull(echo.getValidateDate());
assertTrue(echo.isChanged());
assertNotNull(echo.getChangeDate());
} else {
// What you want? Hm?!
fail();
}
}
use of eu.bcvsolutions.idm.acc.dto.AccPasswordFilterEchoItemDto 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());
}
Aggregations