jrivard před 10 roky
rodič
revize
a934f301f2

+ 33 - 0
pwm/servlet/src/password/pwm/config/PwmSetting.java

@@ -1258,5 +1258,38 @@ public enum PwmSetting {
 
 
         return sb.toString();
         return sb.toString();
     }
     }
+
+    public enum SettingStat {
+        Total,
+        hasProfile,
+        syntaxCounts,
+    }
+
+    public static Map<SettingStat, Object> getStats() {
+        final Map<SettingStat,Object> returnObj = new LinkedHashMap<>();
+        {
+            returnObj.put(SettingStat.Total,PwmSetting.values().length);
+        }
+        {
+            int hasProfile = 0;
+            for (final PwmSetting pwmSetting : values()) {
+                if (pwmSetting.getCategory().hasProfiles()) {
+                    hasProfile++;
+                }
+            }
+            returnObj.put(SettingStat.hasProfile,hasProfile);
+        }
+        {
+            final Map<PwmSettingSyntax,Integer> syntaxCounts = new LinkedHashMap<>();
+            for (final PwmSettingSyntax syntax : PwmSettingSyntax.values()) {
+                syntaxCounts.put(syntax,0);
+            }
+            for (final PwmSetting pwmSetting : values()) {
+                syntaxCounts.put(pwmSetting.getSyntax(), syntaxCounts.get(pwmSetting.getSyntax()) + 1);
+            }
+            returnObj.put(SettingStat.syntaxCounts, syntaxCounts);
+        }
+        return returnObj;
+    }
 }
 }
 
 

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

@@ -3173,7 +3173,7 @@
     </setting>
     </setting>
     <setting key="helpdesk.filter" level="1">
     <setting key="helpdesk.filter" level="1">
         <label>Helpdesk Search Filter</label>
         <label>Helpdesk Search Filter</label>
-        <description><![CDATA[LDAP search filter to query the directory with.  Substitute <i>%USERNAME%</i> for user supplied username.  If not specified, a search filter will be auto calculated based on the Helpdesk Search Form.<p>Examples<ul><li>Edirectory: (&(objectClass=Person)(|((cn=*%USERNAME%*)(uid=*%USERNAME%*)(givenName=*%USERNAME%*)(sn=*%USERNAME%*))))</li><li>Active Directory:(&(objectClass=Person)(|((cn=*%USERNAME%*)(uid=*%USERNAME%*)(sAMAccountName=*%USERNAME%*)(userprincipalname=*%USERNAME%*)(givenName=*%USERNAME%*)(sn=*%USERNAME%*))))</li></ul>]]></description>
+        <description><![CDATA[LDAP search filter to query the directory with.  Substitute <i>%USERNAME%</i> for user supplied username.  If not specified, a search filter will be auto calculated based on the Helpdesk Search Form.<p>Examples<ul><li>Edirectory: <pre>(&(objectClass=Person)(|((cn=*%USERNAME%*)(uid=*%USERNAME%*)(givenName=*%USERNAME%*)(sn=*%USERNAME%*))))</pre></li><li>Active Directory: <pre>(&(objectClass=Person)(|((cn=*%USERNAME%*)(uid=*%USERNAME%*)(sAMAccountName=*%USERNAME%*)(userprincipalname=*%USERNAME%*)(givenName=*%USERNAME%*)(sn=*%USERNAME%*))))</pre></li></ul>]]></description>
         <default/>
         <default/>
     </setting>
     </setting>
     <setting key="helpdesk.result.form" level="1" required="true">
     <setting key="helpdesk.result.form" level="1" required="true">

+ 1 - 1
pwm/servlet/src/password/pwm/i18n/Display.properties

@@ -136,7 +136,7 @@ Display_Seconds=seconds
 Display_SetupHelpdeskResponses=<p>Your administrator requires that you supply the following answers.  These answers are used to verify your identity in the event that you contact your helpdesk for assistance.</p>
 Display_SetupHelpdeskResponses=<p>Your administrator requires that you supply the following answers.  These answers are used to verify your identity in the event that you contact your helpdesk for assistance.</p>
 Display_SetupRandomResponses=
 Display_SetupRandomResponses=
 Display_SetupRequiredResponses=
 Display_SetupRequiredResponses=
