use of org.wso2.carbon.identity.recovery.IdentityRecoveryClientException in project identity-governance by wso2-extensions.
the class ChallengeQuestionManager method triggerChallengeAnswersValidation.
/**
* Trigger challenge question answers validation according to the given event name.
*
* @param user User
* @param userChallengeAnswers Array of challenge answers
* @param eventName Event name
* @throws IdentityRecoveryClientException Error while validating the challenge answers
* @throws IdentityRecoveryServerException Error while getting the user store manager or triggering the event.
*/
private void triggerChallengeAnswersValidation(User user, UserChallengeAnswer[] userChallengeAnswers, Map<String, String> existingQuestionAndAnswers, String eventName) throws IdentityRecoveryClientException, IdentityRecoveryServerException {
Map<String, Object> properties = new HashMap<>();
properties.put(IdentityEventConstants.EventProperty.USER, user);
properties.put(IdentityEventConstants.EventProperty.USER_CHALLENGE_ANSWERS, userChallengeAnswers);
properties.put(IdentityEventConstants.EventProperty.USER_OLD_CHALLENGE_ANSWERS, existingQuestionAndAnswers);
try {
UserStoreManager userStoreManager;
if (IdentityUtil.getPrimaryDomainName().equals(user.getUserStoreDomain())) {
userStoreManager = (UserStoreManager) CarbonContext.getThreadLocalCarbonContext().getUserRealm().getUserStoreManager();
} else {
userStoreManager = ((UserStoreManager) CarbonContext.getThreadLocalCarbonContext().getUserRealm().getUserStoreManager()).getSecondaryUserStoreManager(user.getUserStoreDomain());
}
properties.put(IdentityEventConstants.EventProperty.USER_STORE_MANAGER, userStoreManager);
} catch (UserStoreException e) {
throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_FAILED_TO_LOAD_USER_STORE_MANAGER, null, e);
}
Event identityMgtEvent = new Event(eventName, properties);
try {
IdentityRecoveryServiceDataHolder.getInstance().getIdentityEventService().handleEvent(identityMgtEvent);
} catch (IdentityEventClientException e) {
throw new IdentityRecoveryClientException(e.getErrorCode(), e.getMessage(), e);
} catch (IdentityEventServerException e) {
throw new IdentityRecoveryServerException(e.getErrorCode(), e.getMessage(), e);
} catch (IdentityEventException e) {
throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_PUBLISH_EVENT, eventName, e);
}
}
use of org.wso2.carbon.identity.recovery.IdentityRecoveryClientException in project identity-governance by wso2-extensions.
the class NotificationPasswordRecoveryManager method getValidatedUser.
/**
* Method to validate confirmation code of password reset flow.
*
* @param code confirmation code
* @param recoveryStep recovery step
* @throws IdentityRecoveryException
*/
public User getValidatedUser(String code, String recoveryStep) throws IdentityRecoveryException {
UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
UserRecoveryData userRecoveryData = userRecoveryDataStore.load(code);
String contextTenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String userTenantDomain = userRecoveryData.getUser().getTenantDomain();
if (!StringUtils.equals(contextTenantDomain, userTenantDomain)) {
throw new IdentityRecoveryClientException("Invalid tenant domain: " + userTenantDomain);
}
if (StringUtils.isNotBlank(recoveryStep) && !recoveryStep.equals(userRecoveryData.getRecoveryStep().name())) {
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_CODE, null);
}
User user = userRecoveryData.getUser();
String domainQualifiedName = IdentityUtil.addDomainToName(user.getUserName(), userRecoveryData.getUser().getUserStoreDomain());
if (log.isDebugEnabled()) {
log.debug("Valid confirmation code for user: " + domainQualifiedName);
}
return user;
}
use of org.wso2.carbon.identity.recovery.IdentityRecoveryClientException in project identity-governance by wso2-extensions.
the class SecurityQuestionPasswordRecoveryManager method validateUserChallengeQuestions.
public ChallengeQuestionResponse validateUserChallengeQuestions(UserChallengeAnswer[] userChallengeAnswer, String code, org.wso2.carbon.identity.recovery.model.Property[] properties) throws IdentityRecoveryException {
UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
UserRecoveryData userRecoveryData = userRecoveryDataStore.load(code);
// if return data from load, it means the code is validated. Otherwise it returns exceptions.
User user = userRecoveryData.getUser();
validateFunctionalityForUser(user);
try {
boolean isRecoveryEnable = Boolean.parseBoolean(Utils.getRecoveryConfigs(IdentityRecoveryConstants.ConnectorConfig.QUESTION_BASED_PW_RECOVERY, userRecoveryData.getUser().getTenantDomain()));
if (!isRecoveryEnable) {
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_QUESTION_BASED_RECOVERY_NOT_ENABLE, null);
}
verifyUserExists(user);
if (Utils.isAccountDisabled(user)) {
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_DISABLED_ACCOUNT, user.getUserName());
} else if (Utils.isAccountLocked(user)) {
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_LOCKED_ACCOUNT, user.getUserName());
}
if (userChallengeAnswer == null) {
String error = "Challenge answers cannot be found for user: " + userRecoveryData.getUser();
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND, error);
}
String challengeQuestionSeparator = IdentityUtil.getProperty(IdentityRecoveryConstants.ConnectorConfig.QUESTION_CHALLENGE_SEPARATOR);
if (StringUtils.isEmpty(challengeQuestionSeparator)) {
challengeQuestionSeparator = IdentityRecoveryConstants.DEFAULT_CHALLENGE_QUESTION_SEPARATOR;
}
if (RecoverySteps.VALIDATE_CHALLENGE_QUESTION.equals(userRecoveryData.getRecoveryStep())) {
if (userChallengeAnswer.length > 1) {
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_MULTIPLE_QUESTION_NOT_ALLOWED, null);
}
ChallengeQuestionManager challengeQuestionManager = ChallengeQuestionManager.getInstance();
boolean verified = challengeQuestionManager.verifyUserChallengeAnswer(userRecoveryData.getUser(), userChallengeAnswer[0]);
if (verified) {
boolean resetFailedLoginCount = false;
userRecoveryDataStore.invalidate(code);
String remainingSetIds = userRecoveryData.getRemainingSetIds();
ChallengeQuestionResponse challengeQuestionResponse = new ChallengeQuestionResponse();
String secretKey = UUIDGenerator.generateUUID();
challengeQuestionResponse.setCode(secretKey);
UserRecoveryData recoveryData = new UserRecoveryData(userRecoveryData.getUser(), secretKey, RecoveryScenarios.QUESTION_BASED_PWD_RECOVERY);
if (StringUtils.isNotBlank(remainingSetIds)) {
String[] ids = remainingSetIds.split(challengeQuestionSeparator);
ChallengeQuestion challengeQuestion = challengeQuestionManager.getUserChallengeQuestion(userRecoveryData.getUser(), ids[0]);
challengeQuestionResponse.setQuestion(challengeQuestion);
recoveryData.setRecoveryStep(RecoverySteps.VALIDATE_CHALLENGE_QUESTION);
challengeQuestionResponse.setStatus(IdentityRecoveryConstants.RECOVERY_STATUS_INCOMPLETE);
if (ids.length > 1) {
for (int i = 1; i < ids.length; i++) {
if (i == 1) {
remainingSetIds = ids[1];
} else {
remainingSetIds = remainingSetIds + challengeQuestionSeparator + ids[i];
}
}
recoveryData.setRemainingSetIds(remainingSetIds);
}
} else {
resetFailedLoginCount = true;
recoveryData.setRecoveryStep(RecoverySteps.UPDATE_PASSWORD);
challengeQuestionResponse.setStatus(IdentityRecoveryConstants.RECOVERY_STATUS_COMPLETE);
}
userRecoveryDataStore.store(recoveryData);
// Reset password recovery failed attempts
if (isPerUserFunctionalityLockingEnabled) {
resetRecoveryPasswordProperties(userRecoveryData.getUser(), resetFailedLoginCount);
} else {
resetRecoveryPasswordFailedAttempts(userRecoveryData.getUser(), resetFailedLoginCount);
}
return challengeQuestionResponse;
} else {
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_ANSWER_FOR_SECURITY_QUESTION, null);
}
} else if (RecoverySteps.VALIDATE_ALL_CHALLENGE_QUESTION.equals(userRecoveryData.getRecoveryStep())) {
String allChallengeQuestions = userRecoveryData.getRemainingSetIds();
if (StringUtils.isNotBlank(allChallengeQuestions)) {
String[] requestedQuestions = allChallengeQuestions.split(challengeQuestionSeparator);
if (requestedQuestions.length != userChallengeAnswer.length) {
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NEED_TO_ANSWER_TO_REQUESTED_QUESTIONS, null);
}
validateQuestion(requestedQuestions, userChallengeAnswer);
// Validate whether user answered all the requested questions
} else {
String error = "Could not find requested challenge questions for user: " + userRecoveryData.getUser();
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND, error);
}
ChallengeQuestionManager challengeQuestionManager = ChallengeQuestionManager.getInstance();
for (int i = 0; i < userChallengeAnswer.length; i++) {
boolean verified = challengeQuestionManager.verifyUserChallengeAnswer(userRecoveryData.getUser(), userChallengeAnswer[i]);
if (!verified) {
// handleAnswerVerificationFail(userRecoveryData.getUser());
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_ANSWER_FOR_SECURITY_QUESTION, null);
}
}
// Reset password recovery failed attempts
if (isPerUserFunctionalityLockingEnabled) {
resetRecoveryPasswordProperties(userRecoveryData.getUser(), true);
} else {
resetRecoveryPasswordFailedAttempts(userRecoveryData.getUser(), true);
}
userRecoveryDataStore.invalidate(code);
ChallengeQuestionResponse challengeQuestionResponse = new ChallengeQuestionResponse();
String secretKey = UUIDGenerator.generateUUID();
challengeQuestionResponse.setCode(secretKey);
challengeQuestionResponse.setStatus(IdentityRecoveryConstants.RECOVERY_STATUS_COMPLETE);
UserRecoveryData recoveryData = new UserRecoveryData(userRecoveryData.getUser(), secretKey, RecoveryScenarios.QUESTION_BASED_PWD_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) {
if (isPerUserFunctionalityLockingEnabled) {
handleAnswerVerificationFailInFunctionalityLockMode(userRecoveryData.getUser());
throw e;
}
handleAnswerVerificationFail(userRecoveryData.getUser());
throw e;
}
}
use of org.wso2.carbon.identity.recovery.IdentityRecoveryClientException in project identity-governance by wso2-extensions.
the class SecurityQuestionPasswordRecoveryManager method verifyUserExists.
private void verifyUserExists(User user) throws IdentityRecoveryClientException, IdentityRecoveryServerException {
UserStoreManager userStoreManager;
try {
int tenantId = IdentityTenantUtil.getTenantId(user.getTenantDomain());
userStoreManager = IdentityRecoveryServiceDataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId).getUserStoreManager();
String domainQualifiedUsername = IdentityUtil.addDomainToName(user.getUserName(), user.getUserStoreDomain());
if (!userStoreManager.isExistingUser(domainQualifiedUsername)) {
if (log.isDebugEnabled()) {
log.debug("No user found for recovery with username: " + user.toFullQualifiedUsername());
}
boolean notifyUserExistence = Boolean.parseBoolean(IdentityUtil.getProperty(IdentityRecoveryConstants.ConnectorConfig.NOTIFY_USER_EXISTENCE));
if (notifyUserExistence) {
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_USER, domainQualifiedUsername);
} else {
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND, user.getUserName());
}
}
} catch (UserStoreException e) {
throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_UNEXPECTED, null);
}
}
use of org.wso2.carbon.identity.recovery.IdentityRecoveryClientException in project identity-governance by wso2-extensions.
the class ChallengeQuestionManagementAdminService method setUserChallengeAnswers.
/**
* Set challenge question answers for a user
*
* @param user
* @param userChallengeAnswers
* @throws IdentityRecoveryException
*/
public void setUserChallengeAnswers(User user, UserChallengeAnswer[] userChallengeAnswers) throws IdentityRecoveryException {
if (user == null) {
log.error("User object provided is null.");
throw new IdentityRecoveryClientException("User object provided is null.");
}
String tenantAwareUserName = MultitenantUtils.getTenantAwareUsername(user.getUserName());
if (ArrayUtils.isEmpty(userChallengeAnswers)) {
String errorMsg = "No challenge question answers provided by the user " + tenantAwareUserName;
log.error(errorMsg);
throw new IdentityRecoveryClientException(errorMsg);
}
String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String loggedInName = CarbonContext.getThreadLocalCarbonContext().getUsername();
// TODO externalize the authorization logic
if (tenantAwareUserName != null && !isValidUser(user.getUserStoreDomain(), tenantAwareUserName, loggedInName)) {
boolean isAuthorized = isUserAuthorized(loggedInName, tenantDomain);
if (!isAuthorized) {
throw new IdentityRecoveryClientException("Unauthorized access!! Possible elevation of privilege attack. " + "User " + loggedInName + " trying to change challenge questions for user " + tenantAwareUserName);
}
} else if (tenantAwareUserName == null) {
tenantAwareUserName = loggedInName;
}
try {
questionManager.setChallengesOfUser(user, userChallengeAnswers);
} catch (IdentityException e) {
String errorMessage = "Error while persisting user challenges for user : " + tenantAwareUserName;
log.error(errorMessage, e);
throw new IdentityRecoveryException(errorMessage, e);
}
}
Aggregations