Skip to content

Commit

Permalink
Refactor fallback logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Rashmini committed Sep 19, 2023
1 parent d2feb17 commit 75f0fa8
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -271,21 +271,9 @@ public PasswordResetCodeDTO confirm(String otp, String confirmationCode, String
IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RECOVERY_CODE.getCode(),
IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_CODE.getMessage(), code);
} catch (IdentityRecoveryException e) {
// This is a fallback logic to support already initiated email link based recovery flows using the
// recovery V1 API, which do not have recovery flow ids.
UserRecoveryData userRecoveryData = userAccountRecoveryManager.getUserRecoveryDataFromConfirmationCode(
recoveryFlowId, recoveryFlowId, RecoverySteps.UPDATE_PASSWORD);
if (!tenantDomain.equals(userRecoveryData.getUser().getTenantDomain())) {
throw Utils.handleClientException(
IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_USER_TENANT_DOMAIN_MISS_MATCH_WITH_CONTEXT,
tenantDomain);
}
String domainQualifiedName = IdentityUtil.addDomainToName(userRecoveryData.getUser().getUserName(),
userRecoveryData.getUser().getUserStoreDomain());
if (log.isDebugEnabled()) {
log.debug("Valid confirmation code for user: " + domainQualifiedName);
}
return buildPasswordResetCodeDTO(recoveryFlowId);
/* This is a fallback logic to support already initiated email link based recovery flows using the
recovery V1 API, which do not have recovery flow ids. */
return validateConfirmationCode(userAccountRecoveryManager, recoveryFlowId, tenantDomain);
}
}

Expand Down Expand Up @@ -874,4 +862,47 @@ private boolean isMinNoOfRecoveryQuestionsAnswered(String username, String tenan
return isMinNoOfRecoveryQuestionsAnswered;
}

/**
* This method is to validate the confirmation code when there's no recovery flow id. This is added as a fallback
* logic to handle the already initiated email link based recovery flows which do not have recovery flow ids,
* which were initiated before moving to the Recovery V2 API. This shouldn't be used for any other purpose and
* should be kept for sometime.
*
* @param userAccountRecoveryManager UserAccountRecoveryManager.
* @param confirmationCode Confirmation code.
* @param tenantDomain Tenant domain.
* @return PasswordResetCodeDTO {@link PasswordResetCodeDTO} object which contains password reset code.
* @throws IdentityRecoveryException Error while confirming password recovery.
*/
@Deprecated
private PasswordResetCodeDTO validateConfirmationCode(UserAccountRecoveryManager userAccountRecoveryManager,
String confirmationCode, String tenantDomain)
throws IdentityRecoveryException {
UserRecoveryData userRecoveryData;
try {
userRecoveryData = userAccountRecoveryManager.getUserRecoveryData(confirmationCode,
RecoverySteps.UPDATE_PASSWORD);
} catch (IdentityRecoveryException e) {
if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RECOVERY_CODE.getCode().equals(e.getErrorCode())) {
e.setErrorCode(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RECOVERY_FLOW_ID.getCode());
}
throw e;
}
if (!StringUtils.equals(userRecoveryData.getRemainingSetIds(),
NotificationChannels.EMAIL_CHANNEL.getChannelType())) {
throw Utils.handleClientException(
IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RECOVERY_FLOW_ID, confirmationCode);
}
if (!tenantDomain.equals(userRecoveryData.getUser().getTenantDomain())) {
throw Utils.handleClientException(
IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_USER_TENANT_DOMAIN_MISS_MATCH_WITH_CONTEXT,
tenantDomain);
}
String domainQualifiedName = IdentityUtil.addDomainToName(userRecoveryData.getUser().getUserName(),
userRecoveryData.getUser().getUserStoreDomain());
if (log.isDebugEnabled()) {
log.debug("Valid confirmation code for user: " + domainQualifiedName);
}
return buildPasswordResetCodeDTO(confirmationCode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.wso2.carbon.identity.recovery.RecoveryScenarios;
import org.wso2.carbon.identity.recovery.RecoverySteps;
import org.wso2.carbon.identity.recovery.bean.NotificationResponseBean;
import org.wso2.carbon.identity.recovery.dto.PasswordResetCodeDTO;
import org.wso2.carbon.identity.recovery.internal.IdentityRecoveryServiceDataHolder;
import org.wso2.carbon.identity.recovery.internal.service.impl.UserAccountRecoveryManager;
import org.wso2.carbon.identity.recovery.model.Property;
Expand Down Expand Up @@ -687,20 +688,10 @@ public User updateUserPassword(String code, String confirmationCode, String pass
IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_CODE.getMessage(), code);
}
} catch (IdentityRecoveryException e) {
// This is a fallback logic to support already initiated email link based recovery flows using the
// recovery V1 API, which do not have recovery flow ids.
userRecoveryData = userAccountRecoveryManager.getUserRecoveryDataFromConfirmationCode(code,
confirmationCode, RecoverySteps.UPDATE_PASSWORD);
validateCallback(properties, userRecoveryData.getUser().getTenantDomain());
publishEvent(userRecoveryData.getUser(), null, code, password, properties,
IdentityEventConstants.Event.PRE_ADD_NEW_PASSWORD, userRecoveryData);
validateTenantDomain(userRecoveryData.getUser());

// Validate recovery step.
if (!RecoverySteps.UPDATE_PASSWORD.equals(userRecoveryData.getRecoveryStep())) {
throw Utils.handleClientException(
IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_CODE, code);
}
/* This is a fallback logic to support already initiated email link based recovery flows using the
recovery V1 API, which do not have recovery flow ids. */
userRecoveryData = validateUserRecoveryDataFromCode(userAccountRecoveryManager, code, confirmationCode,
password, properties);
}

