Search in sources :

Example 1 with UserRecoveryData

use of org.wso2.carbon.identity.recovery.model.UserRecoveryData in project identity-governance by wso2-extensions.

the class PasswordRecoveryReCaptchaConnector method preValidate.

@Override
public CaptchaPreValidationResponse preValidate(ServletRequest servletRequest, ServletResponse servletResponse) throws CaptchaException {
    CaptchaPreValidationResponse preValidationResponse = new CaptchaPreValidationResponse();
    boolean forgotPasswordRecaptchaEnabled = checkReCaptchaEnabledForForgotPassoword(servletRequest, FORGOT_PASSWORD_RECAPTCHA_ENABLE);
    String pathUrl = ((HttpServletRequest) servletRequest).getRequestURI();
    if (forgotPasswordRecaptchaEnabled && (CaptchaUtil.isPathAvailable(pathUrl, ACCOUNT_SECURITY_QUESTION_URL) || CaptchaUtil.isPathAvailable(pathUrl, ACCOUNT_SECURITY_QUESTIONS_URL) || CaptchaUtil.isPathAvailable(pathUrl, RECOVER_PASSWORD_URL))) {
        preValidationResponse.setCaptchaValidationRequired(true);
    }
    // Handle recover with Email option.
    if (pathUrl.equals(RECOVER_PASSWORD_URL)) {
        return preValidationResponse;
    }
    // Handle recover with security questions option.
    HttpServletRequest httpServletRequestWrapper;
    try {
        httpServletRequestWrapper = new CaptchaHttpServletRequestWrapper((HttpServletRequest) servletRequest);
        preValidationResponse.setWrappedHttpServletRequest(httpServletRequestWrapper);
    } catch (IOException e) {
        log.error("Error occurred while wrapping ServletRequest.", e);
        return preValidationResponse;
    }
    String path = httpServletRequestWrapper.getRequestURI();
    User user = new User();
    boolean initializationFlow = false;
    if (CaptchaUtil.isPathAvailable(path, ACCOUNT_SECURITY_QUESTION_URL) || CaptchaUtil.isPathAvailable(path, ACCOUNT_SECURITY_QUESTIONS_URL)) {
        user.setUserName(servletRequest.getParameter("username"));
        if (StringUtils.isNotBlank(servletRequest.getParameter("realm"))) {
            user.setUserStoreDomain(servletRequest.getParameter("realm"));
        } else {
            user.setUserStoreDomain(IdentityUtil.getPrimaryDomainName());
        }
        user.setTenantDomain(servletRequest.getParameter("tenant-domain"));
        initializationFlow = true;
    } else {
        JsonObject requestObject;
        try {
            try (InputStream in = httpServletRequestWrapper.getInputStream()) {
                requestObject = new JsonParser().parse(IOUtils.toString(in)).getAsJsonObject();
            }
        } catch (IOException e) {
            return preValidationResponse;
        }
        UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
        try {
            UserRecoveryData userRecoveryData = userRecoveryDataStore.load(requestObject.get("key").getAsString());
            if (userRecoveryData != null) {
                user = userRecoveryData.getUser();
            }
        } catch (IdentityRecoveryException e) {
            return preValidationResponse;
        }
    }
    if (StringUtils.isBlank(user.getUserName())) {
        // Invalid Request
        return preValidationResponse;
    }
    if (StringUtils.isBlank(user.getTenantDomain())) {
        user.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
    }
    Property[] connectorConfigs;
    try {
        connectorConfigs = identityGovernanceService.getConfiguration(new String[] { RECOVERY_QUESTION_PASSWORD_RECAPTCHA_ENABLE, RECOVERY_QUESTION_PASSWORD_RECAPTCHA_MAX_FAILED_ATTEMPTS }, user.getTenantDomain());
    } catch (IdentityGovernanceException e) {
        throw new CaptchaServerException("Unable to retrieve connector configs.", e);
    }
    String connectorEnabled = null;
    String maxAttemptsStr = null;
    for (Property connectorConfig : connectorConfigs) {
        if ((RECOVERY_QUESTION_PASSWORD_RECAPTCHA_ENABLE).equals(connectorConfig.getName())) {
            connectorEnabled = connectorConfig.getValue();
        } else if ((RECOVERY_QUESTION_PASSWORD_RECAPTCHA_MAX_FAILED_ATTEMPTS).equals(connectorConfig.getName())) {
            maxAttemptsStr = connectorConfig.getValue();
        }
    }
    if (!Boolean.parseBoolean(connectorEnabled)) {
        return preValidationResponse;
    }
    if (StringUtils.isBlank(maxAttemptsStr) || !NumberUtils.isNumber(maxAttemptsStr)) {
        log.warn("Invalid configuration found in the PasswordRecoveryReCaptchaConnector for the tenant - " + user.getTenantDomain());
        return preValidationResponse;
    }
    int maxFailedAttempts = Integer.parseInt(maxAttemptsStr);
    int tenantId;
    try {
        tenantId = IdentityTenantUtil.getTenantId(user.getTenantDomain());
    } catch (Exception e) {
        // Invalid tenant
        return preValidationResponse;
    }
    try {
        if (CaptchaDataHolder.getInstance().getAccountLockService().isAccountLocked(user.getUserName(), user.getTenantDomain(), user.getUserStoreDomain())) {
            return preValidationResponse;
        }
    } catch (AccountLockServiceException e) {
        if (log.isDebugEnabled()) {
            log.debug("Error while validating if account is locked for user: " + user.getUserName() + " of user " + "store domain: " + user.getUserStoreDomain() + " and tenant domain: " + user.getTenantDomain());
        }
        return preValidationResponse;
    }
    Map<String, String> claimValues = CaptchaUtil.getClaimValues(user, tenantId, new String[] { FAIL_ATTEMPTS_CLAIM });
    if (claimValues == null || claimValues.isEmpty()) {
        // Invalid user
        return preValidationResponse;
    }
    int currentFailedAttempts = 0;
    if (NumberUtils.isNumber(claimValues.get(FAIL_ATTEMPTS_CLAIM))) {
        currentFailedAttempts = Integer.parseInt(claimValues.get(FAIL_ATTEMPTS_CLAIM));
    }
    HttpServletResponse httpServletResponse = ((HttpServletResponse) servletResponse);
    if (currentFailedAttempts > maxFailedAttempts) {
        if (initializationFlow) {
            httpServletResponse.setHeader("reCaptcha", "true");
            httpServletResponse.setHeader("reCaptchaKey", CaptchaDataHolder.getInstance().getReCaptchaSiteKey());
            httpServletResponse.setHeader("reCaptchaAPI", CaptchaDataHolder.getInstance().getReCaptchaAPIUrl());
        } else {
            preValidationResponse.setCaptchaValidationRequired(true);
            preValidationResponse.setMaxFailedLimitReached(true);
            addPostValidationData(servletRequest);
        }
    } else if (currentFailedAttempts == maxFailedAttempts && !initializationFlow) {
        addPostValidationData(servletRequest);
    }
    return preValidationResponse;
}
Also used : AccountLockServiceException(org.wso2.carbon.identity.handler.event.account.lock.exception.AccountLockServiceException) CaptchaHttpServletRequestWrapper(org.wso2.carbon.identity.captcha.util.CaptchaHttpServletRequestWrapper) User(org.wso2.carbon.identity.application.common.model.User) InputStream(java.io.InputStream) JsonObject(com.google.gson.JsonObject) HttpServletResponse(javax.servlet.http.HttpServletResponse) CaptchaServerException(org.wso2.carbon.identity.captcha.exception.CaptchaServerException) IOException(java.io.IOException) CaptchaClientException(org.wso2.carbon.identity.captcha.exception.CaptchaClientException) CaptchaException(org.wso2.carbon.identity.captcha.exception.CaptchaException) IOException(java.io.IOException) CaptchaServerException(org.wso2.carbon.identity.captcha.exception.CaptchaServerException) IdentityRecoveryException(org.wso2.carbon.identity.recovery.IdentityRecoveryException) IdentityGovernanceException(org.wso2.carbon.identity.governance.IdentityGovernanceException) AccountLockServiceException(org.wso2.carbon.identity.handler.event.account.lock.exception.AccountLockServiceException) IdentityGovernanceException(org.wso2.carbon.identity.governance.IdentityGovernanceException) CaptchaPreValidationResponse(org.wso2.carbon.identity.captcha.connector.CaptchaPreValidationResponse) HttpServletRequest(javax.servlet.http.HttpServletRequest) UserRecoveryData(org.wso2.carbon.identity.recovery.model.UserRecoveryData) UserRecoveryDataStore(org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore) IdentityRecoveryException(org.wso2.carbon.identity.recovery.IdentityRecoveryException) Property(org.wso2.carbon.identity.application.common.model.Property) JsonParser(com.google.gson.JsonParser)

