Esempio n. 1
0
 void initRequestAttributes(final PwmRequest pwmRequest) throws PwmUnrecoverableException {
   final ConfigurationReader configurationReader =
       pwmRequest.getContextManager().getConfigReader();
   pwmRequest.setAttribute(
       PwmRequest.Attribute.PageTitle,
       LocaleHelper.getLocalizedMessage(Config.Title_ConfigManager, pwmRequest));
   pwmRequest.setAttribute(
       PwmRequest.Attribute.ApplicationPath,
       pwmRequest.getPwmApplication().getPwmEnvironment().getApplicationPath().getAbsolutePath());
   pwmRequest.setAttribute(
       PwmRequest.Attribute.ConfigFilename, configurationReader.getConfigFile().getAbsolutePath());
   {
     final Date lastModifyTime = configurationReader.getStoredConfiguration().modifyTime();
     final String output =
         lastModifyTime == null
             ? LocaleHelper.getLocalizedMessage(Display.Value_NotApplicable, pwmRequest)
             : PwmConstants.DEFAULT_DATETIME_FORMAT.format(lastModifyTime);
     pwmRequest.setAttribute(PwmRequest.Attribute.ConfigLastModified, output);
   }
   pwmRequest.setAttribute(
       PwmRequest.Attribute.ConfigHasPassword,
       LocaleHelper.booleanString(
           configurationReader.getStoredConfiguration().hasPassword(),
           pwmRequest.getLocale(),
           pwmRequest.getConfig()));
 }
Esempio n. 2
0
  protected static void restValidateForm(
      final PwmRequest pwmRequest, final UpdateProfileBean updateProfileBean)
      throws IOException, ServletException, PwmUnrecoverableException, ChaiUnavailableException {
    boolean success = true;
    String userMessage =
        Message.getLocalizedMessage(
            pwmRequest.getLocale(), Message.Success_UpdateForm, pwmRequest.getConfig());
    final Map<FormConfiguration, String> formValues = updateProfileBean.getFormData();

    try {
      // read in the responses from the request
      readFromJsonRequest(pwmRequest, updateProfileBean);

      // verify form meets the form requirements
      verifyFormAttributes(pwmRequest, formValues, true);
    } catch (PwmOperationalException e) {
      success = false;
      userMessage =
          e.getErrorInformation()
              .toUserStr(pwmRequest.getPwmSession(), pwmRequest.getPwmApplication());
    }

    final LinkedHashMap<String, String> outputMap = new LinkedHashMap<>();
    outputMap.put("version", "1");
    outputMap.put("message", userMessage);
    outputMap.put("success", String.valueOf(success));

    pwmRequest.outputJsonResult(new RestResultBean(outputMap));
  }
Esempio n. 3
0
 private void showSummary(final PwmRequest pwmRequest)
     throws IOException, ServletException, PwmUnrecoverableException {
   final StoredConfigurationImpl storedConfiguration = readCurrentConfiguration(pwmRequest);
   final LinkedHashMap<String, Object> outputMap =
       new LinkedHashMap<>(storedConfiguration.toOutputMap(pwmRequest.getLocale()));
   pwmRequest.setAttribute(PwmRequest.Attribute.ConfigurationSummaryOutput, outputMap);
   pwmRequest.forwardToJsp(PwmConstants.JSP_URL.CONFIG_MANAGER_EDITOR_SUMMARY);
 }
Esempio n. 4
0
  private void readFormParametersFromRequest(
      final PwmRequest pwmRequest, final UpdateProfileBean updateProfileBean)
      throws PwmUnrecoverableException, PwmDataValidationException, ChaiUnavailableException {
    final List<FormConfiguration> formFields =
        pwmRequest.getConfig().readSettingAsForm(PwmSetting.UPDATE_PROFILE_FORM);

    final Map<FormConfiguration, String> existingForm = updateProfileBean.getFormData();

    // read the values from the request
    existingForm.putAll(
        FormUtility.readFormValuesFromRequest(pwmRequest, formFields, pwmRequest.getLocale()));
  }
  private static void forwardToJsp(final PwmRequest pwmRequest)
      throws ServletException, PwmUnrecoverableException, IOException {
    final int persistentSeconds = figureMaxLoginSeconds(pwmRequest);
    final String time =
        new TimeDuration(persistentSeconds * 1000).asLongString(pwmRequest.getLocale());

    final ConfigLoginHistory configLoginHistory = readConfigLoginHistory(pwmRequest);

    pwmRequest.setAttribute(PwmConstants.REQUEST_ATTR.ConfigLoginHistory, configLoginHistory);
    pwmRequest.setAttribute(PwmConstants.REQUEST_ATTR.ConfigPasswordRememberTime, time);
    pwmRequest.forwardToJsp(PwmConstants.JSP_URL.CONFIG_MANAGER_LOGIN);
  }
