use of org.wso2.carbon.identity.recovery.RecoveryScenarios in project identity-governance by wso2-extensions.
the class UserAccountRecoveryManager method addRecoveryDataObject.
/**
* Add the notification channel recovery data to the store.
*
* @param username Username
* @param tenantDomain Tenant domain
* @param secretKey RecoveryId
* @param scenario RecoveryScenario
* @param recoveryData Data to be stored as mata which are needed to evaluate the recovery data object
* @throws IdentityRecoveryServerException If an error occurred while storing recovery data.
*/
private void addRecoveryDataObject(String username, String tenantDomain, String secretKey, RecoveryScenarios scenario, String recoveryData) throws IdentityRecoveryServerException {
// Create a user object.
User user = Utils.buildUser(username, tenantDomain);
UserRecoveryData recoveryDataDO = new UserRecoveryData(user, secretKey, scenario, RecoverySteps.SEND_RECOVERY_INFORMATION);
// Store available channels in remaining setIDs.
recoveryDataDO.setRemainingSetIds(recoveryData);
try {
UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
userRecoveryDataStore.invalidate(user);
userRecoveryDataStore.store(recoveryDataDO);
} catch (IdentityRecoveryException e) {
throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_ERROR_STORING_RECOVERY_DATA, "Error Storing Recovery Data", e);
}
}
use of org.wso2.carbon.identity.recovery.RecoveryScenarios in project identity-governance by wso2-extensions.
the class UserAccountRecoveryManager method isFunctionalityLocked.
/**
* Verify whether the functionality is locked or not and return true if it is locked. Else return false.
*
* @param username Username.
* @param tenantDomain TenantDomain.
* @param channelType ChannelType (SMS or EMail).
* @param recoveryScenarios RecoveryScenarios.
* @return Return true if it is locked. Else return false.
* @throws IdentityRecoveryServerException
*/
private boolean isFunctionalityLocked(String username, String tenantDomain, String channelType, RecoveryScenarios recoveryScenarios) throws IdentityRecoveryServerException {
if (PER_USER_FUNCTIONALITY_LOCKING_ENABLED) {
String functionalityType = FUNCTIONALITY_PREFIX + recoveryScenarios.name() + "_" + channelType;
// for recovery.
if (IdentityRecoveryConstants.FunctionalityTypes.getFunctionality(functionalityType) != null) {
String functionalityIdentifier = IdentityRecoveryConstants.FunctionalityTypes.getFunctionality(functionalityType).getFunctionalityIdentifier();
FunctionalityLockStatus functionalityLockStatus = getFunctionalityStatusOfUser(username, tenantDomain, functionalityIdentifier);
return functionalityLockStatus.getLockStatus();
}
}
return false;
}
use of org.wso2.carbon.identity.recovery.RecoveryScenarios in project identity-governance by wso2-extensions.
the class UserAccountRecoveryManager method retrieveUserRecoveryInformation.
/**
* Initiate the recovery flow for the user with matching claims.
*
* @param claims User claims
* @param tenantDomain Tenant domain
* @param recoveryScenario Recovery scenario
* @param properties Meta properties
* @return RecoveryChannelInfoDTO object.
*/
public RecoveryChannelInfoDTO retrieveUserRecoveryInformation(Map<String, String> claims, String tenantDomain, RecoveryScenarios recoveryScenario, Map<String, String> properties) throws IdentityRecoveryException {
// Retrieve the user who matches the given set of claims.
String username = getUsernameByClaims(claims, tenantDomain);
if (StringUtils.isNotEmpty(username)) {
User user = Utils.buildUser(username, tenantDomain);
// If the account is locked or disabled, do not let the user to recover the account.
checkAccountLockedStatus(user);
List<NotificationChannel> notificationChannels;
// Get the notification management mechanism.
boolean isNotificationsInternallyManaged = Utils.isNotificationsInternallyManaged(tenantDomain, properties);
/* If the notification is internally managed, then notification channels available for the user needs to
be retrieved. If external notifications are enabled, external channel list should be returned.*/
if (isNotificationsInternallyManaged) {
notificationChannels = getInternalNotificationChannelList(username, tenantDomain, recoveryScenario);
} else {
notificationChannels = getExternalNotificationChannelList();
}
// Validate whether the user account is eligible for account recovery.
checkUserValidityForAccountRecovery(user, recoveryScenario, notificationChannels, properties);
// This flow will be initiated only if the user has any verified channels.
NotificationChannelDTO[] notificationChannelDTOS = getNotificationChannelsResponseDTOList(tenantDomain, notificationChannels);
UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
// Get the existing RESEND_CONFIRMATION_CODE details if there is any.
UserRecoveryData recoveryDataDO = userRecoveryDataStore.loadWithoutCodeExpiryValidation(user, recoveryScenario, RecoverySteps.RESEND_CONFIRMATION_CODE);
String recoveryCode = UUIDGenerator.generateUUID();
String notificationChannelList = getNotificationChannelListForRecovery(notificationChannels);
/* Check whether the existing confirmation code can be used based on the email confirmation code tolerance
with the extracted RESEND_CONFIRMATION_CODE details. */
if (Utils.reIssueExistingConfirmationCode(recoveryDataDO, NotificationChannels.EMAIL_CHANNEL.getChannelType())) {
/* Update the existing RESEND_CONFIRMATION_CODE details with new code details without changing the
time created of the RESEND_CONFIRMATION_CODE. */
userRecoveryDataStore.invalidateWithoutChangeTimeCreated(recoveryDataDO.getSecret(), recoveryCode, RecoverySteps.SEND_RECOVERY_INFORMATION, notificationChannelList);
} else {
addRecoveryDataObject(username, tenantDomain, recoveryCode, recoveryScenario, notificationChannelList);
}
return buildUserRecoveryInformationResponseDTO(username, recoveryCode, notificationChannelDTOS);
} else {
if (log.isDebugEnabled()) {
log.debug("No valid user found for the given claims");
}
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_USER_FOUND, null);
}
}
use of org.wso2.carbon.identity.recovery.RecoveryScenarios in project identity-governance by wso2-extensions.
the class UserAccountRecoveryManager method checkUserValidityForAccountRecovery.
/**
* Check whether the user account is eligible for account recovery.
*
* @param user The user.
* @param recoveryScenario Account recovery scenario.
* @param recoveryNotificationChannels Notification channel.
* @param metaProperties Meta details.
* @throws IdentityRecoveryException If account doesn't satisfy the conditions to recover.
*/
private void checkUserValidityForAccountRecovery(User user, RecoveryScenarios recoveryScenario, List<NotificationChannel> recoveryNotificationChannels, Map<String, String> metaProperties) throws IdentityRecoveryException {
HashMap<String, Object> properties = new HashMap<>();
properties.put(IdentityEventConstants.EventProperty.USER, user);
properties.put(IdentityEventConstants.EventProperty.USER_STORE_MANAGER, getUserStoreManager(user));
properties.put(IdentityEventConstants.EventProperty.RECOVERY_SCENARIO, recoveryScenario);
properties.put(IdentityEventConstants.EventProperty.NOTIFICATION_CHANNEL, recoveryNotificationChannels);
if (MapUtils.isNotEmpty(metaProperties)) {
for (Map.Entry<String, String> metaProperty : metaProperties.entrySet()) {
if (StringUtils.isNotBlank(metaProperty.getValue()) && StringUtils.isNotBlank(metaProperty.getKey())) {
properties.put(metaProperty.getKey(), metaProperty.getValue());
}
}
}
Event identityMgtEvent = new Event(IdentityEventConstants.Event.PRE_ACCOUNT_RECOVERY, properties);
try {
IdentityRecoveryServiceDataHolder.getInstance().getIdentityEventService().handleEvent(identityMgtEvent);
} catch (IdentityEventException e) {
if (log.isDebugEnabled()) {
log.debug("Error occurred while validating user account " + user.getUserName() + " for account recovery.");
}
String errorMessage = e.getMessage();
String errorCode = IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_USER_ACCOUNT_RECOVERY_VALIDATION_FAILED.getCode();
if (USERNAME_RECOVERY.equals(recoveryScenario)) {
errorCode = IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_USERNAME_RECOVERY_VALIDATION_FAILED.getCode();
} else if (NOTIFICATION_BASED_PW_RECOVERY.equals(recoveryScenario) || QUESTION_BASED_PWD_RECOVERY.equals(recoveryScenario)) {
errorCode = IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_PASSWORD_RECOVERY_VALIDATION_FAILED.getCode();
}
throw Utils.handleClientException(errorCode, errorMessage, user.getUserName());
}
}
use of org.wso2.carbon.identity.recovery.RecoveryScenarios in project identity-governance by wso2-extensions.
the class JDBCRecoveryDataStore method load.
@Override
public UserRecoveryData load(User user) throws IdentityRecoveryException {
handleRecoveryDataEventPublishing(PRE_GET_USER_RECOVERY_DATA, GET_USER_RECOVERY_DATA_SCENARIO_WITH_CODE_EXPIRY_VALIDATION, null, null, null, user, new UserRecoveryData(user, null, null, null));
PreparedStatement prepStmt = null;
ResultSet resultSet = null;
Connection connection = IdentityDatabaseUtil.getDBConnection(false);
String code = null;
UserRecoveryData userRecoveryData = null;
Boolean isOperationSuccess = false;
Enum description = ERROR_CODE_RECOVERY_DATA_NOT_FOUND_FOR_USER;
try {
String sql;
if (IdentityUtil.isUserStoreCaseSensitive(user.getUserStoreDomain(), IdentityTenantUtil.getTenantId(user.getTenantDomain()))) {
sql = IdentityRecoveryConstants.SQLQueries.LOAD_RECOVERY_DATA_OF_USER;
} else {
sql = IdentityRecoveryConstants.SQLQueries.LOAD_RECOVERY_DATA_OF_USER_CASE_INSENSITIVE;
}
prepStmt = connection.prepareStatement(sql);
prepStmt.setString(1, user.getUserName());
prepStmt.setString(2, user.getUserStoreDomain().toUpperCase());
prepStmt.setInt(3, IdentityTenantUtil.getTenantId(user.getTenantDomain()));
resultSet = prepStmt.executeQuery();
if (resultSet.next()) {
Timestamp timeCreated = resultSet.getTimestamp("TIME_CREATED", Calendar.getInstance(TimeZone.getTimeZone(UTC)));
RecoveryScenarios scenario = RecoveryScenarios.valueOf(resultSet.getString("SCENARIO"));
RecoverySteps step = RecoverySteps.valueOf(resultSet.getString("STEP"));
code = resultSet.getString("CODE");
String remainingSets = resultSet.getString("REMAINING_SETS");
userRecoveryData = new UserRecoveryData(user, code, scenario, step);
if (isCodeExpired(user.getTenantDomain(), scenario, step, timeCreated.getTime(), remainingSets)) {
isOperationSuccess = false;
description = ERROR_CODE_EXPIRED_CODE;
throw Utils.handleClientException(ERROR_CODE_EXPIRED_CODE, code);
}
if (StringUtils.isNotBlank(remainingSets)) {
userRecoveryData.setRemainingSetIds(resultSet.getString("REMAINING_SETS"));
}
isOperationSuccess = true;
description = null;
return userRecoveryData;
}
} catch (SQLException e) {
isOperationSuccess = false;
description = ERROR_CODE_UNEXPECTED;
throw Utils.handleServerException(ERROR_CODE_UNEXPECTED, null, e);
} finally {
handleRecoveryDataEventPublishing(POST_GET_USER_RECOVERY_DATA, GET_USER_RECOVERY_DATA_SCENARIO_WITH_CODE_EXPIRY_VALIDATION, isOperationSuccess, description, code, user, userRecoveryData);
IdentityDatabaseUtil.closeAllConnections(connection, resultSet, prepStmt);
}
return null;
}
Aggregations