Search in sources :

Example 96 with Notification

use of org.wso2.carbon.identity.mgt.mail.Notification in project identity-governance by wso2-extensions.

the class UserSelfRegistrationManager method registerUser.

public NotificationResponseBean registerUser(User user, String password, Claim[] claims, Property[] properties) throws IdentityRecoveryException {
    publishEvent(user, claims, properties, IdentityEventConstants.Event.PRE_SELF_SIGNUP_REGISTER);
    String consent = getPropertyValue(properties, IdentityRecoveryConstants.Consent.CONSENT);
    String tenantDomain = user.getTenantDomain();
    if (StringUtils.isEmpty(tenantDomain)) {
        tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
    }
    // Callback URL validation
    String callbackURL = null;
    try {
        callbackURL = Utils.getCallbackURLFromRegistration(properties);
        if (StringUtils.isNotBlank(callbackURL) && !Utils.validateCallbackURL(callbackURL, tenantDomain, IdentityRecoveryConstants.ConnectorConfig.SELF_REGISTRATION_CALLBACK_REGEX)) {
            throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CALLBACK_URL_NOT_VALID, callbackURL);
        }
    } catch (MalformedURLException | UnsupportedEncodingException | IdentityEventException e) {
        throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CALLBACK_URL_NOT_VALID, callbackURL);
    }
    if (StringUtils.isBlank(user.getTenantDomain())) {
        user.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
        log.info("registerUser :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("registerUser :User store domain is not in the request. set to default for user : " + user.getUserName());
    }
    boolean enable = Boolean.parseBoolean(Utils.getSignUpConfigs(IdentityRecoveryConstants.ConnectorConfig.ENABLE_SELF_SIGNUP, user.getTenantDomain()));
    if (!enable) {
        throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_DISABLE_SELF_SIGN_UP, user.getUserName());
    }
    NotificationResponseBean notificationResponseBean;
    try {
        RealmService realmService = IdentityRecoveryServiceDataHolder.getInstance().getRealmService();
        UserStoreManager userStoreManager;
        try {
            userStoreManager = realmService.getTenantUserRealm(IdentityTenantUtil.getTenantId(user.getTenantDomain())).getUserStoreManager();
        } catch (UserStoreException e) {
            throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_UNEXPECTED, user.getUserName(), e);
        }
        PrivilegedCarbonContext.startTenantFlow();
        PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
        carbonContext.setTenantId(IdentityTenantUtil.getTenantId(user.getTenantDomain()));
        carbonContext.setTenantDomain(user.getTenantDomain());
        Map<String, String> claimsMap = new HashMap<>();
        for (Claim claim : claims) {
            claimsMap.put(claim.getClaimUri(), claim.getValue());
        }
        // Set arbitrary properties to use in UserSelfRegistrationHandler
        Utils.setArbitraryProperties(properties);
        validateAndFilterFromReceipt(consent, claimsMap);
        // User preferred notification channel.
        String preferredChannel;
        try {
            // TODO It is required to add this role before tenant creation. And also, this role should not not be able remove.
            if (!userStoreManager.isExistingRole(IdentityRecoveryConstants.SELF_SIGNUP_ROLE)) {
                Permission permission = new Permission("/permission/admin/login", IdentityRecoveryConstants.EXECUTE_ACTION);
                userStoreManager.addRole(IdentityRecoveryConstants.SELF_SIGNUP_ROLE, null, new Permission[] { permission });
            }
            String[] userRoles = new String[] { IdentityRecoveryConstants.SELF_SIGNUP_ROLE };
            try {
                NotificationChannelManager notificationChannelManager = Utils.getNotificationChannelManager();
                preferredChannel = notificationChannelManager.resolveCommunicationChannel(user.getUserName(), user.getTenantDomain(), user.getUserStoreDomain(), claimsMap);
            } catch (NotificationChannelManagerException e) {
                throw mapNotificationChannelManagerException(e, user);
            }
            // resolved channel is not empty.
            if (StringUtils.isEmpty(claimsMap.get(IdentityRecoveryConstants.PREFERRED_CHANNEL_CLAIM)) && StringUtils.isNotEmpty(preferredChannel)) {
                claimsMap.put(IdentityRecoveryConstants.PREFERRED_CHANNEL_CLAIM, preferredChannel);
            }
            userStoreManager.addUser(IdentityUtil.addDomainToName(user.getUserName(), user.getUserStoreDomain()), password, userRoles, claimsMap, null);
        } catch (UserStoreException e) {
            Throwable cause = e;
            while (cause != null) {
                if (cause instanceof PolicyViolationException) {
                    throw IdentityException.error(IdentityRecoveryClientException.class, IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_POLICY_VIOLATION.getCode(), cause.getMessage(), e);
                }
                cause = cause.getCause();
            }
            Utils.checkPasswordPatternViolation(e, user);
            return handleClientException(user, e);
        }
        addUserConsent(consent, tenantDomain);
        // Build the notification response.
        notificationResponseBean = buildNotificationResponseBean(user, preferredChannel, claimsMap);
    } finally {
        Utils.clearArbitraryProperties();
        PrivilegedCarbonContext.endTenantFlow();
    }
    publishEvent(user, claims, properties, IdentityEventConstants.Event.POST_SELF_SIGNUP_REGISTER);
    return notificationResponseBean;
}
Also used : MalformedURLException(java.net.MalformedURLException) NotificationChannelManager(org.wso2.carbon.identity.governance.service.notification.NotificationChannelManager) NotificationChannelManagerException(org.wso2.carbon.identity.governance.exceptions.notiification.NotificationChannelManagerException) IdentityEventException(org.wso2.carbon.identity.event.IdentityEventException) HashMap(java.util.HashMap) UnsupportedEncodingException(java.io.UnsupportedEncodingException) PrivilegedCarbonContext(org.wso2.carbon.context.PrivilegedCarbonContext) AbstractUserStoreManager(org.wso2.carbon.user.core.common.AbstractUserStoreManager) UserStoreManager(org.wso2.carbon.user.api.UserStoreManager) NotificationResponseBean(org.wso2.carbon.identity.recovery.bean.NotificationResponseBean) RealmService(org.wso2.carbon.user.core.service.RealmService) UserStoreException(org.wso2.carbon.user.api.UserStoreException) Permission(org.wso2.carbon.user.core.Permission) PolicyViolationException(org.wso2.carbon.identity.mgt.policy.PolicyViolationException) Claim(org.wso2.carbon.user.api.Claim) IdentityRecoveryClientException(org.wso2.carbon.identity.recovery.IdentityRecoveryClientException)