Esempio n. 6
0
  private static void readFromJsonRequest(
      final PwmRequest pwmRequest, final UpdateProfileBean updateProfileBean)
      throws PwmDataValidationException, PwmUnrecoverableException, IOException {
    final List<FormConfiguration> formFields =
        pwmRequest.getConfig().readSettingAsForm(PwmSetting.UPDATE_PROFILE_FORM);
    final Map<FormConfiguration, String> existingForm = updateProfileBean.getFormData();

    final Map<String, String> clientValues = pwmRequest.readBodyAsJsonStringMap();

    if (clientValues != null) {
      existingForm.putAll(
          FormUtility.readFormValuesFromMap(clientValues, formFields, pwmRequest.getLocale()));
    }
  }
Esempio n. 7
0
  static Map<FormConfiguration, String> readFromJsonRequest(
      final PwmRequest pwmRequest,
      final UpdateAttributesProfile updateAttributesProfile,
      final UpdateProfileBean updateProfileBean)
      throws PwmDataValidationException, PwmUnrecoverableException, IOException {
    final List<FormConfiguration> formFields =
        updateAttributesProfile.readSettingAsForm(PwmSetting.UPDATE_PROFILE_FORM);

    final Map<FormConfiguration, String> formValueMap =
        FormUtility.readFormValuesFromMap(
            pwmRequest.readBodyAsJsonStringMap(), formFields, pwmRequest.getLocale());

    updateProfileBean.getFormData().clear();
    updateProfileBean.getFormData().putAll(FormUtility.asStringMap(formValueMap));

    return formValueMap;
  }
Esempio n. 8
0
  final Map<FormConfiguration, String> readFormParametersFromRequest(
      final PwmRequest pwmRequest,
      final UpdateAttributesProfile updateAttributesProfile,
      final UpdateProfileBean updateProfileBean)
      throws PwmUnrecoverableException, PwmDataValidationException, ChaiUnavailableException {
    final List<FormConfiguration> formFields =
        updateAttributesProfile.readSettingAsForm(PwmSetting.UPDATE_PROFILE_FORM);

    // read the values from the request
    final Map<FormConfiguration, String> formValueMap =
        FormUtility.readFormValuesFromRequest(pwmRequest, formFields, pwmRequest.getLocale());

    updateProfileBean.getFormData().clear();
    updateProfileBean.getFormData().putAll(FormUtility.asStringMap(formValueMap));

    return formValueMap;
  }
Esempio n. 9
0
  private void sendUpdateGuestEmailConfirmation(
      final PwmRequest pwmRequest, final UserInfoBean guestUserInfoBean)
      throws PwmUnrecoverableException {
    final Configuration config = pwmRequest.getConfig();
    final Locale locale = pwmRequest.getLocale();
    final EmailItemBean configuredEmailSetting =
        config.readSettingAsEmail(PwmSetting.EMAIL_UPDATEGUEST, locale);

    if (configuredEmailSetting == null) {
      LOGGER.debug(pwmRequest, "unable to send updated guest user email: no email configured");
      return;
    }

    pwmRequest
        .getPwmApplication()
        .getEmailQueue()
        .submitEmail(configuredEmailSetting, guestUserInfoBean, null);
  }
Esempio n. 10
0
  private static void verifyFormAttributes(
      final PwmRequest pwmRequest,
      final Map<FormConfiguration, String> formValues,
      final boolean allowResultCaching)
      throws PwmOperationalException, PwmUnrecoverableException {
    final Locale userLocale = pwmRequest.getLocale();

    // see if the values meet form requirements.
    FormUtility.validateFormValues(pwmRequest.getConfig(), formValues, userLocale);

    // check unique fields against ldap
    FormUtility.validateFormValueUniqueness(
        pwmRequest.getPwmApplication(),
        formValues,
        userLocale,
        Collections.singletonList(pwmRequest.getPwmSession().getUserInfoBean().getUserIdentity()),
        allowResultCaching);
  }