Example 2 with UserRecoveryData

use of org.wso2.carbon.identity.recovery.model.UserRecoveryData in project identity-governance by wso2-extensions.

the class IntrospectCodeApiServiceImpl method introspectCodePost.

@Override
public Response introspectCodePost(CodeValidationRequestDTO codeValidationRequestDTO) {
    UserSelfRegistrationManager userSelfRegistrationManager = Utils.getUserSelfRegistrationManager();
    CodeValidateInfoResponseDTO codeDetails = null;
    UserRecoveryData recoveryData = null;
    try {
        // Get the map of properties in the request.
        HashMap<String, String> propertyMap = Utils.getPropertiesMap(codeValidationRequestDTO.getProperties());
        // Get externally verified channel information.
        VerifiedChannelDTO verifiedChannelDTO = codeValidationRequestDTO.getVerifiedChannel();
        String verifiedChannelType = null;
        String verifiedChannelClaim = null;
        // Handling verified channel details not in the request.
        if (verifiedChannelDTO != null) {
            verifiedChannelClaim = verifiedChannelDTO.getClaim();
            verifiedChannelType = verifiedChannelDTO.getType();
        }
        // Confirm code.
        recoveryData = userSelfRegistrationManager.introspectUserSelfRegistration(true, codeValidationRequestDTO.getCode(), verifiedChannelType, verifiedChannelClaim, propertyMap);
        if (recoveryData != null && recoveryData.getUser() != null && recoveryData.getUser().getUserName() != null) {
            codeDetails = getCodeIntrospectResponse(recoveryData);
        } else {
            Utils.handleNotFound(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_CODE.getMessage(), IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_CODE.getCode());
        }
    } catch (IdentityRecoveryClientException e) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Client Error while confirming sent in code", e);
        }
        Utils.handleBadRequest(e.getMessage(), e.getErrorCode());
    } catch (IdentityRecoveryException e) {
        Utils.handleInternalServerError(Constants.SERVER_ERROR, e.getErrorCode(), LOG, e);
    } catch (Throwable throwable) {
        Utils.handleInternalServerError(Constants.SERVER_ERROR, IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_UNEXPECTED.getCode(), LOG, throwable);
    }
    return Response.accepted(codeDetails).build();
}
Also used : UserRecoveryData(org.wso2.carbon.identity.recovery.model.UserRecoveryData) UserSelfRegistrationManager(org.wso2.carbon.identity.recovery.signup.UserSelfRegistrationManager) CodeValidateInfoResponseDTO(org.wso2.carbon.identity.user.endpoint.dto.CodeValidateInfoResponseDTO) IdentityRecoveryException(org.wso2.carbon.identity.recovery.IdentityRecoveryException) IdentityRecoveryClientException(org.wso2.carbon.identity.recovery.IdentityRecoveryClientException)