Example 97 with Notification

use of org.wso2.carbon.identity.mgt.mail.Notification in project identity-governance by wso2-extensions.

the class UserSelfRegistrationManager method introspectSelfRegistrationCode.

/**
 * Introspects self registration confirmation code details without invalidating it.
 * Does not triggering notification events or update user claims.
 *
 * @param skipExpiredCodeValidation   Skip confirmation code validation against expiration.
 * @param code                      Confirmation code.
 * @return UserRecoveryData           Data associated with the provided code, including related user and scenarios.
 * @throws IdentityRecoveryException  Error validating the confirmation code
 */
private UserRecoveryData introspectSelfRegistrationCode(String code, boolean skipExpiredCodeValidation) throws IdentityRecoveryException {
    UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
    // If the code is validated, the load method will return data. Otherwise method will throw exceptions.
    UserRecoveryData recoveryData;
    if (!skipExpiredCodeValidation) {
        recoveryData = userRecoveryDataStore.load(code);
    } else {
        recoveryData = userRecoveryDataStore.load(code, skipExpiredCodeValidation);
    }
    User user = recoveryData.getUser();
    // Validate context tenant domain name with user tenant domain.
    validateContextTenantDomainWithUserTenantDomain(user);
    return recoveryData;
}
Also used : User(org.wso2.carbon.identity.application.common.model.User) UserRecoveryData(org.wso2.carbon.identity.recovery.model.UserRecoveryData) UserRecoveryDataStore(org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore)

Example 98 with Notification

use of org.wso2.carbon.identity.mgt.mail.Notification in project identity-governance by wso2-extensions.

the class UserSelfRegistrationManager method isPreferredChannelVerified.