Esempio n. 11
0
  protected void handleUpdateRequest(
      final PwmRequest pwmRequest, final GuestRegistrationBean guestRegistrationBean)
      throws ServletException, ChaiUnavailableException, IOException, PwmUnrecoverableException {
    // Fetch the session state bean.
    final PwmSession pwmSession = pwmRequest.getPwmSession();
    final LocalSessionStateBean ssBean = pwmSession.getSessionStateBean();
    final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
    final Configuration config = pwmApplication.getConfig();

    final List<FormConfiguration> formItems =
        pwmApplication.getConfig().readSettingAsForm(PwmSetting.GUEST_UPDATE_FORM);
    final String expirationAttribute =
        config.readSettingAsString(PwmSetting.GUEST_EXPIRATION_ATTRIBUTE);

    try {
      // read the values from the request
      final Map<FormConfiguration, String> formValues =
          FormUtility.readFormValuesFromRequest(pwmRequest, formItems, pwmRequest.getLocale());

      // see if the values meet form requirements.
      FormUtility.validateFormValues(config, formValues, ssBean.getLocale());

      // read current values from user.
      final ChaiUser theGuest =
          pwmSession
              .getSessionManager()
              .getActor(pwmApplication, guestRegistrationBean.getUpdateUserIdentity());

      // check unique fields against ldap
      FormUtility.validateFormValueUniqueness(
          pwmApplication,
          formValues,
          ssBean.getLocale(),
          Collections.singletonList(guestRegistrationBean.getUpdateUserIdentity()),
          false);

      final Date expirationDate = readExpirationFromRequest(pwmRequest);

      // Update user attributes
      Helper.writeFormValuesToLdap(pwmApplication, pwmSession, theGuest, formValues, false);

      // Write expirationDate
      if (expirationDate != null) {
        theGuest.writeDateAttribute(expirationAttribute, expirationDate);
      }

      // send email.
      final UserStatusReader userStatusReader =
          new UserStatusReader(pwmApplication, pwmSession.getLabel());
      final UserInfoBean guestUserInfoBean = new UserInfoBean();
      userStatusReader.populateUserInfoBean(
          guestUserInfoBean,
          pwmSession.getSessionStateBean().getLocale(),
          guestRegistrationBean.getUpdateUserIdentity(),
          theGuest.getChaiProvider());
      this.sendUpdateGuestEmailConfirmation(pwmRequest, guestUserInfoBean);

      pwmApplication.getStatisticsManager().incrementValue(Statistic.UPDATED_GUESTS);

      // everything good so forward to confirmation page.
      pwmRequest.getPwmResponse().forwardToSuccessPage(Message.Success_UpdateGuest);
      return;
    } catch (PwmOperationalException e) {
      LOGGER.error(pwmSession, e.getErrorInformation().toDebugStr());
      pwmRequest.setResponseError(e.getErrorInformation());
    } catch (ChaiOperationException e) {
      final ErrorInformation info =
          new ErrorInformation(
              PwmError.ERROR_UNKNOWN, "unexpected error writing to ldap: " + e.getMessage());
      LOGGER.error(pwmSession, info);
      pwmRequest.setResponseError(info);
    }
    this.forwardToUpdateJSP(pwmRequest, guestRegistrationBean);
  }
