Search in sources :

Example 21 with IdentityEventException

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);
            }
        }
    }
}
Also used : User(org.wso2.carbon.identity.application.common.model.User) IdentityEventException(org.wso2.carbon.identity.event.IdentityEventException) HashMap(java.util.HashMap) UserStoreManager(org.wso2.carbon.user.core.UserStoreManager) UserRecoveryData(org.wso2.carbon.identity.recovery.model.UserRecoveryData) UserRecoveryDataStore(org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore) UserStoreException(org.wso2.carbon.user.core.UserStoreException) IdentityRecoveryException(org.wso2.carbon.identity.recovery.IdentityRecoveryException)

Example 22 with IdentityEventException

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);
    }
}
Also used : HashMap(java.util.HashMap) IdentityEventException(org.wso2.carbon.identity.event.IdentityEventException) Event(org.wso2.carbon.identity.event.event.Event) Property(org.wso2.carbon.identity.recovery.model.Property)

Example 23 with IdentityEventException

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());
    }
}
Also used : IdentityEventException(org.wso2.carbon.identity.event.IdentityEventException) UserStoreException(org.wso2.carbon.user.core.UserStoreException)

Example 24 with IdentityEventException

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);
    }
}
Also used : User(org.wso2.carbon.identity.application.common.model.User) IdentityEventException(org.wso2.carbon.identity.event.IdentityEventException) IdentityRecoveryException(org.wso2.carbon.identity.recovery.IdentityRecoveryException)

Example 25 with IdentityEventException

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);
    }
}
Also used : HashMap(java.util.HashMap) IdentityEventException(org.wso2.carbon.identity.event.IdentityEventException) Event(org.wso2.carbon.identity.event.event.Event) Property(org.wso2.carbon.identity.recovery.model.Property)

Aggregations

IdentityEventException (org.wso2.carbon.identity.event.IdentityEventException)75 HashMap (java.util.HashMap)42 Event (org.wso2.carbon.identity.event.event.Event)39 UserStoreManager (org.wso2.carbon.user.core.UserStoreManager)17 User (org.wso2.carbon.identity.application.common.model.User)14 IdentityRecoveryException (org.wso2.carbon.identity.recovery.IdentityRecoveryException)14 UserRecoveryData (org.wso2.carbon.identity.recovery.model.UserRecoveryData)13 UserRecoveryDataStore (org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore)13 IdentityEventService (org.wso2.carbon.identity.event.services.IdentityEventService)12 Map (java.util.Map)11 UserStoreException (org.wso2.carbon.user.core.UserStoreException)10 JSONObject (org.json.JSONObject)9 UserStoreException (org.wso2.carbon.user.api.UserStoreException)9 Property (org.wso2.carbon.identity.recovery.model.Property)7 Property (org.wso2.carbon.identity.application.common.model.Property)6 RealmService (org.wso2.carbon.user.core.service.RealmService)6 Test (org.testng.annotations.Test)5 Properties (java.util.Properties)4 IdentityGovernanceException (org.wso2.carbon.identity.governance.IdentityGovernanceException)4 NotificationChannelManagerException (org.wso2.carbon.identity.governance.exceptions.notiification.NotificationChannelManagerException)4