public CaptchaInfoBean getCaptcha() throws IdentityMgtServiceException {

    if (log.isDebugEnabled()) {
      log.debug("User get captcha image request received");
    }

    try {
      CaptchaUtil.cleanOldCaptchas();
      CaptchaInfoBean bean = CaptchaUtil.generateCaptchaImage();

      if (log.isDebugEnabled()) {
        log.debug("Captcha stored: " + bean.getImagePath());
        log.debug("Captcha generated successfully");
      }

      return bean;

    } catch (Exception e) {
      String errorMessage = "Error while generating captcha";
      log.error(errorMessage, e);
      throw new IdentityMgtServiceException(errorMessage);
    }
  }
  public VerificationBean verifyUser(String username, CaptchaInfoBean captcha)
      throws IdentityMgtServiceException {

    UserDTO userDTO;
    VerificationBean bean;
    if (log.isDebugEnabled()) {
      log.debug("User verification request received with username : "******" Error while validating captcha", e);
        return bean;
      }
    }

    try {
      userDTO = Utils.processUserId(username);
    } catch (IdentityException e) {
      bean =
          handleError(VerificationBean.ERROR_CODE_INVALID_USER + " invalid user : " + username, e);
      return bean;
    }

    try {
      if (IdentityMgtConfig.getInstance().isSaasEnabled()) {
        PrivilegedCarbonContext.startTenantFlow();
        PrivilegedCarbonContext carbonContext =
            PrivilegedCarbonContext.getThreadLocalCarbonContext();
        carbonContext.setTenantId(userDTO.getTenantId());
        carbonContext.setTenantDomain(userDTO.getTenantDomain());
      }
      RecoveryProcessor processor = IdentityMgtServiceComponent.getRecoveryProcessor();
      return processor.verifyUserForRecovery(1, userDTO);
    } finally {
      if (IdentityMgtConfig.getInstance().isSaasEnabled()) {
        PrivilegedCarbonContext.endTenantFlow();
      }
    }
  }
  /**
   * 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;
  }
  /**
   * 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 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;
  }