Esempio n. 12
0
  private void restLdapHealth(final PwmRequest pwmRequest, final ConfigGuideBean configGuideBean)
      throws IOException, PwmUnrecoverableException {
    final Configuration tempConfiguration =
        new Configuration(configGuideBean.getStoredConfiguration());
    final PwmApplication tempApplication =
        new PwmApplication.PwmEnvironment(
                tempConfiguration, pwmRequest.getPwmApplication().getApplicationPath())
            .setApplicationMode(PwmApplication.MODE.NEW)
            .setInternalRuntimeInstance(true)
            .setWebInfPath(pwmRequest.getPwmApplication().getWebInfPath())
            .createPwmApplication();
    final LDAPStatusChecker ldapStatusChecker = new LDAPStatusChecker();
    final List<HealthRecord> records = new ArrayList<>();
    final LdapProfile ldapProfile = tempConfiguration.getDefaultLdapProfile();
    switch (configGuideBean.getStep()) {
      case LDAP_SERVER:
        {
          try {
            checkLdapServer(configGuideBean);
            records.add(password.pwm.health.HealthRecord.forMessage(HealthMessage.LDAP_OK));
          } catch (Exception e) {
            records.add(
                new HealthRecord(
                    HealthStatus.WARN,
                    HealthTopic.LDAP,
                    "Can not connect to remote server: " + e.getMessage()));
          }
        }
        break;

      case LDAP_ADMIN:
        {
          records.addAll(
              ldapStatusChecker.checkBasicLdapConnectivity(
                  tempApplication, tempConfiguration, ldapProfile, false));
          if (records.isEmpty()) {
            records.add(password.pwm.health.HealthRecord.forMessage(HealthMessage.LDAP_OK));
          }
        }
        break;

      case LDAP_CONTEXT:
        {
          records.addAll(
              ldapStatusChecker.checkBasicLdapConnectivity(
                  tempApplication, tempConfiguration, ldapProfile, true));
          if (records.isEmpty()) {
            records.add(
                new HealthRecord(
                    HealthStatus.GOOD, HealthTopic.LDAP, "LDAP Contextless Login Root validated"));
          }
          try {
            final UserMatchViewerFunction userMatchViewerFunction = new UserMatchViewerFunction();
            final Collection<UserIdentity> results =
                userMatchViewerFunction.discoverMatchingUsers(
                    pwmRequest.getPwmApplication(),
                    2,
                    configGuideBean.getStoredConfiguration(),
                    PwmSetting.QUERY_MATCH_PWM_ADMIN,
                    null);

            if (results.isEmpty()) {
              records.add(
                  new HealthRecord(HealthStatus.WARN, HealthTopic.LDAP, "No matching admin users"));
            } else {
              records.add(
                  new HealthRecord(HealthStatus.GOOD, HealthTopic.LDAP, "Admin group validated"));
            }
          } catch (PwmException e) {
            records.add(
                new HealthRecord(
                    HealthStatus.WARN,
                    HealthTopic.LDAP,
                    "Error during admin group validation: "
                        + e.getErrorInformation().toDebugStr()));
          } catch (Exception e) {
            records.add(
                new HealthRecord(
                    HealthStatus.WARN,
                    HealthTopic.LDAP,
                    "Error during admin group validation: " + e.getMessage()));
          }
        }
        break;

      case LDAP_TESTUSER:
        {
          final String testUserValue = configGuideBean.getFormData().get(PARAM_LDAP_TEST_USER);
          if (testUserValue != null && !testUserValue.isEmpty()) {
            records.addAll(
                ldapStatusChecker.checkBasicLdapConnectivity(
                    tempApplication, tempConfiguration, ldapProfile, false));
            records.addAll(
                ldapStatusChecker.doLdapTestUserCheck(
                    tempConfiguration, ldapProfile, tempApplication));
          } else {
            records.add(
                new HealthRecord(HealthStatus.CAUTION, HealthTopic.LDAP, "No test user specified"));
          }
        }
        break;
    }

    HealthData jsonOutput = new HealthData();
    jsonOutput.records =
        password.pwm.ws.server.rest.bean.HealthRecord.fromHealthRecords(
            records, pwmRequest.getLocale(), tempConfiguration);
    jsonOutput.timestamp = new Date();
    jsonOutput.overall = HealthMonitor.getMostSevereHealthStatus(records).toString();
    final RestResultBean restResultBean = new RestResultBean();
    restResultBean.setData(jsonOutput);
    pwmRequest.outputJsonResult(restResultBean);
  }