-Display_SetupResponses=<p>In you forget your password, you can access your account by answering your security questions.</p><p>Please choose your questions and answers that can be used to verify your identity in case you forget your password.  Because the answers to these questions can be used to access your account, be sure to supply answers that are not easy for others to guess or discover.</p>
+Display_SetupResponses=<p>If you forget your password, you can access your account by answering your security questions.</p><p>Please choose your questions and answers that can be used to verify your identity in case you forget your password.  Because the answers to these questions can be used to access your account, be sure to supply answers that are not easy for others to guess or discover.</p>
 Display_SetupOtpSecret=If you forget your password, you can access your account by using your mobile device.  Follow the instructions below based on your device type.
 Display_SetupOtpSecret=If you forget your password, you can access your account by using your mobile device.  Follow the instructions below based on your device type.
 Display_SetupOtp_Android_Title=Android
 Display_SetupOtp_Android_Title=Android
 Display_SetupOtp_Android_Steps=<b>Install the Google Authenticator app for Android.</b><ol><li>On your phone, go to the Google Play Store.</li><li>Search for <b>Google Authenticator</b>.<br/>(<a target="playstore" href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2">Download from the Google Play Store</a>)</li><li>Download and install the application.</li></ol><b>Next, open and configure Google Authenticator.</b><ol><li>In Google Authenticator, touch Menu and select "Set up account."</li><li>Select "Scan a barcode."</li><li>Use your phone's camera to scan this barcode.</li><li>Once you have scanned the barcode, click the continue button.</li></ol>
 Display_SetupOtp_Android_Steps=<b>Install the Google Authenticator app for Android.</b><ol><li>On your phone, go to the Google Play Store.</li><li>Search for <b>Google Authenticator</b>.<br/>(<a target="playstore" href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2">Download from the Google Play Store</a>)</li><li>Download and install the application.</li></ol><b>Next, open and configure Google Authenticator.</b><ol><li>In Google Authenticator, touch Menu and select "Set up account."</li><li>Select "Scan a barcode."</li><li>Use your phone's camera to scan this barcode.</li><li>Once you have scanned the barcode, click the continue button.</li></ol>

+ 25 - 2
pwm/servlet/src/password/pwm/i18n/LocaleHelper.java

@@ -379,7 +379,7 @@ public class LocaleHelper {
             final Percent percent = new Percent(presentCount, totalCount);
             final Percent percent = new Percent(presentCount, totalCount);
             configLocaleStats.getDescription_percentLocalizations().put(locale, percent.pretty());
             configLocaleStats.getDescription_percentLocalizations().put(locale, percent.pretty());
         }
         }
-            return configLocaleStats;
+        return configLocaleStats;
     }
     }
 
 
     public static LocaleStats getStatsForBundles(final Collection<PwmLocaleBundle> bundles) {
     public static LocaleStats getStatsForBundles(final Collection<PwmLocaleBundle> bundles) {
@@ -489,7 +489,7 @@ public class LocaleHelper {
         }
         }
 
 
         private static List<Locale> knownLocales() {
         private static List<Locale> knownLocales() {
-            final List<Locale> knownLocales = new ArrayList();
+            final List<Locale> knownLocales = new ArrayList<>();
             try {
             try {
                 final StringArrayValue stringArrayValue = (StringArrayValue) PwmSetting.KNOWN_LOCALES.getDefaultValue(PwmSetting.Template.DEFAULT);
                 final StringArrayValue stringArrayValue = (StringArrayValue) PwmSetting.KNOWN_LOCALES.getDefaultValue(PwmSetting.Template.DEFAULT);
                 final List<String> rawValues = stringArrayValue.toNativeObject();
                 final List<String> rawValues = stringArrayValue.toNativeObject();
@@ -509,4 +509,27 @@ public class LocaleHelper {
             return new ArrayList<>(returnMap.values());
             return new ArrayList<>(returnMap.values());
         }
         }
     }
     }
+
+    public static Map<PwmLocaleBundle,Map<String,List<Locale>>> getModifiedKeysInConfig(final Configuration configuration) {
+        final Map<PwmLocaleBundle,Map<String,List<Locale>>> returnObj = new LinkedHashMap<>();
+        for (final PwmLocaleBundle pwmLocaleBundle : PwmLocaleBundle.values()) {
+            for (final String key : pwmLocaleBundle.getKeys()) {
+                for (final Locale locale : configuration.getKnownLocales()) {
+                    final String defaultValue = LocaleHelper.getLocalizedMessage(locale, key, null, pwmLocaleBundle.getTheClass());
+                    final String customizedValue = LocaleHelper.getLocalizedMessage(locale, key, configuration, pwmLocaleBundle.getTheClass());
+                    if (defaultValue != null && !defaultValue.equals(customizedValue)) {
+                        if (!returnObj.containsKey(pwmLocaleBundle)) {
+                            returnObj.put(pwmLocaleBundle,new LinkedHashMap<String, List<Locale>>());
+                        }
+                        if (!returnObj.get(pwmLocaleBundle).containsKey(key)) {
+                            returnObj.get(pwmLocaleBundle).put(key, new ArrayList<Locale>());
+                        }
+
+                        returnObj.get(pwmLocaleBundle).get(key).add(locale);
+                    }
+                }
+            }
+        }
+        return returnObj;
+    }
 }
 }