/**
 * Checks whether the notification channel is already verified for the user.
 *
 * @param username            Username
 * @param notificationChannel Notification channel
 * @param claimsMap           Properties related to the event
 * @return True if the channel is already verified
 * @throws IdentityRecoveryClientException Error while getting the notification channel
 */
private boolean isPreferredChannelVerified(String username, String notificationChannel, Map<String, String> claimsMap) throws IdentityRecoveryClientException {
    boolean isEnableAccountLockForVerifiedPreferredChannelEnabled = Boolean.parseBoolean(IdentityUtil.getProperty(IdentityRecoveryConstants.ConnectorConfig.ENABLE_ACCOUNT_LOCK_FOR_VERIFIED_PREFERRED_CHANNEL));
    if (!isEnableAccountLockForVerifiedPreferredChannelEnabled) {
        NotificationChannels channel = getNotificationChannel(username, notificationChannel);
        // Get the matching claim uri for the channel.
        String verifiedClaimUri = channel.getVerifiedClaimUrl();
        // Get the verified status for given channel.
        String verifiedStatus = claimsMap.get(verifiedClaimUri);
        return StringUtils.isNotEmpty(verifiedStatus) && Boolean.parseBoolean(verifiedStatus);
    }
    return false;
}
Also used : NotificationChannels(org.wso2.carbon.identity.governance.service.notification.NotificationChannels)

Example 99 with Notification

use of org.wso2.carbon.identity.mgt.mail.Notification in project identity-governance by wso2-extensions.

the class UserSelfRegistrationManager method buildLiteNotificationResponseBean.

/**
 * Build the notification response bean.
 *
 * @param user             User
 * @param preferredChannel User preferred channel
 * @param claimsMap        Claim map of the user
 * @return NotificationResponseBean object
 * @throws IdentityRecoveryException Error while building the response.
 */
private NotificationResponseBean buildLiteNotificationResponseBean(User user, String preferredChannel, Map<String, String> claimsMap) throws IdentityRecoveryException {
    boolean isAccountLockOnCreation = Boolean.parseBoolean(Utils.getSignUpConfigs(IdentityRecoveryConstants.ConnectorConfig.LITE_ACCOUNT_LOCK_ON_CREATION, user.getTenantDomain()));
    boolean isNotificationInternallyManage = Boolean.parseBoolean(Utils.getSignUpConfigs(IdentityRecoveryConstants.ConnectorConfig.LITE_SIGN_UP_NOTIFICATION_INTERNALLY_MANAGE, user.getTenantDomain()));
    // Check whether the preferred channel is already verified. In this case no need to send confirmation
    // mails.
    boolean preferredChannelVerified = isPreferredChannelVerified(user.getUserName(), preferredChannel, claimsMap);
    NotificationResponseBean notificationResponseBean = new NotificationResponseBean(user);
    // since, the notification channel is already verified.
    if (preferredChannelVerified) {
        notificationResponseBean.setCode(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_WITH_VERIFIED_CHANNEL.getCode());
        notificationResponseBean.setMessage(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_WITH_VERIFIED_CHANNEL.getMessage());
    } else if (isNotificationInternallyManage && isAccountLockOnCreation) {
        // When the channel is not verified, notifications are internally managed and account is locked
        // on creating, API should ask the user to verify the user account and and notification channel.
        notificationResponseBean.setCode(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_INTERNAL_VERIFICATION.getCode());
        notificationResponseBean.setMessage(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_INTERNAL_VERIFICATION.getMessage());
        notificationResponseBean.setNotificationChannel(preferredChannel);
    } else if (!isAccountLockOnCreation) {
        // When the preferred channel is not verified and account is not locked on user creation, response needs to
        // convey that no verification is needed.
        // In this scenario notification managed mechanism will not effect.
        notificationResponseBean.setCode(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_UNLOCKED_WITH_NO_VERIFICATION.getCode());
        notificationResponseBean.setMessage(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_UNLOCKED_WITH_NO_VERIFICATION.getMessage());
    } else {
        // When the notification is externally managed and the account is locked on user creation.
        UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
        userRecoveryDataStore.invalidate(user);
        String secretKey = UUIDGenerator.generateUUID();
        UserRecoveryData recoveryDataDO = new UserRecoveryData(user, secretKey, RecoveryScenarios.LITE_SIGN_UP, RecoverySteps.CONFIRM_LITE_SIGN_UP);
        recoveryDataDO.setRemainingSetIds(NotificationChannels.EXTERNAL_CHANNEL.getChannelType());
        userRecoveryDataStore.store(recoveryDataDO);
        notificationResponseBean.setCode(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_EXTERNAL_VERIFICATION.getCode());
        notificationResponseBean.setMessage(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_EXTERNAL_VERIFICATION.getMessage());
        notificationResponseBean.setRecoveryId(secretKey);
        notificationResponseBean.setNotificationChannel(NotificationChannels.EXTERNAL_CHANNEL.getChannelType());
        // Populate the key variable in response bean to maintain backward compatibility.
        notificationResponseBean.setKey(secretKey);
    }
    return notificationResponseBean;
}
Also used : NotificationResponseBean(org.wso2.carbon.identity.recovery.bean.NotificationResponseBean) UserRecoveryData(org.wso2.carbon.identity.recovery.model.UserRecoveryData) UserRecoveryDataStore(org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore)