Esempio n. 13
0
  public void initializeToken(
      final PwmRequest pwmRequest,
      final UpdateProfileBean updateProfileBean,
      final TokenVerificationProgress.TokenChannel tokenType)
      throws PwmUnrecoverableException {
    final PwmSession pwmSession = pwmRequest.getPwmSession();
    final PwmApplication pwmApplication = pwmRequest.getPwmApplication();

    if (pwmApplication.getConfig().getTokenStorageMethod() == TokenStorageMethod.STORE_LDAP) {
      throw new PwmUnrecoverableException(
          new ErrorInformation(
              PwmError.CONFIG_FORMAT_ERROR,
              null,
              new String[] {
                "cannot generate new user tokens when storage type is configured as STORE_LDAP."
              }));
    }

    final MacroMachine macroMachine =
        pwmRequest.getPwmSession().getSessionManager().getMacroMachine(pwmApplication);
    final Configuration config = pwmApplication.getConfig();

    switch (tokenType) {
      case SMS:
        {
          final String telephoneNumberAttribute =
              pwmRequest.getConfig().readSettingAsString(PwmSetting.SMS_USER_PHONE_ATTRIBUTE);
          final String toNum = updateProfileBean.getFormData().get(telephoneNumberAttribute);
          final String tokenKey;
          try {
            final TokenPayload tokenPayload =
                pwmApplication
                    .getTokenService()
                    .createTokenPayload(
                        TokenType.UPDATE_SMS,
                        Collections.<String, String>emptyMap(),
                        pwmRequest.getUserInfoIfLoggedIn(),
                        Collections.singleton(toNum));
            tokenKey =
                pwmApplication
                    .getTokenService()
                    .generateNewToken(tokenPayload, pwmRequest.getSessionLabel());
          } catch (PwmOperationalException e) {
            throw new PwmUnrecoverableException(e.getErrorInformation());
          }

          final String message =
              config.readSettingAsLocalizedString(
                  PwmSetting.SMS_UPDATE_PROFILE_TOKEN_TEXT,
                  pwmSession.getSessionStateBean().getLocale());

          try {
            TokenService.TokenSender.sendSmsToken(
                pwmApplication, null, macroMachine, toNum, message, tokenKey);
          } catch (Exception e) {
            throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_UNKNOWN));
          }

          updateProfileBean
              .getTokenVerificationProgress()
              .getIssuedTokens()
              .add(TokenVerificationProgress.TokenChannel.SMS);
          updateProfileBean.getTokenVerificationProgress().setTokenDisplayText(toNum);
          updateProfileBean
              .getTokenVerificationProgress()
              .setPhase(TokenVerificationProgress.TokenChannel.SMS);
        }
        break;

      case EMAIL:
        {
          final EmailItemBean configuredEmailSetting =
              config.readSettingAsEmail(
                  PwmSetting.EMAIL_UPDATEPROFILE_VERIFICATION, pwmRequest.getLocale());
          final String emailAddressAttribute =
              pwmRequest.getConfig().readSettingAsString(PwmSetting.EMAIL_USER_MAIL_ATTRIBUTE);
          final String toAddress = updateProfileBean.getFormData().get(emailAddressAttribute);

          final String tokenKey;
          try {
            final TokenPayload tokenPayload =
                pwmApplication
                    .getTokenService()
                    .createTokenPayload(
                        TokenType.UPDATE_EMAIL,
                        Collections.<String, String>emptyMap(),
                        pwmRequest.getUserInfoIfLoggedIn(),
                        Collections.singleton(toAddress));
            tokenKey =
                pwmApplication
                    .getTokenService()
                    .generateNewToken(tokenPayload, pwmRequest.getSessionLabel());
          } catch (PwmOperationalException e) {
            throw new PwmUnrecoverableException(e.getErrorInformation());
          }

          updateProfileBean
              .getTokenVerificationProgress()
              .getIssuedTokens()
              .add(TokenVerificationProgress.TokenChannel.EMAIL);
          updateProfileBean
              .getTokenVerificationProgress()
              .setPhase(TokenVerificationProgress.TokenChannel.EMAIL);
          updateProfileBean.getTokenVerificationProgress().setTokenDisplayText(toAddress);

          final EmailItemBean emailItemBean =
              new EmailItemBean(
                  toAddress,
                  configuredEmailSetting.getFrom(),
                  configuredEmailSetting.getSubject(),
                  configuredEmailSetting.getBodyPlain().replace("%TOKEN%", tokenKey),
                  configuredEmailSetting.getBodyHtml().replace("%TOKEN%", tokenKey));

          try {
            TokenService.TokenSender.sendEmailToken(
                pwmApplication, null, macroMachine, emailItemBean, toAddress, tokenKey);
          } catch (Exception e) {
            throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_UNKNOWN));
          }
        }
        break;

      default:
        LOGGER.error("Unimplemented token purpose: " + tokenType);
        updateProfileBean.getTokenVerificationProgress().setPhase(null);
    }
  }
