/* * TODO - Important. Refactor this method and use recoveryWithNotification instead. */ public NotificationDataDTO notifyWithEmail(UserRecoveryDTO notificationBean) throws IdentityException { String notificationAddress; String confirmationKey = null; NotificationSendingModule module = null; String userId = notificationBean.getUserId(); String domainName = notificationBean.getTenantDomain(); int tenantId = notificationBean.getTenantId(); confirmationKey = notificationBean.getConfirmationCode(); String userStore = IdentityUtil.extractDomainFromName(userId); String userName = UserCoreUtil.removeDomainFromName(userId); NotificationDataDTO notificationData = new NotificationDataDTO(); String type = notificationBean.getNotificationType(); if (type != null) { module = modules.get(type); } if (module == null) { module = defaultModule; } NotificationData emailNotificationData = new NotificationData(); String emailTemplate = null; notificationAddress = module.getNotificationAddress(userId, tenantId); if ((notificationAddress == null) || (notificationAddress.trim().length() < 0)) { log.warn("Notification address is not defined for user " + userId); } String firstName = Utils.getClaimFromUserStoreManager(userId, tenantId, "http://wso2.org/claims/givenname"); emailNotificationData.setTagData(FIRST_NAME, firstName); emailNotificationData.setTagData(USER_STORE_DOMAIN, userStore); emailNotificationData.setTagData(USER_NAME, userName); emailNotificationData.setTagData(TENANT_DOMAIN, domainName); emailNotificationData.setSendTo(notificationAddress); Config config = null; ConfigBuilder configBuilder = ConfigBuilder.getInstance(); try { config = configBuilder.loadConfiguration(ConfigType.EMAIL, StorageType.REGISTRY, tenantId); } catch (Exception e1) { throw new IdentityException( "Error occurred while loading email templates for user : "******"EMAIL", emailTemplate, emailNotificationData); } catch (Exception e) { throw new IdentityException( "Error occurred while creating notification from email template : " + emailTemplate, e); } notificationData.setNotificationAddress(notificationAddress); notificationData.setUserId(userId); notificationData.setDomainName(domainName); notificationData.setNotificationType(notificationBean.getNotificationType()); if (IdentityMgtConfig.getInstance().isNotificationInternallyManaged()) { module.setNotificationData(notificationData); module.setNotification(emailNotification); notificationSender.sendNotification(module); notificationData.setNotificationSent(true); } else { notificationData.setNotificationSent(false); notificationData.setNotificationCode(confirmationKey); } return notificationData; }
/** * Processing recovery * * @param recoveryDTO class that contains user and tenant Information * @return true if the reset request is processed successfully. * @throws IdentityException if fails */ public NotificationDataDTO recoverWithNotification(UserRecoveryDTO recoveryDTO) throws IdentityException { String notificationAddress; String secretKey = null; String confirmationKey = null; NotificationSendingModule module = null; boolean persistData = true; String userId = recoveryDTO.getUserId(); String domainName = recoveryDTO.getTenantDomain(); int tenantId = recoveryDTO.getTenantId(); String userStore = IdentityUtil.extractDomainFromName(userId); String userName = UserCoreUtil.removeDomainFromName(userId); TenantManager tenantManager = IdentityMgtServiceComponent.getRealmService().getTenantManager(); try { Tenant tenant = tenantManager.getTenant(tenantId); if (tenant != null) { domainName = tenant.getDomain(); } } catch (UserStoreException e) { if (log.isDebugEnabled()) { log.debug("No Tenant domain for tenant id " + tenantId, e); } } NotificationDataDTO notificationData = new NotificationDataDTO(); String internalCode = null; String type = recoveryDTO.getNotificationType(); if (type != null) { module = modules.get(type); } if (module == null) { module = defaultModule; } NotificationData emailNotificationData = new NotificationData(); String emailTemplate = null; notificationAddress = Utils.getEmailAddressForUser(userId, tenantId); String firstName = Utils.getClaimFromUserStoreManager(userId, tenantId, "http://wso2.org/claims/givenname"); emailNotificationData.setTagData(FIRST_NAME, firstName); emailNotificationData.setTagData(USER_STORE_DOMAIN, userStore); emailNotificationData.setTagData(USER_NAME, userName); emailNotificationData.setTagData(TENANT_DOMAIN, domainName); if ((notificationAddress == null) || (notificationAddress.trim().length() < 0)) { throw new IdentityException( "Notification sending failure. Notification address is not defined for user : "******"Building notification with data - First name: " + firstName + " User name: " + userId + " Send To: " + notificationAddress); } Config config = null; ConfigBuilder configBuilder = ConfigBuilder.getInstance(); try { config = configBuilder.loadConfiguration(ConfigType.EMAIL, StorageType.REGISTRY, tenantId); } catch (Exception e1) { throw new IdentityException("Error while loading email templates for user : "******"Error while getting user's external code string.", e); } secretKey = UUIDGenerator.generateUUID(); emailNotificationData.setTagData(CONFIRMATION_CODE, confirmationKey); emailTemplate = config.getProperty(IdentityMgtConstants.Notification.PASSWORD_RESET_RECOVERY); } else if (IdentityMgtConstants.Notification.ACCOUNT_CONFORM.equals(notification)) { confirmationKey = UUIDGenerator.generateUUID(); secretKey = UUIDGenerator.generateUUID(); emailNotificationData.setTagData(CONFIRMATION_CODE, confirmationKey); emailTemplate = config.getProperty(IdentityMgtConstants.Notification.ACCOUNT_CONFORM); } else if (IdentityMgtConstants.Notification.TEMPORARY_PASSWORD.equals(notification)) { String temporaryPassword = recoveryDTO.getTemporaryPassword(); // TODO if (temporaryPassword == null || temporaryPassword.trim().length() < 1) { char[] chars = IdentityMgtConfig.getInstance().getPasswordGenerator().generatePassword(); temporaryPassword = new String(chars); } Utils.updatePassword(userId, tenantId, temporaryPassword); emailNotificationData.setTagData(TEMPORARY_PASSWORD, temporaryPassword); emailTemplate = config.getProperty(IdentityMgtConstants.Notification.TEMPORARY_PASSWORD); persistData = false; } else if (IdentityMgtConstants.Notification.ACCOUNT_UNLOCK.equals(notification)) { emailTemplate = config.getProperty(IdentityMgtConstants.Notification.ACCOUNT_UNLOCK); persistData = false; } else if (IdentityMgtConstants.Notification.ACCOUNT_ID_RECOVERY.equals(notification)) { emailTemplate = config.getProperty(IdentityMgtConstants.Notification.ACCOUNT_ID_RECOVERY); persistData = false; } else if (IdentityMgtConstants.Notification.ASK_PASSWORD.equals(notification)) { if (firstName == null || firstName.isEmpty()) { emailNotificationData.setTagData(FIRST_NAME, userId); } internalCode = generateUserCode(2, userId); try { confirmationKey = getUserExternalCodeStr(internalCode); } catch (Exception e) { throw new IdentityException("Error while with recovering with password.", e); } secretKey = UUIDGenerator.generateUUID(); emailNotificationData.setTagData(CONFIRMATION_CODE, confirmationKey); emailTemplate = config.getProperty(IdentityMgtConstants.Notification.ASK_PASSWORD); } if (log.isDebugEnabled()) { log.debug("Notification type: " + notification); } } Notification emailNotification = null; try { emailNotification = NotificationBuilder.createNotification("EMAIL", emailTemplate, emailNotificationData); } catch (Exception e) { throw new IdentityException("Error when creating notification for user : " + userId, e); } notificationData.setNotificationAddress(notificationAddress); notificationData.setUserId(userId); notificationData.setDomainName(domainName); notificationData.setNotificationType(recoveryDTO.getNotificationType()); if (persistData) { UserRecoveryDataDO recoveryDataDO = new UserRecoveryDataDO(userId, tenantId, internalCode, secretKey); dataStore.invalidate(userId, tenantId); dataStore.store(recoveryDataDO); } if (IdentityMgtConfig.getInstance().isNotificationInternallyManaged()) { module.setNotificationData(notificationData); module.setNotification(emailNotification); notificationSender.sendNotification(module); notificationData.setNotificationSent(true); } else { notificationData.setNotificationSent(false); notificationData.setNotificationCode(confirmationKey); } return notificationData; }
/** * This method locks the created accounts based on the account policies or based on the account * confirmation method being used. Two account confirmation methods are used : Temporary Password * and Verification Code. In the case of temporary password is used the temporary password will be * emailed to the user. In the case of verification code, the code will be emailed to the user. * The security questions filter ad doPreAddUser will be persisted in this method. */ @Override public boolean doPostAddUser( String userName, Object credential, String[] roleList, Map<String, String> claims, String profile, UserStoreManager userStoreManager) throws UserStoreException { if (log.isDebugEnabled()) { log.debug("Post add user is called in IdentityMgtEventListener"); } IdentityMgtConfig config = IdentityMgtConfig.getInstance(); if (!config.isListenerEnable()) { return true; } // reading the value from the thread local UserIdentityClaimsDO userIdentityClaimsDO = (UserIdentityClaimsDO) threadLocalProperties.get().get(USER_IDENTITY_DO); if (config.isEnableUserAccountVerification()) { // empty password account creation if (threadLocalProperties.get().containsKey(EMPTY_PASSWORD_USED)) { // store identity data userIdentityClaimsDO.setAccountLock(false).setPasswordTimeStamp(System.currentTimeMillis()); try { module.store(userIdentityClaimsDO, userStoreManager); } catch (IdentityException e) { throw new UserStoreException("Error while doPostAddUser", e); } // store identity metadata UserRecoveryDataDO metadataDO = new UserRecoveryDataDO(); metadataDO .setUserName(userName) .setTenantId(userStoreManager.getTenantId()) .setCode((String) credential); // try { // UserIdentityManagementUtil.storeUserIdentityMetadata(metadataDO); // } catch (IdentityException e) { // throw new UserStoreException("Error while doPreAddUser", e); // } // set recovery data RecoveryProcessor processor = new RecoveryProcessor(); VerificationBean verificationBean = new VerificationBean(); try { verificationBean = processor.updateConfirmationCode(1, userName, userStoreManager.getTenantId()); } catch (IdentityException e) { // TODO Auto-generated catch block e.printStackTrace(); } // preparing a bean to send the email UserIdentityMgtBean bean = new UserIdentityMgtBean(); bean.setUserId(userName) .setConfirmationCode(verificationBean.getKey()) .setRecoveryType(IdentityMgtConstants.Notification.TEMPORARY_PASSWORD) .setEmail(claims.get(config.getAccountRecoveryClaim())); UserRecoveryDTO recoveryDto = new UserRecoveryDTO(userName); recoveryDto.setNotification(IdentityMgtConstants.Notification.ASK_PASSWORD); recoveryDto.setNotificationType("EMAIL"); recoveryDto.setTenantId(userStoreManager.getTenantId()); recoveryDto.setConfirmationCode(verificationBean.getKey()); NotificationDataDTO notificationDto = null; try { notificationDto = processor.recoverWithNotification(recoveryDto); } catch (IdentityException e) { if (log.isDebugEnabled()) { log.debug(e.getMessage()); } throw new UserStoreException("Error while sending notification. " + e.getMessage()); } if (notificationDto != null && notificationDto.isNotificationSent()) { return true; } else { return false; } // sending email // UserIdentityManagementUtil.notifyViaEmail(bean); } else { // none-empty passwords. lock account and persist /* This scenario needs to be validated. * userIdentityClaimsDO.setAccountLock(true) .setPasswordTimeStamp(System.currentTimeMillis()); try { UserIdentityManagementUtil.storeUserIdentityClaims(userIdentityClaimsDO, userStoreManager); } catch (IdentityException e) { throw new UserStoreException("Error while doPostAddUser", e); } String confirmationCode = UserIdentityManagementUtil.generateRandomConfirmationCode(); // store identity metadata UserRecoveryDataDO metadataDO = new UserRecoveryDataDO(); metadataDO.setUserName(userName).setTenantId(userStoreManager.getTenantId()) .setCode(confirmationCode); try { UserIdentityManagementUtil.storeUserIdentityMetadata(metadataDO); } catch (IdentityException e) { throw new UserStoreException("Error while doPostAddUser", e); } // sending a mail with the confirmation code UserIdentityMgtBean bean = new UserIdentityMgtBean(); bean.setUserId(userName) .setRecoveryType(IdentityMgtConstants.Notification.ACCOUNT_CONFORM) .setConfirmationCode(confirmationCode); UserIdentityManagementUtil.notifyViaEmail(bean); return true; */ } } // No account recoveries are defined, no email will be sent. if (config.isAuthPolicyAccountLockOnCreation()) { // accounts are locked. Admin should unlock userIdentityClaimsDO.setAccountLock(true); userIdentityClaimsDO.setPasswordTimeStamp(System.currentTimeMillis()); try { config.getIdentityDataStore().store(userIdentityClaimsDO, userStoreManager); } catch (IdentityException e) { throw new UserStoreException("Error while doPostAddUser", e); } } return true; }
/** * This method is used to register an user in the system. The account will be locked if the * Authentication.Policy.Account.Lock.On.Creation is set to true. Else user will be able to login * after registration. * * @param userName * @param password * @param claims * @param profileName * @param tenantDomain * @return * @throws IdentityMgtServiceException */ public VerificationBean registerUser( String userName, String password, UserIdentityClaimDTO[] claims, String profileName, String tenantDomain) throws IdentityMgtServiceException { VerificationBean vBean = new VerificationBean(); org.wso2.carbon.user.core.UserStoreManager userStoreManager = null; Permission permission = null; if (!IdentityMgtConfig.getInstance().isSaasEnabled()) { String loggedInTenant = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); if (tenantDomain != null && !tenantDomain.isEmpty() && !loggedInTenant.equals(tenantDomain)) { String msg = "Trying to create users in unauthorized tenant space"; log.error(msg); throw new IdentityMgtServiceException(msg); } if (tenantDomain == null || tenantDomain.isEmpty()) { tenantDomain = loggedInTenant; } } RealmService realmService = IdentityMgtServiceComponent.getRealmService(); int tenantId; try { tenantId = Utils.getTenantId(tenantDomain); if (realmService.getTenantUserRealm(tenantId) != null) { userStoreManager = (org.wso2.carbon.user.core.UserStoreManager) realmService.getTenantUserRealm(tenantId).getUserStoreManager(); } } catch (Exception e) { vBean = handleError( VerificationBean.ERROR_CODE_UNEXPECTED + " Error retrieving the user store manager for the tenant", e); return vBean; } try { if (userStoreManager == null) { vBean = new VerificationBean(); vBean.setVerified(false); vBean.setError( VerificationBean.ERROR_CODE_UNEXPECTED + " Error retrieving the user store manager for the tenant"); return vBean; } Map<String, String> claimsMap = new HashMap<String, String>(); for (UserIdentityClaimDTO userIdentityClaimDTO : claims) { claimsMap.put(userIdentityClaimDTO.getClaimUri(), userIdentityClaimDTO.getClaimValue()); } userStoreManager.addUser(userName, password, null, claimsMap, profileName); String identityRoleName = UserCoreConstants.INTERNAL_DOMAIN + CarbonConstants.DOMAIN_SEPARATOR + IdentityConstants.IDENTITY_DEFAULT_ROLE; if (!userStoreManager.isExistingRole(identityRoleName, false)) { permission = new Permission("/permission/admin/login", UserMgtConstants.EXECUTE_ACTION); userStoreManager.addRole( identityRoleName, new String[] {userName}, new Permission[] {permission}, false); } else { userStoreManager.updateUserListOfRole( identityRoleName, new String[] {}, new String[] {userName}); } IdentityEventListener identityEventListener = IdentityUtil.readEventListenerProperty( UserOperationEventListener.class.getName(), IdentityMgtEventListener.class.getName()); boolean isListenerEnable = true; if (identityEventListener != null) { if (StringUtils.isNotBlank(identityEventListener.getEnable())) { isListenerEnable = Boolean.parseBoolean(identityEventListener.getEnable()); } } IdentityMgtConfig config = IdentityMgtConfig.getInstance(); if (isListenerEnable && config.isAuthPolicyAccountLockOnCreation()) { UserDTO userDTO = new UserDTO(userName); userDTO.setTenantId(tenantId); UserRecoveryDTO dto = new UserRecoveryDTO(userDTO); dto.setNotification(IdentityMgtConstants.Notification.ACCOUNT_CONFORM); dto.setNotificationType("EMAIL"); RecoveryProcessor processor = IdentityMgtServiceComponent.getRecoveryProcessor(); vBean = processor.updateConfirmationCode(1, userName, tenantId); dto.setConfirmationCode(vBean.getKey()); NotificationDataDTO notificationDto = processor.notifyWithEmail(dto); vBean.setVerified(notificationDto.isNotificationSent()); // Send email data only if not internally managed. if (!(IdentityMgtConfig.getInstance().isNotificationInternallyManaged())) { vBean.setNotificationData(notificationDto); } } else { vBean.setVerified(true); } } catch (UserStoreException | IdentityException e) { UserIdentityManagementUtil.getCustomErrorMessages(e, userName); // Rollback if user exists try { if (userStoreManager.isExistingUser(userName)) { userStoreManager.deleteUser(userName); } } catch (org.wso2.carbon.user.core.UserStoreException e1) { UserIdentityManagementUtil.getCustomErrorMessages(e1, userName); } return vBean; } return vBean; }
/** * Verifies the user against the provided claims and captcha information. * * @param claims * @param captcha * @param tenantDomain * @return * @throws IdentityMgtServiceException */ public VerificationBean verifyAccount( UserIdentityClaimDTO[] claims, CaptchaInfoBean captcha, String tenantDomain) throws IdentityMgtServiceException { VerificationBean vBean = new VerificationBean(); if (IdentityMgtConfig.getInstance().isCaptchaVerificationInternallyManaged()) { try { CaptchaUtil.processCaptchaInfoBean(captcha); } catch (Exception e) { vBean = handleError( VerificationBean.ERROR_CODE_INVALID_CAPTCHA + " Error processing captcha", e); return vBean; } } if (!IdentityMgtConfig.getInstance().isSaasEnabled()) { String loggedInTenant = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); if (tenantDomain != null && !tenantDomain.isEmpty() && !loggedInTenant.equals(tenantDomain)) { String msg = "Trying to verify account unauthorized tenant space"; log.error(msg); throw new IdentityMgtServiceException(msg); } if (tenantDomain == null || tenantDomain.isEmpty()) { tenantDomain = loggedInTenant; } } try { int tenantId = Utils.getTenantId(tenantDomain); String userName = UserIdentityManagementUtil.getUsernameByClaims(claims, tenantId); if (userName != null) { UserDTO userDTO = new UserDTO(userName); userDTO.setTenantId(tenantId); UserRecoveryDTO dto = new UserRecoveryDTO(userDTO); dto.setNotification(IdentityMgtConstants.Notification.ACCOUNT_ID_RECOVERY); dto.setNotificationType("EMAIL"); RecoveryProcessor processor = IdentityMgtServiceComponent.getRecoveryProcessor(); NotificationDataDTO notificationDto = processor.notifyWithEmail(dto); vBean.setVerified(notificationDto.isNotificationSent()); // Send email data only if not internally managed. if (!(IdentityMgtConfig.getInstance().isNotificationInternallyManaged())) { vBean.setNotificationData(notificationDto); } } else { vBean.setError("User not found"); vBean.setVerified(false); } } catch (Exception e) { vBean = handleError( VerificationBean.ERROR_CODE_INVALID_USER + " Error verifying user account", e); return vBean; } return vBean; }
public VerificationBean sendRecoveryNotification( String username, String key, String notificationType) throws IdentityMgtServiceException { UserDTO userDTO = null; VerificationBean bean = null; if (log.isDebugEnabled()) { log.debug( "User recovery notification sending request received with username : "******" notification type :" + notificationType); } try { userDTO = Utils.processUserId(username); } catch (IdentityException e) { bean = handleError(VerificationBean.ERROR_CODE_INVALID_USER + " invalid user : "******"Invalid user is trying to recover the password with username : "******" Invalid user is trying to recover the password with username : "******" invalid confirmation code for user : "******"Initiating the notification sending process"); } if (IdentityMgtConfig.getInstance().isSaasEnabled()) { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); carbonContext.setTenantId(userDTO.getTenantId()); carbonContext.setTenantDomain(userDTO.getTenantDomain()); } dataDTO = processor.recoverWithNotification(dto); // Send email data only if not internally managed. if (!(IdentityMgtConfig.getInstance().isNotificationInternallyManaged())) { bean.setNotificationData(dataDTO); } } catch (IdentityException e) { bean = handleError( VerificationBean.ERROR_CODE_UNEXPECTED + " Error when sending recovery message for user: " + username, e); return bean; } finally { if (IdentityMgtConfig.getInstance().isSaasEnabled()) { PrivilegedCarbonContext.endTenantFlow(); } } return bean; }