Example 100 with Notification

use of org.wso2.carbon.identity.mgt.mail.Notification in project identity-governance by wso2-extensions.

the class UserSelfRegistrationManager method registerLiteUser.

public NotificationResponseBean registerLiteUser(User user, Claim[] claims, Property[] properties) throws IdentityRecoveryException {
    String consent = getPropertyValue(properties, IdentityRecoveryConstants.Consent.CONSENT);
    String tenantDomain = user.getTenantDomain();
    if (StringUtils.isEmpty(tenantDomain)) {
        tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
    }
    // Callback URL validation
    String callbackURL = null;
    try {
        callbackURL = Utils.getCallbackURLFromRegistration(properties);
        if (StringUtils.isNotBlank(callbackURL) && !Utils.validateCallbackURL(callbackURL, tenantDomain, IdentityRecoveryConstants.ConnectorConfig.SELF_REGISTRATION_CALLBACK_REGEX)) {
            throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CALLBACK_URL_NOT_VALID, callbackURL);
        }
    } catch (MalformedURLException | UnsupportedEncodingException | IdentityEventException e) {
        throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CALLBACK_URL_NOT_VALID, callbackURL);
    }
    if (StringUtils.isBlank(user.getTenantDomain())) {
        user.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
        log.info("registerUser :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("registerUser :User store domain is not in the request. set to default for user : " + user.getUserName());
    }
    boolean enable = Boolean.parseBoolean(Utils.getSignUpConfigs(IdentityRecoveryConstants.ConnectorConfig.ENABLE_LITE_SIGN_UP, user.getTenantDomain()));
    if (!enable) {
        throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_DISABLE_LITE_SIGN_UP, user.getUserName());
    }
    NotificationResponseBean notificationResponseBean;
    try {
        RealmService realmService = IdentityRecoveryServiceDataHolder.getInstance().getRealmService();
        UserStoreManager userStoreManager;
        try {
            userStoreManager = realmService.getTenantUserRealm(IdentityTenantUtil.getTenantId(user.getTenantDomain())).getUserStoreManager();
        } catch (UserStoreException e) {
            throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_UNEXPECTED, user.getUserName(), e);
        }
        PrivilegedCarbonContext.startTenantFlow();
        PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
        carbonContext.setTenantId(IdentityTenantUtil.getTenantId(user.getTenantDomain()));
        carbonContext.setTenantDomain(user.getTenantDomain());
        Map<String, String> claimsMap = new HashMap<>();
        for (Claim claim : claims) {
            claimsMap.put(claim.getClaimUri(), claim.getValue());
        }
        // Set lite user sign up claim to indicate the profile
        claimsMap.put(IdentityRecoveryConstants.LITE_USER_CLAIM, Boolean.TRUE.toString());
        // Set arbitrary properties to use in UserSelfRegistrationHandler
        Utils.setArbitraryProperties(properties);
        validateAndFilterFromReceipt(consent, claimsMap);
        // User preferred notification channel.
        String preferredChannel;
        try {
            String[] userRoles = new String[] {};
            try {
                NotificationChannelManager notificationChannelManager = Utils.getNotificationChannelManager();
                preferredChannel = notificationChannelManager.resolveCommunicationChannel(user.getUserName(), user.getTenantDomain(), user.getUserStoreDomain(), claimsMap);
            } catch (NotificationChannelManagerException e) {
                throw mapNotificationChannelManagerException(e, user);
            }
            // resolved channel is not empty.
            if (StringUtils.isEmpty(claimsMap.get(IdentityRecoveryConstants.PREFERRED_CHANNEL_CLAIM)) && StringUtils.isNotEmpty(preferredChannel)) {
                claimsMap.put(IdentityRecoveryConstants.PREFERRED_CHANNEL_CLAIM, preferredChannel);
            }
            userStoreManager.addUser(IdentityUtil.addDomainToName(user.getUserName(), user.getUserStoreDomain()), Utils.generateRandomPassword(12), userRoles, claimsMap, null);
        } catch (UserStoreException e) {
            Throwable cause = e;
            while (cause != null) {
                if (cause instanceof PolicyViolationException) {
                    throw IdentityException.error(IdentityRecoveryClientException.class, IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_POLICY_VIOLATION.getCode(), cause.getMessage(), e);
                }
                cause = cause.getCause();
            }
            return handleClientException(user, e);
        }
        addUserConsent(consent, tenantDomain);
        // Build the notification response for lite user.
        notificationResponseBean = buildLiteNotificationResponseBean(user, preferredChannel, claimsMap);
    } finally {
        Utils.clearArbitraryProperties();
        PrivilegedCarbonContext.endTenantFlow();
    }
    return notificationResponseBean;
}
Also used : MalformedURLException(java.net.MalformedURLException) NotificationChannelManager(org.wso2.carbon.identity.governance.service.notification.NotificationChannelManager) NotificationChannelManagerException(org.wso2.carbon.identity.governance.exceptions.notiification.NotificationChannelManagerException) IdentityEventException(org.wso2.carbon.identity.event.IdentityEventException) HashMap(java.util.HashMap) UnsupportedEncodingException(java.io.UnsupportedEncodingException) PrivilegedCarbonContext(org.wso2.carbon.context.PrivilegedCarbonContext) AbstractUserStoreManager(org.wso2.carbon.user.core.common.AbstractUserStoreManager) UserStoreManager(org.wso2.carbon.user.api.UserStoreManager) NotificationResponseBean(org.wso2.carbon.identity.recovery.bean.NotificationResponseBean) RealmService(org.wso2.carbon.user.core.service.RealmService) UserStoreException(org.wso2.carbon.user.api.UserStoreException) PolicyViolationException(org.wso2.carbon.identity.mgt.policy.PolicyViolationException) Claim(org.wso2.carbon.user.api.Claim) IdentityRecoveryClientException(org.wso2.carbon.identity.recovery.IdentityRecoveryClientException)

