Browse Source

minor fixes

jrivard 10 years ago
parent
commit
d0315a0ce9

+ 1 - 1
pwm/servlet/src/password/pwm/config/PwmSetting.xml

@@ -1536,7 +1536,7 @@
         </default>
     </setting>
     <setting key="intruder.enable" level="1" required="true">
-        <label>Intruder Detection Enabled</label>
+        <label>Enable Intruder Detection</label>
         <description><![CDATA[Enable the application level intruder detection system.  Your LDAP directory intruder detection settings will function independently of this setting.]]></description>
         <default>
             <value>true</value>

+ 5 - 3
pwm/servlet/src/password/pwm/config/function/UserMatchViewerFunction.java

@@ -57,13 +57,14 @@ public class UserMatchViewerFunction implements SettingUIFunction {
         final Locale userLocale = pwmSession == null ? PwmConstants.DEFAULT_LOCALE : pwmSession.getSessionStateBean().getLocale();
         final int maxResultSize = Integer.parseInt(
                 pwmApplication.getConfig().readAppProperty(AppProperty.CONFIG_EDITOR_QUERY_FILTER_TEST_LIMIT));
-        final Map<String,List<String>> matchingUsers = discoverMatchingUsers(maxResultSize, storedConfiguration, setting, profile);
+        final Map<String,List<String>> matchingUsers = discoverMatchingUsers(pwmApplication, maxResultSize, storedConfiguration, setting, profile);
         return convertResultsToHtmlTable(
                 pwmApplication, userLocale, matchingUsers, maxResultSize
         );
     }
 
     public Map<String,List<String>> discoverMatchingUsers(
+            final PwmApplication pwmApplication,
             final int maxResultSize,
             final StoredConfiguration storedConfiguration,
             final PwmSetting setting,
@@ -75,9 +76,10 @@ public class UserMatchViewerFunction implements SettingUIFunction {
         final PwmApplication tempApplication = new PwmApplication.PwmEnvironment()
                 .setConfig(config)
                 .setApplicationMode(PwmApplication.MODE.CONFIGURATION)
-                .setApplicationPath(null).setInitLogging(false)
+                .setApplicationPath(pwmApplication.getApplicationPath())
+                .setInitLogging(false)
                 .setConfigurationFile(null)
-                .setWebInfPath(null)
+                .setWebInfPath(pwmApplication.getWebInfPath())
                 .createPwmApplication();
         final List<UserPermission> permissions = (List<UserPermission>)storedConfiguration.readSetting(setting,profile).toNativeObject();
 

+ 3 - 2
pwm/servlet/src/password/pwm/health/LDAPStatusChecker.java

@@ -536,6 +536,7 @@ public class LDAPStatusChecker implements HealthChecker {
     }
 
     public static HealthData healthForNewConfiguration(
+            final PwmApplication pwmApplication,
             final Configuration config,
             final Locale locale,
             final String profileID,
@@ -548,10 +549,10 @@ public class LDAPStatusChecker implements HealthChecker {
         final PwmApplication tempApplication = new PwmApplication.PwmEnvironment()
                 .setConfig(config)
                 .setApplicationMode(PwmApplication.MODE.NEW)
-                .setApplicationPath(null)
+                .setApplicationPath(pwmApplication.getApplicationPath())
                 .setInitLogging(false)
                 .setConfigurationFile(null)
-                .setWebInfPath(null)
+                .setWebInfPath(pwmApplication.getWebInfPath())
                 .createPwmApplication();
 
         final LDAPStatusChecker ldapStatusChecker = new LDAPStatusChecker();

+ 16 - 10
pwm/servlet/src/password/pwm/http/filter/AuthenticationFilter.java

@@ -165,13 +165,13 @@ public class AuthenticationFilter extends AbstractPwmFilter {
         if (!pwmRequest.isAuthenticated() || pwmRequest.getPwmSession().getLoginInfoBean().getAuthenticationType() != AuthenticationType.AUTHENTICATED) {
             return;
         }
-        
+
         if (pwmRequest.getPwmSession().getLoginInfoBean().isAuthRecordCookieSet()) {
             return;
         }
-        
+
         pwmRequest.getPwmSession().getLoginInfoBean().setAuthRecordCookieSet(true);
-        
+
         final String cookieName = pwmRequest.getConfig().readAppProperty(AppProperty.HTTP_COOKIE_AUTHRECORD_NAME);
         if (cookieName == null || cookieName.isEmpty()) {
             LOGGER.debug(pwmRequest, "skipping auth record cookie set, cookie name parameter is blank");
@@ -187,7 +187,7 @@ public class AuthenticationFilter extends AbstractPwmFilter {
         final Date authTime = pwmRequest.getPwmSession().getLoginInfoBean().getLocalAuthTime();
         final String userGuid = pwmRequest.getPwmSession().getUserInfoBean().getUserGuid();
         final AuthRecord authRecord = new AuthRecord(authTime, userGuid);
-        
+
         try {
             pwmRequest.getPwmResponse().writeCookie(cookieName, authRecord, cookieAgeSeconds, true, pwmRequest.getContextPath());
             LOGGER.debug(pwmRequest,"wrote auth record cookie to user browser for use during forgotten password");
@@ -264,7 +264,7 @@ public class AuthenticationFilter extends AbstractPwmFilter {
         }
 
         //store the original requested url
-        final String originalRequestedUrl = req.getRequestURL().toString();
+        final String originalRequestedUrl = figureOriginalRequestUrl(pwmRequest);
 
         pwmRequest.markPreLoginUrl();
 
@@ -413,11 +413,7 @@ public class AuthenticationFilter extends AbstractPwmFilter {
             return false;
         }
 
-        final String originalURL;
-        {
-            final HttpServletRequest req = pwmRequest.getHttpServletRequest();
-            originalURL = req.getRequestURI() + (req.getQueryString() != null ? ('?' + req.getQueryString()) : "");
-        }
+        final String originalURL = figureOriginalRequestUrl(pwmRequest);
 
         final String state = OAuthConsumerServlet.makeStateStringForRequest(pwmRequest, originalURL);
         final String redirectUri = OAuthConsumerServlet.figureOauthSelfEndPointUrl(pwmRequest);
@@ -523,5 +519,15 @@ public class AuthenticationFilter extends AbstractPwmFilter {
 
         return false;
     }
+
+    private static String figureOriginalRequestUrl(final PwmRequest pwmRequest) {
+        final HttpServletRequest req = pwmRequest.getHttpServletRequest();
+        final String queryString = req.getQueryString();
+        if (queryString != null && !queryString.isEmpty()) {
+            return req.getRequestURI() + '?' + queryString;
+        } else {
+            return req.getRequestURI();
+        }
+    }
 }
 

+ 2 - 9
pwm/servlet/src/password/pwm/http/filter/SessionFilter.java

@@ -290,9 +290,7 @@ public class SessionFilter extends AbstractPwmFilter {
     private static String figureValidationURL(final HttpServletRequest req, final String validationKey) {
         final StringBuilder sb = new StringBuilder();
         sb.append(req.getRequestURL());
-        if (!req.getParameterMap().isEmpty()) {
-            sb.append("?");
-        }
+
         for (final Enumeration paramEnum = req.getParameterNames(); paramEnum.hasMoreElements(); ) {
             final String paramName = (String) paramEnum.nextElement();
 
@@ -303,14 +301,9 @@ public class SessionFilter extends AbstractPwmFilter {
 
                     for (final Iterator<String> valueIter = paramValues.iterator(); valueIter.hasNext(); ) {
                         final String value = valueIter.next();
+                        sb.append(sb.toString().contains("?") ? "&" : "?");
                         sb.append(StringUtil.urlEncode(paramName)).append("=");
                         sb.append(StringUtil.urlEncode(value));
-                        if (valueIter.hasNext()) {
-                            sb.append("&");
-                        }
-                    }
-                    if (paramEnum.hasMoreElements()) {
-                        sb.append("&");
                     }
                 }
             } else {

+ 1 - 1
pwm/servlet/src/password/pwm/http/servlet/ConfigEditorServlet.java

@@ -597,7 +597,7 @@ public class ConfigEditorServlet extends PwmServlet {
         LOGGER.debug(pwmRequest, "beginning restLdapHealthCheck");
         final String profileID = pwmRequest.readParameterAsString("profile");
         final Configuration config = new Configuration(configManagerBean.getStoredConfiguration());
-        final HealthData healthData = LDAPStatusChecker.healthForNewConfiguration(config, pwmRequest.getLocale(), profileID, true, true);
+        final HealthData healthData = LDAPStatusChecker.healthForNewConfiguration(pwmRequest.getPwmApplication(), config, pwmRequest.getLocale(), profileID, true, true);
         final RestResultBean restResultBean = new RestResultBean();
         restResultBean.setData(healthData);
 

+ 4 - 2
pwm/servlet/src/password/pwm/http/servlet/ConfigGuideServlet.java

@@ -339,10 +339,10 @@ public class ConfigGuideServlet extends PwmServlet {
         final PwmApplication tempApplication = new PwmApplication.PwmEnvironment()
                 .setConfig(tempConfiguration)
                 .setApplicationMode(PwmApplication.MODE.NEW)
-                .setApplicationPath(null)
+                .setApplicationPath(pwmRequest.getPwmApplication().getApplicationPath())
                 .setInitLogging(false)
                 .setConfigurationFile(null)
-                .setWebInfPath(null).createPwmApplication();
+                .setWebInfPath(pwmRequest.getPwmApplication().getWebInfPath()).createPwmApplication();
         final LDAPStatusChecker ldapStatusChecker = new LDAPStatusChecker();
         final List<HealthRecord> records = new ArrayList<>();
         final LdapProfile ldapProfile = tempConfiguration.getDefaultLdapProfile();
@@ -363,6 +363,7 @@ public class ConfigGuideServlet extends PwmServlet {
                 try {
                     final UserMatchViewerFunction userMatchViewerFunction = new UserMatchViewerFunction();
                     final Map<String, List<String>> results = userMatchViewerFunction.discoverMatchingUsers(
+                            pwmRequest.getPwmApplication(),
                             2,
                             configGuideBean.getStoredConfiguration(),
                             PwmSetting.QUERY_MATCH_PWM_ADMIN,
@@ -411,6 +412,7 @@ public class ConfigGuideServlet extends PwmServlet {
         final int maxResults = 1000;
         try {
             final Map<String, List<String>> results = userMatchViewerFunction.discoverMatchingUsers(
+                    pwmRequest.getPwmApplication(),
                     1000,
                     configGuideBean.getStoredConfiguration(),
                     PwmSetting.QUERY_MATCH_PWM_ADMIN,

+ 70 - 48
pwm/servlet/src/password/pwm/http/servlet/PeopleSearchServlet.java

@@ -22,7 +22,6 @@
 
 package password.pwm.http.servlet;
 
-import com.google.gson.reflect.TypeToken;
 import com.novell.ldapchai.ChaiUser;
 import com.novell.ldapchai.exception.ChaiException;
 import com.novell.ldapchai.exception.ChaiOperationException;
@@ -63,6 +62,27 @@ public class PeopleSearchServlet extends PwmServlet {
 
     private static final PwmLogger LOGGER = PwmLogger.forClass(PeopleSearchServlet.class);
 
+    public static class SearchResultBean implements Serializable {
+        private List searchResults = new ArrayList<>();
+        private boolean sizeExceeded;
+
+        public List getSearchResults() {
+            return searchResults;
+        }
+
+        public void setSearchResults(List searchResults) {
+            this.searchResults = searchResults;
+        }
+
+        public boolean isSizeExceeded() {
+            return sizeExceeded;
+        }
+
+        public void setSizeExceeded(boolean sizeExceeded) {
+            this.sizeExceeded = sizeExceeded;
+        }
+    }
+
     public static class UserDetailBean implements Serializable {
         private String displayName;
         private String userKey;
@@ -313,19 +333,23 @@ public class PeopleSearchServlet extends PwmServlet {
     )
             throws ServletException, IOException, ChaiUnavailableException, PwmUnrecoverableException
     {
-        final boolean publicAccessEnabled = pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.PEOPLE_SEARCH_ENABLE_PUBLIC);
-        if (!publicAccessEnabled) {
-            if (!pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.PEOPLE_SEARCH_ENABLE)) {
-                pwmRequest.respondWithError(new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE));
+        if (!pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.PEOPLE_SEARCH_ENABLE)) {
+            pwmRequest.respondWithError(new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE));
+            return;
+        }
+
+        if (pwmRequest.getURL().isPublicUrl()) {
+            if (!pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.PEOPLE_SEARCH_ENABLE_PUBLIC)) {
+                pwmRequest.respondWithError(new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE,"public peoplesearch service is not enabled"));
                 return;
             }
-
+        } else {
             if (!pwmRequest.getPwmSession().getSessionManager().checkPermission(pwmRequest.getPwmApplication(), Permission.PEOPLE_SEARCH)) {
                 pwmRequest.respondWithError(new ErrorInformation(PwmError.ERROR_UNAUTHORIZED));
                 return;
             }
-        }
 
+        }
         final int peopleSearchIdleTimeout = (int)pwmRequest.getConfig().readSettingAsLong(PwmSetting.PEOPLE_SEARCH_IDLE_TIMEOUT_SECONDS);
         if (peopleSearchIdleTimeout > 0 && pwmRequest.getURL().isPrivateUrl()) {
             pwmRequest.getPwmSession().setSessionTimeout(pwmRequest.getHttpServletRequest().getSession(), peopleSearchIdleTimeout);
@@ -393,7 +417,8 @@ public class PeopleSearchServlet extends PwmServlet {
     private void restSearchRequest(
             final PwmRequest pwmRequest
     )
-            throws ChaiUnavailableException, PwmUnrecoverableException, IOException, ServletException {
+            throws ChaiUnavailableException, PwmUnrecoverableException, IOException, ServletException
+    {
         final Date startTime = new Date();
         final String bodyString = pwmRequest.readRequestBodyAsString();
         final Map<String, String> valueMap = JsonUtil.deserializeStringMap(bodyString);
@@ -403,43 +428,42 @@ public class PeopleSearchServlet extends PwmServlet {
         final CacheKey cacheKey = CacheKey.makeCacheKey(
                 this.getClass(),
                 useProxy ? null : pwmRequest.getPwmSession().getUserInfoBean().getUserIdentity(),
-                "search-" + SecureHelper.hash(username, SecureHelper.HashAlgorithm.SHA1)
-        );
+                "search-" + SecureHelper.hash(username, SecureHelper.HashAlgorithm.SHA1));
+
         {
             final String cachedOutput = pwmRequest.getPwmApplication().getCacheService().get(cacheKey);
             if (cachedOutput != null) {
-                final HashMap<String, Object> resultOutput = JsonUtil.deserialize(cachedOutput,
-                        new TypeToken<HashMap<String, Object>>() {}
-                );
+                final SearchResultBean resultOutput = JsonUtil.deserialize(cachedOutput, SearchResultBean.class);
                 final RestResultBean restResultBean = new RestResultBean();
-                restResultBean.setData(new LinkedHashMap<>(resultOutput));
-                pwmRequest.outputJsonResult(restResultBean);
-                LOGGER.trace(pwmRequest.getPwmSession(), "finished rest peoplesearch search using CACHE in " + TimeDuration.fromCurrent(
-                        startTime).asCompactString() + ", size=" + resultOutput.size());
-
-                if (pwmRequest.getPwmApplication().getStatisticsManager() != null) {
-                    pwmRequest.getPwmApplication().getStatisticsManager().incrementValue(Statistic.PEOPLESEARCH_SEARCHES);
-                }
+                pwmRequest.outputJsonResult(new RestResultBean(restResultBean));
+                LOGGER.trace(pwmRequest, "finished rest peoplesearch search using CACHE in "
+                        + TimeDuration.fromCurrent(startTime).asCompactString()
+                        + ", size=" + resultOutput.getSearchResults().size());
 
                 return;
             }
         }
 
-        final List<FormConfiguration> searchForm = pwmRequest.getConfig().readSettingAsForm(
-                PwmSetting.PEOPLE_SEARCH_RESULT_FORM);
-        final int maxResults = (int) pwmRequest.getConfig().readSettingAsLong(
-                PwmSetting.PEOPLE_SEARCH_RESULT_LIMIT);
+        final SearchResultBean outputData = makeSearchResultsImpl(pwmRequest, username);
+        final RestResultBean restResultBean = new RestResultBean(outputData);
+        pwmRequest.outputJsonResult(restResultBean);
+        storeDataInCache(pwmRequest.getPwmApplication(), cacheKey, outputData);
+    }
+
+    private SearchResultBean makeSearchResultsImpl(
+            final PwmRequest pwmRequest,
+            final String username
+    )
+            throws ChaiUnavailableException, PwmUnrecoverableException
+    {
+        final Date startTime = new Date();
 
         if (username == null || username.length() < 1) {
-            final HashMap<String, Object> emptyResults = new HashMap<>();
-            emptyResults.put("searchResults", new ArrayList<Map<String, String>>());
-            emptyResults.put("sizeExceeded", false);
-            final RestResultBean restResultBean = new RestResultBean();
-            restResultBean.setData(emptyResults);
-            pwmRequest.outputJsonResult(restResultBean);
-            return;
+            final SearchResultBean searchResultBean = new SearchResultBean();
+            return searchResultBean;
         }
 
+        final boolean useProxy = useProxy(pwmRequest.getPwmApplication(), pwmRequest.getPwmSession());
         final UserSearchEngine userSearchEngine = new UserSearchEngine(pwmRequest);
         final UserSearchEngine.SearchConfiguration searchConfiguration = new UserSearchEngine.SearchConfiguration();
         searchConfiguration.setContexts(
@@ -456,32 +480,30 @@ public class PeopleSearchServlet extends PwmServlet {
         final UserSearchEngine.UserSearchResults results;
         final boolean sizeExceeded;
         try {
+            final List<FormConfiguration> searchForm = pwmRequest.getConfig().readSettingAsForm(
+                    PwmSetting.PEOPLE_SEARCH_RESULT_FORM);
+            final int maxResults = (int) pwmRequest.getConfig().readSettingAsLong(
+                    PwmSetting.PEOPLE_SEARCH_RESULT_LIMIT);
             final Locale locale = pwmRequest.getLocale();
             results = userSearchEngine.performMultiUserSearchFromForm(locale, searchConfiguration, maxResults, searchForm);
             sizeExceeded = results.isSizeExceeded();
         } catch (PwmOperationalException e) {
             final ErrorInformation errorInformation = e.getErrorInformation();
             LOGGER.error(pwmRequest.getSessionLabel(), errorInformation.toDebugStr());
-            final RestResultBean restResultBean = new RestResultBean();
-            restResultBean.setData(new ArrayList<Map<String, String>>());
-            pwmRequest.outputJsonResult(restResultBean);
-            return;
+            throw new PwmUnrecoverableException(errorInformation);
         }
 
-        final LinkedHashMap<String, Object> outputData = new LinkedHashMap<>();
-        outputData.put("searchResults", new ArrayList<>(results.resultsAsJsonOutput(pwmRequest.getPwmApplication())));
-        outputData.put("sizeExceeded", sizeExceeded);
-
-        final RestResultBean restResultBean = new RestResultBean(outputData);
-        pwmRequest.outputJsonResult(restResultBean);
-        storeDataInCache(pwmRequest.getPwmApplication(), cacheKey, outputData);
-
         if (pwmRequest.getPwmApplication().getStatisticsManager() != null) {
             pwmRequest.getPwmApplication().getStatisticsManager().incrementValue(Statistic.PEOPLESEARCH_SEARCHES);
         }
 
         LOGGER.trace(pwmRequest.getPwmSession(), "finished rest peoplesearch search in " + TimeDuration.fromCurrent(
-                startTime).asCompactString() + " using CACHE, size=" + results.getResults().size());
+                startTime).asCompactString() + " not using cache, size=" + results.getResults().size());
+
+        final SearchResultBean searchResultBean = new SearchResultBean();
+        searchResultBean.setSearchResults(new ArrayList<>(results.resultsAsJsonOutput(pwmRequest.getPwmApplication())));
+        searchResultBean.setSizeExceeded(sizeExceeded);
+        return searchResultBean;
     }
 
     private static UserSearchEngine.UserSearchResults doDetailLookup(
@@ -567,6 +589,7 @@ public class PeopleSearchServlet extends PwmServlet {
     )
             throws PwmUnrecoverableException
     {
+        final Date startTime = new Date();
         final boolean useProxy = useProxy(pwmRequest.getPwmApplication(), pwmRequest.getPwmSession());
 
         final CacheKey cacheKey = CacheKey.makeCacheKey(
@@ -609,6 +632,7 @@ public class PeopleSearchServlet extends PwmServlet {
                 userTreeData.setSiblings(new ArrayList<>(sortedSiblings.values()));
             }
             storeDataInCache(pwmRequest.getPwmApplication(), cacheKey, userTreeData);
+            LOGGER.trace(pwmRequest, "completed building userTreeData in " + TimeDuration.fromCurrent(startTime).asCompactString());
             return userTreeData;
         } catch (ChaiException e) {
             throw new PwmUnrecoverableException(new ErrorInformation(PwmError.forChaiError(e.getErrorCode()),e.getMessage()));
@@ -709,9 +733,7 @@ public class PeopleSearchServlet extends PwmServlet {
             }
         }
 
-        LOGGER.debug(pwmRequest.getPwmSession(), "finished non-cached rest detail request in " + TimeDuration.fromCurrent(
-                startTime).asCompactString() + ", results=" + JsonUtil.serialize(userDetailBean));
-
+        LOGGER.trace(pwmRequest.getPwmSession(), "finished building userDetail result in " + TimeDuration.fromCurrent(startTime).asCompactString());
         storeDataInCache(pwmRequest.getPwmApplication(), cacheKey, userDetailBean);
         StatisticsManager.incrementStat(pwmRequest, Statistic.PEOPLESEARCH_SEARCHES);
         return userDetailBean;

+ 1 - 0
pwm/servlet/src/password/pwm/i18n/Config.properties

@@ -27,6 +27,7 @@ Button_Previous=Previous
 Button_CheckSettings=Check Settings
 Button_ShowAdvanced=Show %1% Advanced Settings
 Button_HideAdvanced=Hide Advanced Settings
+Confirm_RemoveProfile=Are you sure you want to remove the profile <code>%1%</code>?  The setting values associated with this profile will also be removed.
 Confirm_LockConfig=Are you sure you want to close the configuration?  After you close the configuration, you must authenticate using your LDAP directory credentials before authenticating, so be sure your LDAP configuration is working properly before closing.
 Confirm_SkipGuide=Are you sure you want to skip the configuration guide?
 Confirm_UploadConfig=Are you sure you wish to overwrite the current running configuration with the selected file?

+ 44 - 1
pwm/servlet/src/password/pwm/ldap/UserSearchEngine.java

@@ -557,8 +557,51 @@ public class UserSearchEngine {
 
         public UserSearchResults(Map<String, String> headerAttributeMap, Map<UserIdentity, Map<String, String>> results, boolean sizeExceeded) {
             this.headerAttributeMap = headerAttributeMap;
-            this.results = results;
+            this.results = Collections.unmodifiableMap(defaultSort(results, headerAttributeMap));
             this.sizeExceeded = sizeExceeded;
+
+        }
+
+        private static Map<UserIdentity, Map<String, String>> defaultSort(
+                final Map<UserIdentity, Map<String, String>> results,
+                final Map<String,String> headerAttributeMap
+        )
+        {
+            final Date startTime = new Date();
+            if (headerAttributeMap == null || headerAttributeMap.isEmpty() || results == null) {
+                return results;
+            }
+
+            final String sortAttribute = headerAttributeMap.keySet().iterator().next();
+            final Comparator<UserIdentity> comparator = new Comparator<UserIdentity>() {
+                @Override
+                public int compare(UserIdentity o1, UserIdentity o2) {
+                    final String s1 = getSortValueByIdentity(o1);
+                    final String s2 = getSortValueByIdentity(o2);
+                    return s1.compareTo(s2);
+                }
+
+                private String getSortValueByIdentity(final UserIdentity userIdentity) {
+                    final Map<String,String> valueMap = results.get(userIdentity);
+                    if (valueMap != null) {
+                        final String sortValue = valueMap.get(sortAttribute);
+                        if (sortValue != null) {
+                            return sortValue;
+                        }
+                    }
+                    return "";
+                }
+            };
+
+            final List<UserIdentity> identitySortMap = new ArrayList<>();
+            identitySortMap.addAll(results.keySet());
+            Collections.sort(identitySortMap,comparator);
+
+            final Map<UserIdentity, Map<String, String>> sortedResults = new LinkedHashMap<>();
+            for (final UserIdentity userIdentity : identitySortMap) {
+                sortedResults.put(userIdentity, results.get(userIdentity));
+            }
+            return sortedResults;
         }
 
         public Map<String, String> getHeaderAttributeMap() {

+ 2 - 1
pwm/servlet/src/password/pwm/util/cli/MainClass.java

@@ -357,7 +357,8 @@ public class MainClass {
                 .setApplicationPathType(MAIN_OPTIONS.applicationPathType)
                 .setInitLogging(false)
                 .setConfigurationFile(configurationFile)
-                .setWebInfPath(null).createPwmApplication();
+                .setWebInfPath(null)
+                .createPwmApplication();
         final PwmApplication.MODE runningMode = pwmApplication.getApplicationMode();
 
         if (runningMode != mode) {

+ 2 - 2
pwm/servlet/src/password/pwm/util/db/DatabaseAccessorImpl.java

@@ -777,7 +777,7 @@ public class DatabaseAccessorImpl implements PwmService, DatabaseAccessor {
     }
 
     public static class JdbcDriverClassLoader extends ClassLoader {
-
+        private static final String CLASS_FILE_SEPERATOR = "/";
         private final byte[] jdbcDriverJar;
 
         public JdbcDriverClassLoader(byte[] jdbcDriverJar) {
@@ -802,7 +802,7 @@ public class DatabaseAccessorImpl implements PwmService, DatabaseAccessor {
         private byte[] loadClassData(String name)
                 throws IOException
         {
-            final String literalFileName = name.replace(".",File.separator) + ".class";
+            final String literalFileName = name.replace(".", CLASS_FILE_SEPERATOR) + ".class";
             final JarInputStream jarInputStream = new JarInputStream(new ByteArrayInputStream(jdbcDriverJar));
             JarEntry jarEntry;
             while ((jarEntry = jarInputStream.getNextJarEntry()) != null) {

+ 73 - 0
pwm/servlet/web/WEB-INF/jsp/forgottenpassword-naaf.jsp

@@ -0,0 +1,73 @@
+<%--
+  ~ Password Management Servlets (PWM)
+  ~ http://code.google.com/p/pwm/
+  ~
+  ~ Copyright (c) 2006-2009 Novell, Inc.
+  ~ Copyright (c) 2009-2015 The PWM Project
+  ~
+  ~ This program is free software; you can redistribute it and/or modify
+  ~ it under the terms of the GNU General Public License as published by
+  ~ the Free Software Foundation; either version 2 of the License, or
+  ~ (at your option) any later version.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  ~ GNU General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU General Public License
+  ~ along with this program; if not, write to the Free Software
+  ~ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  --%>
+
+<!DOCTYPE html>
+<%@ page language="java" session="true" isThreadSafe="true" contentType="text/html; charset=UTF-8" %>
+<%@ page import="password.pwm.http.bean.ForgottenPasswordBean" %>
+<%@ taglib uri="pwm" prefix="pwm" %>
+<%@ include file="fragment/header.jsp" %>
+<html dir="<pwm:LocaleOrientation/>">
+<body class="nihilo">
+<div id="wrapper">
+    <jsp:include page="fragment/header-body.jsp">
+        <jsp:param name="pwm.PageName" value="Title_ForgottenPassword"/>
+    </jsp:include>
+    <div id="centerbody">
+        <%
+            final ForgottenPasswordBean fpb = JspUtility.getPwmSession(pageContext).getForgottenPasswordBean();
+        %>
+        <p>NAAF Auth</p>
+        <form action="<pwm:url url='ForgottenPassword'/>" method="post" enctype="application/x-www-form-urlencoded" name="search" class="pwm-form">
+            <%@ include file="/WEB-INF/jsp/fragment/message.jsp" %>
+            <h2>Input something!</h2>
+            <input type="text" pattern="[0-9]*" id="userinput" name="userinput" class="inputfield" required="required" autofocus/>
+            <div class="buttonbar">
+                <button type="submit" class="btn" name="search" id="submitBtn">
+                    <pwm:if test="showIcons"><span class="btn-icon fa fa-check"></span></pwm:if>
+                    <pwm:display key="Button_CheckCode"/>
+                </button>
+                <% if ("true".equals(JspUtility.getAttribute(pageContext, PwmConstants.REQUEST_ATTR.ForgottenPasswordOptionalPageView))) { %>
+                <button type="button" id="button-goBack" name="button-goBack" class="btn" >
+                    <pwm:if test="showIcons"><span class="btn-icon fa fa-backward"></span></pwm:if>
+                    <pwm:display key="Button_GoBack"/>
+                </button>
+                <% } %>
+                <%@ include file="/WEB-INF/jsp/fragment/button-reset.jsp" %>
+                <%@ include file="/WEB-INF/jsp/fragment/forgottenpassword-cancel.jsp" %>
+                <input type="hidden" id="processAction" name="processAction" value="enterOtp"/>
+                <input type="hidden" id="pwmFormID" name="pwmFormID" value="<pwm:FormID/>"/>
+            </div>
+        </form>
+    </div>
+    <div class="push"></div>
+</div>
+<pwm:script>
+    <script>
+        PWM_GLOBAL['startupFunctions'].push(function(){
+            PWM_MAIN.submitPostAction('button-goBack','ForgottenPassword','<%=ForgottenPasswordServlet.ForgottenPasswordAction.verificationChoice%>');
+        });
+    </script>
+</pwm:script>
+<%@ include file="fragment/footer.jsp" %>
+</body>
+</html>
+

+ 1 - 1
pwm/servlet/web/WEB-INF/jsp/setupotpsecret.jsp

@@ -93,13 +93,13 @@
             <form action="<pwm:url url='SetupOtp'/>" method="post" name="setupOtpSecret-skip"
                   enctype="application/x-www-form-urlencoded" id="setupOtpSecret-skip" class="pwm-form">
                 <input type="hidden" name="processAction" value="skip"/>
+                <input type="hidden" name="pwmFormID" value="<pwm:FormID/>"/>
                 <% if (forcedPageView) { %>
                 <% if (allowSkip) { %>
                 <button type="submit" name="continue" class="btn" id="skipbutton">
                     <pwm:if test="showIcons"><span class="btn-icon fa fa-fighter-jet"></span></pwm:if>
                     <pwm:display key="Button_Skip"/>
                 </button>
-                <input type="hidden" name="pwmFormID" value="<pwm:FormID/>"/>
                 <% } %>
                 <% } else { %>
                 <pwm:if test="showCancel">

+ 2 - 0
pwm/servlet/web/WEB-INF/web.xml

@@ -362,6 +362,8 @@
         <servlet-name>PeopleSearchServlet</servlet-name>
         <url-pattern>/private/PeopleSearch</url-pattern>
         <url-pattern>/public/PeopleSearch</url-pattern>
+        <url-pattern>/private/peoplesearch</url-pattern>
+        <url-pattern>/public/peoplesearch</url-pattern>
     </servlet-mapping>
     <servlet-mapping>
         <servlet-name>CaptchaServlet</servlet-name>

+ 2 - 1
pwm/servlet/web/public/resources/js/configeditor-settings.js

@@ -351,6 +351,7 @@ StringArrayValueHandler.arrayMoveUtil = function(arr, fromIndex, toIndex) {
 
 StringArrayValueHandler.removeValue = function(settingKey, iteration) {
     var syntax = PWM_SETTINGS['settings'][settingKey]['syntax'];
+    var profileName = PWM_VAR['clientSettingCache'][settingKey][iteration];
     var deleteFunction = function() {
         var currentValues = PWM_VAR['clientSettingCache'][settingKey];
         currentValues.splice(iteration,1);
@@ -358,7 +359,7 @@ StringArrayValueHandler.removeValue = function(settingKey, iteration) {
     };
     if (syntax == 'PROFILE') {
         PWM_MAIN.showConfirmDialog({
-            text:'Are you sure you want to remove the profile?',
+            text:PWM_CONFIG.showString('Confirm_RemoveProfile',{value1:profileName}),
             okAction:function(){
                 deleteFunction();
             }

+ 1 - 0
pwm/servlet/web/public/resources/js/configmanager.js

@@ -139,6 +139,7 @@ PWM_CONFIG.showString=function (key, options) {
     options = options === undefined ? {} : options;
     options['bundle'] = 'Config';
     return PWM_MAIN.showString(key,options);
+
 };
 
 PWM_CONFIG.openLogViewer=function(level) {

+ 9 - 5
pwm/servlet/web/public/resources/js/helpdesk.js

@@ -231,11 +231,9 @@ PWM_HELPDESK.processHelpdeskSearch = function() {
             var sizeExceeded = data['data']['sizeExceeded'];
             grid.refresh();
             grid.renderArray(gridData);
-            grid.on(".dgrid-row:click", function(evt){
-                var row = grid.row(evt);
-                PWM_HELPDESK.loadSearchDetails(row.data['userKey']);
-            });
-            grid.set("sort",1);
+            var sortState = grid.get("sort");
+            grid.set("sort", sortState);
+
             if (sizeExceeded) {
                 PWM_MAIN.getObject('maxResultsIndicator').style.display = 'inherit';
                 PWM_MAIN.showTooltip({id:'maxResultsIndicator',position:'below',text:PWM_MAIN.showString('Display_SearchResultsExceeded')})
@@ -269,6 +267,12 @@ PWM_HELPDESK.makeSearchGrid = function(nextAction) {
                 if (nextAction) {
                     nextAction();
                 }
+
+                PWM_VAR['heldesk_search_grid'].on(".dgrid-row:click", function(evt){
+                    var row = PWM_VAR['heldesk_search_grid'].row(evt);
+                    PWM_HELPDESK.loadSearchDetails(row.data['userKey']);
+                });
+
             });
     });
 };