// Get the notification channel.
Expand Down Expand Up @@ -766,6 +757,51 @@ public User updateUserPassword(String code, String confirmationCode, String pass
return userRecoveryData.getUser();
}

/**
* This method is to validate user recovery data using the reset code when there's no recovery flow id.
* This is added as a fallback logic to handle the already initiated email link based recovery flows which do not
* have recovery flow ids, which were initiated before moving to the Recovery V2 API.
* This shouldn't be used for any other purpose and should be kept for sometime.
*
* @param userAccountRecoveryManager UserAccountRecoveryManager.
* @param code Password Reset code.
* @param confirmationCode Confirmation code.
* @param password New password.
* @param properties Properties.
* @return UserRecoveryData.
* @throws IdentityRecoveryException Error while updating the password.
*/
@Deprecated
private UserRecoveryData validateUserRecoveryDataFromCode(UserAccountRecoveryManager userAccountRecoveryManager, String code,
String confirmationCode, String password, Property[] properties)
throws IdentityRecoveryException {
UserRecoveryData userRecoveryData;
try {
userRecoveryData = userAccountRecoveryManager.getUserRecoveryData(code, RecoverySteps.UPDATE_PASSWORD);
} catch (IdentityRecoveryException e) {
if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RECOVERY_CODE.getCode().equals(e.getErrorCode())) {
e.setErrorCode(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RECOVERY_FLOW_ID.getCode());
}
throw e;
}
if (!StringUtils.equals(userRecoveryData.getRemainingSetIds(),
NotificationChannels.EMAIL_CHANNEL.getChannelType())) {
throw Utils.handleClientException(
IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RECOVERY_FLOW_ID, confirmationCode);
}
validateCallback(properties, userRecoveryData.getUser().getTenantDomain());
publishEvent(userRecoveryData.getUser(), null, code, password, properties,
IdentityEventConstants.Event.PRE_ADD_NEW_PASSWORD, userRecoveryData);
validateTenantDomain(userRecoveryData.getUser());

// Validate recovery step.
if (!RecoverySteps.UPDATE_PASSWORD.equals(userRecoveryData.getRecoveryStep())) {
throw Utils.handleClientException(
IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_CODE, code);
}
return userRecoveryData;
}

/**
* Update the new password of the user.
*
Expand Down

0 comments on commit 75f0fa8

Please sign in to comment.