Esempio n. 14
0
  public static void doProfileUpdate(
      final PwmRequest pwmRequest, final Map<String, String> formValues, final ChaiUser theUser)
      throws PwmUnrecoverableException, ChaiUnavailableException, PwmOperationalException {
    final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
    final PwmSession pwmSession = pwmRequest.getPwmSession();
    final UserInfoBean uiBean = pwmRequest.getPwmSession().getUserInfoBean();
    final UpdateAttributesProfile updateAttributesProfile =
        pwmRequest.getPwmSession().getSessionManager().getUpdateAttributeProfile(pwmApplication);

    final List<FormConfiguration> formFields =
        updateAttributesProfile.readSettingAsForm(PwmSetting.UPDATE_PROFILE_FORM);
    final Map<FormConfiguration, String> formMap =
        FormUtility.readFormValuesFromMap(formValues, formFields, pwmRequest.getLocale());

    // verify form meets the form requirements (may be redundant, but shouldn't hurt)
    verifyFormAttributes(pwmRequest, formMap, false);

    // write values.
    LOGGER.info(
        "updating profile for " + pwmRequest.getPwmSession().getUserInfoBean().getUserIdentity());

    pwmRequest.getPwmSession().getSessionManager().getChaiProvider();

    Helper.writeFormValuesToLdap(
        pwmRequest.getPwmApplication(), pwmRequest.getPwmSession(), theUser, formMap, false);

    final UserIdentity userIdentity = uiBean.getUserIdentity();

    // re-populate the uiBean because we have changed some values.
    final UserStatusReader userStatusReader =
        new UserStatusReader(pwmRequest.getPwmApplication(), pwmRequest.getSessionLabel());
    userStatusReader.populateActorUserInfoBean(pwmRequest.getPwmSession(), userIdentity);

    // clear cached read attributes.
    pwmRequest.getPwmSession().getSessionManager().clearUserDataReader();

    { // execute configured actions
      final List<ActionConfiguration> actions =
          updateAttributesProfile.readSettingAsAction(PwmSetting.UPDATE_PROFILE_WRITE_ATTRIBUTES);
      if (actions != null && !actions.isEmpty()) {
        LOGGER.debug(pwmRequest, "executing configured actions to user " + userIdentity);

        final ActionExecutor actionExecutor =
            new ActionExecutor.ActionExecutorSettings(pwmApplication, userIdentity)
                .setExpandPwmMacros(true)
                .setMacroMachine(pwmSession.getSessionManager().getMacroMachine(pwmApplication))
                .createActionExecutor();

        actionExecutor.executeActions(actions, pwmSession);
      }
    }

    sendProfileUpdateEmailNotice(pwmSession, pwmApplication);

    // mark the event log
    pwmApplication
        .getAuditManager()
        .submit(AuditEvent.UPDATE_PROFILE, pwmSession.getUserInfoBean(), pwmSession);

    // mark the uiBean so we user isn't recycled to the update profile page by the CommandServlet
    uiBean.setRequiresUpdateProfile(false);

    // clear out the updateProfileBean
    pwmApplication.getSessionStateService().clearBean(pwmRequest, UpdateProfileBean.class);

    // success, so forward to success page
    pwmApplication.getStatisticsManager().incrementValue(Statistic.UPDATE_ATTRIBUTES);
  }