+ 3 - 3
pwm/servlet/src/password/pwm/i18n/PwmLocaleBundle.java

@@ -36,16 +36,16 @@ public enum PwmLocaleBundle {
     HEALTH(Health.class, true),
     HEALTH(Health.class, true),
     ;
     ;
 
 
-    private final Class theClass;
+    private final Class<? extends PwmDisplayBundle> theClass;
     private final boolean adminOnly;
     private final boolean adminOnly;
     private Set<String> keys = null;
     private Set<String> keys = null;
 
 
-    PwmLocaleBundle(final Class theClass, final boolean adminOnly) {
+    PwmLocaleBundle(final Class<? extends PwmDisplayBundle> theClass, final boolean adminOnly) {
         this.theClass = theClass;
         this.theClass = theClass;
         this.adminOnly = adminOnly;
         this.adminOnly = adminOnly;
     }
     }
 
 
-    public Class getTheClass() {
+    public Class<? extends PwmDisplayBundle> getTheClass() {
         return theClass;
         return theClass;
     }
     }
 
 

+ 6 - 1
pwm/servlet/src/password/pwm/util/cli/AbstractCliCommand.java

@@ -61,7 +61,12 @@ public abstract class AbstractCliCommand implements CliCommand  {
         }
         }
     }
     }
 
 
