private VerificationBean handleError(String error, Exception e) { VerificationBean bean = new VerificationBean(); bean.setVerified(false); if (error != null) { bean.setError(error); log.error(error, e); } else { bean.setError(e.getMessage()); log.error(e.getMessage(), e); } return bean; }
/** * 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 used to confirm the self registered user account and unlock it. * * @param username * @param code * @param captcha * @param tenantDomain * @return * @throws IdentityMgtServiceException */ public VerificationBean confirmUserSelfRegistration( String username, String code, CaptchaInfoBean captcha, String tenantDomain) throws IdentityMgtServiceException { VerificationBean bean = new VerificationBean(); if (log.isDebugEnabled()) { log.debug("User registration verification request received with username :"******" Error while validating captcha for user : "******"Trying to confirm users in unauthorized tenant space"; log.error(msg); } if (tenantDomain == null || tenantDomain.isEmpty()) { tenantDomain = loggedInTenant; } } UserDTO userDTO = null; try { userDTO = Utils.processUserId(username + "@" + tenantDomain); } catch (IdentityException e) { bean = handleError( VerificationBean.ERROR_CODE_INVALID_USER + " Error verifying user account for user : "******"Error retrieving the user store manager for the tenant : " + tenantDomain, e); return bean; } try { bean = processor.verifyConfirmationCode(1, username, code); if (bean.isVerified()) { UserIdentityManagementUtil.unlockUserAccount(username, userStoreManager); bean.setVerified(true); } else { bean.setVerified(false); bean.setKey(""); log.error("User verification failed against the given confirmation code"); } } catch (IdentityException e) { bean = handleError("Error while validating confirmation code for user : " + username, e); return bean; } } finally { if (IdentityMgtConfig.getInstance().isSaasEnabled()) { PrivilegedCarbonContext.endTenantFlow(); } } return bean; }
/** * 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; }
/** * This method is to verify the user supplied answer for the challenge question. * * @param userName * @param confirmation * @param questionId * @param answer * @return status and key details about the operation status. * @throws IdentityMgtServiceException */ public VerificationBean verifyUserChallengeAnswer( String userName, String confirmation, String questionId, String answer) throws IdentityMgtServiceException { VerificationBean bean = new VerificationBean(); bean.setVerified(false); if (log.isDebugEnabled()) { log.debug("User challenge answer request received with username :"******"No challenge question id provided for verification"; bean.setError(error); if (log.isDebugEnabled()) { log.debug(error); } return bean; } UserDTO userDTO = null; try { userDTO = Utils.processUserId(userName); } catch (IdentityException e) { bean = handleError( VerificationBean.ERROR_CODE_INVALID_USER + " Error verifying user: "******" Error verifying confirmation code for user : "******""); bean.setUserId(userName); if (log.isDebugEnabled()) { log.debug("User answer verification successful for user: "******"Challenge answer verification failed for user : "******""); // clear the key to avoid returning to caller. log.error(bean.getError()); } } finally { if (IdentityMgtConfig.getInstance().isSaasEnabled()) { PrivilegedCarbonContext.endTenantFlow(); } } return bean; }
/** * To get the challenge question for the user. * * @param userName * @param confirmation * @param questionId - Question id returned from the getUserChanllegneQuestionIds method. * @return Populated question bean with the question details and the key. * @throws IdentityMgtServiceException */ public UserChallengesDTO getUserChallengeQuestion( String userName, String confirmation, String questionId) throws IdentityMgtServiceException { UserDTO userDTO = null; UserChallengesDTO userChallengesDTO = new UserChallengesDTO(); if (log.isDebugEnabled()) { log.debug("User challenge question request received with username :"******"Error validating user : "******"Invalid confirmation code for user : "******"User challenge question retrieved successfully"); } } else { if (log.isDebugEnabled()) { log.debug("Verification failed for user. Error : " + bean.getError()); } userChallengesDTO.setError( VerificationBean.ERROR_CODE_INVALID_USER + " " + bean.getError()); } } finally { if (IdentityMgtConfig.getInstance().isSaasEnabled()) { PrivilegedCarbonContext.endTenantFlow(); } } return userChallengesDTO; }
public ChallengeQuestionIdsDTO getUserChallengeQuestionIds(String username, String confirmation) throws IdentityMgtServiceException { UserDTO userDTO = null; ChallengeQuestionIdsDTO idsDTO = new ChallengeQuestionIdsDTO(); if (log.isDebugEnabled()) { log.debug("User challenge questions id request received with username: "******"Error while getting challenge question ids for user : "******"Error when validating code", e1); return idsDTO; } if (bean.isVerified()) { try { idsDTO = processor .getQuestionProcessor() .getUserChallengeQuestionIds(userDTO.getUserId(), userDTO.getTenantId()); idsDTO.setKey(bean.getKey()); if (log.isDebugEnabled()) { log.debug("User challenge question response successful for user: "******"Error when getting user challenge questions for user : "******"Verification failed for user. Error : " + bean.getError(); log.error(msg); idsDTO.setError(VerificationBean.ERROR_CODE_UNEXPECTED + " " + msg); idsDTO.setKey(""); } } finally { if (IdentityMgtConfig.getInstance().isSaasEnabled()) { PrivilegedCarbonContext.endTenantFlow(); } } return idsDTO; }
/** * This method is used to update the password in the system for password recovery process. Before * calling this method caller needs to call verifyConfirmationCode and get the newly generated * confirmation code. * * @param username - username * @param confirmationCode - newly generated confirmation code * @param newPassword - new password * @return - VerificationBean with operation status true or false. * @throws IdentityMgtServiceException */ public VerificationBean updatePassword( String username, String confirmationCode, String newPassword) throws IdentityMgtServiceException { RecoveryProcessor recoveryProcessor = IdentityMgtServiceComponent.getRecoveryProcessor(); VerificationBean bean = null; if (log.isDebugEnabled()) { log.debug("User update password request received with username: "******"No Tenant id for tenant domain " + userDTO.getTenantDomain(), e); } if (recoveryProcessor .verifyConfirmationCode(3, userDTO.getUserId(), confirmationCode) .isVerified()) { Utils.updatePassword(userDTO.getUserId(), tenantId, newPassword); log.info( "Credential is updated for user : "******" and tenant domain : " + userDTO.getTenantDomain()); IdentityMgtConfig.getInstance() .getRecoveryDataStore() .invalidate(userDTO.getUserId(), tenantId); bean = new VerificationBean(true); } else { String msg = "Invalid user tried to update credential with user Id : " + userDTO.getUserId() + " and tenant domain : " + userDTO.getTenantDomain(); bean = new VerificationBean(VerificationBean.ERROR_CODE_INVALID_USER + " " + msg); bean.setVerified(false); log.error(msg); } } catch (Exception e) { bean = handleError( VerificationBean.ERROR_CODE_UNEXPECTED + " Error while updating credential for user: " + username, e); return bean; } finally { if (IdentityMgtConfig.getInstance().isSaasEnabled()) { PrivilegedCarbonContext.endTenantFlow(); } } return bean; }
/** * This method is used to verify the confirmation code sent to user is correct and validates. * Before calling this method it needs to supply a Captcha and should call getCaptcha(). * * @param username - username of whom the password needs to be recovered. * @param code - confirmation code sent to user by notification. * @param captcha - generated captcha with answer for this communication. * @return - VerificationBean with new code to be used in updatePassword(). * @throws IdentityMgtServiceException */ public VerificationBean verifyConfirmationCode( String username, String code, CaptchaInfoBean captcha) throws IdentityMgtServiceException { UserDTO userDTO; VerificationBean bean = new VerificationBean(); if (log.isDebugEnabled()) { log.debug("User confirmation code verification request received with username :"******" Error while validating captcha for user : "******" invalid user : "******"User confirmation code verification successful for user: "******""); log.error(bean.getError()); } } catch (IdentityException e) { bean = handleError( VerificationBean.ERROR_CODE_INVALID_CODE + " Error verifying confirmation code for user : " + username, e); return bean; } finally { if (IdentityMgtConfig.getInstance().isSaasEnabled()) { PrivilegedCarbonContext.endTenantFlow(); } } return bean; }
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; }