Esempio n. 15
0
  private void advanceToNextStep(
      final PwmRequest pwmRequest,
      final UpdateAttributesProfile updateAttributesProfile,
      final UpdateProfileBean updateProfileBean)
      throws IOException, ServletException, PwmUnrecoverableException, ChaiUnavailableException {
    final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
    final PwmSession pwmSession = pwmRequest.getPwmSession();

    final String updateProfileAgreementText =
        updateAttributesProfile.readSettingAsLocalizedString(
            PwmSetting.UPDATE_PROFILE_AGREEMENT_MESSAGE,
            pwmSession.getSessionStateBean().getLocale());

    if (updateProfileAgreementText != null && updateProfileAgreementText.length() > 0) {
      if (!updateProfileBean.isAgreementPassed()) {
        final MacroMachine macroMachine =
            pwmRequest
                .getPwmSession()
                .getSessionManager()
                .getMacroMachine(pwmRequest.getPwmApplication());
        final String expandedText = macroMachine.expandMacros(updateProfileAgreementText);
        pwmRequest.setAttribute(PwmRequest.Attribute.AgreementText, expandedText);
        pwmRequest.forwardToJsp(PwmConstants.JSP_URL.UPDATE_ATTRIBUTES_AGREEMENT);
        return;
      }
    }

    // make sure there is form data in the bean.
    if (updateProfileBean.getFormData() == null) {
      updateProfileBean.setFormData(formDataFromLdap(pwmRequest, updateAttributesProfile));
      forwardToForm(pwmRequest, updateAttributesProfile, updateProfileBean);
      return;
    }

    if (!updateProfileBean.isFormSubmitted()) {
      forwardToForm(pwmRequest, updateAttributesProfile, updateProfileBean);
      return;
    }

    // validate the form data.
    try {
      // verify form meets the form requirements
      final List<FormConfiguration> formFields =
          updateAttributesProfile.readSettingAsForm(PwmSetting.UPDATE_PROFILE_FORM);
      final Map<FormConfiguration, String> formValues =
          FormUtility.readFormValuesFromMap(
              updateProfileBean.getFormData(), formFields, pwmRequest.getLocale());
      verifyFormAttributes(pwmRequest, formValues, true);
    } catch (PwmException e) {
      LOGGER.error(pwmSession, e.getMessage());
      pwmRequest.setResponseError(e.getErrorInformation());
      forwardToForm(pwmRequest, updateAttributesProfile, updateProfileBean);
      return;
    }

    final boolean requireConfirmation =
        updateAttributesProfile.readSettingAsBoolean(PwmSetting.UPDATE_PROFILE_SHOW_CONFIRMATION);
    if (requireConfirmation && !updateProfileBean.isConfirmationPassed()) {
      forwardToConfirmForm(pwmRequest, updateAttributesProfile, updateProfileBean);
      return;
    }

    final Set<TokenVerificationProgress.TokenChannel> requiredVerifications =
        determineTokenPhaseRequired(pwmRequest, updateProfileBean, updateAttributesProfile);
    if (requiredVerifications != null) {
      for (final TokenVerificationProgress.TokenChannel tokenChannel : requiredVerifications) {
        if (requiredVerifications.contains(tokenChannel)) {
          if (!updateProfileBean
              .getTokenVerificationProgress()
              .getIssuedTokens()
              .contains(tokenChannel)) {
            initializeToken(pwmRequest, updateProfileBean, tokenChannel);
          }

          if (!updateProfileBean
              .getTokenVerificationProgress()
              .getPassedTokens()
              .contains(tokenChannel)) {
            updateProfileBean.getTokenVerificationProgress().setPhase(tokenChannel);
            pwmRequest.forwardToJsp(PwmConstants.JSP_URL.UPDATE_ATTRIBUTES_ENTER_CODE);
            return;
          }
        }
      }
    }

    try {
      // write the form values
      final ChaiUser theUser = pwmSession.getSessionManager().getActor(pwmApplication);
      doProfileUpdate(pwmRequest, updateProfileBean.getFormData(), theUser);
      pwmRequest.getPwmResponse().forwardToSuccessPage(Message.Success_UpdateProfile);
      return;
    } catch (PwmException e) {
      LOGGER.error(pwmSession, e.getMessage());
      pwmRequest.setResponseError(e.getErrorInformation());
    } catch (ChaiException e) {
      final ErrorInformation errorInformation =
          new ErrorInformation(PwmError.ERROR_UPDATE_ATTRS_FAILURE, e.toString());
      LOGGER.error(pwmSession, errorInformation.toDebugStr());
      pwmRequest.setResponseError(errorInformation);
    }

    forwardToForm(pwmRequest, updateAttributesProfile, updateProfileBean);
  }