Java tutorial
/* * * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.wso2.carbon.identity.recovery.password; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.wso2.carbon.identity.common.base.event.EventContext; import org.wso2.carbon.identity.common.base.event.model.Event; import org.wso2.carbon.identity.common.base.exception.IdentityException; import org.wso2.carbon.identity.event.EventConstants; import org.wso2.carbon.identity.mgt.User; import org.wso2.carbon.identity.recovery.ChallengeQuestionManager; 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.RecoveryScenarios; import org.wso2.carbon.identity.recovery.RecoverySteps; import org.wso2.carbon.identity.recovery.bean.ChallengeQuestionsResponse; import org.wso2.carbon.identity.recovery.internal.IdentityRecoveryServiceDataHolder; import org.wso2.carbon.identity.recovery.mapping.SecurityQuestionsConfig; import org.wso2.carbon.identity.recovery.model.ChallengeQuestion; import org.wso2.carbon.identity.recovery.model.UserChallengeAnswer; import org.wso2.carbon.identity.recovery.model.UserRecoveryData; import org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore; import org.wso2.carbon.identity.recovery.util.Utils; import org.wso2.carbon.kernel.utils.LambdaExceptionUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Random; import java.util.UUID; import java.util.stream.Collectors; /** * Security Question Password Recovery Manager */ public class SecurityQuestionPasswordRecoveryManager { private static final Logger log = LoggerFactory.getLogger(SecurityQuestionPasswordRecoveryManager.class); private static SecurityQuestionsConfig securityQuestionsConfig = new SecurityQuestionsConfig(); ChallengeQuestionManager challengeQuestionManager; UserRecoveryDataStore userRecoveryDataStore; public SecurityQuestionPasswordRecoveryManager(UserRecoveryDataStore userRecoveryDataStore, ChallengeQuestionManager challengeQuestionManager) { this.userRecoveryDataStore = userRecoveryDataStore; this.challengeQuestionManager = challengeQuestionManager; } /** * To initiate challenge question based password recovery, answer questions one by one * * @param user User object * @return ChallengeQuestionsResponse, with security question to be asked and recovery code * @throws IdentityRecoveryException */ public ChallengeQuestionsResponse initiateUserChallengeQuestion(User user) throws IdentityRecoveryException { String uniqueUserId = user.getUniqueUserId(); userRecoveryDataStore.invalidateByUserUniqueId(uniqueUserId); String challengeQuestionSeparator = securityQuestionsConfig.getQuestionSeparator(); // check account disable/lock handleAccountState(uniqueUserId); //TODO notification sending handleNotification(uniqueUserId); int minNoOfQuestionsToAnswer = securityQuestionsConfig.getMinAnswers(); //TODO get from config bean List<String> ids = challengeQuestionManager.getUserChallengeQuestionIds(user); //TODO change to list if (ids.isEmpty()) { return new ChallengeQuestionsResponse(Collections.EMPTY_LIST); } //when user has more than required number of security questions answered if (ids.size() > minNoOfQuestionsToAnswer) { ids = getRandomQuestionIds(ids, minNoOfQuestionsToAnswer); } //generate selected list of security question String metaData = String.join(challengeQuestionSeparator, ids); //get first question ChallengeQuestion userChallengeQuestion = challengeQuestionManager.getUserChallengeQuestion(uniqueUserId, ids.get(0)); List<ChallengeQuestion> questions = new ArrayList<>(); questions.add(userChallengeQuestion); ChallengeQuestionsResponse challengeQuestionsResponse = new ChallengeQuestionsResponse(questions); //get recovery code String secretKey = UUID.randomUUID().toString(); challengeQuestionsResponse.setCode(secretKey); //construct and store user recovery data UserRecoveryData recoveryData = new UserRecoveryData(uniqueUserId, secretKey, RecoveryScenarios.QUESTION_BASED_PW_RECOVERY, RecoverySteps.VALIDATE_CHALLENGE_QUESTION); recoveryData.setRemainingSetIds(metaData); userRecoveryDataStore.store(recoveryData); challengeQuestionsResponse.setStatus(IdentityRecoveryConstants.RECOVERY_STATUS_INCOMPLETE); return challengeQuestionsResponse; } /** * To initiate challenge question based password recovery, answer questions at once * * @param user User object * @return ChallengeQuestionsResponse, with security questions to be asked and recovery code * @throws IdentityRecoveryException */ public ChallengeQuestionsResponse initiateUserChallengeQuestionAtOnce(User user) throws IdentityRecoveryException { String challengeQuestionSeparator = securityQuestionsConfig.getQuestionSeparator(); String uniqueUserID = user.getUniqueUserId(); userRecoveryDataStore.invalidateByUserUniqueId(uniqueUserID); //check account disable/lock handleAccountState(uniqueUserID); //TODO notification sending handleNotification(uniqueUserID); int minNoOfQuestionsToAnswer = securityQuestionsConfig.getMinAnswers(); List<String> ids = challengeQuestionManager.getUserChallengeQuestionIds(user); if (ids.isEmpty()) { //When no security questions are answered by the user return new ChallengeQuestionsResponse(new ArrayList<>()); } //when user has more than required number of security questions answered if (ids.size() > minNoOfQuestionsToAnswer) { ids = getRandomQuestionIds(ids, minNoOfQuestionsToAnswer); } List<ChallengeQuestion> randomQuestions; //select random set of security questions to be answered String allChallengeQuestions = String.join(challengeQuestionSeparator, ids); randomQuestions = ids.stream() .map(LambdaExceptionUtils.rethrowFunction( id -> challengeQuestionManager.getUserChallengeQuestion(user.getUniqueUserId(), id))) .collect(Collectors.toList()); ChallengeQuestionsResponse challengeQuestionResponse = new ChallengeQuestionsResponse(randomQuestions); //recovery code String secretKey = UUID.randomUUID().toString(); challengeQuestionResponse.setCode(secretKey); //construct and store user recovery data UserRecoveryData recoveryData = new UserRecoveryData(uniqueUserID, secretKey, RecoveryScenarios.QUESTION_BASED_PW_RECOVERY, RecoverySteps.VALIDATE_ALL_CHALLENGE_QUESTIONS); recoveryData.setRemainingSetIds(allChallengeQuestions); userRecoveryDataStore.store(recoveryData); return challengeQuestionResponse; } private void handleAccountState(String uniqueUserId) throws IdentityRecoveryException { if (Utils.isAccountDisabled(uniqueUserId)) { throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_DISABLED_ACCOUNT, null); } else if (Utils.isAccountLocked(uniqueUserId)) { throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_LOCKED_ACCOUNT, null); } } private void handleNotification(String uniqueUserID) { boolean isNotificationInternallyManaged = securityQuestionsConfig.isNotificationInternallyManaged(); boolean isNotificationSendWhenInitiatingPWRecovery = securityQuestionsConfig .isNotifyWhenStartRecoveryFlow(); if (isNotificationInternallyManaged && isNotificationSendWhenInitiatingPWRecovery) { try { triggerNotification(uniqueUserID, IdentityRecoveryConstants.NOTIFICATION_TYPE_PASSWORD_RESET_INITIATE, null); } catch (Exception e) { log.warn("Error while sending password reset initiating notification to userID:" + uniqueUserID); } } } /** * Validate user answers for the security question(s) asked for recovery * * @param userChallengeAnswer List of UserChallengeAnswers * @param code recovery code sent in previous step * @return ChallengeQuestionsResponse with recovery status, * previously asked question(s) will be sent again in error scenarios * if answer is valid, next question will be sent when answer questions one by one * @throws IdentityRecoveryException */ public ChallengeQuestionsResponse validateUserChallengeQuestions(List<UserChallengeAnswer> userChallengeAnswer, String code) throws IdentityRecoveryException { UserRecoveryData userRecoveryData; List<ChallengeQuestion> questions = new ArrayList<>(); ChallengeQuestionsResponse challengeQuestionResponse = new ChallengeQuestionsResponse(questions); String challengeQuestionSeparator = securityQuestionsConfig.getQuestionSeparator(); //load recovery data using provided code //if return data from load, it means the code is validated. Otherwise it returns exceptions. try { userRecoveryData = userRecoveryDataStore.loadByCode(code); } catch (IdentityRecoveryException e) { log.error("Error while loading recovery data with code: " + code, e); String errorCode = !StringUtils.isEmpty(e.getErrorCode()) ? e.getErrorCode() : IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_UNEXPECTED.getCode(); challengeQuestionResponse.setCode(code); challengeQuestionResponse.setStatus(errorCode); return challengeQuestionResponse; } String secretKey = userRecoveryData.getSecret(); challengeQuestionResponse.setCode(secretKey); try { if (userChallengeAnswer == null) { throw Utils.handleClientException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND, null); } //if validate security questions one by one if (RecoverySteps.VALIDATE_CHALLENGE_QUESTION.equals(userRecoveryData.getRecoveryStep())) { if (userChallengeAnswer.size() > 1) { throw Utils.handleClientException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_MULTIPLE_QUESTION_NOT_ALLOWED, null); } //match first question of remaining questions to be answered(asked question), with answered question //exception will be thrown if answered to other question String[] remainingQuestionIds = userRecoveryData.getRemainingSetIds() .split(challengeQuestionSeparator); questions.add(getValidatedQuestion(remainingQuestionIds[0], userChallengeAnswer.get(0), userRecoveryData.getUserUniqueId(), challengeQuestionManager)); challengeQuestionResponse.setQuestions(questions); //verify users answer boolean verified = challengeQuestionManager .verifyUserChallengeAnswer(userRecoveryData.getUserUniqueId(), userChallengeAnswer.get(0)); if (verified) { userRecoveryDataStore.invalidateByCode(code); secretKey = UUID.randomUUID().toString(); challengeQuestionResponse.setCode(secretKey); //construct new user recovery data UserRecoveryData recoveryData = new UserRecoveryData(userRecoveryData.getUserUniqueId(), secretKey, RecoveryScenarios.QUESTION_BASED_PW_RECOVERY); String remainingSetIds; List<String> ids = new ArrayList<>(Arrays.asList(remainingQuestionIds)); //if there are more questions to be answered if (ids.size() > 1) { //update remaining questions list ids.remove(0); remainingSetIds = String.join(challengeQuestionSeparator, ids); //next question to be asked ChallengeQuestion challengeQuestion = challengeQuestionManager.getUserChallengeQuestion( userRecoveryData.getUserUniqueId(), remainingQuestionIds[1]); questions.remove(0); questions.add(challengeQuestion); challengeQuestionResponse.setQuestions(questions); //update user recovery data recoveryData.setRecoveryStep(RecoverySteps.VALIDATE_CHALLENGE_QUESTION); challengeQuestionResponse.setStatus(IdentityRecoveryConstants.RECOVERY_STATUS_INCOMPLETE); recoveryData.setRemainingSetIds(remainingSetIds); } else { questions.remove(0); recoveryData.setRemainingSetIds(""); recoveryData.setRecoveryStep(RecoverySteps.UPDATE_PASSWORD); challengeQuestionResponse.setStatus(IdentityRecoveryConstants.RECOVERY_STATUS_COMPLETE); } //store user recovery data userRecoveryDataStore.store(recoveryData); //TODO Reset password recovery failed attempts //resetRecoveryPasswordFailedAttempts(userRecoveryData.getUser()); return challengeQuestionResponse; } else { //TODO handle recovery failed attempts //handleAnswerVerificationFail(userRecoveryData.getUser()); challengeQuestionResponse.setStatus( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_ANSWER_FOR_SECURITY_QUESTION .getCode()); return challengeQuestionResponse; } } else if (RecoverySteps.VALIDATE_ALL_CHALLENGE_QUESTIONS.equals(userRecoveryData.getRecoveryStep())) { //validate all the questions at once String allChallengeQuestions = userRecoveryData.getRemainingSetIds(); //validate asked questions with answered questions if (StringUtils.isNotBlank(allChallengeQuestions)) { String[] requestedQuestions = allChallengeQuestions.split(challengeQuestionSeparator); if (requestedQuestions.length != userChallengeAnswer.size()) { throw Utils.handleClientException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NEED_TO_ANSWER_TO_REQUESTED_QUESTIONS, null); } questions = getValidatedQuestions(requestedQuestions, userChallengeAnswer, userRecoveryData.getUserUniqueId(), challengeQuestionManager); challengeQuestionResponse.setQuestions(questions); //Validate whether user answered all the requested questions } else { throw Utils.handleClientException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND, null); } //verify user answered for the questions for (int i = 0; i < userChallengeAnswer.size(); i++) { boolean verified = challengeQuestionManager.verifyUserChallengeAnswer( userRecoveryData.getUserUniqueId(), userChallengeAnswer.get(i)); if (!verified) { //TODO //handleAnswerVerificationFail(userRecoveryData.getUser()); challengeQuestionResponse.setStatus( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_ANSWER_FOR_SECURITY_QUESTION .getCode()); return challengeQuestionResponse; } } //TODO Reset password recovery failed attempts //resetRecoveryPasswordFailedAttempts(userRecoveryData.getUser()); userRecoveryDataStore.invalidateByCode(code); secretKey = UUID.randomUUID().toString(); challengeQuestionResponse.setCode(secretKey); challengeQuestionResponse.setStatus(IdentityRecoveryConstants.RECOVERY_STATUS_COMPLETE); UserRecoveryData recoveryData = new UserRecoveryData(userRecoveryData.getUserUniqueId(), secretKey, RecoveryScenarios.QUESTION_BASED_PW_RECOVERY); recoveryData.setRecoveryStep(RecoverySteps.UPDATE_PASSWORD); userRecoveryDataStore.store(recoveryData); return challengeQuestionResponse; } else { throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_CODE, null); } } catch (IdentityRecoveryClientException e) { //handleAnswerVerificationFail(userRecoveryData.getUser()); throw e; } } /** * Validate requested questions with answered questions * * @param requestedQuestions list of questions asked, setIDs * @param userChallengeAnswers list of questions answered * @param userUniqueID unique ID of user * @param challengeQuestionManager ChallengeQuestionManager instance * @return List of asked questions * @throws IdentityRecoveryException */ private List<ChallengeQuestion> getValidatedQuestions(String[] requestedQuestions, List<UserChallengeAnswer> userChallengeAnswers, String userUniqueID, ChallengeQuestionManager challengeQuestionManager) throws IdentityRecoveryException { List<String> userChallengeIds = new ArrayList<>(); List<ChallengeQuestion> questions = new ArrayList<>(); userChallengeIds.addAll(userChallengeAnswers.stream() .map(answer -> answer.getQuestion().getQuestionSetId().toLowerCase()).collect(Collectors.toList())); for (int i = 0; i < requestedQuestions.length; i++) { //check whether answered question is available in asked question if (!userChallengeIds.contains(StringUtils.lowerCase(requestedQuestions[i]))) { throw Utils.handleClientException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NEED_TO_ANSWER_TO_REQUESTED_QUESTIONS, null); } else { //if answered question is in asked questions String q = challengeQuestionManager.getUserChallengeQuestion(userUniqueID, requestedQuestions[i]) .getQuestion(); ChallengeQuestion question = new ChallengeQuestion(requestedQuestions[i], q); questions.add(question); } } //list of asked questions return questions; } /** * Validate requested questions with answered question * * @param requestedQuestionSetId asked question, setID * @param userChallengeAnswer question answered * @param userUniqueID unique ID of user * @param challengeQuestionManager ChallengeQuestionManager instance * @return asked question * @throws IdentityRecoveryException */ private ChallengeQuestion getValidatedQuestion(String requestedQuestionSetId, UserChallengeAnswer userChallengeAnswer, String userUniqueID, ChallengeQuestionManager challengeQuestionManager) throws IdentityRecoveryException { if (!requestedQuestionSetId.equals(userChallengeAnswer.getQuestion().getQuestionSetId())) { throw Utils.handleClientException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NEED_TO_ANSWER_TO_ASKED_SECURITY_QUESTION, null); } String question = challengeQuestionManager .getUserChallengeQuestion(userUniqueID, userChallengeAnswer.getQuestion().getQuestionSetId()) .getQuestion(); return new ChallengeQuestion(userChallengeAnswer.getQuestion().getQuestionSetId(), question); } /** * Select random list from provided list * * @param challengeQuestions all the questions user has answered * @param minNoOfQuestionsToAnswer number of questions to be selected * @return selected list of question setIDs */ private List<String> getRandomQuestionIds(List<String> challengeQuestions, int minNoOfQuestionsToAnswer) { List<String> selectedQuestions = new ArrayList<>(); List<String> remainingQuestions = new ArrayList<>(challengeQuestions); for (int i = 0; i < minNoOfQuestionsToAnswer; i++) { int random = new Random().nextInt(remainingQuestions.size()); selectedQuestions.add(remainingQuestions.get(random)); remainingQuestions.remove(random); } return selectedQuestions; } private void triggerNotification(String userUniqueId, String type, String code) throws IdentityRecoveryException { String eventName = EventConstants.Event.TRIGGER_NOTIFICATION; HashMap<String, Object> properties = new HashMap<>(); properties.put(EventConstants.EventProperty.USER_UNIQUE_ID, userUniqueId); if (StringUtils.isNotBlank(code)) { properties.put(IdentityRecoveryConstants.CONFIRMATION_CODE, code); } properties.put(IdentityRecoveryConstants.TEMPLATE_TYPE, type); Event identityMgtEvent = new Event(eventName, properties); EventContext eventContext = new EventContext(); try { IdentityRecoveryServiceDataHolder.getInstance().getIdentityEventService().pushEvent(identityMgtEvent, eventContext); } catch (IdentityException e) { throw Utils.handleServerException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_TRIGGER_NOTIFICATION, userUniqueId, e); } } // private Property[] getConnectorConfigs(String tenantDomain) throws IdentityRecoveryException { // // Property[] connectorConfigs; // try { // connectorConfigs = IdentityRecoveryServiceDataHolder.getInstance() // .getIdentityGovernanceService() // .getConfiguration( // new String[]{PROPERTY_ACCOUNT_LOCK_ON_FAILURE, PROPERTY_ACCOUNT_LOCK_ON_FAILURE_MAX}, // tenantDomain); // } catch (Exception e) { // throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages // .ERROR_CODE_FAILED_TO_LOAD_GOV_CONFIGS, null, e); // } // return connectorConfigs; // } // private void resetRecoveryPasswordFailedAttempts(User user) throws IdentityRecoveryException { // Property[] connectorConfigs = getConnectorConfigs(user.getTenantDomain()); // // for (Property connectorConfig : connectorConfigs) { // if ((PROPERTY_ACCOUNT_LOCK_ON_FAILURE.equals(connectorConfig.getName())) && // !Boolean.parseBoolean(connectorConfig.getValue())) { // return; // } // } // // int tenantId = IdentityTenantUtil.getTenantId(user.getTenantDomain()); // // RealmService realmService = IdentityRecoveryServiceDataHolder.getInstance().getRealmService(); // UserRealm userRealm; // try { // userRealm = (UserRealm) realmService.getTenantUserRealm(tenantId); // } catch (UserStoreException e) { // throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages // .ERROR_CODE_FAILED_TO_LOAD_REALM_SERVICE, user.getTenantDomain(), e); // } // // org.wso2.carbon.user.core.UserStoreManager userStoreManager; // try { // userStoreManager = userRealm.getUserStoreManager(); // } catch (UserStoreException e) { // throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages // .ERROR_CODE_FAILED_TO_LOAD_USER_STORE_MANAGER, null, e); // } // // Map<String, String> updatedClaims = new HashMap<>(); // updatedClaims.put(IdentityRecoveryConstants.PASSWORD_RESET_FAIL_ATTEMPTS_CLAIM, "0"); // try { // userStoreManager.setUserClaimValues(IdentityUtil.addDomainToName(user.getUserName(), // user.getUserStoreDomain()), updatedClaims, UserCoreConstants.DEFAULT_PROFILE); // } catch (org.wso2.carbon.user.core.UserStoreException e) { // throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages // .ERROR_CODE_FAILED_TO_UPDATE_USER_CLAIMS, null, e); // } // } // private void handleAnswerVerificationFail(User user) throws IdentityRecoveryException { // Property[] connectorConfigs = getConnectorConfigs(user.getTenantDomain()); // // int maxAttempts = 0; // for (Property connectorConfig : connectorConfigs) { // if ((PROPERTY_ACCOUNT_LOCK_ON_FAILURE.equals(connectorConfig.getName())) && // !Boolean.parseBoolean(connectorConfig.getValue())) { // return; // } else if (PROPERTY_ACCOUNT_LOCK_ON_FAILURE_MAX.equals(connectorConfig.getName()) // && NumberUtils.isNumber(connectorConfig.getValue())) { // maxAttempts = Integer.parseInt(connectorConfig.getValue()); // } // } // // int tenantId = IdentityTenantUtil.getTenantId(user.getTenantDomain()); // // RealmService realmService = IdentityRecoveryServiceDataHolder.getInstance().getRealmService(); // UserRealm userRealm; // try { // userRealm = (UserRealm) realmService.getTenantUserRealm(tenantId); // } catch (UserStoreException e) { // throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages // .ERROR_CODE_FAILED_TO_LOAD_REALM_SERVICE, user.getTenantDomain(), e); // } // // org.wso2.carbon.user.core.UserStoreManager userStoreManager; // try { // userStoreManager = userRealm.getUserStoreManager(); // } catch (UserStoreException e) { // throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages // .ERROR_CODE_FAILED_TO_LOAD_USER_STORE_MANAGER, null, e); // } // // Map<String, String> claimValues = null; // try { // claimValues = userStoreManager.getUserClaimValues(IdentityUtil.addDomainToName(user.getUserName(), // user.getUserStoreDomain()), // new String[]{IdentityRecoveryConstants.ACCOUNT_LOCKED_CLAIM, // IdentityRecoveryConstants.PASSWORD_RESET_FAIL_ATTEMPTS_CLAIM}, // UserCoreConstants.DEFAULT_PROFILE); // } catch (org.wso2.carbon.user.core.UserStoreException e) { // throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages // .ERROR_CODE_FAILED_TO_LOAD_USER_CLAIMS, null, e); // } // // if (Boolean.parseBoolean(claimValues.get(IdentityRecoveryConstants.ACCOUNT_LOCKED_CLAIM))) { // return; // } // // int currentAttempts = 0; // if (NumberUtils.isNumber(claimValues.get(IdentityRecoveryConstants.PASSWORD_RESET_FAIL_ATTEMPTS_CLAIM))) { // currentAttempts = Integer.parseInt(claimValues.get(IdentityRecoveryConstants // .PASSWORD_RESET_FAIL_ATTEMPTS_CLAIM)); // } // // Map<String, String> updatedClaims = new HashMap<>(); // if ((currentAttempts + 1) >= maxAttempts) { // updatedClaims.put(IdentityRecoveryConstants.ACCOUNT_LOCKED_CLAIM, Boolean.TRUE.toString()); // updatedClaims.put(IdentityRecoveryConstants.PASSWORD_RESET_FAIL_ATTEMPTS_CLAIM, "0"); // try { // userStoreManager.setUserClaimValues(IdentityUtil.addDomainToName(user.getUserName(), // user.getUserStoreDomain()), updatedClaims, UserCoreConstants.DEFAULT_PROFILE); // throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages // .ERROR_CODE_LOCKED_ACCOUNT, IdentityUtil.addDomainToName(user.getUserName(), // user.getUserStoreDomain())); // } catch (org.wso2.carbon.user.core.UserStoreException e) { // throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages // .ERROR_CODE_FAILED_TO_UPDATE_USER_CLAIMS, null, e); // } // } else { // updatedClaims.put(IdentityRecoveryConstants.PASSWORD_RESET_FAIL_ATTEMPTS_CLAIM, // String.valueOf(currentAttempts + 1)); // try { // userStoreManager.setUserClaimValues(IdentityUtil.addDomainToName(user.getUserName(), // user.getUserStoreDomain()), updatedClaims, UserCoreConstants.DEFAULT_PROFILE); // } catch (org.wso2.carbon.user.core.UserStoreException e) { // throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages // .ERROR_CODE_FAILED_TO_UPDATE_USER_CLAIMS, null, e); // } // } // } }