Aggregations

HashMap (java.util.HashMap)31 IdentityEventException (org.wso2.carbon.identity.event.IdentityEventException)25 UserRecoveryData (org.wso2.carbon.identity.recovery.model.UserRecoveryData)21 UserRecoveryDataStore (org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore)18 IdentityRecoveryException (org.wso2.carbon.identity.recovery.IdentityRecoveryException)17 UserStoreException (org.wso2.carbon.user.api.UserStoreException)17 Event (org.wso2.carbon.identity.event.event.Event)14 IdentityException (org.wso2.carbon.identity.base.IdentityException)13 User (org.wso2.carbon.identity.application.common.model.User)10 NotificationResponseBean (org.wso2.carbon.identity.recovery.bean.NotificationResponseBean)10 ArrayList (java.util.ArrayList)8 QName (javax.xml.namespace.QName)8 PrivilegedCarbonContext (org.wso2.carbon.context.PrivilegedCarbonContext)8 Map (java.util.Map)7 Test (org.testng.annotations.Test)7 Property (org.wso2.carbon.identity.recovery.model.Property)7 NotificationChannels (org.wso2.carbon.identity.governance.service.notification.NotificationChannels)6 UserStoreException (org.wso2.carbon.user.core.UserStoreException)6 NotificationException (org.wso2.carbon.apimgt.impl.notification.exception.NotificationException)5 NotificationDataDTO (org.wso2.carbon.identity.mgt.dto.NotificationDataDTO)5