diff --git a/components/org.wso2.carbon.identity.api.user.recovery/org.wso2.carbon.identity.rest.api.user.recovery.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/recovery/v2/impl/core/PasswordRecoveryService.java b/components/org.wso2.carbon.identity.api.user.recovery/org.wso2.carbon.identity.rest.api.user.recovery.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/recovery/v2/impl/core/PasswordRecoveryService.java index 26ee3a048..e986993ff 100644 --- a/components/org.wso2.carbon.identity.api.user.recovery/org.wso2.carbon.identity.rest.api.user.recovery.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/recovery/v2/impl/core/PasswordRecoveryService.java +++ b/components/org.wso2.carbon.identity.api.user.recovery/org.wso2.carbon.identity.rest.api.user.recovery.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/recovery/v2/impl/core/PasswordRecoveryService.java @@ -18,11 +18,13 @@ package org.wso2.carbon.identity.rest.api.user.recovery.v2.impl.core; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.identity.api.user.common.Util; import org.wso2.carbon.identity.api.user.recovery.commons.UserAccountRecoveryServiceDataHolder; +import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.governance.service.notification.NotificationChannels; import org.wso2.carbon.identity.recovery.IdentityRecoveryClientException; import org.wso2.carbon.identity.recovery.IdentityRecoveryConstants; @@ -54,6 +56,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; /** @@ -85,8 +88,44 @@ public Response initiatePasswordRecovery(InitRequest initRequest) { return Response.ok().entity(buildPasswordRecoveryInitResponse(tenantDomain, recoveryInformationDTO)) .build(); } catch (IdentityRecoveryClientException e) { - throw RecoveryUtil.handleClientException(e, tenantDomain, - IdentityRecoveryConstants.PASSWORD_RECOVERY_SCENARIO, Util.getCorrelation()); + if (StringUtils.isEmpty(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, e.getErrorCode(), Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } + String errorCode = RecoveryUtil.prependOperationScenarioToErrorCode(e.getErrorCode(), + IdentityRecoveryConstants.PASSWORD_RECOVERY_SCENARIO); + if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_DISABLED_ACCOUNT.getCode().equals(e.getErrorCode()) + || IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_LOCKED_ACCOUNT.getCode().equals( + e.getErrorCode()) || IdentityRecoveryConstants.ErrorMessages. + ERROR_CODE_PASSWORD_RECOVERY_NOT_ENABLED.getCode().equals(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_FORBIDDEN_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.FORBIDDEN); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_MULTIPLE_MATCHING_USERS.getCode().equals( + e.getErrorCode())) { + // If user notify is not enabled, throw a accepted response. + if (!Boolean.parseBoolean(IdentityUtil + .getProperty(IdentityRecoveryConstants.ConnectorConfig.NOTIFY_USER_EXISTENCE))) { + throw new WebApplicationException(Response.accepted().build()); + } + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_USER_FOUND.getCode().equals( + e.getErrorCode())) { + // If user notify is not enabled, throw a accepted response. + if (!Boolean.parseBoolean(IdentityUtil + .getProperty(IdentityRecoveryConstants.ConnectorConfig.NOTIFY_USER_EXISTENCE))) { + throw new WebApplicationException(Response.accepted().build()); + } + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_NOT_FOUND_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.NOT_FOUND); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_VERIFIED_CHANNELS_FOR_USER. + getCode().equals(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_NOT_FOUND_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.NOT_FOUND); + } else { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } } catch (IdentityRecoveryException e) { throw RecoveryUtil.handleException(e, e.getErrorCode(), Constants.STATUS_INTERNAL_SERVER_ERROR_MESSAGE_DEFAULT, @@ -124,8 +163,31 @@ public Response recoverPassword(RecoveryRequest recoveryRequest) { return buildPasswordRecoveryResponse(tenantDomain, passwordRecoverDTO.getNotificationChannel(), passwordRecoverDTO); } catch (IdentityRecoveryClientException e) { - throw RecoveryUtil.handleClientException(e, tenantDomain, - IdentityRecoveryConstants.PASSWORD_RECOVERY_SCENARIO, Util.getCorrelation()); + if (StringUtils.isEmpty(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, e.getErrorCode(), Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } + String errorCode = RecoveryUtil.prependOperationScenarioToErrorCode(e.getErrorCode(), + IdentityRecoveryConstants.PASSWORD_RECOVERY_SCENARIO); + if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_PASSWORD_RECOVERY_WITH_NOTIFICATIONS_NOT_ENABLED. + getCode().equals(e.getErrorCode()) || IdentityRecoveryConstants.ErrorMessages. + ERROR_CODE_DISABLED_ACCOUNT.getCode().equals(e.getErrorCode()) || IdentityRecoveryConstants. + ErrorMessages.ERROR_CODE_LOCKED_ACCOUNT.getCode().equals(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_FORBIDDEN_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.FORBIDDEN); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_ACCOUNT_RECOVERY_DATA.getCode().equals( + e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_NOT_FOUND_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.NOT_FOUND); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RECOVERY_CODE.getCode().equals( + e.getErrorCode()) || IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_EXPIRED_RECOVERY_CODE + .getCode().equals(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_METHOD_NOT_ACCEPTED_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.NOT_ACCEPTABLE); + } else { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } } catch (IdentityRecoveryException e) { throw RecoveryUtil.handleException(e, e.getErrorCode(), Constants.STATUS_INTERNAL_SERVER_ERROR_MESSAGE_DEFAULT, @@ -152,8 +214,29 @@ public Response confirmRecovery(ConfirmRequest confirmRequest) { RecoveryUtil.buildPropertiesMap(confirmRequest.getProperties())); return Response.ok().entity(buildResetCodeResponse(tenantDomain, passwordResetCodeDTO)).build(); } catch (IdentityRecoveryClientException e) { - throw RecoveryUtil.handleClientException(e, tenantDomain, - IdentityRecoveryConstants.PASSWORD_RECOVERY_SCENARIO, Util.getCorrelation()); + if (StringUtils.isEmpty(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, e.getErrorCode(), Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } + String errorCode = RecoveryUtil.prependOperationScenarioToErrorCode(e.getErrorCode(), + IdentityRecoveryConstants.PASSWORD_RECOVERY_SCENARIO); + if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_USER_TENANT_DOMAIN_MISS_MATCH_WITH_CONTEXT.getCode(). + equals(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_ACCOUNT_RECOVERY_DATA.getCode().equals( + e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_NOT_FOUND_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.NOT_FOUND); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RECOVERY_CODE.getCode().equals( + e.getErrorCode()) || IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_EXPIRED_RECOVERY_CODE + .getCode().equals(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_METHOD_NOT_ACCEPTED_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.NOT_ACCEPTABLE); + } else { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } } catch (IdentityRecoveryException e) { throw RecoveryUtil.handleException(e, e.getErrorCode(), Constants.STATUS_INTERNAL_SERVER_ERROR_MESSAGE_DEFAULT, @@ -182,10 +265,35 @@ public Response resetPassword(ResetRequest resetRequest) { RecoveryUtil.buildPropertiesMap(resetRequest.getProperties())); return Response.ok().entity(buildPasswordResetResponse(successfulPasswordResetDTO)).build(); } catch (IdentityRecoveryClientException e) { - // Send the reset code again for a retry attempt. - throw RecoveryUtil.handleClientException(e, tenantDomain, - IdentityRecoveryConstants.PASSWORD_RECOVERY_SCENARIO, resetRequest.getResetCode(), - Util.getCorrelation()); + if (StringUtils.isEmpty(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, e.getErrorCode(), Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } + String errorCode = RecoveryUtil.prependOperationScenarioToErrorCode(e.getErrorCode(), + IdentityRecoveryConstants.PASSWORD_RECOVERY_SCENARIO); + if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_USER_TENANT_DOMAIN_MISS_MATCH_WITH_CONTEXT.getCode(). + equals(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_ACCOUNT_RECOVERY_DATA.getCode().equals( + e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_NOT_FOUND_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.NOT_FOUND); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RECOVERY_CODE.getCode().equals( + e.getErrorCode()) || IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_EXPIRED_RECOVERY_CODE. + getCode().equals(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_METHOD_NOT_ACCEPTED_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.NOT_ACCEPTABLE); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_PASSWORD_HISTORY_VIOLATION.getCode().equals( + e.getErrorCode()) || IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_PASSWORD_POLICY_VIOLATION. + getCode().equals(e.getErrorCode())) { + // Send the reset code again for a retry attempt. + throw RecoveryUtil.buildRetryPasswordResetObject(tenantDomain, e.getMessage(), errorCode, + resetRequest.getResetCode(), Util.getCorrelation()); + } else { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } } catch (IdentityRecoveryException e) { throw RecoveryUtil.handleException(e, e.getErrorCode(), Constants.STATUS_INTERNAL_SERVER_ERROR_MESSAGE_DEFAULT, @@ -220,8 +328,30 @@ public Response resendConfirmation(ResendConfirmationRequest resendConfirmationR } return buildResendConfirmationResponse(tenantDomain, resendConfirmationDTO); } catch (IdentityRecoveryClientException e) { - throw RecoveryUtil.handleClientException(e, tenantDomain, - IdentityRecoveryConstants.PASSWORD_RECOVERY_SCENARIO, Util.getCorrelation()); + if (StringUtils.isEmpty(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, e.getErrorCode(), Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } + String errorCode = RecoveryUtil.prependOperationScenarioToErrorCode(e.getErrorCode(), + IdentityRecoveryConstants.PASSWORD_RECOVERY_SCENARIO); + if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_USER_TENANT_DOMAIN_MISS_MATCH_WITH_CONTEXT.getCode(). + equals(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_ACCOUNT_RECOVERY_DATA.getCode().equals( + e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_NOT_FOUND_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.NOT_FOUND); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RECOVERY_CODE.getCode().equals( + e.getErrorCode()) || IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RESEND_CODE. + getCode().equals(e.getErrorCode()) || IdentityRecoveryConstants.ErrorMessages. + ERROR_CODE_EXPIRED_RECOVERY_CODE.getCode().equals(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_METHOD_NOT_ACCEPTED_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.NOT_ACCEPTABLE); + } else { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } } catch (IdentityRecoveryException e) { throw RecoveryUtil.handleException(e, e.getErrorCode(), Constants.STATUS_INTERNAL_SERVER_ERROR_MESSAGE_DEFAULT, diff --git a/components/org.wso2.carbon.identity.api.user.recovery/org.wso2.carbon.identity.rest.api.user.recovery.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/recovery/v2/impl/core/UsernameRecoveryService.java b/components/org.wso2.carbon.identity.api.user.recovery/org.wso2.carbon.identity.rest.api.user.recovery.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/recovery/v2/impl/core/UsernameRecoveryService.java index ee511e28e..8ccae416c 100644 --- a/components/org.wso2.carbon.identity.api.user.recovery/org.wso2.carbon.identity.rest.api.user.recovery.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/recovery/v2/impl/core/UsernameRecoveryService.java +++ b/components/org.wso2.carbon.identity.api.user.recovery/org.wso2.carbon.identity.rest.api.user.recovery.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/recovery/v2/impl/core/UsernameRecoveryService.java @@ -23,8 +23,8 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.identity.api.user.common.Util; import org.wso2.carbon.identity.api.user.recovery.commons.UserAccountRecoveryServiceDataHolder; +import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.governance.service.notification.NotificationChannels; import org.wso2.carbon.identity.recovery.IdentityRecoveryClientException; import org.wso2.carbon.identity.recovery.IdentityRecoveryConstants; @@ -45,6 +45,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; /** @@ -57,8 +58,7 @@ public class UsernameRecoveryService { /** * Initiate userName recovery from POST. * - * @param initRequest {@link InitRequest} object which holds the information in the account recovery - * request + * @param initRequest {@link InitRequest} object which holds the information in the account recovery request * @return Response */ public Response initiateUsernameRecovery(InitRequest initRequest) { @@ -81,8 +81,44 @@ public Response initiateUsernameRecovery(InitRequest initRequest) { return Response.ok().entity(buildUsernameRecoveryInitResponse(recoveryInformationDTO, tenantDomain)) .build(); } catch (IdentityRecoveryClientException e) { - throw RecoveryUtil.handleClientException(e, tenantDomain, IdentityRecoveryConstants.USER_NAME_RECOVERY, - Util.getCorrelation()); + if (StringUtils.isEmpty(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, e.getErrorCode(), Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } + String errorCode = RecoveryUtil.prependOperationScenarioToErrorCode(e.getErrorCode(), + IdentityRecoveryConstants.USER_NAME_RECOVERY); + if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_USERNAME_RECOVERY_NOT_ENABLED.getCode().equals( + e.getErrorCode()) || IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_DISABLED_ACCOUNT.getCode(). + equals(e.getErrorCode()) || IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_LOCKED_ACCOUNT. + getCode().equals(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_FORBIDDEN_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.FORBIDDEN); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_MULTIPLE_MATCHING_USERS.getCode().equals( + e.getErrorCode())) { + // If user notify is not enabled, throw a accepted response. + if (!Boolean.parseBoolean(IdentityUtil + .getProperty(IdentityRecoveryConstants.ConnectorConfig.NOTIFY_USER_EXISTENCE))) { + throw new WebApplicationException(Response.accepted().build()); + } + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_USER_FOUND.getCode().equals( + e.getErrorCode())) { + // If user notify is not enabled, throw a accepted response. + if (!Boolean.parseBoolean(IdentityUtil + .getProperty(IdentityRecoveryConstants.ConnectorConfig.NOTIFY_USER_EXISTENCE))) { + throw new WebApplicationException(Response.accepted().build()); + } + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_NOT_FOUND_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.NOT_FOUND); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_VERIFIED_CHANNELS_FOR_USER. + getCode().equals(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_NOT_FOUND_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.NOT_FOUND); + } else { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } } catch (IdentityRecoveryException e) { throw RecoveryUtil.handleException(e, e.getErrorCode(), Constants.STATUS_INTERNAL_SERVER_ERROR_MESSAGE_DEFAULT, @@ -115,8 +151,29 @@ public Response recoverUsername(RecoveryRequest recoveryRequest) { } return buildUsernameRecoveryResponse(usernameRecoverDTO.getNotificationChannel(), usernameRecoverDTO); } catch (IdentityRecoveryClientException e) { - throw RecoveryUtil.handleClientException(e, tenantDomain, IdentityRecoveryConstants.USER_NAME_RECOVERY, - StringUtils.EMPTY, Util.getCorrelation()); + if (StringUtils.isEmpty(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, e.getErrorCode(), Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } + String errorCode = RecoveryUtil.prependOperationScenarioToErrorCode(e.getErrorCode(), + IdentityRecoveryConstants.USER_NAME_RECOVERY); + if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_USERNAME_RECOVERY_NOT_ENABLED.getCode().equals( + e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_FORBIDDEN_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.FORBIDDEN); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_ACCOUNT_RECOVERY_DATA.getCode().equals( + e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_NOT_FOUND_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.NOT_FOUND); + } else if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RECOVERY_CODE.getCode().equals( + e.getErrorCode()) || IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_EXPIRED_RECOVERY_CODE. + getCode().equals(e.getErrorCode())) { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_METHOD_NOT_ACCEPTED_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.NOT_ACCEPTABLE); + } else { + throw RecoveryUtil.handleException(e, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, + e.getMessage(), Response.Status.CONFLICT); + } } catch (IdentityRecoveryException e) { throw RecoveryUtil.handleException(e, e.getErrorCode(), Constants.STATUS_INTERNAL_SERVER_ERROR_MESSAGE_DEFAULT, diff --git a/components/org.wso2.carbon.identity.api.user.recovery/org.wso2.carbon.identity.rest.api.user.recovery.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/recovery/v2/impl/core/utils/RecoveryUtil.java b/components/org.wso2.carbon.identity.api.user.recovery/org.wso2.carbon.identity.rest.api.user.recovery.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/recovery/v2/impl/core/utils/RecoveryUtil.java index 26bc5db84..ebe0b101f 100644 --- a/components/org.wso2.carbon.identity.api.user.recovery/org.wso2.carbon.identity.rest.api.user.recovery.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/recovery/v2/impl/core/utils/RecoveryUtil.java +++ b/components/org.wso2.carbon.identity.api.user.recovery/org.wso2.carbon.identity.rest.api.user.recovery.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/recovery/v2/impl/core/utils/RecoveryUtil.java @@ -27,8 +27,6 @@ import org.wso2.carbon.identity.core.ServiceURLBuilder; import org.wso2.carbon.identity.core.URLBuilderException; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; -import org.wso2.carbon.identity.core.util.IdentityUtil; -import org.wso2.carbon.identity.recovery.IdentityRecoveryClientException; import org.wso2.carbon.identity.recovery.IdentityRecoveryConstants; import org.wso2.carbon.identity.recovery.IdentityRecoveryException; import org.wso2.carbon.identity.recovery.dto.NotificationChannelDTO; @@ -46,7 +44,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import static org.wso2.carbon.identity.api.user.common.Constants.TENANT_CONTEXT_PATH_COMPONENT; @@ -58,15 +55,6 @@ public class RecoveryUtil { private static final Log log = LogFactory.getLog(RecoveryUtil.class); - private static final String LOG_MESSAGE_PREFIX = "INITIATOR"; - private static final String FORBIDDEN_ERROR_CATEGORY = "FORBIDDEN_ERROR_CATEGORY"; - private static final String CONFLICT_REQUEST_ERROR_CATEGORY = "CONFLICT_REQUEST_ERROR_CATEGORY"; - private static final String REQUEST_NOT_FOUND_ERROR_CATEGORY = "REQUEST_NOT_FOUND_ERROR_CATEGORY"; - private static final String REQUEST_NOT_ACCEPTABLE_ERROR_CATEGORY = "REQUEST_NOT_ACCEPTABLE_ERROR_CATEGORY"; - private static final String RETRY_ERROR_CATEGORY = "RETRY_ERROR_CATEGORY"; - - // Map with the error codes categorized in to different error groups. - private static final Map clientErrorMap = generateClientErrorMap(); /** * Converts a list of UserClaim in to a UserClaim array. @@ -126,85 +114,6 @@ public static List buildRecoveryChannelInformation(Notification return recoveryChannelDTOs; } - /** - * Handle client errors with specific http codes. - * - * @param scenario Recovery scenario. - * @param exception IdentityRecoveryClientException. - * @return WebApplicationException (NOTE: Returns null when the client error is for no user available or for - * multiple users available. - */ - public static WebApplicationException handleClientException(IdentityRecoveryClientException exception, - String tenantDomain, String scenario, - String correlationId) { - - return handleClientException(exception, tenantDomain, scenario, StringUtils.EMPTY, correlationId); - } - - /** - * Handle client errors with specific http codes. - * - * @param scenario Recovery scenario. - * @param code Recovery code. - * @param exception IdentityRecoveryClientException. - * @return WebApplicationException (NOTE: Returns null when the client error is for no user available or for - * multiple users available. - */ - public static WebApplicationException handleClientException(IdentityRecoveryClientException exception, - String tenantDomain, String scenario, String code, - String correlationId) { - - if (StringUtils.isEmpty(exception.getErrorCode())) { - return handleException(exception, exception.getErrorCode(), Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, - exception.getMessage(), Response.Status.CONFLICT); - } - String errorCode = prependOperationScenarioToErrorCode(exception.getErrorCode(), scenario); - - if (clientErrorMap.containsKey(errorCode)) { - String errorCategory = clientErrorMap.get(errorCode); - - // Throw errors according to exception category. - switch (errorCategory) { - case FORBIDDEN_ERROR_CATEGORY: - return handleException(exception, errorCode, Constants.STATUS_FORBIDDEN_MESSAGE_DEFAULT, - exception.getMessage(), Response.Status.FORBIDDEN); - case CONFLICT_REQUEST_ERROR_CATEGORY: - if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_MULTIPLE_MATCHING_USERS.getCode() - .equals(errorCode)) { - // If user notify is not enabled, throw a accepted response. - if (!Boolean.parseBoolean(IdentityUtil - .getProperty(IdentityRecoveryConstants.ConnectorConfig.NOTIFY_USER_EXISTENCE))) { - return new WebApplicationException(Response.accepted().build()); - } - } - return handleException(exception, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, - exception.getMessage(), Response.Status.CONFLICT); - case REQUEST_NOT_FOUND_ERROR_CATEGORY: - if (IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_USER_FOUND.getCode().equals(errorCode)) { - // If user notify is not enabled, throw a accepted response. - if (!Boolean.parseBoolean(IdentityUtil - .getProperty(IdentityRecoveryConstants.ConnectorConfig.NOTIFY_USER_EXISTENCE))) { - return new WebApplicationException(Response.accepted().build()); - } - } - return handleException(exception, errorCode, Constants.STATUS_NOT_FOUND_MESSAGE_DEFAULT, - exception.getMessage(), Response.Status.NOT_FOUND); - case REQUEST_NOT_ACCEPTABLE_ERROR_CATEGORY: - return handleException(exception, errorCode, Constants.STATUS_METHOD_NOT_ACCEPTED_MESSAGE_DEFAULT, - exception.getMessage(), Response.Status.NOT_ACCEPTABLE); - case RETRY_ERROR_CATEGORY: - return buildRetryPasswordResetObject(tenantDomain, exception.getMessage(), errorCode, - code, correlationId); - default: - return handleException(exception, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, - exception.getMessage(), Response.Status.CONFLICT); - } - } else { - return handleException(exception, errorCode, Constants.STATUS_CONFLICT_MESSAGE_DEFAULT, - exception.getMessage(), Response.Status.CONFLICT); - } - } - /** * Build API call information. * @@ -272,6 +181,55 @@ public static APIError handleException(IdentityRecoveryException e, String error return new APIError(status, errorResponse); } + /** + * Returns a new PreconditionFailedException. + * + * @param tenantDomain Tenant domain. + * @param description Description of the exception. + * @param code Error code. + * @param resetCode Reset code given to the user by confirmation API. + * @param correlationId Correlation Id. + * @return A new PreconditionFailedException with the specified details as a response. + */ + public static PreconditionFailedException buildRetryPasswordResetObject(String tenantDomain, String description, + String code, String resetCode, + String correlationId) { + + // Build next API calls. + ArrayList apiCallsArrayList = new ArrayList<>(); + apiCallsArrayList.add(RecoveryUtil + .buildApiCall(APICalls.RESET_PASSWORD_API.getType(), Constants.RelationStates.NEXT_REL, + buildURIForBody(tenantDomain, APICalls.RESET_PASSWORD_API.getApiUrl(), + Constants.ACCOUNT_RECOVERY_ENDPOINT_BASEPATH), null)); + RetryErrorResponse retryErrorResponse = buildRetryErrorResponse( + Constants.STATUS_PRECONDITION_FAILED_MESSAGE_DEFAULT, code, description, resetCode, correlationId, + apiCallsArrayList); + log.error(description); + return new PreconditionFailedException(retryErrorResponse); + } + + /** + * Prepend the operation scenario to the existing exception error code. + * (Eg: USR-20045) + * + * @param exceptionErrorCode Existing error code. + * @param scenario Operation scenario. + * @return New error code with the scenario prepended. + */ + public static String prependOperationScenarioToErrorCode(String exceptionErrorCode, String scenario) { + + if (StringUtils.isNotEmpty(exceptionErrorCode)) { + if (exceptionErrorCode.contains(IdentityRecoveryConstants.EXCEPTION_SCENARIO_SEPARATOR)) { + return exceptionErrorCode; + } + if (StringUtils.isNotEmpty(scenario)) { + exceptionErrorCode = + scenario + IdentityRecoveryConstants.EXCEPTION_SCENARIO_SEPARATOR + exceptionErrorCode; + } + } + return exceptionErrorCode; + } + /** * Builds the API context on whether the tenant qualified url is enabled or not. In tenant qualified mode the * ServiceURLBuilder appends the tenant domain to the URI as a path param automatically. But @@ -324,33 +282,6 @@ private static ErrorResponse.Builder getErrorBuilder(String errorCode, String er .withDescription(errorDescription); } - /** - * Returns a new PreconditionFailedException. - * - * @param tenantDomain Tenant domain. - * @param description Description of the exception. - * @param code Error code. - * @param resetCode Reset code given to the user by confirmation API. - * @param correlationId Correlation Id. - * @return A new PreconditionFailedException with the specified details as a response. - */ - private static PreconditionFailedException buildRetryPasswordResetObject(String tenantDomain, String description, - String code, String resetCode, - String correlationId) { - - // Build next API calls. - ArrayList apiCallsArrayList = new ArrayList<>(); - apiCallsArrayList.add(RecoveryUtil - .buildApiCall(APICalls.RESET_PASSWORD_API.getType(), Constants.RelationStates.NEXT_REL, - buildURIForBody(tenantDomain, APICalls.RESET_PASSWORD_API.getApiUrl(), - Constants.ACCOUNT_RECOVERY_ENDPOINT_BASEPATH), null)); - RetryErrorResponse retryErrorResponse = buildRetryErrorResponse( - Constants.STATUS_PRECONDITION_FAILED_MESSAGE_DEFAULT, code, description, resetCode, correlationId, - apiCallsArrayList); - log.error(description); - return new PreconditionFailedException(retryErrorResponse); - } - /** * Build the RetryErrorResponse for not valid password scenario. * @@ -375,82 +306,4 @@ private static RetryErrorResponse buildRetryErrorResponse(String message, String retryErrorResponse.setLinks(apiCallsArrayList); return retryErrorResponse; } - - /** - * Prepend the operation scenario to the existing exception error code. - * (Eg: USR-20045) - * - * @param exceptionErrorCode Existing error code. - * @param scenario Operation scenario. - * @return New error code with the scenario prepended. - */ - private static String prependOperationScenarioToErrorCode(String exceptionErrorCode, String scenario) { - - if (StringUtils.isNotEmpty(exceptionErrorCode)) { - if (exceptionErrorCode.contains(IdentityRecoveryConstants.EXCEPTION_SCENARIO_SEPARATOR)) { - return exceptionErrorCode; - } - if (StringUtils.isNotEmpty(scenario)) { - exceptionErrorCode = - scenario + IdentityRecoveryConstants.EXCEPTION_SCENARIO_SEPARATOR + exceptionErrorCode; - } - } - return exceptionErrorCode; - } - - /** - * Generate the map which categorizes the exceptions for different http error groups. - * - * @return Grouped client error map. - */ - private static Map generateClientErrorMap() { - - Map clientErrorMap = new HashMap<>(); - - // Errors for not enabling account recovery, user account locked, user account disabled. - clientErrorMap - .put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_PASSWORD_RECOVERY_WITH_NOTIFICATIONS_NOT_ENABLED - .getCode(), FORBIDDEN_ERROR_CATEGORY); - clientErrorMap.put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_USERNAME_RECOVERY_NOT_ENABLED.getCode(), - FORBIDDEN_ERROR_CATEGORY); - clientErrorMap.put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_DISABLED_ACCOUNT.getCode(), - FORBIDDEN_ERROR_CATEGORY); - clientErrorMap.put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_LOCKED_ACCOUNT.getCode(), - FORBIDDEN_ERROR_CATEGORY); - clientErrorMap.put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_PASSWORD_RECOVERY_NOT_ENABLED.getCode(), - FORBIDDEN_ERROR_CATEGORY); - - // Tenant miss match error. - clientErrorMap.put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_USER_TENANT_DOMAIN_MISS_MATCH_WITH_CONTEXT - .getCode(), CONFLICT_REQUEST_ERROR_CATEGORY); - - // Multiples users found error. - clientErrorMap.put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_MULTIPLE_MATCHING_USERS.getCode(), - CONFLICT_REQUEST_ERROR_CATEGORY); - - // No user found error. - clientErrorMap.put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_USER_FOUND.getCode(), - REQUEST_NOT_FOUND_ERROR_CATEGORY); - - // No recovery code found and no verified channels found errors. - clientErrorMap.put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_ACCOUNT_RECOVERY_DATA.getCode(), - REQUEST_NOT_FOUND_ERROR_CATEGORY); - clientErrorMap.put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_VERIFIED_CHANNELS_FOR_USER.getCode(), - REQUEST_NOT_FOUND_ERROR_CATEGORY); - - // Invalid recovery codes errors. - clientErrorMap.put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RECOVERY_CODE.getCode(), - REQUEST_NOT_ACCEPTABLE_ERROR_CATEGORY); - clientErrorMap.put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_RESEND_CODE.getCode(), - REQUEST_NOT_ACCEPTABLE_ERROR_CATEGORY); - clientErrorMap.put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_EXPIRED_RECOVERY_CODE.getCode(), - REQUEST_NOT_ACCEPTABLE_ERROR_CATEGORY); - - // Password reset password history violation errors and password policy violation errors. - clientErrorMap.put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_PASSWORD_HISTORY_VIOLATION.getCode(), - RETRY_ERROR_CATEGORY); - clientErrorMap.put(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_PASSWORD_POLICY_VIOLATION.getCode(), - RETRY_ERROR_CATEGORY); - return clientErrorMap; - } }