Example 3 with UserRecoveryData

use of org.wso2.carbon.identity.recovery.model.UserRecoveryData in project identity-governance by wso2-extensions.

the class MeApiServiceImpl method doResendConfirmationCode.

private NotificationResponseBean doResendConfirmationCode(String recoveryScenario, NotificationResponseBean notificationResponseBean, ResendCodeRequestDTO resendCodeRequestDTO) {
    UserRecoveryData userRecoveryData = null;
    // Currently this me/resend-code API supports resend code during mobile verification scenario only.
    if (RecoveryScenarios.MOBILE_VERIFICATION_ON_UPDATE.toString().equals(recoveryScenario)) {
        userRecoveryData = Utils.getUserRecoveryData(resendCodeRequestDTO, recoveryScenario);
    }
    if (userRecoveryData == null) {
        return notificationResponseBean;
    }
    ResendConfirmationManager resendConfirmationManager = Utils.getResendConfirmationManager();
    if (RecoveryScenarios.MOBILE_VERIFICATION_ON_UPDATE.toString().equals(recoveryScenario) && RecoveryScenarios.MOBILE_VERIFICATION_ON_UPDATE.equals(userRecoveryData.getRecoveryScenario()) && RecoverySteps.VERIFY_MOBILE_NUMBER.equals(userRecoveryData.getRecoveryStep())) {
        notificationResponseBean = setNotificationResponseBean(resendConfirmationManager, RecoveryScenarios.MOBILE_VERIFICATION_ON_UPDATE.toString(), RecoverySteps.VERIFY_MOBILE_NUMBER.toString(), IdentityRecoveryConstants.NOTIFICATION_TYPE_VERIFY_MOBILE_ON_UPDATE, resendCodeRequestDTO);
    }
    return notificationResponseBean;
}
Also used : UserRecoveryData(org.wso2.carbon.identity.recovery.model.UserRecoveryData) ResendConfirmationManager(org.wso2.carbon.identity.recovery.confirmation.ResendConfirmationManager)

Example 4 with UserRecoveryData

use of org.wso2.carbon.identity.recovery.model.UserRecoveryData in project identity-governance by wso2-extensions.

the class Utils method getCodeIntrospectResponse.

