Jelajahi Sumber

prep for helpdesk ui refactoring

Jason Rivard 7 tahun lalu
induk
melakukan
d1f66df215

+ 2 - 0
server/src/main/java/password/pwm/bean/pub/PublicUserInfoBean.java

@@ -46,6 +46,7 @@ public class PublicUserInfoBean implements Serializable {
     private String userID;
     private String userGUID;
     private String userEmailAddress;
+    private String userSmsNumber;
     private Instant passwordExpirationTime;
     private Instant passwordLastModifiedTime;
     private Instant lastLoginTime;
@@ -75,6 +76,7 @@ public class PublicUserInfoBean implements Serializable {
         publicUserInfoBean.userID = userInfoBean.getUsername();
         publicUserInfoBean.userGUID = publicUserInfoBean.getUserGUID();
         publicUserInfoBean.userEmailAddress = userInfoBean.getUserEmailAddress();
+        publicUserInfoBean.userSmsNumber = userInfoBean.getUserSmsNumber();
         publicUserInfoBean.passwordExpirationTime = userInfoBean.getPasswordExpirationTime();
         publicUserInfoBean.passwordLastModifiedTime = userInfoBean.getPasswordLastModifiedTime();
         publicUserInfoBean.passwordStatus = userInfoBean.getPasswordStatus();

+ 91 - 81
server/src/main/java/password/pwm/http/servlet/helpdesk/HelpdeskDetailInfoBean.java

@@ -22,21 +22,29 @@
 
 package password.pwm.http.servlet.helpdesk;
 
+import com.novell.ldapchai.ChaiPasswordRule;
 import com.novell.ldapchai.ChaiUser;
 import com.novell.ldapchai.exception.ChaiUnavailableException;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Setter;
+import password.pwm.bean.ResponseInfoBean;
 import password.pwm.bean.UserIdentity;
-import password.pwm.ldap.UserInfo;
-import password.pwm.ldap.UserInfoBean;
-import password.pwm.config.value.data.FormConfiguration;
-import password.pwm.util.form.FormUtility;
+import password.pwm.bean.pub.PublicUserInfoBean;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.profile.HelpdeskProfile;
+import password.pwm.config.profile.PwmPasswordRule;
+import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.http.PwmRequest;
+import password.pwm.http.tag.PasswordRequirementsTag;
 import password.pwm.i18n.Display;
+import password.pwm.ldap.UserInfo;
 import password.pwm.ldap.UserInfoFactory;
 import password.pwm.svc.event.UserAuditRecord;
 import password.pwm.util.LocaleHelper;
+import password.pwm.util.form.FormUtility;
+import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.JsonUtil;
 import password.pwm.util.java.TimeDuration;
 import password.pwm.util.logging.PwmLogger;
@@ -46,16 +54,19 @@ import javax.servlet.ServletException;
 import java.io.IOException;
 import java.io.Serializable;
 import java.time.Instant;
+import java.util.Collections;
 import java.util.Date;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
+@Getter
+@Setter(AccessLevel.PRIVATE)
 public class HelpdeskDetailInfoBean implements Serializable {
     private static final PwmLogger LOGGER = PwmLogger.forClass(HelpdeskDetailInfoBean.class);
 
-
-    private UserInfo userInfo = UserInfoBean.builder().build();
+    private PublicUserInfoBean userInfo;
     private String userDisplayName;
 
     private boolean intruderLocked;
@@ -67,6 +78,18 @@ public class HelpdeskDetailInfoBean implements Serializable {
     private Map<FormConfiguration, List<String>> searchDetails;
     private String passwordSetDelta;
 
+    private Map<String, String> passwordPolicyRules;
+    private List<String> passwordRequirements;
+    private String passwordPolicyDN;
+    private String passwordPolicyID;
+
+    private boolean hasOtpRecord;
+    private String otpRecordTimestamp;
+
+    private ResponseInfoBean responseInfoBean;
+
+    private transient UserInfo backingUserInfo;
+
     static HelpdeskDetailInfoBean makeHelpdeskDetailInfo(
             final PwmRequest pwmRequest,
             final HelpdeskProfile helpdeskProfile,
@@ -91,7 +114,9 @@ public class HelpdeskDetailInfoBean implements Serializable {
                 userIdentity,
                 theUser.getChaiProvider()
         );
-        detailInfo.setUserInfo(userInfo);
+        final MacroMachine macroMachine = new MacroMachine(pwmRequest.getPwmApplication(), pwmRequest.getSessionLabel(), userInfo, null);
+
+        detailInfo.setUserInfo(PublicUserInfoBean.fromUserInfoBean(userInfo, pwmRequest.getConfig(), pwmRequest.getLocale(), macroMachine));
 
         try {
             detailInfo.setIntruderLocked(theUser.isPasswordLocked());
@@ -119,7 +144,7 @@ public class HelpdeskDetailInfoBean implements Serializable {
         }
 
         try {
-            detailInfo.setUserHistory(pwmRequest.getPwmApplication().getAuditManager().readUserHistory(detailInfo.getUserInfo()));
+            detailInfo.setUserHistory(pwmRequest.getPwmApplication().getAuditManager().readUserHistory(userInfo));
         } catch (Exception e) {
             LOGGER.error(pwmRequest, "unexpected error reading userHistory for user '" + userIdentity + "', " + e.getMessage());
         }
@@ -133,94 +158,79 @@ public class HelpdeskDetailInfoBean implements Serializable {
 
         {
             final List<FormConfiguration> detailFormConfig = helpdeskProfile.readSettingAsForm(PwmSetting.HELPDESK_DETAIL_FORM);
-            final Map<FormConfiguration,List<String>> formData = FormUtility.populateFormMapFromLdap(detailFormConfig, pwmRequest.getPwmSession().getLabel(), userInfo);
+            final Map<FormConfiguration, List<String>> formData = FormUtility.populateFormMapFromLdap(detailFormConfig, pwmRequest.getPwmSession().getLabel(), userInfo);
             detailInfo.setSearchDetails(formData);
         }
 
-        final String configuredDisplayName = helpdeskProfile.readSettingAsString(PwmSetting.HELPDESK_DETAIL_DISPLAY_NAME);
-        if (configuredDisplayName != null && !configuredDisplayName.isEmpty()) {
-            final MacroMachine macroMachine = new MacroMachine(pwmRequest.getPwmApplication(), pwmRequest.getSessionLabel(), detailInfo.getUserInfo(), null);
-            final String displayName = macroMachine.expandMacros(configuredDisplayName);
-            detailInfo.setUserDisplayName(displayName);
+        {
+            final Map<String,String> passwordRules = new LinkedHashMap<>();
+            if (userInfo.getPasswordPolicy() != null) {
+                for (final PwmPasswordRule rule : PwmPasswordRule.values()) {
+                    if (userInfo.getPasswordPolicy().getValue(rule) != null) {
+                        if (ChaiPasswordRule.RuleType.BOOLEAN == rule.getRuleType()) {
+                            final boolean value = Boolean.parseBoolean(userInfo.getPasswordPolicy().getValue(rule));
+                            final String sValue = LocaleHelper.booleanString(value, pwmRequest);
+                            passwordRules.put(rule.getLabel(pwmRequest.getLocale(), pwmRequest.getConfig()), sValue);
+                        } else {
+                            passwordRules.put(rule.getLabel(pwmRequest.getLocale(), pwmRequest.getConfig()),
+                                    userInfo.getPasswordPolicy().getValue(rule));
+                        }
+                    }
+                }
+            }
+            detailInfo.setPasswordPolicyRules(Collections.unmodifiableMap(passwordRules));
         }
 
-        final TimeDuration timeDuration = TimeDuration.fromCurrent(startTime);
-        if (pwmRequest.getConfig().isDevDebugMode()) {
-            LOGGER.trace(pwmRequest, "completed assembly of detail data report for user " + userIdentity
-                    + " in " + timeDuration.asCompactString() + ", contents: " + JsonUtil.serialize(detailInfo));
+        {
+            final List<String> requirementLines = PasswordRequirementsTag.getPasswordRequirementsStrings(
+                    userInfo.getPasswordPolicy(),
+                    pwmRequest.getConfig(),
+                    pwmRequest.getLocale(),
+                    macroMachine
+            );
+            detailInfo.setPasswordRequirements(Collections.unmodifiableList(requirementLines));
         }
-        return detailInfo;
-    }
-
-    public String getUserDisplayName() {
-        return userDisplayName;
-    }
-
-    public void setUserDisplayName(final String userDisplayName) {
-        this.userDisplayName = userDisplayName;
-    }
-
-    public UserInfo getUserInfo() {
-        return userInfo;
-    }
-
-    public void setUserInfo(final UserInfo userInfo) {
-        this.userInfo = userInfo;
-    }
 
-    public boolean isIntruderLocked() {
-        return intruderLocked;
-    }
-
-    public void setIntruderLocked(final boolean intruderLocked) {
-        this.intruderLocked = intruderLocked;
-    }
-
-    public boolean isAccountEnabled() {
-        return accountEnabled;
-    }
-
-    public void setAccountEnabled(final boolean accountEnabled) {
-        this.accountEnabled = accountEnabled;
-    }
+        if ((userInfo.getPasswordPolicy() != null)
+                && (userInfo.getPasswordPolicy().getChaiPasswordPolicy() != null)
+                && (userInfo.getPasswordPolicy().getChaiPasswordPolicy().getPolicyEntry() != null)
+                && (userInfo.getPasswordPolicy().getChaiPasswordPolicy().getPolicyEntry().getEntryDN() != null)) {
+            detailInfo.setPasswordPolicyDN(userInfo.getPasswordPolicy().getChaiPasswordPolicy().getPolicyEntry().getEntryDN());
+        } else {
+            detailInfo.setPasswordPolicyDN(LocaleHelper.getLocalizedMessage(Display.Value_NotApplicable, pwmRequest));
+        }
 
-    public Instant getLastLoginTime() {
-        return lastLoginTime;
-    }
+        if ((userInfo.getPasswordPolicy() != null)
+                && userInfo.getPasswordPolicy().getIdentifier() != null) {
+            detailInfo.setPasswordPolicyID(userInfo.getPasswordPolicy().getIdentifier());
+        } else {
+            detailInfo.setPasswordPolicyID(LocaleHelper.getLocalizedMessage(Display.Value_NotApplicable, pwmRequest));
+        }
 
-    public void setLastLoginTime(final Instant lastLoginTime) {
-        this.lastLoginTime = lastLoginTime;
-    }
+        detailInfo.hasOtpRecord = userInfo.getOtpUserRecord() != null;
 
-    public List<UserAuditRecord> getUserHistory() {
-        return userHistory;
-    }
+        detailInfo.otpRecordTimestamp = userInfo.getOtpUserRecord() != null && userInfo.getOtpUserRecord().getTimestamp() != null
+                ? JavaHelper.toIsoDate(userInfo.getOtpUserRecord().getTimestamp())
+                : LocaleHelper.getLocalizedMessage(Display.Value_NotApplicable, pwmRequest);
 
-    public void setUserHistory(final List<UserAuditRecord> userHistory) {
-        this.userHistory = userHistory;
-    }
+        detailInfo.responseInfoBean = userInfo.getResponseInfoBean();
 
-    public Map<FormConfiguration, List<String>> getSearchDetails() {
-        return searchDetails;
-    }
+        detailInfo.setBackingUserInfo(userInfo);
 
-    public void setSearchDetails(final Map<FormConfiguration, List<String>> searchDetails) {
-        this.searchDetails = searchDetails;
-    }
-
-    public String getPasswordSetDelta() {
-        return passwordSetDelta;
-    }
+            final String configuredDisplayName = helpdeskProfile.readSettingAsString(PwmSetting.HELPDESK_DETAIL_DISPLAY_NAME);
+        if (configuredDisplayName != null && !configuredDisplayName.isEmpty()) {
+            final String displayName = macroMachine.expandMacros(configuredDisplayName);
+            detailInfo.setUserDisplayName(displayName);
+        }
 
-    public void setPasswordSetDelta(final String passwordSetDelta) {
-        this.passwordSetDelta = passwordSetDelta;
-    }
+        final TimeDuration timeDuration = TimeDuration.fromCurrent(startTime);
+        if (pwmRequest.getConfig().isDevDebugMode()) {
+            LOGGER.trace(pwmRequest, "completed assembly of detail data report for user " + userIdentity
+                    + " in " + timeDuration.asCompactString() + ", contents: " + JsonUtil.serialize(detailInfo));
+        }
 
-    public boolean isAccountExpired() {
-        return accountExpired;
-    }
 
-    public void setAccountExpired(final boolean accountExpired) {
-        this.accountExpired = accountExpired;
+        return detailInfo;
     }
 }
+

+ 26 - 13
server/src/main/java/password/pwm/http/servlet/helpdesk/HelpdeskServlet.java

@@ -126,6 +126,7 @@ public class HelpdeskServlet extends ControlledPwmServlet {
         unlockIntruder(HttpMethod.POST),
         clearOtpSecret(HttpMethod.POST),
         search(HttpMethod.POST),
+        showDetail(HttpMethod.POST),
         detail(HttpMethod.POST),
         executeAction(HttpMethod.POST),
         deleteUser(HttpMethod.POST),
@@ -402,8 +403,8 @@ public class HelpdeskServlet extends ControlledPwmServlet {
         return ProcessStatus.Halt;
     }
 
-    @ActionHandler(action = "detail")
-    private ProcessStatus processDetailRequest(
+    @ActionHandler(action = "showDetail")
+    private ProcessStatus processShowDetailRequest(
             final PwmRequest pwmRequest
     )
             throws ChaiUnavailableException, PwmUnrecoverableException, IOException, ServletException {
@@ -416,19 +417,31 @@ public class HelpdeskServlet extends ControlledPwmServlet {
         }
 
         final UserIdentity userIdentity = UserIdentity.fromKey(userKey, pwmRequest.getPwmApplication()).canonicalized(pwmRequest.getPwmApplication());
-        HelpdeskServletUtil.processDetailRequest(pwmRequest, helpdeskProfile, userIdentity);
-        final HelpdeskAuditRecord auditRecord = new AuditRecordFactory(pwmRequest).createHelpdeskAuditRecord(
-                AuditEvent.HELPDESK_VIEW_DETAIL,
-                pwmRequest.getPwmSession().getUserInfo().getUserIdentity(),
-                null,
-                userIdentity,
-                pwmRequest.getSessionLabel().getSrcAddress(),
-                pwmRequest.getSessionLabel().getSrcHostname()
-        );
-        pwmRequest.getPwmApplication().getAuditManager().submit(auditRecord);
+        HelpdeskServletUtil.processShowDetailRequest(pwmRequest, helpdeskProfile, userIdentity);
         return ProcessStatus.Halt;
     }
 
+    @ActionHandler(action = "detail")
+    private ProcessStatus processDetailRequest(
+            final PwmRequest pwmRequest
+    )
+            throws ChaiUnavailableException, PwmUnrecoverableException, IOException, ServletException
+    {
+        final HelpdeskProfile helpdeskProfile = getHelpdeskProfile(pwmRequest);
+        final String userKey = pwmRequest.readParameterAsString("userKey", PwmHttpRequestWrapper.Flag.BypassValidation);
+        if (userKey.length() < 1) {
+            pwmRequest.respondWithError(
+                    new ErrorInformation(PwmError.ERROR_MISSING_PARAMETER, "userKey parameter is missing"));
+            return ProcessStatus.Halt;
+        }
+
+        final UserIdentity userIdentity = UserIdentity.fromKey(userKey, pwmRequest.getPwmApplication()).canonicalized(pwmRequest.getPwmApplication());
+        final HelpdeskDetailInfoBean helpdeskDetailInfoBean =  HelpdeskServletUtil.processDetailRequestImpl(pwmRequest, helpdeskProfile, userIdentity);
+
+        final RestResultBean restResultBean = new RestResultBean(helpdeskDetailInfoBean);
+        pwmRequest.outputJsonResult(restResultBean);
+        return ProcessStatus.Halt;
+    }
 
     @ActionHandler(action = "search")
     private ProcessStatus restSearchRequest(
@@ -696,7 +709,7 @@ public class HelpdeskServlet extends ControlledPwmServlet {
             pwmRequest.outputJsonResult(RestResultBean.fromError(errorInformation, pwmRequest));
             return ProcessStatus.Halt;
         }
-        final UserInfo userInfo = helpdeskDetailInfoBean.getUserInfo();
+        final UserInfo userInfo = helpdeskDetailInfoBean.getBackingUserInfo();
         final MacroMachine macroMachine = new MacroMachine(pwmRequest.getPwmApplication(), pwmRequest.getSessionLabel(), userInfo, null);
         final String configuredTokenString = config.readAppProperty(AppProperty.HELPDESK_TOKEN_VALUE);
         final String tokenKey = macroMachine.expandMacros(configuredTokenString);

+ 45 - 18
server/src/main/java/password/pwm/http/servlet/helpdesk/HelpdeskServletUtil.java

@@ -18,6 +18,9 @@ import password.pwm.http.PwmHttpRequestWrapper;
 import password.pwm.http.PwmRequest;
 import password.pwm.http.PwmRequestAttribute;
 import password.pwm.ldap.LdapPermissionTester;
+import password.pwm.svc.event.AuditEvent;
+import password.pwm.svc.event.AuditRecordFactory;
+import password.pwm.svc.event.HelpdeskAuditRecord;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.svc.stats.StatisticsManager;
 import password.pwm.util.logging.PwmLogger;
@@ -76,7 +79,34 @@ class HelpdeskServletUtil {
         }
     }
 
-    static void processDetailRequest(
+    static void processShowDetailRequest(
+            final PwmRequest pwmRequest,
+            final HelpdeskProfile helpdeskProfile,
+            final UserIdentity userIdentity
+    )
+            throws ChaiUnavailableException, PwmUnrecoverableException, IOException, ServletException
+    {
+        final HelpdeskDetailInfoBean helpdeskDetailInfoBean;
+        try {
+            helpdeskDetailInfoBean = processDetailRequestImpl(pwmRequest, helpdeskProfile, userIdentity);
+        } catch (PwmUnrecoverableException e) {
+            LOGGER.debug(pwmRequest, e.getErrorInformation());
+            pwmRequest.respondWithError(e.getErrorInformation(), false);
+            return;
+        }
+
+        if (helpdeskDetailInfoBean != null && helpdeskDetailInfoBean.getUserInfo() != null) {
+            final String obfuscatedDN = helpdeskDetailInfoBean.getBackingUserInfo().getUserIdentity().toObfuscatedKey(pwmRequest.getPwmApplication());
+            pwmRequest.setAttribute(PwmRequestAttribute.HelpdeskObfuscatedDN, obfuscatedDN);
+            pwmRequest.setAttribute(PwmRequestAttribute.HelpdeskUsername, helpdeskDetailInfoBean.getUserInfo().getUserID());
+        }
+
+        pwmRequest.setAttribute(PwmRequestAttribute.HelpdeskDetail, helpdeskDetailInfoBean);
+        pwmRequest.setAttribute(PwmRequestAttribute.HelpdeskVerificationEnabled, !helpdeskProfile.readOptionalVerificationMethods().isEmpty());
+        pwmRequest.forwardToJsp(JspUrl.HELPDESK_DETAIL);
+    }
+
+    static HelpdeskDetailInfoBean processDetailRequestImpl(
             final PwmRequest pwmRequest,
             final HelpdeskProfile helpdeskProfile,
             final UserIdentity userIdentity
@@ -88,9 +118,7 @@ class HelpdeskServletUtil {
         if (actorUserIdentity.canonicalEquals(userIdentity, pwmRequest.getPwmApplication())) {
             final String errorMsg = "cannot select self";
             final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNAUTHORIZED,errorMsg);
-            LOGGER.debug(pwmRequest, errorInformation);
-            pwmRequest.respondWithError(errorInformation, false);
-            return;
+            throw new PwmUnrecoverableException(errorInformation);
         }
         LOGGER.trace(pwmRequest, "helpdesk detail view request for user details of " + userIdentity.toString() + " by actor " + actorUserIdentity.toString());
 
@@ -102,23 +130,22 @@ class HelpdeskServletUtil {
         if (!HelpdeskServletUtil.checkIfRequiredVerificationPassed(userIdentity, verificationStateBean, helpdeskProfile)) {
             final String errorMsg = "selected user has not been verified";
             final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNAUTHORIZED,errorMsg);
-            LOGGER.debug(pwmRequest, errorInformation);
-            pwmRequest.respondWithError(errorInformation, false);
-            return;
+            throw new PwmUnrecoverableException(errorInformation);
         }
 
         final HelpdeskDetailInfoBean helpdeskDetailInfoBean = HelpdeskDetailInfoBean.makeHelpdeskDetailInfo(pwmRequest, helpdeskProfile, userIdentity);
-        pwmRequest.setAttribute(PwmRequestAttribute.HelpdeskDetail, helpdeskDetailInfoBean);
-
-        if (helpdeskDetailInfoBean != null && helpdeskDetailInfoBean.getUserInfo() != null) {
-            final String obfuscatedDN = helpdeskDetailInfoBean.getUserInfo().getUserIdentity().toObfuscatedKey(pwmRequest.getPwmApplication());
-            pwmRequest.setAttribute(PwmRequestAttribute.HelpdeskObfuscatedDN, obfuscatedDN);
-            pwmRequest.setAttribute(PwmRequestAttribute.HelpdeskUsername, helpdeskDetailInfoBean.getUserInfo().getUsername());
-        }
+        final HelpdeskAuditRecord auditRecord = new AuditRecordFactory(pwmRequest).createHelpdeskAuditRecord(
+                AuditEvent.HELPDESK_VIEW_DETAIL,
+                pwmRequest.getPwmSession().getUserInfo().getUserIdentity(),
+                null,
+                userIdentity,
+                pwmRequest.getSessionLabel().getSrcAddress(),
+                pwmRequest.getSessionLabel().getSrcHostname()
+        );
+        pwmRequest.getPwmApplication().getAuditManager().submit(auditRecord);
 
         StatisticsManager.incrementStat(pwmRequest, Statistic.HELPDESK_USER_LOOKUP);
-        pwmRequest.setAttribute(PwmRequestAttribute.HelpdeskVerificationEnabled, !helpdeskProfile.readOptionalVerificationMethods().isEmpty());
-        pwmRequest.forwardToJsp(JspUrl.HELPDESK_DETAIL);
+        return helpdeskDetailInfoBean;
     }
 
     static UserIdentity userIdentityFromMap(final PwmRequest pwmRequest, final Map<String,String> bodyMap) throws PwmUnrecoverableException {
@@ -165,13 +192,13 @@ class HelpdeskServletUtil {
         final MacroMachine macroMachine = new MacroMachine(
                 pwmApplication,
                 pwmRequest.getSessionLabel(),
-                helpdeskDetailInfoBean.getUserInfo(),
+                helpdeskDetailInfoBean.getBackingUserInfo(),
                 null
         );
 
         pwmApplication.getEmailQueue().submitEmail(
                 configuredEmailSetting,
-                helpdeskDetailInfoBean.getUserInfo(),
+                helpdeskDetailInfoBean.getBackingUserInfo(),
                 macroMachine
         );
     }

+ 32 - 19
server/src/main/java/password/pwm/http/servlet/peoplesearch/PeopleSearchClientConfigBean.java

@@ -22,36 +22,49 @@
 
 package password.pwm.http.servlet.peoplesearch;
 
+import lombok.Getter;
+import lombok.Setter;
+import password.pwm.config.Configuration;
+import password.pwm.config.PwmSetting;
+import password.pwm.config.value.data.FormConfiguration;
+
 import java.io.Serializable;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 
+@Getter
+@Setter
 public class PeopleSearchClientConfigBean implements Serializable {
 
     private Map<String,String> peoplesearch_search_columns;
     private boolean peoplesearch_enablePhoto;
     private boolean peoplesearch_orgChartEnabled;
+    private boolean orgChartShowChildCount;
+    private int orgChartMaxParents;
 
-    public Map<String, String> getPeoplesearch_search_columns() {
-        return peoplesearch_search_columns;
-    }
-
-    public void setPeoplesearch_search_columns(final Map<String, String> peoplesearch_search_columns) {
-        this.peoplesearch_search_columns = peoplesearch_search_columns;
-    }
-
-    public boolean isPeoplesearch_enablePhoto() {
-        return peoplesearch_enablePhoto;
-    }
 
-    public void setPeoplesearch_enablePhoto(final boolean peoplesearch_enablePhoto) {
-        this.peoplesearch_enablePhoto = peoplesearch_enablePhoto;
-    }
+    static PeopleSearchClientConfigBean fromConfig(
+            final Configuration configuration,
+            final PeopleSearchConfiguration peopleSearchConfiguration,
+            final Locale locale
+            )
+    {
+        final Map<String, String> searchColumns = new LinkedHashMap<>();
+        final List<FormConfiguration> searchForm = configuration.readSettingAsForm(PwmSetting.PEOPLE_SEARCH_RESULT_FORM);
+        for (final FormConfiguration formConfiguration : searchForm) {
+            searchColumns.put(formConfiguration.getName(),
+                    formConfiguration.getLabel(locale));
+        }
 
-    public boolean isPeoplesearch_orgChartEnabled() {
-        return peoplesearch_orgChartEnabled;
-    }
+        final PeopleSearchClientConfigBean peopleSearchClientConfigBean = new PeopleSearchClientConfigBean();
+        peopleSearchClientConfigBean.setPeoplesearch_search_columns(searchColumns);
+        peopleSearchClientConfigBean.setPeoplesearch_enablePhoto(peopleSearchConfiguration.isPhotosEnabled());
+        peopleSearchClientConfigBean.setPeoplesearch_orgChartEnabled(peopleSearchConfiguration.isOrgChartEnabled());
+        peopleSearchClientConfigBean.setOrgChartShowChildCount(peopleSearchConfiguration.isOrgChartShowChildCount());
+        peopleSearchClientConfigBean.setOrgChartMaxParents(peopleSearchClientConfigBean.getOrgChartMaxParents());
 
-    public void setPeoplesearch_orgChartEnabled(final boolean peoplesearch_orgChartEnabled) {
-        this.peoplesearch_orgChartEnabled = peoplesearch_orgChartEnabled;
+        return peopleSearchClientConfigBean;
     }
 }

+ 5 - 14
server/src/main/java/password/pwm/http/servlet/peoplesearch/PeopleSearchServlet.java

@@ -24,7 +24,6 @@ package password.pwm.http.servlet.peoplesearch;
 
 import com.novell.ldapchai.exception.ChaiUnavailableException;
 import password.pwm.bean.UserIdentity;
-import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.config.PwmSetting;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmError;
@@ -50,8 +49,6 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 
 public abstract class PeopleSearchServlet extends ControlledPwmServlet {
@@ -112,17 +109,11 @@ public abstract class PeopleSearchServlet extends ControlledPwmServlet {
     {
         final PeopleSearchConfiguration peopleSearchConfiguration = PeopleSearchConfiguration.fromConfiguration(pwmRequest.getConfig());
 
-        final Map<String, String> searchColumns = new LinkedHashMap<>();
-        final List<FormConfiguration> searchForm = pwmRequest.getConfig().readSettingAsForm(PwmSetting.PEOPLE_SEARCH_RESULT_FORM);
-        for (final FormConfiguration formConfiguration : searchForm) {
-            searchColumns.put(formConfiguration.getName(),
-                    formConfiguration.getLabel(pwmRequest.getLocale()));
-        }
-
-        final PeopleSearchClientConfigBean peopleSearchClientConfigBean = new PeopleSearchClientConfigBean();
-        peopleSearchClientConfigBean.setPeoplesearch_search_columns(searchColumns);
-        peopleSearchClientConfigBean.setPeoplesearch_enablePhoto(peopleSearchConfiguration.isPhotosEnabled());
-        peopleSearchClientConfigBean.setPeoplesearch_orgChartEnabled(peopleSearchConfiguration.isOrgChartEnabled());
+        final PeopleSearchClientConfigBean peopleSearchClientConfigBean = PeopleSearchClientConfigBean.fromConfig(
+                pwmRequest.getConfig(),
+                peopleSearchConfiguration,
+                pwmRequest.getLocale()
+        );
 
         final RestResultBean restResultBean = new RestResultBean(peopleSearchClientConfigBean);
         LOGGER.trace(pwmRequest, "returning clientData: " + JsonUtil.serialize(restResultBean));

+ 36 - 48
server/src/main/webapp/WEB-INF/jsp/helpdesk-detail.jsp

@@ -23,14 +23,14 @@
 <%@ page import="com.novell.ldapchai.ChaiPasswordRule" %>
 <%@ page import="com.novell.ldapchai.cr.Challenge" %>
 <%@ page import="password.pwm.bean.ResponseInfoBean" %>
-<%@ page import="password.pwm.ldap.UserInfo" %>
-<%@ page import="password.pwm.config.value.data.ActionConfiguration" %>
-<%@ page import="password.pwm.config.value.data.FormConfiguration" %>
+<%@ page import="password.pwm.bean.pub.PublicUserInfoBean" %>
 <%@ page import="password.pwm.config.PwmSetting" %>
 <%@ page import="password.pwm.config.option.HelpdeskUIMode" %>
 <%@ page import="password.pwm.config.option.ViewStatusFields" %>
 <%@ page import="password.pwm.config.profile.HelpdeskProfile" %>
 <%@ page import="password.pwm.config.profile.PwmPasswordRule" %>
+<%@ page import="password.pwm.config.value.data.ActionConfiguration" %>
+<%@ page import="password.pwm.config.value.data.FormConfiguration" %>
 <%@ page import="password.pwm.http.PwmSession" %>
 <%@ page import="password.pwm.http.servlet.helpdesk.HelpdeskDetailInfoBean" %>
 <%@ page import="password.pwm.http.tag.PasswordRequirementsTag" %>
@@ -44,6 +44,7 @@
 <%@ page import="java.util.Iterator" %>
 <%@ page import="java.util.List" %>
 <%@ page import="java.util.Set" %>
+<%@ page import="org.apache.commons.text.StringEscapeUtils" %>
 <!DOCTYPE html>
 <%@ page language="java" session="true" isThreadSafe="true" contentType="text/html; charset=UTF-8" %>
 <%@ taglib uri="pwm" prefix="pwm" %>
@@ -56,12 +57,11 @@
 
     // user info
     final HelpdeskDetailInfoBean helpdeskDetailInfoBean = (HelpdeskDetailInfoBean)pwmRequest.getAttribute(PwmRequestAttribute.HelpdeskDetail);
-    final UserInfo searchedUserInfo = helpdeskDetailInfoBean.getUserInfo();
-    final ResponseInfoBean responseInfoBean = searchedUserInfo.getResponseInfoBean();
+    final PublicUserInfoBean searchedUserInfo = helpdeskDetailInfoBean.getUserInfo();
+    final ResponseInfoBean responseInfoBean = helpdeskDetailInfoBean.getResponseInfoBean();
 
     final String displayName = helpdeskDetailInfoBean.getUserDisplayName();
     final Set<ViewStatusFields> viewStatusFields = helpdeskProfile.readSettingAsOptionList(PwmSetting.HELPDESK_VIEW_STATUS_VALUES,ViewStatusFields.class);
-    final boolean hasOtp = searchedUserInfo.getOtpUserRecord() != null;
 %>
 <html lang="<pwm:value name="<%=PwmValue.localeCode%>"/>" dir="<pwm:value name="<%=PwmValue.localeDir%>"/>">
 <%@ include file="/WEB-INF/jsp/fragment/header.jsp" %>
@@ -117,7 +117,7 @@
                                     </td>
                                     <td>
                                         <span style="word-wrap: break-word; word-break: break-all">
-                                        <%= StringUtil.escapeHtml(searchedUserInfo.getUserIdentity().getUserDN()) %>
+                                        <%= StringUtil.escapeHtml(searchedUserInfo.getUserDN()) %>
                                         </span>
                                     </td>
                                 </tr>
@@ -127,7 +127,7 @@
                                         <pwm:display key="Field_LdapProfile"/>
                                     </td>
                                     <td>
-                                        <%= StringUtil.escapeHtml(pwmApplication.getConfig().getLdapProfiles().get(searchedUserInfo.getUserIdentity().getLdapProfileID()).getDisplayName(pwmSession.getSessionStateBean().getLocale())) %>
+                                        <%= StringUtil.escapeHtml(pwmApplication.getConfig().getLdapProfiles().get(searchedUserInfo.getLdapProfile()).getDisplayName(pwmSession.getSessionStateBean().getLocale())) %>
                                     </td>
                                 </tr>
                                 <% } %>
@@ -138,7 +138,7 @@
                                         <pwm:display key="Field_Username"/>
                                     </td>
                                     <td>
-                                        <%= StringUtil.escapeHtml(searchedUserInfo.getUsername()) %>
+                                        <%= StringUtil.escapeHtml(searchedUserInfo.getUserID()) %>
                                     </td>
                                 </tr>
                                 <% } %>
@@ -374,7 +374,7 @@
                                             <pwm:display key="Field_OTP_Stored"/>
                                         </td>
                                         <td>
-                                            <%if (searchedUserInfo.getOtpUserRecord() != null) {%><pwm:display key="Value_True"/><% } else { %><pwm:display key="Value_False"/><% } %>
+                                            <%if (helpdeskDetailInfoBean.isHasOtpRecord()) {%><pwm:display key="Value_True"/><% } else { %><pwm:display key="Value_False"/><% } %>
                                         </td>
                                     </tr>
                                     <% } %>
@@ -383,15 +383,9 @@
                                         <td class="key">
                                             <pwm:display key="Field_OTP_Timestamp"/>
                                         </td>
-                                        <% if (searchedUserInfo.getOtpUserRecord() == null || searchedUserInfo.getOtpUserRecord().getTimestamp() == null) { %>
-                                        <td>
-                                            <pwm:display key="Value_NotApplicable"/>
-                                        </td>
-                                        <% } else { %>
                                         <td class="timestamp">
-                                            <%= JavaHelper.toIsoDate(searchedUserInfo.getOtpUserRecord().getTimestamp()) %>
+                                            <%= helpdeskDetailInfoBean.getOtpRecordTimestamp() %>
                                         </td>
-                                        <% } %>
                                     </tr>
                                     <% } %>
                                 </pwm:if>
@@ -401,7 +395,7 @@
                                         <pwm:display key="Field_UserGUID"/>
                                     </td>
                                     <td>
-                                        <%= StringUtil.escapeHtml(searchedUserInfo.getUserGuid()) %>
+                                        <%= StringUtil.escapeHtml(searchedUserInfo.getUserGUID()) %>
                                     </td>
                                 </tr>
                                 <% } %>
@@ -434,14 +428,7 @@
                                             <pwm:display key="Field_Policy"/>
                                         </td>
                                         <td>
-                                            <% if ((searchedUserInfo.getPasswordPolicy() != null)
-                                                    && (searchedUserInfo.getPasswordPolicy().getChaiPasswordPolicy() != null)
-                                                    && (searchedUserInfo.getPasswordPolicy().getChaiPasswordPolicy().getPolicyEntry() != null)
-                                                    && (searchedUserInfo.getPasswordPolicy().getChaiPasswordPolicy().getPolicyEntry().getEntryDN() != null)) { %>
-                                            <%= searchedUserInfo.getPasswordPolicy().getChaiPasswordPolicy().getPolicyEntry().getEntryDN() %>
-                                            <% } else { %>
-                                            <pwm:display key="Value_NotApplicable"/>
-                                            <% } %>
+                                            <%= StringUtil.escapeHtml(helpdeskDetailInfoBean.getPasswordPolicyDN()) %>
                                         </td>
                                     </tr>
                                     <tr>
@@ -449,10 +436,7 @@
                                             <pwm:display key="Field_Profile"/>
                                         </td>
                                         <td>
-                                            <%= searchedUserInfo.getPasswordPolicy().getIdentifier() == null
-                                                    ? JspUtility.getMessage(pageContext, Display.Value_NotApplicable)
-                                                    : searchedUserInfo.getPasswordPolicy().getIdentifier()
-                                            %>
+                                            <%= StringUtil.escapeHtml(helpdeskDetailInfoBean.getPasswordPolicyID()) %>
                                         </td>
                                     </tr>
                                     <tr>
@@ -461,10 +445,7 @@
                                         </td>
                                         <td>
                                             <ul>
-                                                <%
-                                                    final MacroMachine macroMachine = JspUtility.getPwmSession(pageContext).getSessionManager().getMacroMachine(ContextManager.getPwmApplication(session));
-                                                    final List<String> requirementLines = PasswordRequirementsTag.getPasswordRequirementsStrings(searchedUserInfo.getPasswordPolicy(), ContextManager.getPwmApplication(session).getConfig(), pwmSession.getSessionStateBean().getLocale(), macroMachine); %>
-                                                <% for (final String requirementLine : requirementLines) { %>
+                                                <% for (final String requirementLine : helpdeskDetailInfoBean.getPasswordRequirements()) { %>
                                                 <li><%=requirementLine%>
                                                 </li>
                                                 <% } %>
@@ -473,23 +454,13 @@
                                     </tr>
                                 </table>
                                 <table class="nomargin">
-                                    <% for (final PwmPasswordRule rule : PwmPasswordRule.values()) { %>
+                                    <% for (final String key : helpdeskDetailInfoBean.getPasswordPolicyRules().keySet()) { %>
                                     <tr>
                                         <td class="key">
-                                            <%= rule.getLabel(pwmSession.getSessionStateBean().getLocale(),pwmApplication.getConfig()) %>
+                                            <%= StringUtil.escapeHtml(key) %>
                                         </td>
                                         <td>
-                                            <% if (searchedUserInfo.getPasswordPolicy().getValue(rule) != null) { %>
-                                            <% if (ChaiPasswordRule.RuleType.BOOLEAN == rule.getRuleType()) { %>
-                                            <% if (Boolean.parseBoolean(searchedUserInfo.getPasswordPolicy().getValue(rule))) { %>
-                                            <pwm:display key="Value_True"/>
-                                            <% } else { %>
-                                            <pwm:display key="Value_False"/>
-                                            <% } %>
-                                            <% } else { %>
-                                            <%= StringUtil.escapeHtml(searchedUserInfo.getPasswordPolicy().getValue(rule)) %>
-                                            <% } %>
-                                            <% } %>
+                                            <%= StringUtil.escapeHtml(helpdeskDetailInfoBean.getPasswordPolicyRules().get(key)) %>
                                         </td>
                                     </tr>
                                     <% } %>
@@ -570,7 +541,7 @@
                         <% } %>
                         <% } %>
                         <% if (helpdeskProfile.readSettingAsBoolean(PwmSetting.HELPDESK_CLEAR_OTP_BUTTON) && pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.OTP_ENABLED)) { %>
-                        <% if (hasOtp) { %>
+                        <% if (helpdeskDetailInfoBean.isHasOtpRecord()) { %>
                         <button id="helpdesk_clearOtpSecretBtn" class="helpdesk-detail-btn btn">
                             <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-eraser"></span></pwm:if>
                             <pwm:display key="Button_HelpdeskClearOtpSecret"/>
@@ -595,6 +566,23 @@
                         </button>
                         <% } %>
                         <% final List<ActionConfiguration> actions = helpdeskProfile.readSettingAsAction(PwmSetting.HELPDESK_ACTIONS); %>
+
+                        <button id="loadDetail" style="display:none">Load Detail</button>
+                        <pwm:script>
+                            <script type="text/javascript">
+                                PWM_GLOBAL['startupFunctions'].push(function(){
+                                    PWM_MAIN.addEventHandler('loadDetail','click',function(){
+                                        var url = 'helpdesk';
+                                        url = PWM_MAIN.addParamToUrl(url, 'processAction', 'detail');
+                                        url = PWM_MAIN.addParamToUrl(url, 'userKey', PWM_VAR['helpdesk_obfuscatedDN']);
+                                        url = PWM_MAIN.addParamToUrl(url, 'verificationState', PWM_MAIN.Preferences.readSessionStorage(PREF_KEY_VERIFICATION_STATE));
+                                        PWM_MAIN.ajaxRequest(url,function () {
+                                        });
+                                    });
+                                });
+                            </script>
+                        </pwm:script>
+
                         <% for (final ActionConfiguration loopAction : actions) { %>
                         <button class="helpdesk-detail-btn btn" name="action-<%=loopAction.getName()%>" id="action-<%=loopAction.getName()%>">
                             <pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-location-arrow"></span></pwm:if>

+ 1 - 1
server/src/main/webapp/public/resources/js/helpdesk.js

@@ -252,7 +252,7 @@ PWM_HELPDESK.loadSearchDetails = function(userKey) {
             if (PWM_MAIN.Preferences.readSessionStorage(PREF_KEY_VERIFICATION_STATE)) {
                 contents[PARAM_VERIFICATION_STATE] = PWM_MAIN.Preferences.readSessionStorage(PREF_KEY_VERIFICATION_STATE);
             }
-            PWM_MAIN.submitPostAction(window.location.href,'detail',contents);
+            PWM_MAIN.submitPostAction(window.location.href,'showDetail',contents);
         }});
     };