-    boolean promptForContinue() {
+    boolean promptForContinue(final String msg) {
+        if (cliEnvironment.getMainOptions().isForceFlag()) {
+            return true;
+        }
+        out(msg);
+        out("");
         out("To proceed, type 'continue'");
         out("To proceed, type 'continue'");
         final Scanner scanner = new Scanner(System.in);
         final Scanner scanner = new Scanner(System.in);
         final String input = scanner.nextLine();
         final String input = scanner.nextLine();

+ 5 - 6
pwm/servlet/src/password/pwm/util/cli/ClearResponsesCommand.java

@@ -30,12 +30,11 @@ public class ClearResponsesCommand extends AbstractCliCommand {
     void doCommand()
     void doCommand()
             throws Exception
             throws Exception
     {
     {
-        out("Proceeding with this operation will clear all stored responses from the LocalDB.");
-        out("Please consider exporting the responses before proceeding. ");
-        out("");
-        out("The application must be stopped for this operation to succeed.");
-        out("");
-        if (!promptForContinue()) {
+        final String msg = "Proceeding with this operation will clear all stored responses from the LocalDB." + "\n"
+                + "Please consider exporting the responses before proceeding. " + "\n"
+                + "\n"
+                + "The application must be stopped for this operation to succeed." + "\n";
+        if (!promptForContinue(msg)) {
             return;
             return;
         }
         }
 
 

+ 8 - 1
pwm/servlet/src/password/pwm/util/cli/CliEnvironment.java

@@ -40,6 +40,7 @@ public class CliEnvironment {
     final LocalDB localDB;
     final LocalDB localDB;
     final Writer debugWriter;
     final Writer debugWriter;
     final Map<String,Object> options;
     final Map<String,Object> options;
+    final MainClass.MainOptions mainOptions;
 
 
     public CliEnvironment(
     public CliEnvironment(
             ConfigurationReader configurationReader,
             ConfigurationReader configurationReader,
@@ -49,7 +50,8 @@ public class CliEnvironment {
             PwmApplication pwmApplication,
             PwmApplication pwmApplication,
             LocalDB localDB,
             LocalDB localDB,
             Writer debugWriter,
             Writer debugWriter,
-            Map<String, Object> options
+            Map<String, Object> options,
+            MainClass.MainOptions mainOptions
     )
     )
     {
     {
         this.configurationReader = configurationReader;
         this.configurationReader = configurationReader;
@@ -60,6 +62,7 @@ public class CliEnvironment {
         this.localDB = localDB;
         this.localDB = localDB;
         this.debugWriter = debugWriter;
         this.debugWriter = debugWriter;
         this.options = options;
         this.options = options;
+        this.mainOptions = mainOptions;
     }
     }
 
 
     public Configuration getConfig()
     public Configuration getConfig()
@@ -95,4 +98,8 @@ public class CliEnvironment {
     public ConfigurationReader getConfigurationReader() {
     public ConfigurationReader getConfigurationReader() {
         return configurationReader;
         return configurationReader;
     }
     }
+
+    public MainClass.MainOptions getMainOptions() {
+        return mainOptions;
+    }
 }
 }

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

@@ -35,7 +35,7 @@ public class ConfigDeleteCommand extends AbstractCliCommand {
         }
         }
 
 
 
 
-        if (!promptForContinue()) {
+        if (!promptForContinue("Proceeding will delete the existing configuration")) {
             return;
             return;
         }
         }
 
 

+ 5 - 11
pwm/servlet/src/password/pwm/util/cli/ImportLocalDBCommand.java

@@ -29,7 +29,6 @@ import password.pwm.util.localdb.LocalDBUtility;
 
 
 import java.io.File;
 import java.io.File;
 import java.util.Collections;
 import java.util.Collections;
-import java.util.Scanner;
 
 
 public class ImportLocalDBCommand extends AbstractCliCommand {
 public class ImportLocalDBCommand extends AbstractCliCommand {
     protected static final String INPUT_FILE_OPTIONNAME = "inputFile";
     protected static final String INPUT_FILE_OPTIONNAME = "inputFile";
@@ -41,16 +40,11 @@ public class ImportLocalDBCommand extends AbstractCliCommand {
         final Configuration config = cliEnvironment.getConfig();
         final Configuration config = cliEnvironment.getConfig();
         final LocalDB localDB = cliEnvironment.getLocalDB();
         final LocalDB localDB = cliEnvironment.getLocalDB();
 
 
-        out("Proceeding with this operation will clear ALL data from the LocalDB.");
-        out("Please consider backing up the LocalDB before proceeding. ");
-        out("");
-        out("The application must be stopped for this operation to succeed.");
-        out("");
-        out("To proceed, type 'continue'");
-        final Scanner scanner = new Scanner(System.in);
-        final String input = scanner.nextLine();
-
-        if (!"continue".equalsIgnoreCase(input)) {
+        final String msg = "Proceeding with this operation will clear ALL data from the LocalDB." + "\n"
+                + "Please consider backing up the LocalDB before proceeding. " + "\n"
+                + "\n"
+                + "The application must be stopped for this operation to succeed.";
+        if (!promptForContinue(msg)) {
             out("exiting...");
             out("exiting...");
             return;
             return;
         }
         }

+ 0 - 66
pwm/servlet/src/password/pwm/util/cli/IntegrityReportCommand.java

@@ -1,66 +0,0 @@
-/*
- * Password Management Servlets (PWM)
- * http://code.google.com/p/pwm/
- *
- * Copyright (c) 2006-2009 Novell, Inc.
- * Copyright (c) 2009-2014 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
- */
-
-package password.pwm.util.cli;
-
-import password.pwm.util.CodeIntegrityChecker;
-import password.pwm.util.TimeDuration;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.util.Collections;
-
-public class IntegrityReportCommand extends AbstractCliCommand {
-    @Override
-    void doCommand()
-            throws Exception
-    {
-        final File outputFile = (File)cliEnvironment.getOptions().get(CliParameters.REQUIRED_NEW_FILE.getName());
-        if (outputFile.exists()) {
-            out("outputFile '" + outputFile.getAbsolutePath() + "' already exists");
-            return;
-        }
-
-        final long startTime = System.currentTimeMillis();
-        out("beginning output to " + outputFile.getAbsolutePath());
-        final CodeIntegrityChecker codeIntegrityChecker = new CodeIntegrityChecker();
-        final FileWriter writer = new FileWriter(outputFile,true);
-        writer.write(codeIntegrityChecker.asPrettyJsonOutput());
-        writer.close();
-        out("completed operation in " + TimeDuration.fromCurrent(startTime).asLongString());
-
-    }
-
-    @Override
-    public CliParameters getCliParameters()
-    {
-        CliParameters cliParameters = new CliParameters();
-        cliParameters.commandName = "IntegrityReport";
-        cliParameters.description = "Dump code integrity report (useful only for developers)";
-        cliParameters.options = Collections.singletonList(CliParameters.REQUIRED_NEW_FILE);
-
-        cliParameters.needsLocalDB = true;
-        cliParameters.readOnly = true;
-
-        return cliParameters;
-    }
-}

+ 30 - 5
pwm/servlet/src/password/pwm/util/cli/MainClass.java

@@ -67,7 +67,6 @@ public class MainClass {
         commandList.add(new ClearResponsesCommand());
         commandList.add(new ClearResponsesCommand());
         commandList.add(new ImportResponsesCommand());
         commandList.add(new ImportResponsesCommand());
         commandList.add(new TokenInfoCommand());
         commandList.add(new TokenInfoCommand());
-        commandList.add(new IntegrityReportCommand());
         commandList.add(new ConfigNewCommand());
         commandList.add(new ConfigNewCommand());
         commandList.add(new VersionCommand());
         commandList.add(new VersionCommand());
         commandList.add(new LdapSchemaExtendCommand());
         commandList.add(new LdapSchemaExtendCommand());
@@ -98,6 +97,15 @@ public class MainClass {
             output.append("       ").append(command.getCliParameters().description);
             output.append("       ").append(command.getCliParameters().description);
             output.append("\n");
             output.append("\n");
         }
         }
+        output.append("\n");
+        output.append("options:\n");
+        output.append(" -force                force operations skipping any confirmation\n");
+        output.append(" -debugLevel=x         set the debug level where x is TRACE, DEBUG, INFO, WARN or FATAL\n");
+        output.append(" -applicationPath=x    set the application path, default is current path\n");
+        output.append("\n");
+        output.append("usage: \n");
+        output.append(" command[.bat/.sh] <options> CommandName <command options>");
+
         return output.toString();
         return output.toString();
     }
     }
 
 
@@ -130,7 +138,8 @@ public class MainClass {
                 pwmApplication,
                 pwmApplication,
                 localDB,
                 localDB,
                 new OutputStreamWriter(System.out),
                 new OutputStreamWriter(System.out),
-                options
+                options,
+                MAIN_OPTIONS
         );
         );
     }
     }
 
 
@@ -220,9 +229,8 @@ public class MainClass {
                     final List<String> argList = new LinkedList<>(Arrays.asList(args));
                     final List<String> argList = new LinkedList<>(Arrays.asList(args));
                     argList.remove(0);
                     argList.remove(0);
 
 
-                    CliEnvironment cliEnvironment;
                     try {
                     try {
-                        cliEnvironment = createEnv(command.getCliParameters(), argList);
+                        final CliEnvironment cliEnvironment = createEnv(command.getCliParameters(), argList);
                         command.execute(commandStr, cliEnvironment);
                         command.execute(commandStr, cliEnvironment);
                     } catch (CliException e) {
                     } catch (CliException e) {
                         System.out.println(e.getMessage());
                         System.out.println(e.getMessage());
@@ -240,6 +248,7 @@ public class MainClass {
     static String[] parseCommandOptions(String[] args) {
     static String[] parseCommandOptions(String[] args) {
         final String OPT_DEBUG_LEVEL = "-debugLevel";
         final String OPT_DEBUG_LEVEL = "-debugLevel";
         final String OPT_APP_PATH = "-applicationPath";
         final String OPT_APP_PATH = "-applicationPath";
+        final String OPT_FORCE = "-force";
 
 
         if (args == null || args.length < 1) {
         if (args == null || args.length < 1) {
             return args;
             return args;
@@ -278,6 +287,8 @@ public class MainClass {
                         }
                         }
                         MAIN_OPTIONS.applicationPath = pathValue;
                         MAIN_OPTIONS.applicationPath = pathValue;
                     }
                     }
+                } else if (arg.equals(OPT_FORCE)) {
+                    MAIN_OPTIONS.forceFlag = true;
                 } else {
                 } else {
                     outputArgs.add(arg);
                     outputArgs.add(arg);
                 }
                 }
@@ -290,6 +301,7 @@ public class MainClass {
         if (logLevel == null) {
         if (logLevel == null) {
             Logger.getRootLogger().removeAllAppenders();
             Logger.getRootLogger().removeAllAppenders();
             Logger.getRootLogger().addAppender(new NullAppender());
             Logger.getRootLogger().addAppender(new NullAppender());
+            PwmLogger.markInitialized();
             return;
             return;
         }
         }
 
 
@@ -353,9 +365,22 @@ public class MainClass {
         System.out.println(txt + "\n");
         System.out.println(txt + "\n");
     }
     }
 
 
-    private static class MainOptions {
+    public static class MainOptions {
         private PwmLogLevel pwmLogLevel = null;
         private PwmLogLevel pwmLogLevel = null;
         private File applicationPath = null;
         private File applicationPath = null;
+        private boolean forceFlag = false;
+
+        public PwmLogLevel getPwmLogLevel() {
+            return pwmLogLevel;
+        }
+
+        public File getApplicationPath() {
+            return applicationPath;
+        }
+
+        public boolean isForceFlag() {
+            return forceFlag;
+        }
     }
     }
 
 
     private static void exitWithError(final String msg) {
     private static void exitWithError(final String msg) {

+ 91 - 72
pwm/servlet/web/WEB-INF/jsp/configmanager-summary.jsp

@@ -1,5 +1,8 @@
+<%@ page import="password.pwm.config.Configuration" %>
 <%@ page import="password.pwm.error.PwmException" %>
 <%@ page import="password.pwm.error.PwmException" %>
 <%@ page import="password.pwm.http.JspUtility" %>
 <%@ page import="password.pwm.http.JspUtility" %>
+<%@ page import="password.pwm.i18n.LocaleHelper" %>
+<%@ page import="password.pwm.i18n.PwmLocaleBundle" %>
 <%@ page import="password.pwm.util.StringUtil" %>
 <%@ page import="password.pwm.util.StringUtil" %>
 <%@ page import="java.util.*" %>
 <%@ page import="java.util.*" %>
 <%--
 <%--
@@ -33,15 +36,16 @@
 
 
     settingData.addAll((List<Map<String,String>>)outputData.get("settings"));
     settingData.addAll((List<Map<String,String>>)outputData.get("settings"));
   } catch (PwmException e) {
   } catch (PwmException e) {
-        /* noop */
+          /* noop */
   }
   }
 %>
 %>
 <!DOCTYPE html>
 <!DOCTYPE html>
 <%@ page language="java" session="true" isThreadSafe="true" contentType="text/html; charset=UTF-8" %>
 <%@ page language="java" session="true" isThreadSafe="true" contentType="text/html; charset=UTF-8" %>
 <%@ taglib uri="pwm" prefix="pwm" %>
 <%@ taglib uri="pwm" prefix="pwm" %>
+<% JspUtility.setFlag(pageContext, PwmRequest.Flag.HIDE_HEADER_WARNINGS); %>
 <% JspUtility.setFlag(pageContext, PwmRequest.Flag.HIDE_THEME); %>
 <% JspUtility.setFlag(pageContext, PwmRequest.Flag.HIDE_THEME); %>
+<% JspUtility.setFlag(pageContext, PwmRequest.Flag.NO_REQ_COUNTER); %>
 <% JspUtility.setFlag(pageContext, PwmRequest.Flag.HIDE_HEADER_BUTTONS); %>
 <% JspUtility.setFlag(pageContext, PwmRequest.Flag.HIDE_HEADER_BUTTONS); %>
-<% JspUtility.setFlag(pageContext, PwmRequest.Flag.HIDE_HEADER_WARNINGS); %>
 <% JspUtility.setFlag(pageContext, PwmRequest.Flag.HIDE_FOOTER_TEXT); %>
 <% JspUtility.setFlag(pageContext, PwmRequest.Flag.HIDE_FOOTER_TEXT); %>
 <html dir="<pwm:LocaleOrientation/>">
 <html dir="<pwm:LocaleOrientation/>">
 <%@ include file="fragment/header.jsp" %>
 <%@ include file="fragment/header.jsp" %>
@@ -58,86 +62,101 @@
       </div>
       </div>
       <div>
       <div>
         Current Time: <span class="timestamp"><%=PwmConstants.DEFAULT_DATETIME_FORMAT.format(new Date())%></span>
         Current Time: <span class="timestamp"><%=PwmConstants.DEFAULT_DATETIME_FORMAT.format(new Date())%></span>
-      <br/>
+        <br/>
         Configuration Template: <%=outputData.get("template")%>
         Configuration Template: <%=outputData.get("template")%>
         <br/>
         <br/>
         <br/>
         <br/>
         <span class="footnote">Only settings modified from their default value are shown.</span>
         <span class="footnote">Only settings modified from their default value are shown.</span>
       </div>
       </div>
-      
-    </div>
-    <br/>
-    <% for (final Map<String,String> record : settingData) { %>
-    <table style="width:800px">
-      <col class="key" style="width:100px">
-      <col style="max-width: 700px; overflow: auto">
-      <tr>
-        <td>
-          Title
-        </td>
-        <td>
-          <%=record.get("label")%>
-        </td>
-      </tr>
-      <% if (record.containsKey("profile")) { %>
-      <tr>
-        <td>
-          Profile
-        </td>
-        <td>
-          <div>
-            <%=StringUtil.escapeHtml(record.get("profile"))%>
-          </div>
-        </td>
-      </tr>
+
+      <br/>
+      <% for (final Map<String,String> record : settingData) { %>
+      <table style="width:800px">
+        <col class="key" style="width:100px">
+        <col style="max-width: 700px; overflow: auto">
+        <tr>
+          <td>
+            Title
+          </td>
+          <td>
+            <%=record.get("label")%>
+          </td>
+        </tr>
+        <% if (record.containsKey("profile")) { %>
+        <tr>
+          <td>
+            Profile
+          </td>
+          <td>
+            <div>
+              <%=StringUtil.escapeHtml(record.get("profile"))%>
+            </div>
+          </td>
+        </tr>
+        <% } %>
+        <% if (record.containsKey("modifyTime")) { %>
+        <tr>
+          <td>
+            Modify Time
+          </td>
+          <td>
+            <div>
+              <span class="timestamp"><%=StringUtil.escapeHtml(record.get("modifyTime"))%></span>
+            </div>
+          </td>
+        </tr>
+        <% } %>
+        <% if (record.containsKey("modifyUser")) { %>
+        <tr>
+          <td>
+            Modified by
+          </td>
+          <td>
+            <div>
+              <%=StringUtil.escapeHtml(record.get("modifyUser"))%>
+            </div>
+          </td>
+        </tr>
+        <% } %>
+        <tr>
+          <td>
+            Value
+          </td>
+          <td>
+            <div>
+              <pre style="white-space: pre-wrap"><%=StringUtil.escapeHtml(record.get("value"))%></pre>
+            </div>
+          </td>
+        </tr>
+      </table>
+      <br/>
+      <br/>
       <% } %>
       <% } %>
-      <% if (record.containsKey("modifyTime")) { %>
-      <tr>
-        <td>
-          Modify Time
-        </td>
-        <td>
-          <div>
-            <span class="timestamp"><%=StringUtil.escapeHtml(record.get("modifyTime"))%></span>
-          </div>
-        </td>
-      </tr>
+      <% final Configuration pwmConfig = JspUtility.getPwmRequest(pageContext).getConfig(); %>
+      <% Map<PwmLocaleBundle,Map<String,List<Locale>>> modifiedKeys = LocaleHelper.getModifiedKeysInConfig(pwmConfig); %>
+      <% if (modifiedKeys != null && !modifiedKeys.isEmpty()) { %>
+      <% for (final PwmLocaleBundle pwmLocaleBundle : modifiedKeys.keySet()) { %>
+      <% for (final String key : modifiedKeys.get(pwmLocaleBundle).keySet()) { %>
+      <table style="width: 800px">
+        <tr>
+          <td colspan="5"><%=pwmLocaleBundle.getTheClass().getSimpleName()%> - <%= key%></td>
+        </tr>
+        <% for (final Locale locale : modifiedKeys.get(pwmLocaleBundle).get(key)) { %>
+        <tr>
+          <td class="key"><%=LocaleHelper.debugLabel(locale)%></td>
+          <td><%=LocaleHelper.getLocalizedMessage(locale,key,pwmConfig,pwmLocaleBundle.getTheClass())%></td>
+        </tr>
+        <% } %>
+      </table>
+      <br/>
       <% } %>
       <% } %>
-      <% if (record.containsKey("modifyUser")) { %>
-      <tr>
-        <td>
-          Modified by
-        </td>
-        <td>
-          <div>
-            <%=StringUtil.escapeHtml(record.get("modifyUser"))%>
-          </div>
-        </td>
-      </tr>
       <% } %>
       <% } %>
-      <tr>
-        <td>
-          Value
-        </td>
-        <td>
-          <div>
-            <pre style="white-space: pre-wrap"><%=StringUtil.escapeHtml(record.get("value"))%></pre>
-          </div>
-        </td>
-      </tr>
-    </table>
-    <br/>
-    <% } %>
+      <% } %>
+    </div>
   </div>
   </div>
-  <div class="push"></div>
 </div>
 </div>
-<pwm:script>
-  <script type="text/javascript">
-    PWM_GLOBAL['startupFunctions'].push(function(){
-      PWM_GLOBAL['idle_suspendTimeout'] = true;
-    });
-  </script>
-</pwm:script>
+<div class="push"></div>
+</div>
 <%@ include file="/WEB-INF/jsp/fragment/footer.jsp" %>
 <%@ include file="/WEB-INF/jsp/fragment/footer.jsp" %>
 </body>
 </body>
 </html>
 </html>

+ 1 - 1
pwm/servlet/web/public/reference/localeinfo.jsp

@@ -40,7 +40,7 @@
             LocaleHelper.parseLocaleString("en"),
             LocaleHelper.parseLocaleString("en"),
             LocaleHelper.parseLocaleString("fr"),
             LocaleHelper.parseLocaleString("fr"),
             LocaleHelper.parseLocaleString("zh_tw"),
             LocaleHelper.parseLocaleString("zh_tw"),
-            LocaleHelper.parseLocaleString("ge"),
+            LocaleHelper.parseLocaleString("de"),
             LocaleHelper.parseLocaleString("ja"),
             LocaleHelper.parseLocaleString("ja"),
             LocaleHelper.parseLocaleString("pt_BR"),
             LocaleHelper.parseLocaleString("pt_BR"),
             LocaleHelper.parseLocaleString("es"),
             LocaleHelper.parseLocaleString("es"),

+ 36 - 0
pwm/servlet/web/public/reference/referencedoc.jsp

@@ -70,6 +70,9 @@
                 <% } %>
                 <% } %>
                 <% } %>
                 <% } %>
             </ol>
             </ol>
+            <% if (pwmRequest.readParameterAsBoolean("advanced")) { %>
+            <li><a href="#settingSummary">Setting Summary</a></li>
+            <% } %>
             <li><a href="#displayStrings">Display Strings</a></li>
             <li><a href="#displayStrings">Display Strings</a></li>
             <ol>
             <ol>
                 <% for (PwmLocaleBundle bundle : PwmLocaleBundle.values()) { %>
                 <% for (PwmLocaleBundle bundle : PwmLocaleBundle.values()) { %>
@@ -315,6 +318,39 @@
         <% } %>
         <% } %>
         <% } %>
         <% } %>
         <% } %>
         <% } %>