public static CodeValidateInfoResponseDTO getCodeIntrospectResponse(UserRecoveryData userRecoveryData) {
    CodeValidateInfoResponseDTO codeValidateInfoResponseDTO = new CodeValidateInfoResponseDTO();
    codeValidateInfoResponseDTO.setUser(getRecoveryUser(userRecoveryData.getUser()));
    codeValidateInfoResponseDTO.setRecoveryStep(userRecoveryData.getRecoveryStep().name());
    codeValidateInfoResponseDTO.setRecoveryScenario(userRecoveryData.getRecoveryScenario().name());
    codeValidateInfoResponseDTO.setIsExpired(userRecoveryData.isCodeExpired());
    return codeValidateInfoResponseDTO;
}
Also used : CodeValidateInfoResponseDTO(org.wso2.carbon.identity.user.endpoint.dto.CodeValidateInfoResponseDTO)

Example 5 with UserRecoveryData

use of org.wso2.carbon.identity.recovery.model.UserRecoveryData in project identity-governance by wso2-extensions.

the class MeApiServiceImplTest method testMeResendCodePost.

@Test
public void testMeResendCodePost() throws IdentityRecoveryException {
    try {
        String carbonHome = Paths.get(System.getProperty("user.dir"), "src", "test", "resources").toString();
        System.setProperty(CarbonBaseConstants.CARBON_HOME, carbonHome);
        PrivilegedCarbonContext.startTenantFlow();
        PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(USERNAME);
        PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(-1234);
        Mockito.when(resendConfirmationManager.resendConfirmationCode(isNull(), anyString(), anyString(), anyString(), isNull())).thenReturn(notificationResponseBean);
        mockedUtils.when(() -> Utils.getUserRecoveryData(any(ResendCodeRequestDTO.class), anyString())).thenReturn(userRecoveryData);
        mockedUtils.when(Utils::getResendConfirmationManager).thenReturn(resendConfirmationManager);
        Mockito.when(userRecoveryData.getRecoveryScenario()).thenReturn(RecoveryScenarios.getRecoveryScenario("MOBILE_VERIFICATION_ON_UPDATE"));
        Mockito.when(userRecoveryData.getRecoveryStep()).thenReturn(RecoverySteps.getRecoveryStep("VERIFY_MOBILE_NUMBER"));
        assertEquals(meApiService.meResendCodePost(meResendCodeRequestDTO()).getStatus(), 201);
        assertEquals(meApiService.meResendCodePost(meResendCodeRequestDTOWithInvalidScenarioProperty()).getStatus(), 400);
        mockedUtils.when(() -> Utils.getUserRecoveryData(any(ResendCodeRequestDTO.class), anyString())).thenReturn(null);
        assertEquals(meApiService.meResendCodePost(meResendCodeRequestDTO()).getStatus(), 400);
        Mockito.when(userRecoveryData.getRecoveryScenario()).thenReturn(RecoveryScenarios.getRecoveryScenario("ASK_PASSWORD"));
        assertEquals(meApiService.meResendCodePost(meResendCodeRequestDTO()).getStatus(), 400);
    } finally {
        PrivilegedCarbonContext.endTenantFlow();
    }
}
Also used : MeResendCodeRequestDTO(org.wso2.carbon.identity.user.endpoint.dto.MeResendCodeRequestDTO) ResendCodeRequestDTO(org.wso2.carbon.identity.user.endpoint.dto.ResendCodeRequestDTO) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Test(org.testng.annotations.Test)

Aggregations

UserRecoveryData (org.wso2.carbon.identity.recovery.model.UserRecoveryData)50 UserRecoveryDataStore (org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore)35 IdentityRecoveryException (org.wso2.carbon.identity.recovery.IdentityRecoveryException)21 User (org.wso2.carbon.identity.application.common.model.User)19 IdentityEventException (org.wso2.carbon.identity.event.IdentityEventException)16 HashMap (java.util.HashMap)10 NotificationResponseBean (org.wso2.carbon.identity.recovery.bean.NotificationResponseBean)6 Connection (java.sql.Connection)5 PreparedStatement (java.sql.PreparedStatement)5 ResultSet (java.sql.ResultSet)5 SQLException (java.sql.SQLException)5 Timestamp (java.sql.Timestamp)5 IdentityRecoveryClientException (org.wso2.carbon.identity.recovery.IdentityRecoveryClientException)5 Event (org.wso2.carbon.identity.event.event.Event)4 Property (org.wso2.carbon.identity.recovery.model.Property)4 UserStoreException (org.wso2.carbon.user.api.UserStoreException)4 UserStoreManager (org.wso2.carbon.user.api.UserStoreManager)4 JSONObject (org.json.JSONObject)3 ChallengeQuestionManager (org.wso2.carbon.identity.recovery.ChallengeQuestionManager)3 RecoveryScenarios (org.wso2.carbon.identity.recovery.RecoveryScenarios)3