use of org.wso2.carbon.identity.recovery.ChallengeQuestionManager in project identity-governance by wso2-extensions.
the class IdentityRecoveryServiceComponent method activate.
@Activate
protected void activate(ComponentContext context) {
try {
BundleContext bundleContext = context.getBundleContext();
bundleContext.registerService(NotificationPasswordRecoveryManager.class.getName(), NotificationPasswordRecoveryManager.getInstance(), null);
bundleContext.registerService(SecurityQuestionPasswordRecoveryManager.class.getName(), SecurityQuestionPasswordRecoveryManager.getInstance(), null);
bundleContext.registerService(NotificationUsernameRecoveryManager.class.getName(), NotificationUsernameRecoveryManager.getInstance(), null);
bundleContext.registerService(UserSelfRegistrationManager.class.getName(), UserSelfRegistrationManager.getInstance(), null);
bundleContext.registerService(ChallengeQuestionManager.class.getName(), ChallengeQuestionManager.getInstance(), null);
bundleContext.registerService(ResendConfirmationManager.class.getName(), ResendConfirmationManager.getInstance(), null);
bundleContext.registerService(AbstractEventHandler.class.getName(), new AccountConfirmationValidationHandler(), null);
bundleContext.registerService(AbstractEventHandler.class.getName(), new UserSelfRegistrationHandler(), null);
bundleContext.registerService(AbstractEventHandler.class.getName(), new LiteUserRegistrationHandler(), null);
bundleContext.registerService(AbstractEventHandler.class.getName(), new UserEmailVerificationHandler(), null);
bundleContext.registerService(AbstractEventHandler.class.getName(), new MobileNumberVerificationHandler(), null);
bundleContext.registerService(AbstractEventHandler.class.getName(), new AdminForcedPasswordResetHandler(), null);
bundleContext.registerService(AbstractEventHandler.class.getName(), new TenantRegistrationVerificationHandler(), null);
bundleContext.registerService(AbstractEventHandler.class.getName(), new IdentityUserMetadataMgtHandler(), null);
bundleContext.registerService(IdentityConnectorConfig.class.getName(), new RecoveryConfigImpl(), null);
bundleContext.registerService(IdentityConnectorConfig.class.getName(), new SelfRegistrationConfigImpl(), null);
bundleContext.registerService(IdentityConnectorConfig.class.getName(), new LiteRegistrationConfigImpl(), null);
bundleContext.registerService(IdentityConnectorConfig.class.getName(), new UserEmailVerificationConfigImpl(), null);
bundleContext.registerService(IdentityConnectorConfig.class.getName(), new UserClaimUpdateConfigImpl(), null);
bundleContext.registerService(IdentityConnectorConfig.class.getName(), new AdminForcedPasswordResetConfigImpl(), null);
bundleContext.registerService(AbstractEventHandler.class.getName(), new CodeInvalidationHandler(), null);
UsernameRecoveryManager usernameRecoveryManager = new UsernameRecoveryManagerImpl();
bundleContext.registerService(UsernameRecoveryManager.class.getName(), usernameRecoveryManager, null);
PasswordRecoveryManager passwordRecoveryManager = new PasswordRecoveryManagerImpl();
bundleContext.registerService(PasswordRecoveryManager.class.getName(), passwordRecoveryManager, null);
// Registering missing challenge question handler as a post authn handler
PostAuthenticationHandler postAuthnMissingChallengeQuestions = PostAuthnMissingChallengeQuestionsHandler.getInstance();
bundleContext.registerService(PostAuthenticationHandler.class.getName(), postAuthnMissingChallengeQuestions, null);
bundleContext.registerService(AbstractEventHandler.class.getName(), new ChallengeAnswerValidationHandler(), null);
} catch (Exception e) {
log.error("Error while activating identity governance component.", e);
}
// register the tenant management listener
TenantMgtListener tenantMgtListener = new TenantManagementListener();
context.getBundleContext().registerService(TenantMgtListener.class.getName(), tenantMgtListener, null);
// register default challenge questions
try {
if (log.isDebugEnabled()) {
log.debug("Loading default challenge questions for super tenant.");
}
loadDefaultChallengeQuestions();
// new ChallengeQuestionManager().getAllChallengeQuestions("carbon.super", "lk_LK");
} catch (IdentityRecoveryException e) {
log.error("Error persisting challenge question for super tenant.", e);
}
}
use of org.wso2.carbon.identity.recovery.ChallengeQuestionManager in project identity-governance by wso2-extensions.
the class PostAuthnMissingChallengeQuestionsHandlerTest method testBeforeRequestingChallengeQuestionFlow.
@Test(description = "Test the flow of challenge question post authentication handler before requesting challenge " + "questions from the user")
public void testBeforeRequestingChallengeQuestionFlow() throws Exception {
AuthenticationContext context = spy(new AuthenticationContext());
when(context.getTenantDomain()).thenReturn("carbon.super");
IdentityProvider residentIdp = spy(new IdentityProvider());
IdentityProviderProperty[] idpProperties = new IdentityProviderProperty[1];
IdentityProviderProperty idpProp = new IdentityProviderProperty();
idpProp.setName(IdentityRecoveryConstants.ConnectorConfig.FORCE_ADD_PW_RECOVERY_QUESTION);
idpProp.setValue("true");
idpProperties[0] = idpProp;
residentIdp.setIdpProperties(idpProperties);
mockedIdentityProviderManager.when(IdentityProviderManager::getInstance).thenReturn(identityProviderManager);
when(identityProviderManager.getResidentIdP("carbon.super")).thenReturn(residentIdp);
SequenceConfig sequenceConfig = spy(new SequenceConfig());
AuthenticatedUser user = spy(new AuthenticatedUser());
user.setUserName("admin");
when(sequenceConfig.getAuthenticatedUser()).thenReturn(user);
context.setSequenceConfig(sequenceConfig);
mockedMultitenantUtils.when(() -> MultitenantUtils.getTenantDomain("admin")).thenReturn("carbon.super");
mockedUtils.when(() -> Utils.getTenantId("carbon.super")).thenReturn(-1234);
mockedIdentityRecoveryServiceDataHolder.when(IdentityRecoveryServiceDataHolder::getInstance).thenReturn(frameworkServiceDataHolder);
RealmService realmService = mock(RealmService.class);
UserStoreManager userStoreManager = mock(UserStoreManager.class);
UserRealm userRealm = mock(UserRealm.class);
when(userRealm.getUserStoreManager()).thenReturn(userStoreManager);
when(realmService.getTenantUserRealm(-1234)).thenReturn(userRealm);
when(frameworkServiceDataHolder.getRealmService()).thenReturn(realmService);
when(userRealm.getUserStoreManager()).thenReturn(userStoreManager);
Map<String, String> claimsMap = new HashMap<>();
when(userStoreManager.getUserClaimValues("admin", new String[] { IdentityRecoveryConstants.CHALLENGE_QUESTION_URI }, UserCoreConstants.DEFAULT_PROFILE)).thenReturn(claimsMap);
List<ChallengeQuestion> challengeQuestions = new ArrayList<>();
ChallengeQuestion challengeQuestion = spy(new ChallengeQuestion());
challengeQuestion.setQuestionSetId("dummy_set");
challengeQuestion.setQuestionId("dummy_id");
challengeQuestion.setQuestion("dummy_question");
challengeQuestions.add(challengeQuestion);
when(challengeQuestionManager.getAllChallengeQuestions("carbon.super")).thenReturn(challengeQuestions);
mockedChallengeQuestionManager.when(ChallengeQuestionManager::getInstance).thenReturn(challengeQuestionManager);
doNothing().doThrow(Exception.class).when(httpServletResponse).sendRedirect((String) any());
when(configurationFacade.getAuthenticationEndpointURL()).thenReturn("");
when(ConfigurationFacade.getInstance()).thenReturn(configurationFacade);
PostAuthnHandlerFlowStatus flowStatus = PostAuthnMissingChallengeQuestionsHandler.getInstance().handle(httpServletRequest, httpServletResponse, context);
String expectedResult = PostAuthnHandlerFlowStatus.INCOMPLETE.name();
assertEquals(flowStatus.name(), expectedResult);
}
use of org.wso2.carbon.identity.recovery.ChallengeQuestionManager 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.ChallengeQuestionManager in project identity-governance by wso2-extensions.
the class SecurityQuestionPasswordRecoveryManager method initiateUserChallengeQuestion.
public ChallengeQuestionResponse initiateUserChallengeQuestion(User user) throws IdentityRecoveryException {
Utils.validateEmailUsername(user.getUserName());
if (StringUtils.isBlank(user.getTenantDomain())) {
user.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
log.info("initiateUserChallengeQuestion :Tenant domain is not in the request. set to default for user : " + user.getUserName());
}
if (StringUtils.isBlank(user.getUserStoreDomain())) {
user.setUserStoreDomain(IdentityUtil.getPrimaryDomainName());
log.info("initiateUserChallengeQuestion :User store domain is not in the request. set to default for user" + " : " + user.getUserName());
}
boolean isNotificationInternallyManaged = Boolean.parseBoolean(Utils.getRecoveryConfigs(IdentityRecoveryConstants.ConnectorConfig.NOTIFICATION_INTERNALLY_MANAGE, user.getTenantDomain()));
boolean isRecoveryEnable = Boolean.parseBoolean(Utils.getRecoveryConfigs(IdentityRecoveryConstants.ConnectorConfig.QUESTION_BASED_PW_RECOVERY, user.getTenantDomain()));
if (!isRecoveryEnable) {
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_QUESTION_BASED_RECOVERY_NOT_ENABLE, null);
}
verifyUserExists(user);
validateFunctionalityForUser(user);
UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
userRecoveryDataStore.invalidate(user);
String challengeQuestionSeparator = IdentityUtil.getProperty(IdentityRecoveryConstants.ConnectorConfig.QUESTION_CHALLENGE_SEPARATOR);
if (StringUtils.isEmpty(challengeQuestionSeparator)) {
challengeQuestionSeparator = IdentityRecoveryConstants.DEFAULT_CHALLENGE_QUESTION_SEPARATOR;
}
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());
}
boolean isNotificationSendWhenInitiatingPWRecovery = Boolean.parseBoolean(Utils.getRecoveryConfigs(IdentityRecoveryConstants.ConnectorConfig.NOTIFICATION_SEND_RECOVERY_SECURITY_START, user.getTenantDomain()));
if (isNotificationInternallyManaged && isNotificationSendWhenInitiatingPWRecovery) {
try {
triggerNotification(user, IdentityRecoveryConstants.NOTIFICATION_TYPE_PASSWORD_RESET_INITIATE, null);
} catch (Exception e) {
log.warn("Error while sending password reset initiating notification to user :" + user.getUserName());
}
}
int minNoOfQuestionsToAnswer = Integer.parseInt(Utils.getRecoveryConfigs(IdentityRecoveryConstants.ConnectorConfig.QUESTION_MIN_NO_ANSWER, user.getTenantDomain()));
ChallengeQuestionManager challengeQuestionManager = ChallengeQuestionManager.getInstance();
String[] ids = challengeQuestionManager.getUserChallengeQuestionIds(user);
if (ids == null || ids.length == 0) {
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CHALLENGE_QUESTION_NOT_FOUND, user.getUserName());
}
if (ids.length > minNoOfQuestionsToAnswer) {
ids = getRandomQuestionIds(ids, minNoOfQuestionsToAnswer);
}
String metaData = null;
for (int i = 1; i < ids.length; i++) {
if (i == 1) {
metaData = ids[1];
} else {
metaData = metaData + challengeQuestionSeparator + ids[i];
}
}
ChallengeQuestion userChallengeQuestion = challengeQuestionManager.getUserChallengeQuestion(user, ids[0]);
ChallengeQuestionResponse challengeQuestionResponse = new ChallengeQuestionResponse(userChallengeQuestion);
String secretKey = UUIDGenerator.generateUUID();
UserRecoveryData recoveryData = new UserRecoveryData(user, secretKey, RecoveryScenarios.QUESTION_BASED_PWD_RECOVERY, RecoverySteps.VALIDATE_CHALLENGE_QUESTION);
recoveryData.setRemainingSetIds(metaData);
challengeQuestionResponse.setCode(secretKey);
if (ids.length > 1) {
challengeQuestionResponse.setStatus(IdentityRecoveryConstants.RECOVERY_STATUS_INCOMPLETE);
}
userRecoveryDataStore.store(recoveryData);
return challengeQuestionResponse;
}
use of org.wso2.carbon.identity.recovery.ChallengeQuestionManager in project identity-governance by wso2-extensions.
the class TenantManagementListener method onTenantCreate.
@Override
public void onTenantCreate(TenantInfoBean tenantInfoBean) throws StratosException {
String tenantDomain = tenantInfoBean.getTenantDomain();
PrivilegedCarbonContext.getThreadLocalCarbonContext().startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain);
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantInfoBean.getTenantId());
ChallengeQuestionManager questionManager = ChallengeQuestionManager.getInstance();
try {
questionManager.setDefaultChallengeQuestions(tenantDomain);
if (log.isDebugEnabled()) {
log.debug("Default Challenge Questions persisted to the " + tenantDomain + " tenant");
}
} catch (IdentityRecoveryException e) {
log.error("Error when trying to set default challenge question for tenant : " + tenantDomain, e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
Aggregations