+        <% if (pwmRequest.readParameterAsBoolean("advanced")) { %>
+        <h2><a id="settingSummary">Setting Summary</a></h2>
+        <% Map<PwmSetting.SettingStat,Object> settingStats = PwmSetting.getStats(); %>
+        <table>
+            <tr>
+                <td class="key">
+                    Total Settings
+                </td>
+                <td>
+                    <%= settingStats.get(PwmSetting.SettingStat.Total) %>
+                </td>
+            </tr>
+            <tr>
+                <td class="key">
+                    Settings that are part of a Profile
+                </td>
+                <td>
+                    <%= settingStats.get(PwmSetting.SettingStat.hasProfile) %>
+                </td>
+            </tr>
+            <% Map<PwmSettingSyntax,Integer> syntaxCounts = (Map<PwmSettingSyntax,Integer>)settingStats.get(PwmSetting.SettingStat.syntaxCounts); %>
+            <% for (final PwmSettingSyntax loopSyntax : syntaxCounts.keySet()) { %>
+            <tr>
+                <td class="key" style="width: auto; white-space: nowrap">
+                    Settings with syntax type <%= loopSyntax.toString() %>
+                </td>
+                <td>
+                    <%= syntaxCounts.get(loopSyntax) %>
+                </td>
+            </tr>
+            <% } %>
+        </table>
+        <% } %>
         <h1><a id="displayStrings">Display Strings</a></h1>
         <h1><a id="displayStrings">Display Strings</a></h1>
         <% for (PwmLocaleBundle bundle : PwmLocaleBundle.values()) { %>
         <% for (PwmLocaleBundle bundle : PwmLocaleBundle.values()) { %>
         <h2>
         <h2>

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

@@ -2026,7 +2026,7 @@ ChallengeSettingHandler.editLocale = function(keyName, localeKey) {
                     dialogBody += ' onchange="PWM_VAR[\'clientSettingCache\'][\'' + keyName + '\'][\'' + localeKey + '\'][\'' + rowKey + '\'][\'maxQuestionCharsInAnswer\'] = this.value"/><br/> Max Question Chars';
                     dialogBody += ' onchange="PWM_VAR[\'clientSettingCache\'][\'' + keyName + '\'][\'' + localeKey + '\'][\'' + rowKey + '\'][\'maxQuestionCharsInAnswer\'] = this.value"/><br/> Max Question Chars';
 
 
                     dialogBody += '</td><td style="padding-bottom: 15px; border:0">';
                     dialogBody += '</td><td style="padding-bottom: 15px; border:0">';
-                    dialogBody += '<label class="checkboxWrapper"><input type="checkbox" id="value-wordlist-' + inputID + '" disabled/>Wordlist</label>';
+                    dialogBody += '<label class="checkboxWrapper"><input type="checkbox" id="value-wordlist-' + inputID + '" disabled/>Apply Wordlist</label>';
 
 
                     dialogBody += '</td></tr>';
                     dialogBody += '</td></tr>';
                     dialogBody += '</table></td><td style="border:0; vertical-align: top">';
                     dialogBody += '</table></td><td style="border:0; vertical-align: top">';
@@ -2069,10 +2069,10 @@ ChallengeSettingHandler.editLocale = function(keyName, localeKey) {
 
 
                         // admin defined checkbox
                         // admin defined checkbox
                         PWM_MAIN.getObject('value-adminDefined-' + inputID).disabled = false;
                         PWM_MAIN.getObject('value-adminDefined-' + inputID).disabled = false;
-                        PWM_MAIN.getObject('value-adminDefined-' + inputID).checked = !multiValues[rowKey]['adminDefined'];
+                        PWM_MAIN.getObject('value-adminDefined-' + inputID).checked = multiValues[rowKey]['adminDefined'];
                         PWM_MAIN.addEventHandler('value-adminDefined-' + inputID,'change',function(){
                         PWM_MAIN.addEventHandler('value-adminDefined-' + inputID,'change',function(){
                             var checked = PWM_MAIN.getObject('value-adminDefined-' + inputID).checked;
                             var checked = PWM_MAIN.getObject('value-adminDefined-' + inputID).checked;
-                            multiValues[rowKey]['adminDefined'] = !checked;
+                            multiValues[rowKey]['adminDefined'] = checked;
                             processQuestion();
                             processQuestion();
                         });
                         });