use of org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore 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;
}
use of org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore in project identity-governance by wso2-extensions.
the class UserSelfRegistrationHandler method handleEvent.
@Override
public void handleEvent(Event event) throws IdentityEventException {
Map<String, Object> eventProperties = event.getEventProperties();
String userName = (String) eventProperties.get(IdentityEventConstants.EventProperty.USER_NAME);
UserStoreManager userStoreManager = (UserStoreManager) eventProperties.get(IdentityEventConstants.EventProperty.USER_STORE_MANAGER);
String tenantDomain = (String) eventProperties.get(IdentityEventConstants.EventProperty.TENANT_DOMAIN);
String domainName = userStoreManager.getRealmConfiguration().getUserStoreProperty(UserCoreConstants.RealmConfig.PROPERTY_DOMAIN_NAME);
String[] roleList = (String[]) eventProperties.get(IdentityEventConstants.EventProperty.ROLE_LIST);
User user = new User();
user.setUserName(userName);
user.setTenantDomain(tenantDomain);
user.setUserStoreDomain(domainName);
boolean enable = Boolean.parseBoolean(Utils.getConnectorConfig(IdentityRecoveryConstants.ConnectorConfig.ENABLE_SELF_SIGNUP, user.getTenantDomain()));
if (!enable) {
if (log.isDebugEnabled()) {
log.debug("Self signup feature is disabled in tenant: " + tenantDomain);
}
return;
}
// Check selfSignupRole is in the request. If it is not there, this handler will not do anything. just retrun
if (roleList == null) {
return;
} else {
List<String> roles = Arrays.asList(roleList);
if (!roles.contains(IdentityRecoveryConstants.SELF_SIGNUP_ROLE)) {
return;
}
}
boolean isAccountLockOnCreation = Boolean.parseBoolean(Utils.getConnectorConfig(IdentityRecoveryConstants.ConnectorConfig.ACCOUNT_LOCK_ON_CREATION, user.getTenantDomain()));
boolean isEnableConfirmationOnCreation = Boolean.parseBoolean(Utils.getConnectorConfig(IdentityRecoveryConstants.ConnectorConfig.SEND_CONFIRMATION_NOTIFICATION, user.getTenantDomain()));
boolean isNotificationInternallyManage = Boolean.parseBoolean(Utils.getConnectorConfig(IdentityRecoveryConstants.ConnectorConfig.SIGN_UP_NOTIFICATION_INTERNALLY_MANAGE, user.getTenantDomain()));
if (IdentityEventConstants.Event.POST_ADD_USER.equals(event.getEventName())) {
UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
try {
// Get the user preferred notification channel.
String preferredChannel = resolveNotificationChannel(eventProperties, userName, tenantDomain, domainName);
// If the preferred channel is already verified, no need to send the notifications or lock
// the account.
boolean notificationChannelVerified = isNotificationChannelVerified(userName, tenantDomain, preferredChannel, eventProperties);
if (notificationChannelVerified) {
return;
}
boolean isSelfRegistrationConfirmationNotify = Boolean.parseBoolean(Utils.getSignUpConfigs(IdentityRecoveryConstants.ConnectorConfig.SELF_REGISTRATION_NOTIFY_ACCOUNT_CONFIRMATION, user.getTenantDomain()));
// EnableConfirmationOnCreation are disabled then send account creation notification.
if (!isAccountLockOnCreation && !isEnableConfirmationOnCreation && isNotificationInternallyManage && isSelfRegistrationConfirmationNotify) {
triggerAccountCreationNotification(user);
}
// If notifications are externally managed, no send notifications.
if ((isAccountLockOnCreation || isEnableConfirmationOnCreation) && isNotificationInternallyManage) {
userRecoveryDataStore.invalidate(user);
// Create a secret key based on the preferred notification channel.
String secretKey = generateSecretKey(preferredChannel);
// Resolve event name.
String eventName = resolveEventName(preferredChannel, userName, domainName, tenantDomain);
UserRecoveryData recoveryDataDO = new UserRecoveryData(user, secretKey, RecoveryScenarios.SELF_SIGN_UP, RecoverySteps.CONFIRM_SIGN_UP);
// Notified channel is stored in remaining setIds for recovery purposes.
recoveryDataDO.setRemainingSetIds(preferredChannel);
userRecoveryDataStore.store(recoveryDataDO);
triggerNotification(user, preferredChannel, secretKey, Utils.getArbitraryProperties(), eventName);
}
} catch (IdentityRecoveryException e) {
throw new IdentityEventException("Error while sending self sign up notification ", e);
}
if (isAccountLockOnCreation || isEnableConfirmationOnCreation) {
HashMap<String, String> userClaims = new HashMap<>();
if (isAccountLockOnCreation) {
// Need to lock user account.
userClaims.put(IdentityRecoveryConstants.ACCOUNT_LOCKED_CLAIM, Boolean.TRUE.toString());
userClaims.put(IdentityRecoveryConstants.ACCOUNT_LOCKED_REASON_CLAIM, IdentityMgtConstants.LockedReason.PENDING_SELF_REGISTRATION.toString());
}
if (Utils.isAccountStateClaimExisting(tenantDomain)) {
userClaims.put(IdentityRecoveryConstants.ACCOUNT_STATE_CLAIM_URI, IdentityRecoveryConstants.PENDING_SELF_REGISTRATION);
}
try {
userStoreManager.setUserClaimValues(user.getUserName(), userClaims, null);
if (log.isDebugEnabled()) {
if (isAccountLockOnCreation) {
log.debug("Locked user account: " + user.getUserName());
}
if (isEnableConfirmationOnCreation) {
log.debug("Send verification notification for user account: " + user.getUserName());
}
}
} catch (UserStoreException e) {
throw new IdentityEventException("Error while lock user account :" + user.getUserName(), e);
}
}
}
}
use of org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore in project identity-governance by wso2-extensions.
the class CodeInvalidationHandler method handleEvent.
@Override
public void handleEvent(Event event) throws IdentityEventException {
String eventName = event.getEventName();
if (log.isDebugEnabled()) {
log.debug("Handling event : " + eventName);
}
if (IdentityEventConstants.Event.POST_DELETE_USER.equals(event.getEventName())) {
UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
Map<String, Object> eventProperties = event.getEventProperties();
String userName = (String) eventProperties.get(IdentityEventConstants.EventProperty.USER_NAME);
UserStoreManager userStoreManager = (UserStoreManager) eventProperties.get(IdentityEventConstants.EventProperty.USER_STORE_MANAGER);
String tenantDomain = (String) eventProperties.get(IdentityEventConstants.EventProperty.TENANT_DOMAIN);
String domainName = userStoreManager.getRealmConfiguration().getUserStoreProperty(UserCoreConstants.RealmConfig.PROPERTY_DOMAIN_NAME);
User user = new User();
user.setUserName(userName);
user.setTenantDomain(tenantDomain);
user.setUserStoreDomain(domainName);
try {
userRecoveryDataStore.invalidate(user);
} catch (IdentityRecoveryException e) {
throw new IdentityEventException("Error while invalidating codes.", e);
}
}
}
use of org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore in project identity-governance by wso2-extensions.
the class LiteUserRegistrationHandler method handleEvent.
@Override
public void handleEvent(Event event) throws IdentityEventException {
Map<String, Object> eventProperties = event.getEventProperties();
String userName = (String) eventProperties.get(IdentityEventConstants.EventProperty.USER_NAME);
UserStoreManager userStoreManager = (UserStoreManager) eventProperties.get(IdentityEventConstants.EventProperty.USER_STORE_MANAGER);
String tenantDomain = (String) eventProperties.get(IdentityEventConstants.EventProperty.TENANT_DOMAIN);
String domainName = userStoreManager.getRealmConfiguration().getUserStoreProperty(UserCoreConstants.RealmConfig.PROPERTY_DOMAIN_NAME);
boolean isLiteSignUp = Utils.isLiteSignUp(Utils.getArbitraryProperties());
if (!isLiteSignUp) {
// Lite sign up feature is disabled
if (log.isDebugEnabled()) {
log.debug("Not lite sign up flow for the user.");
}
// this handler will not do anything. just return
return;
}
User user = new User();
user.setUserName(userName);
user.setTenantDomain(tenantDomain);
user.setUserStoreDomain(domainName);
boolean enable = Boolean.parseBoolean(Utils.getConnectorConfig(IdentityRecoveryConstants.ConnectorConfig.ENABLE_LITE_SIGN_UP, user.getTenantDomain()));
if (!enable) {
// Lite sign up feature is disabled
if (log.isDebugEnabled()) {
log.debug("Lite sign up feature is disabled in tenant: " + tenantDomain);
}
// this handler will not do anything. just return
return;
}
boolean isAccountLockOnCreation = Boolean.parseBoolean(Utils.getConnectorConfig(IdentityRecoveryConstants.ConnectorConfig.LITE_ACCOUNT_LOCK_ON_CREATION, user.getTenantDomain()));
boolean isNotificationInternallyManage = Boolean.parseBoolean(Utils.getConnectorConfig(IdentityRecoveryConstants.ConnectorConfig.LITE_SIGN_UP_NOTIFICATION_INTERNALLY_MANAGE, user.getTenantDomain()));
if (IdentityEventConstants.Event.POST_ADD_USER.equals(event.getEventName())) {
UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
try {
// Get the user preferred notification channel.
String preferredChannel = resolveNotificationChannel(eventProperties, userName, tenantDomain, domainName);
// If the preferred channel is already verified, no need to send the notifications or lock
// the account.
boolean notificationChannelVerified = isNotificationChannelVerified(userName, tenantDomain, preferredChannel, eventProperties);
if (notificationChannelVerified) {
return;
}
// If notifications are externally managed, no send notifications.
if (isNotificationInternallyManage && isAccountLockOnCreation) {
userRecoveryDataStore.invalidate(user);
// Create a secret key based on the preferred notification channel.
String secretKey = generateSecretKey(preferredChannel);
// Resolve event name.
String eventName = resolveEventName(preferredChannel, userName, domainName, tenantDomain);
UserRecoveryData recoveryDataDO = new UserRecoveryData(user, secretKey, RecoveryScenarios.LITE_SIGN_UP, RecoverySteps.CONFIRM_LITE_SIGN_UP);
// Notified channel is stored in remaining setIds for recovery purposes.
recoveryDataDO.setRemainingSetIds(preferredChannel);
userRecoveryDataStore.store(recoveryDataDO);
triggerNotification(user, preferredChannel, secretKey, Utils.getArbitraryProperties(), eventName);
}
} catch (IdentityRecoveryException e) {
throw new IdentityEventException("Error while sending lite sign up notification ", e);
}
if (isAccountLockOnCreation) {
HashMap<String, String> userClaims = new HashMap<>();
// Need to lock user account
userClaims.put(IdentityRecoveryConstants.ACCOUNT_LOCKED_CLAIM, Boolean.TRUE.toString());
if (Utils.isAccountStateClaimExisting(tenantDomain)) {
userClaims.put(IdentityRecoveryConstants.ACCOUNT_STATE_CLAIM_URI, IdentityRecoveryConstants.PENDING_LITE_REGISTRATION);
}
try {
userStoreManager.setUserClaimValues(user.getUserName(), userClaims, null);
if (log.isDebugEnabled()) {
log.debug("Locked user account: " + user.getUserName());
}
} catch (UserStoreException e) {
throw new IdentityEventException("Error while lock user account :" + user.getUserName(), e);
}
}
}
}
use of org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore in project identity-governance by wso2-extensions.
the class UserEmailVerificationHandler method initNotification.
protected void initNotification(User user, Enum recoveryScenario, Enum recoveryStep, String notificationType, String secretKey) throws IdentityEventException {
UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
try {
userRecoveryDataStore.invalidate(user);
UserRecoveryData recoveryDataDO = new UserRecoveryData(user, secretKey, recoveryScenario, recoveryStep);
userRecoveryDataStore.store(recoveryDataDO);
triggerNotification(user, notificationType, secretKey, Utils.getArbitraryProperties(), recoveryDataDO);
} catch (IdentityRecoveryException e) {
throw new IdentityEventException("Error while sending notification ", e);
}
}
Aggregations