use of org.wso2.carbon.identity.event.IdentityEventException 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.event.IdentityEventException in project identity-governance by wso2-extensions.
the class MobileNumberVerificationHandler method triggerNotification.
/**
* Trigger the SMS notification.
*
* @param user User.
* @param code SMS OTP.
* @param props Other properties.
* @param verificationPendingMobileNumber Mobile number to which the SMS should be sent.
* @throws IdentityRecoveryException
*/
private void triggerNotification(User user, String code, Property[] props, String verificationPendingMobileNumber) throws IdentityRecoveryException {
String notificationType = IdentityRecoveryConstants.NOTIFICATION_TYPE_VERIFY_MOBILE_ON_UPDATE;
if (log.isDebugEnabled()) {
log.debug("Sending: " + notificationType + " notification to user: " + user.toFullQualifiedUsername());
}
String eventName = IdentityEventConstants.Event.TRIGGER_SMS_NOTIFICATION;
HashMap<String, Object> properties = new HashMap<>();
properties.put(IdentityEventConstants.EventProperty.USER_NAME, user.getUserName());
properties.put(IdentityEventConstants.EventProperty.TENANT_DOMAIN, user.getTenantDomain());
properties.put(IdentityEventConstants.EventProperty.USER_STORE_DOMAIN, user.getUserStoreDomain());
properties.put(IdentityEventConstants.EventProperty.NOTIFICATION_CHANNEL, NotificationChannels.SMS_CHANNEL.getChannelType());
properties.put(IdentityRecoveryConstants.TEMPLATE_TYPE, notificationType);
if (StringUtils.isNotBlank(verificationPendingMobileNumber)) {
properties.put(IdentityRecoveryConstants.SEND_TO, verificationPendingMobileNumber);
}
if (props != null && props.length > 0) {
for (Property prop : props) {
properties.put(prop.getKey(), prop.getValue());
}
}
if (StringUtils.isNotBlank(code)) {
properties.put(IdentityRecoveryConstants.CONFIRMATION_CODE, code);
}
Event identityMgtEvent = new Event(eventName, properties);
try {
IdentityRecoveryServiceDataHolder.getInstance().getIdentityEventService().handleEvent(identityMgtEvent);
} catch (IdentityEventException e) {
throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_TRIGGER_NOTIFICATION, user.toFullQualifiedUsername(), e);
}
}
use of org.wso2.carbon.identity.event.IdentityEventException in project identity-governance by wso2-extensions.
the class MobileNumberVerificationHandler method preSetUserClaimOnMobileNumberUpdate.
/**
* If the mobile claim is updated, set it to the 'MOBILE_NUMBER_PENDING_VALUE_CLAIM' claim.
* Set thread local state to skip sending verification notification in inapplicable claim update scenarios.
*
* @param claims Map of claims to be updated.
* @param userStoreManager User store manager.
* @param user User.
* @throws IdentityEventException
*/
private void preSetUserClaimOnMobileNumberUpdate(Map<String, String> claims, UserStoreManager userStoreManager, User user) throws IdentityEventException {
if (IdentityRecoveryConstants.SkipMobileNumberVerificationOnUpdateStates.SKIP_ON_CONFIRM.toString().equals(Utils.getThreadLocalToSkipSendingSmsOtpVerificationOnUpdate())) {
// Not required to handle in this handler.
return;
}
if (Utils.getThreadLocalToSkipSendingSmsOtpVerificationOnUpdate() != null) {
Utils.unsetThreadLocalToSkipSendingSmsOtpVerificationOnUpdate();
}
if (MapUtils.isEmpty(claims)) {
// Not required to handle in this handler.
Utils.setThreadLocalToSkipSendingSmsOtpVerificationOnUpdate(IdentityRecoveryConstants.SkipMobileNumberVerificationOnUpdateStates.SKIP_ON_INAPPLICABLE_CLAIMS.toString());
return;
}
String mobileNumber = claims.get(IdentityRecoveryConstants.MOBILE_NUMBER_CLAIM);
if (StringUtils.isNotBlank(mobileNumber) && isVerificationPendingMobileClaimConfigAvailable(user.getTenantDomain())) {
String existingMobileNumber;
String username = user.getUserName();
try {
existingMobileNumber = userStoreManager.getUserClaimValue(username, IdentityRecoveryConstants.MOBILE_NUMBER_CLAIM, null);
} catch (UserStoreException e) {
String error = String.format("Error occurred while retrieving existing mobile number for user: %s in " + "domain: %s and user store: %s", username, user.getTenantDomain(), user.getUserStoreDomain());
throw new IdentityEventException(error, e);
}
if (StringUtils.equals(mobileNumber, existingMobileNumber)) {
if (log.isDebugEnabled()) {
log.debug(String.format("The mobile number to be updated: %s is same as the existing mobile " + "number for user: %s in domain: %s and user store: %s. Hence an SMS OTP verification " + "will not be triggered.", mobileNumber, username, user.getTenantDomain(), user.getUserStoreDomain()));
}
Utils.setThreadLocalToSkipSendingSmsOtpVerificationOnUpdate(IdentityRecoveryConstants.SkipMobileNumberVerificationOnUpdateStates.SKIP_ON_EXISTING_MOBILE_NUM.toString());
invalidatePendingMobileVerification(user, userStoreManager, claims);
return;
}
/*
When 'UseVerifyClaim' is enabled, the verification should happen only if the 'verifyMobile'
temporary claim exists as 'true' in the claim list. If 'UseVerifyClaim' is disabled, no need to
check for 'verifyMobile' claim.
*/
if (Utils.isUseVerifyClaimEnabled() && !isVerifyMobileClaimAvailable(claims)) {
Utils.setThreadLocalToSkipSendingSmsOtpVerificationOnUpdate(IdentityRecoveryConstants.SkipMobileNumberVerificationOnUpdateStates.SKIP_ON_INAPPLICABLE_CLAIMS.toString());
invalidatePendingMobileVerification(user, userStoreManager, claims);
return;
}
// The verification should not happen if the claim update is invoked by a user other than the claim owner.
if (!isInvokedByUser(user)) {
Utils.setThreadLocalToSkipSendingSmsOtpVerificationOnUpdate(IdentityRecoveryConstants.SkipMobileNumberVerificationOnUpdateStates.SKIP_ON_INAPPLICABLE_CLAIMS.toString());
return;
}
claims.put(IdentityRecoveryConstants.MOBILE_NUMBER_PENDING_VALUE_CLAIM, mobileNumber);
claims.remove(IdentityRecoveryConstants.MOBILE_NUMBER_CLAIM);
} else {
Utils.setThreadLocalToSkipSendingSmsOtpVerificationOnUpdate(IdentityRecoveryConstants.SkipMobileNumberVerificationOnUpdateStates.SKIP_ON_INAPPLICABLE_CLAIMS.toString());
}
}
use of org.wso2.carbon.identity.event.IdentityEventException in project identity-governance by wso2-extensions.
the class TenantRegistrationVerificationHandler method handleClaimUpdate.
protected void handleClaimUpdate(Map<String, Object> eventProperties, UserStoreManager userStoreManager, Map<String, String> claims) throws IdentityEventException {
User user = getUser(eventProperties, userStoreManager);
if (log.isDebugEnabled()) {
log.debug("PreSetUserClaim - TenantRegistrationVerificationHandler for : " + user.toString() + ". This is an update request for the claim: " + IdentityRecoveryConstants.TENANT_ADMIN_ASK_PASSWORD_CLAIM);
}
// Remove claim to prevent persisting this temporary claim.
claims.remove(IdentityRecoveryConstants.TENANT_ADMIN_ASK_PASSWORD_CLAIM);
String uuid = UUIDGenerator.generateUUID();
String notificationType = IdentityRecoveryConstants.NOTIFICATION_TYPE_TENANT_REGISTRATION_CONFIRMATION;
if (claims.containsKey(IdentityRecoveryConstants.ACCOUNT_LOCKED_CLAIM)) {
claims.remove(IdentityRecoveryConstants.ACCOUNT_LOCKED_CLAIM);
}
setRecoveryData(user, RecoveryScenarios.TENANT_ADMIN_ASK_PASSWORD, RecoverySteps.UPDATE_PASSWORD, uuid);
lockAccount(user, userStoreManager);
try {
triggerNotification(user, notificationType, uuid, Utils.getArbitraryProperties());
} catch (IdentityRecoveryException e) {
throw new IdentityEventException("Error while sending notification.", e);
}
}
use of org.wso2.carbon.identity.event.IdentityEventException in project identity-governance by wso2-extensions.
the class UserEmailVerificationHandler method triggerNotification.
private void triggerNotification(User user, String type, String code, Property[] props, String verificationPendingEmailAddress, UserRecoveryData recoveryDataDO) throws IdentityRecoveryException {
if (log.isDebugEnabled()) {
log.debug("Sending : " + type + " notification to user : " + user.toString());
}
String eventName = IdentityEventConstants.Event.TRIGGER_NOTIFICATION;
HashMap<String, Object> properties = new HashMap<>();
properties.put(IdentityEventConstants.EventProperty.USER_NAME, user.getUserName());
properties.put(IdentityEventConstants.EventProperty.TENANT_DOMAIN, user.getTenantDomain());
properties.put(IdentityEventConstants.EventProperty.USER_STORE_DOMAIN, user.getUserStoreDomain());
if (StringUtils.isNotBlank(verificationPendingEmailAddress)) {
properties.put(IdentityRecoveryConstants.SEND_TO, verificationPendingEmailAddress);
}
if (props != null && props.length > 0) {
for (Property prop : props) {
properties.put(prop.getKey(), prop.getValue());
}
}
if (StringUtils.isNotBlank(code)) {
properties.put(IdentityRecoveryConstants.CONFIRMATION_CODE, code);
}
properties.put(IdentityRecoveryConstants.TEMPLATE_TYPE, type);
if (recoveryDataDO != null) {
properties.put(IdentityEventConstants.EventProperty.RECOVERY_SCENARIO, recoveryDataDO.getRecoveryScenario().name());
}
Event identityMgtEvent = new Event(eventName, properties);
try {
IdentityRecoveryServiceDataHolder.getInstance().getIdentityEventService().handleEvent(identityMgtEvent);
} catch (IdentityEventException e) {
throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_TRIGGER_NOTIFICATION, user.getUserName(), e);
}
}
Aggregations