Bladeren bron

whitespace reformating

Jason Rivard 7 jaren geleden
bovenliggende
commit
6d44f8d87a
66 gewijzigde bestanden met toevoegingen van 7780 en 5744 verwijderingen
  1. 21 22
      onejar/src/main/java/password/pwm/Argument.java
  2. 128 79
      onejar/src/main/java/password/pwm/ArgumentParser.java
  3. 1 1
      onejar/src/main/java/password/pwm/ArgumentParserException.java
  4. 6 6
      onejar/src/main/java/password/pwm/Resource.java
  5. 3 2
      onejar/src/main/java/password/pwm/TomcatConfig.java
  6. 3 2
      onejar/src/main/java/password/pwm/TomcatOneJarException.java
  7. 81 56
      onejar/src/main/java/password/pwm/TomcatOneJarMain.java
  8. 1 1
      server/pom.xml
  9. 294 286
      server/src/main/java/password/pwm/AppProperty.java
  10. 488 331
      server/src/main/java/password/pwm/PwmApplication.java
  11. 1 0
      server/src/main/java/password/pwm/PwmEnvironment.java
  12. 4 3
      server/src/main/java/password/pwm/bean/TelemetryPublishBean.java
  13. 488 492
      server/src/main/java/password/pwm/config/PwmSetting.java
  14. 17 11
      server/src/main/java/password/pwm/config/function/SMSGatewayCertImportFunction.java
  15. 4 1
      server/src/main/java/password/pwm/config/option/ConfigurationOption.java
  16. 2 1
      server/src/main/java/password/pwm/config/option/SyslogOutputFormat.java
  17. 3 2
      server/src/main/java/password/pwm/health/LDAPStatusChecker.java
  18. 112 80
      server/src/main/java/password/pwm/http/PwmResponse.java
  19. 180 120
      server/src/main/java/password/pwm/http/filter/ConfigAccessFilter.java
  20. 29 17
      server/src/main/java/password/pwm/http/filter/GZIPFilter.java
  21. 417 279
      server/src/main/java/password/pwm/http/filter/RequestInitializationFilter.java
  22. 374 277
      server/src/main/java/password/pwm/http/servlet/ActivateUserServlet.java
  23. 1 1
      server/src/main/java/password/pwm/http/servlet/ClientApiServlet.java
  24. 118 95
      server/src/main/java/password/pwm/http/servlet/ForgottenUsernameServlet.java
  25. 369 289
      server/src/main/java/password/pwm/http/servlet/UpdateProfileServlet.java
  26. 398 309
      server/src/main/java/password/pwm/http/servlet/configeditor/ConfigEditorServlet.java
  27. 472 342
      server/src/main/java/password/pwm/http/servlet/forgottenpw/ForgottenPasswordServlet.java
  28. 70 52
      server/src/main/java/password/pwm/http/servlet/forgottenpw/ForgottenPasswordUtil.java
  29. 142 100
      server/src/main/java/password/pwm/http/servlet/helpdesk/HelpdeskDetailInfoBean.java
  30. 377 295
      server/src/main/java/password/pwm/http/servlet/helpdesk/HelpdeskServlet.java
  31. 328 245
      server/src/main/java/password/pwm/http/servlet/newuser/NewUserUtils.java
  32. 1 0
      server/src/main/java/password/pwm/http/servlet/oauth/OAuthConsumerServlet.java
  33. 1 0
      server/src/main/java/password/pwm/http/servlet/oauth/OAuthRequestState.java
  34. 6 1
      server/src/main/java/password/pwm/http/servlet/peoplesearch/PeopleSearchClientConfigBean.java
  35. 1 0
      server/src/main/java/password/pwm/http/servlet/resource/ResourceFileServlet.java
  36. 3 2
      server/src/main/java/password/pwm/http/tag/PasswordRequirementsTag.java
  37. 1 2
      server/src/main/java/password/pwm/i18n/PwmSetting.java
  38. 30 20
      server/src/main/java/password/pwm/ldap/PwmLdapVendor.java
  39. 1 0
      server/src/main/java/password/pwm/ldap/ViewableUserInfoDisplayReader.java
  40. 1 0
      server/src/main/java/password/pwm/svc/event/HelpdeskAuditRecord.java
  41. 218 153
      server/src/main/java/password/pwm/svc/event/SyslogAuditService.java
  42. 1 0
      server/src/main/java/password/pwm/svc/event/UserAuditRecord.java
  43. 1 0
      server/src/main/java/password/pwm/svc/intruder/IntruderManager.java
  44. 1 0
      server/src/main/java/password/pwm/svc/report/ReportSummaryData.java
  45. 28 15
      server/src/main/java/password/pwm/svc/sessiontrack/UserAgentUtils.java
  46. 157 117
      server/src/main/java/password/pwm/svc/telemetry/TelemetryService.java
  47. 367 256
      server/src/main/java/password/pwm/svc/token/TokenService.java
  48. 29 29
      server/src/main/java/password/pwm/svc/wordlist/AbstractWordlist.java
  49. 7 5
      server/src/main/java/password/pwm/svc/wordlist/Populator.java
  50. 4 4
      server/src/main/java/password/pwm/svc/wordlist/SeedlistManager.java
  51. 2 2
      server/src/main/java/password/pwm/svc/wordlist/WordlistManager.java
  52. 1 0
      server/src/main/java/password/pwm/util/LDAPPermissionCalculator.java
  53. 2 0
      server/src/main/java/password/pwm/util/PwmPasswordRuleValidator.java
  54. 293 204
      server/src/main/java/password/pwm/util/RandomPasswordGenerator.java
  55. 1 0
      server/src/main/java/password/pwm/util/cli/CliEnvironment.java
  56. 255 183
      server/src/main/java/password/pwm/util/cli/MainClass.java
  57. 278 176
      server/src/main/java/password/pwm/util/db/DatabaseAccessorImpl.java
  58. 1 0
      server/src/main/java/password/pwm/util/form/FormUtility.java
  59. 187 116
      server/src/main/java/password/pwm/util/java/JsonUtil.java
  60. 3 0
      server/src/main/java/password/pwm/util/logging/PwmLogEvent.java
  61. 379 270
      server/src/main/java/password/pwm/util/operations/PasswordUtility.java
  62. 240 171
      server/src/main/java/password/pwm/util/queue/SmsQueueManager.java
  63. 2 2
      server/src/main/java/password/pwm/util/secure/SecureEngine.java
  64. 255 152
      server/src/main/java/password/pwm/ws/server/RestServlet.java
  65. 90 67
      server/src/main/java/password/pwm/ws/server/rest/RestRandomPasswordServer.java
  66. 1 0
      server/src/main/java/password/pwm/ws/server/rest/RestStatisticsServer.java

+ 21 - 22
onejar/src/main/java/password/pwm/Argument.java

@@ -17,66 +17,65 @@ enum Argument
     port,
     context,
     properties,
-    localAddress,
+    localAddress,;
 
-    ;
-
-    static Options asOptions()
+    static Options asOptions( )
     {
         final Options options = new Options();
         asOptionMap().values().forEach( options::addOption );
         return options;
     }
 
-    static Map<Argument,Option> asOptionMap() {
-        final Map<Argument,Option> optionMap = new TreeMap<>(  );
+    static Map<Argument, Option> asOptionMap( )
+    {
+        final Map<Argument, Option> optionMap = new TreeMap<>();
 
-        optionMap.put(Argument.applicationPath, Option.builder(Argument.applicationPath.name()  )
+        optionMap.put( Argument.applicationPath, Option.builder( Argument.applicationPath.name() )
                 .desc( "application path (required)" )
                 .numberOfArgs( 1 )
-                .build());
+                .build() );
 
-        optionMap.put(Argument.workPath, Option.builder(Argument.workPath.name() )
+        optionMap.put( Argument.workPath, Option.builder( Argument.workPath.name() )
                 .desc( "temporary work path" )
                 .numberOfArgs( 1 )
-                .build());
+                .build() );
 
-        optionMap.put(Argument.version, Option.builder(Argument.version.name()  )
+        optionMap.put( Argument.version, Option.builder( Argument.version.name() )
                 .desc( "show version" )
                 .numberOfArgs( 0 )
-                .build());
+                .build() );
 
-        optionMap.put(Argument.port, Option.builder( Argument.port.name() )
+        optionMap.put( Argument.port, Option.builder( Argument.port.name() )
                 .desc( "web server port (default " + Resource.defaultPort.getValue() + ")" )
                 .numberOfArgs( 1 )
                 .build() );
 
-        optionMap.put(Argument.localAddress, Option.builder( Argument.localAddress.name() )
+        optionMap.put( Argument.localAddress, Option.builder( Argument.localAddress.name() )
                 .desc( "local network address (default localhost)" )
                 .numberOfArgs( 1 )
                 .build() );
 
-        optionMap.put(Argument.context, Option.builder(Argument.context.name() )
+        optionMap.put( Argument.context, Option.builder( Argument.context.name() )
                 .desc( "context (url path) name (default " + Resource.defaultContext.getValue() + ")" )
                 .numberOfArgs( 1 )
                 .build() );
 
-        optionMap.put(Argument.help, Option.builder(Argument.help.name())
+        optionMap.put( Argument.help, Option.builder( Argument.help.name() )
                 .desc( "show this help" )
                 .numberOfArgs( 0 )
-                .build());
+                .build() );
 
-        optionMap.put(Argument.properties, Option.builder(Argument.properties.name())
+        optionMap.put( Argument.properties, Option.builder( Argument.properties.name() )
                 .desc( "read arguments from properties file" )
                 .numberOfArgs( 1 )
-                .build());
+                .build() );
 
-        optionMap.put(Argument.war, Option.builder(Argument.war.name())
+        optionMap.put( Argument.war, Option.builder( Argument.war.name() )
                 .desc( "source war file (default embedded)" )
                 .numberOfArgs( 1 )
-                .build());
+                .build() );
 
-        return Collections.unmodifiableMap(optionMap);
+        return Collections.unmodifiableMap( optionMap );
     }
 
 }

+ 128 - 79
onejar/src/main/java/password/pwm/ArgumentParser.java

@@ -23,41 +23,59 @@ public class ArgumentParser
 {
     private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 
-    public TomcatConfig parseArguments(final String[] args)
+    public TomcatConfig parseArguments( final String[] args )
             throws ArgumentParserException, TomcatOneJarException
     {
-        if (args == null || args.length == 0) {
+        if ( args == null || args.length == 0 )
+        {
             ArgumentParser.outputHelp();
-        } else {
+        }
+        else
+        {
             final CommandLine commandLine;
 
-            try {
+            try
+            {
                 commandLine = new DefaultParser().parse( Argument.asOptions(), args );
-            } catch ( ParseException e ) {
-                throw new ArgumentParserException( "unable to parse command line: " + e.getMessage());
+            }
+            catch ( ParseException e )
+            {
+                throw new ArgumentParserException( "unable to parse command line: " + e.getMessage() );
             }
 
-            if ( commandLine.hasOption( Argument.version.name() ) ) {
+            if ( commandLine.hasOption( Argument.version.name() ) )
+            {
                 TomcatOneJarMain.out( TomcatOneJarMain.getVersion() );
                 return null;
-            } else if ( commandLine.hasOption( Argument.help.name() ) ) {
+            }
+            else if ( commandLine.hasOption( Argument.help.name() ) )
+            {
                 ArgumentParser.outputHelp();
                 return null;
-            } else {
+            }
+            else
+            {
                 final Map<Argument, String> argumentMap;
-                if (commandLine.hasOption( Argument.properties.name())) {
-                    if (args.length > 2) {
+                if ( commandLine.hasOption( Argument.properties.name() ) )
+                {
+                    if ( args.length > 2 )
+                    {
                         throw new ArgumentParserException( Argument.properties.name() + " must be the only argument specified" );
                     }
                     final String filename = commandLine.getOptionValue( Argument.properties.name() );
                     argumentMap = mapFromProperties( filename );
-                } else {
+                }
+                else
+                {
                     argumentMap = mapFromCommandLine( commandLine );
                 }
                 final TomcatConfig tomcatConfig;
-                try {
+                try
+                {
                     tomcatConfig = makeTomcatConfig( argumentMap );
-                } catch ( IOException e ) {
+                }
+                catch ( IOException e )
+                {
                     throw new ArgumentParserException( "error while reading input: " + e.getMessage() );
                 }
                 return tomcatConfig;
@@ -67,21 +85,27 @@ public class ArgumentParser
         return null;
     }
 
-    private Map<Argument,String> mapFromProperties(final String filename) throws ArgumentParserException
+    private Map<Argument, String> mapFromProperties( final String filename ) throws ArgumentParserException
     {
         final Properties props = new Properties();
-        try {
-            props.load(new FileInputStream( new File( filename) ));
-        } catch ( IOException e ) {
-            throw new ArgumentParserException( "unable to read properties input file: " + e.getMessage());
+        try
+        {
+            props.load( new FileInputStream( new File( filename ) ) );
+        }
+        catch ( IOException e )
+        {
+            throw new ArgumentParserException( "unable to read properties input file: " + e.getMessage() );
         }
 
-        final Map<Argument,String> map = new HashMap<>(  );
-        for (final Option option : Argument.asOptionMap().values()) {
-            if (option.hasArg()) {
+        final Map<Argument, String> map = new HashMap<>();
+        for ( final Option option : Argument.asOptionMap().values() )
+        {
+            if ( option.hasArg() )
+            {
                 final Argument argument = Argument.valueOf( option.getOpt() );
                 final String value = props.getProperty( argument.name() );
-                if (value != null) {
+                if ( value != null )
+                {
                     map.put( argument, value );
                 }
             }
@@ -89,22 +113,26 @@ public class ArgumentParser
         return Collections.unmodifiableMap( map );
     }
 
-    private Map<Argument,String> mapFromCommandLine(final CommandLine commandLine) {
-        final Map<Argument,String> map = new HashMap<>(  );
-        for (final Option option : Argument.asOptionMap().values()) {
-            if (option.hasArg()) {
-                if (commandLine.hasOption( option.getOpt() )) {
+    private Map<Argument, String> mapFromCommandLine( final CommandLine commandLine )
+    {
+        final Map<Argument, String> map = new HashMap<>();
+        for ( final Option option : Argument.asOptionMap().values() )
+        {
+            if ( option.hasArg() )
+            {
+                if ( commandLine.hasOption( option.getOpt() ) )
+                {
                     final Argument argument = Argument.valueOf( option.getOpt() );
                     final String value = commandLine.getOptionValue( option.getOpt() );
                     map.put( argument, value );
                 }
             }
         }
-        return Collections.unmodifiableMap(map);
+        return Collections.unmodifiableMap( map );
     }
 
 
-    private TomcatConfig makeTomcatConfig( final Map<Argument,String> argumentMap) throws IOException, ArgumentParserException
+    private TomcatConfig makeTomcatConfig( final Map<Argument, String> argumentMap ) throws IOException, ArgumentParserException
     {
         final TomcatConfig tomcatConfig = new TomcatConfig();
         tomcatConfig.setKeystorePass( genRandomString( 32 ) );
@@ -112,49 +140,62 @@ public class ArgumentParser
 
         tomcatConfig.setContext( argumentMap.getOrDefault( Argument.context, Resource.defaultContext.getValue() ) );
 
-        if (argumentMap.containsKey( Argument.war )) {
-            final File inputWarFile = new File ( argumentMap.get( Argument.war ));
-            if (!inputWarFile.exists()) {
+        if ( argumentMap.containsKey( Argument.war ) )
+        {
+            final File inputWarFile = new File( argumentMap.get( Argument.war ) );
+            if ( !inputWarFile.exists() )
+            {
                 System.out.println( "output war file " + inputWarFile.getAbsolutePath() + "does not exist" );
                 System.exit( -1 );
                 return null;
             }
             tomcatConfig.setWar( new FileInputStream( inputWarFile ) );
-        } else {
+        }
+        else
+        {
             tomcatConfig.setWar( getEmbeddedWar() );
         }
 
         tomcatConfig.setPort( Integer.parseInt( Resource.defaultPort.getValue() ) );
-        if (argumentMap.containsKey( Argument.port )) {
-            try {
+        if ( argumentMap.containsKey( Argument.port ) )
+        {
+            try
+            {
                 tomcatConfig.setPort( Integer.parseInt( argumentMap.get( Argument.port ) ) );
-            } catch (NumberFormatException e) {
-                System.out.println( Argument.port.name()  + " argument must be numeric" );
+            }
+            catch ( NumberFormatException e )
+            {
+                System.out.println( Argument.port.name() + " argument must be numeric" );
                 System.exit( -1 );
             }
         }
 
         tomcatConfig.setLocalAddress( argumentMap.getOrDefault( Argument.localAddress, Resource.defaultLocalAddress.getValue() ) );
 
-        try {
-            final ServerSocket socket = new ServerSocket(tomcatConfig.getPort(), 100, InetAddress.getByName( tomcatConfig.getLocalAddress() ));
+        try
+        {
+            final ServerSocket socket = new ServerSocket( tomcatConfig.getPort(), 100, InetAddress.getByName( tomcatConfig.getLocalAddress() ) );
             socket.close();
-        } catch(Exception e) {
+        }
+        catch ( Exception e )
+        {
             throw new ArgumentParserException( "port or address conflict: " + e.getMessage() );
         }
 
-        if (argumentMap.containsKey( Argument.workPath )) {
-            tomcatConfig.setWorkingPath( parseFileOption( argumentMap, Argument.workPath   ) );
-        } else {
-            tomcatConfig.setWorkingPath( figureDefaultWorkPath( tomcatConfig) );
+        if ( argumentMap.containsKey( Argument.workPath ) )
+        {
+            tomcatConfig.setWorkingPath( parseFileOption( argumentMap, Argument.workPath ) );
+        }
+        else
+        {
+            tomcatConfig.setWorkingPath( figureDefaultWorkPath( tomcatConfig ) );
         }
 
         return tomcatConfig;
     }
 
 
-
-    private static void outputHelp() throws TomcatOneJarException
+    private static void outputHelp( ) throws TomcatOneJarException
     {
         final HelpFormatter formatter = new HelpFormatter();
         System.out.println( TomcatOneJarMain.getVersion() );
@@ -163,48 +204,52 @@ public class ArgumentParser
                 System.console().writer(),
                 HelpFormatter.DEFAULT_WIDTH,
                 Argument.asOptions(),
-                3 ,
-                8);
+                3,
+                8 );
     }
 
 
-    private static File parseFileOption(final Map<Argument,String> argumentMap, final Argument argName) throws ArgumentParserException
+    private static File parseFileOption( final Map<Argument, String> argumentMap, final Argument argName ) throws ArgumentParserException
     {
-        if (!argumentMap.containsKey( argName )) {
-            throw new ArgumentParserException( "option " + argName + " required");
+        if ( !argumentMap.containsKey( argName ) )
+        {
+            throw new ArgumentParserException( "option " + argName + " required" );
         }
-        final File file = new File(argumentMap.get( argName ));
-        if (!file.isAbsolute()) {
-            throw new ArgumentParserException( "a fully qualified file path name is required for " + argName);
+        final File file = new File( argumentMap.get( argName ) );
+        if ( !file.isAbsolute() )
+        {
+            throw new ArgumentParserException( "a fully qualified file path name is required for " + argName );
         }
-        if (!file.exists()) {
-            throw new ArgumentParserException( "path specified by " + argName + " must exist");
+        if ( !file.exists() )
+        {
+            throw new ArgumentParserException( "path specified by " + argName + " must exist" );
         }
         return file;
     }
 
-    private static File figureDefaultWorkPath(final TomcatConfig tomcatConfig) throws ArgumentParserException
+    private static File figureDefaultWorkPath( final TomcatConfig tomcatConfig ) throws ArgumentParserException
     {
         final String userHomePath = System.getProperty( "user.home" );
-        if (userHomePath != null && !userHomePath.isEmpty()) {
-            final File basePath = new File(userHomePath + File.separator
-                    + Resource.defaultWorkPathName.getValue());
+        if ( userHomePath != null && !userHomePath.isEmpty() )
+        {
+            final File basePath = new File( userHomePath + File.separator
+                    + Resource.defaultWorkPathName.getValue() );
             basePath.mkdir();
 
             final String workPath;
             {
-                String s = basePath.getPath() + File.separator + "work"
+                String workPathStr = basePath.getPath() + File.separator + "work"
                         + "-"
                         + escapeFilename( tomcatConfig.getContext() )
                         + "-"
                         + escapeFilename( Integer.toString( tomcatConfig.getPort() ) );
 
-                if (tomcatConfig.getLocalAddress() != null && !tomcatConfig.getLocalAddress().isEmpty()) {
-                    s += "-"
-                            + escapeFilename( tomcatConfig.getLocalAddress() );
+                if ( tomcatConfig.getLocalAddress() != null && !tomcatConfig.getLocalAddress().isEmpty() )
+                {
+                    workPathStr += "-" + escapeFilename( tomcatConfig.getLocalAddress() );
 
                 }
-                workPath = s;
+                workPath = workPathStr;
             }
             final File workFile = new File( workPath );
             workFile.mkdirs();
@@ -215,27 +260,31 @@ public class ArgumentParser
         throw new ArgumentParserException( "cant locate user home directory" );
     }
 
-    private static InputStream getEmbeddedWar() throws IOException, ArgumentParserException
+    private static InputStream getEmbeddedWar( ) throws IOException, ArgumentParserException
     {
         final Class clazz = TomcatOneJarMain.class;
         final String className = clazz.getSimpleName() + ".class";
-        final String classPath = clazz.getResource(className).toString();
-        if (!classPath.startsWith("jar")) {
-            throw new ArgumentParserException("not running from war, war option must be specified");
+        final String classPath = clazz.getResource( className ).toString();
+        if ( !classPath.startsWith( "jar" ) )
+        {
+            throw new ArgumentParserException( "not running from war, war option must be specified" );
         }
-        final String warPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) +
-                "/" + Resource.defaultWarFileName.getValue();
-        return new URL(warPath).openStream();
+        final String warPath = classPath.substring( 0, classPath.lastIndexOf( "!" ) + 1 )
+                + "/" + Resource.defaultWarFileName.getValue();
+        return new URL( warPath ).openStream();
     }
 
-    private static String escapeFilename(final String input) {
-        return input.replaceAll("\\W+", "_");
+    private static String escapeFilename( final String input )
+    {
+        return input.replaceAll( "\\W+", "_" );
     }
 
-    private static String genRandomString( final int length) {
-        final SecureRandom secureRandom = new SecureRandom(  );
-        final StringBuilder stringBuilder = new StringBuilder(  );
-        while (stringBuilder.length() < length) {
+    private static String genRandomString( final int length )
+    {
+        final SecureRandom secureRandom = new SecureRandom();
+        final StringBuilder stringBuilder = new StringBuilder();
+        while ( stringBuilder.length() < length )
+        {
             stringBuilder.append( ALPHABET.charAt( secureRandom.nextInt( ALPHABET.length() ) ) );
         }
         return stringBuilder.toString();

+ 1 - 1
onejar/src/main/java/password/pwm/ArgumentParserException.java

@@ -4,6 +4,6 @@ public class ArgumentParserException extends Exception
 {
     public ArgumentParserException( final String msg )
     {
-        super(msg);
+        super( msg );
     }
 }

+ 6 - 6
onejar/src/main/java/password/pwm/Resource.java

@@ -8,16 +8,16 @@ enum Resource
     defaultWorkPathName,
     defaultPort,
     defaultLocalAddress,
-    defaultWarFileName,
+    defaultWarFileName,;
 
-    ;
-
-    String getValue() {
+    String getValue()
+    {
         return readResource( this );
     }
 
-    private static String readResource(final Resource resource) {
-        final ResourceBundle bundle = ResourceBundle.getBundle(Resource.class.getName());
+    private static String readResource( final Resource resource )
+    {
+        final ResourceBundle bundle = ResourceBundle.getBundle( Resource.class.getName() );
         return bundle.getString( resource.name() );
     }
 

+ 3 - 2
onejar/src/main/java/password/pwm/TomcatConfig.java

@@ -3,7 +3,8 @@ package password.pwm;
 import java.io.File;
 import java.io.InputStream;
 
-class TomcatConfig {
+class TomcatConfig
+{
     private int port;
     private File applicationPath;
     private File workingPath;
@@ -77,7 +78,7 @@ class TomcatConfig {
         return keystorePass;
     }
 
-    public void setKeystorePass( String keystorePass )
+    public void setKeystorePass( final String keystorePass )
     {
         this.keystorePass = keystorePass;
     }

+ 3 - 2
onejar/src/main/java/password/pwm/TomcatOneJarException.java

@@ -2,7 +2,8 @@ package password.pwm;
 
 public class TomcatOneJarException extends Exception
 {
-    public TomcatOneJarException(final String msg) {
-        super(msg);
+    public TomcatOneJarException( final String msg )
+    {
+        super( msg );
     }
 }

+ 81 - 56
onejar/src/main/java/password/pwm/TomcatOneJarMain.java

@@ -33,38 +33,48 @@ public class TomcatOneJarMain
     //private static final String TEMP_WAR_FILE_NAME = "embed.war";
     private static final String KEYSTORE_ALIAS = "https";
 
-    public static void main(final String[] args)
+    public static void main( final String[] args )
     {
         final ArgumentParser argumentParser = new ArgumentParser();
         TomcatConfig tomcatConfig = null;
-        try {
+        try
+        {
             tomcatConfig = argumentParser.parseArguments( args );
-        } catch ( ArgumentParserException | TomcatOneJarException e ) {
-            out("error parsing command line: " + e.getMessage());
         }
-        if (tomcatConfig != null) {
-            try {
+        catch ( ArgumentParserException | TomcatOneJarException e )
+        {
+            out( "error parsing command line: " + e.getMessage() );
+        }
+        if ( tomcatConfig != null )
+        {
+            try
+            {
                 startTomcat( tomcatConfig );
-            } catch ( TomcatOneJarException | ServletException | IOException e ) {
-                out("error starting tomcat: " + e.getMessage());
+            }
+            catch ( TomcatOneJarException | ServletException | IOException e )
+            {
+                out( "error starting tomcat: " + e.getMessage() );
             }
         }
     }
 
-    private static File getWarFolder(final TomcatConfig tomcatConfig) throws IOException {
-        return new File(tomcatConfig.getWorkingPath().getAbsoluteFile() + File.separator + "war");
+    private static File getWarFolder( final TomcatConfig tomcatConfig ) throws IOException
+    {
+        return new File( tomcatConfig.getWorkingPath().getAbsoluteFile() + File.separator + "war" );
     }
 
-    private static File getKeystoreFile( final TomcatConfig tomcatConfig ) {
-        return new File(tomcatConfig.getWorkingPath().getAbsoluteFile() + File.separator + "keystore");
+    private static File getKeystoreFile( final TomcatConfig tomcatConfig )
+    {
+        return new File( tomcatConfig.getWorkingPath().getAbsoluteFile() + File.separator + "keystore" );
     }
 
-    private static File getPwmAppPropertiesFile( final TomcatConfig tomcatConfig ) {
-        return new File(tomcatConfig.getWorkingPath().getAbsoluteFile() + File.separator + "application.properties");
+    private static File getPwmAppPropertiesFile( final TomcatConfig tomcatConfig )
+    {
+        return new File( tomcatConfig.getWorkingPath().getAbsoluteFile() + File.separator + "application.properties" );
     }
 
 
-    private static void explodeWar( final TomcatConfig tomcatConfig) throws IOException
+    private static void explodeWar( final TomcatConfig tomcatConfig ) throws IOException
     {
         final InputStream warSource = tomcatConfig.getWar();
         final ZipInputStream zipInputStream = new ZipInputStream( warSource );
@@ -73,11 +83,13 @@ public class TomcatOneJarMain
 
         ZipEntry zipEntry = zipInputStream.getNextEntry();
 
-        while( zipEntry!=null ) {
+        while ( zipEntry != null )
+        {
             final String fileName = zipEntry.getName();
             final File newFile = new File( outputFolder + File.separator + fileName );
 
-            if (!zipEntry.isDirectory()) {
+            if ( !zipEntry.isDirectory() )
+            {
                 newFile.getParentFile().mkdirs();
                 Files.copy( zipInputStream, newFile.toPath() );
             }
@@ -86,7 +98,7 @@ public class TomcatOneJarMain
 
     }
 
-    private static void startTomcat( final TomcatConfig tomcatConfig) throws ServletException, IOException, TomcatOneJarException
+    private static void startTomcat( final TomcatConfig tomcatConfig ) throws ServletException, IOException, TomcatOneJarException
     {
         final Instant startTime = Instant.now();
 
@@ -95,10 +107,13 @@ public class TomcatOneJarMain
         explodeWar( tomcatConfig );
         out( "deployed war" );
 
-        try {
+        try
+        {
             generatePwmKeystore( tomcatConfig );
-            out("keystore generated");
-        } catch ( Exception e ) {
+            out( "keystore generated" );
+        }
+        catch ( Exception e )
+        {
             throw new TomcatOneJarException( "error generating keystore: " + e.getMessage() );
         }
 
@@ -126,19 +141,22 @@ public class TomcatOneJarMain
         }
 
 
-        tomcat.getHost().setAutoDeploy(false);
-        tomcat.getHost().setDeployOnStartup(false);
+        tomcat.getHost().setAutoDeploy( false );
+        tomcat.getHost().setDeployOnStartup( false );
 
         final String warPath = getWarFolder( tomcatConfig ).getAbsolutePath();
         tomcat.addWebapp( "/" + tomcatConfig.getContext(), warPath );
 
-        try {
+        try
+        {
             tomcat.start();
 
             tomcat.setConnector( makeConnector( tomcatConfig ) );
 
-            out("tomcat started in " + Duration.between( Instant.now(), startTime ).toString());
-        } catch (LifecycleException e) {
+            out( "tomcat started in " + Duration.between( Instant.now(), startTime ).toString() );
+        }
+        catch ( LifecycleException e )
+        {
             throw new TomcatOneJarException( "unable to start tomcat: " + e.getMessage() );
         }
 
@@ -147,11 +165,12 @@ public class TomcatOneJarMain
         System.out.println( "\n" );
     }
 
-    private static Connector makeConnector(final TomcatConfig tomcatConfig) {
-        final Connector connector = new Connector("HTTP/1.1");
-        connector.setPort(tomcatConfig.getPort());
+    private static Connector makeConnector( final TomcatConfig tomcatConfig )
+    {
+        final Connector connector = new Connector( "HTTP/1.1" );
+        connector.setPort( tomcatConfig.getPort() );
 
-        if (tomcatConfig.getLocalAddress() != null && !tomcatConfig.getLocalAddress().isEmpty())
+        if ( tomcatConfig.getLocalAddress() != null && !tomcatConfig.getLocalAddress().isEmpty() )
         {
             connector.setProperty( "address", tomcatConfig.getLocalAddress() );
         }
@@ -161,7 +180,7 @@ public class TomcatOneJarMain
         connector.setAttribute( "keystoreFile", getKeystoreFile( tomcatConfig ).getAbsolutePath() );
         connector.setAttribute( "keystorePass", tomcatConfig.getKeystorePass() );
         connector.setAttribute( "keyAlias", KEYSTORE_ALIAS );
-        connector.setAttribute( "clientAuth", "false");
+        connector.setAttribute( "clientAuth", "false" );
 
         return connector;
     }
@@ -173,53 +192,58 @@ public class TomcatOneJarMain
             final Class clazz = TomcatOneJarMain.class;
             final String className = clazz.getSimpleName() + ".class";
             final String classPath = clazz.getResource( className ).toString();
-            if ( !classPath.startsWith( "jar" ) ) {
+            if ( !classPath.startsWith( "jar" ) )
+            {
                 // Class not from JAR
                 return "version missing, not running inside jar";
             }
-            final String manifestPath = classPath.substring( 0, classPath.lastIndexOf( "!" ) + 1 ) +
-                    "/META-INF/MANIFEST.MF";
+            final String manifestPath = classPath.substring( 0, classPath.lastIndexOf( "!" ) + 1 )
+                    + "/META-INF/MANIFEST.MF";
             final Manifest manifest = new Manifest( new URL( manifestPath ).openStream() );
             final Attributes attr = manifest.getMainAttributes();
             return attr.getValue( "Implementation-Version-Display" )
                     + "  [" + ServerInfo.getServerInfo() + "]";
-        } catch (IOException e) {
-            throw new TomcatOneJarException("error reading internal version info: " + e.getMessage());
+        }
+        catch ( IOException e )
+        {
+            throw new TomcatOneJarException( "error reading internal version info: " + e.getMessage() );
         }
     }
 
-    private static void purgeDirectory(final Path rootPath)
+    private static void purgeDirectory( final Path rootPath )
             throws IOException
     {
-        System.out.println("purging work directory: " + rootPath);
-        Files.walk(rootPath, FileVisitOption.FOLLOW_LINKS)
-                .sorted( Comparator.reverseOrder())
-                .map(Path::toFile)
+        System.out.println( "purging work directory: " + rootPath );
+        Files.walk( rootPath, FileVisitOption.FOLLOW_LINKS )
+                .sorted( Comparator.reverseOrder() )
+                .map( Path::toFile )
                 .filter( file -> !rootPath.toString().equals( file.getPath() ) )
-                .forEach(File::delete);
+                .forEach( File::delete );
     }
 
 
-
-    static void out(final String output) {
+    static void out( final String output )
+    {
         System.out.println( output );
     }
 
 
-    static void generatePwmKeystore( final TomcatConfig tomcatConfig) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException
+    static void generatePwmKeystore( final TomcatConfig tomcatConfig )
+            throws IOException, ClassNotFoundException, IllegalAccessException, NoSuchMethodException, InvocationTargetException
     {
         final File warPath = getWarFolder( tomcatConfig );
         final String keystoreFile = getKeystoreFile( tomcatConfig ).getAbsolutePath();
-        final File webInfPath = new File(warPath.getAbsolutePath() + File.separator + "WEB-INF" + File.separator + "lib");
+        final File webInfPath = new File( warPath.getAbsolutePath() + File.separator + "WEB-INF" + File.separator + "lib" );
         final File[] jarFiles = webInfPath.listFiles();
-        final List<URL> jarURLList = new ArrayList<>(  );
-        for (final File jarFile : jarFiles) {
+        final List<URL> jarURLList = new ArrayList<>();
+        for ( final File jarFile : jarFiles )
+        {
             jarURLList.add( jarFile.toURI().toURL() );
         }
-        final URLClassLoader classLoader = URLClassLoader.newInstance( jarURLList.toArray( new URL[jarURLList.size()] ) );
+        final URLClassLoader classLoader = URLClassLoader.newInstance( jarURLList.toArray( new URL[ jarURLList.size() ] ) );
         final Class pwmMainClass = classLoader.loadClass( "password.pwm.util.cli.MainClass" );
         final Method mainMethod = pwmMainClass.getMethod( "main", String[].class );
-        final String[] arguments = new String[]{
+        final String[] arguments = new String[] {
                 "-applicationPath=" + tomcatConfig.getApplicationPath().getAbsolutePath(),
                 "ExportHttpsKeyStore",
                 keystoreFile,
@@ -227,22 +251,23 @@ public class TomcatOneJarMain
                 tomcatConfig.getKeystorePass(),
         };
 
-        mainMethod.invoke( null, (Object)arguments );
+        mainMethod.invoke( null, ( Object ) arguments );
         classLoader.close();
     }
 
-    static void setupEnv(final TomcatConfig tomcatConfig) {
+    static void setupEnv( final TomcatConfig tomcatConfig )
+    {
         System.setProperty( "PWM_APPLICATIONPATH", tomcatConfig.getApplicationPath().getAbsolutePath() );
         System.setProperty( "PWM_APPLICATIONFLAGS", "ManageHttps" );
         System.setProperty( "PWM_APPLICATIONPARAMFILE", getPwmAppPropertiesFile( tomcatConfig ).getAbsolutePath() );
     }
 
-    static void outputPwmAppProperties(final TomcatConfig tomcatConfig) throws IOException
+    static void outputPwmAppProperties( final TomcatConfig tomcatConfig ) throws IOException
     {
         final Properties properties = new Properties();
-        properties.setProperty( "AutoExportHttpsKeyStoreFile", getKeystoreFile( tomcatConfig ).getAbsolutePath());
-        properties.setProperty( "AutoExportHttpsKeyStorePassword", tomcatConfig.getKeystorePass());
-        properties.setProperty( "AutoExportHttpsKeyStoreAlias", KEYSTORE_ALIAS);
+        properties.setProperty( "AutoExportHttpsKeyStoreFile", getKeystoreFile( tomcatConfig ).getAbsolutePath() );
+        properties.setProperty( "AutoExportHttpsKeyStorePassword", tomcatConfig.getKeystorePass() );
+        properties.setProperty( "AutoExportHttpsKeyStoreAlias", KEYSTORE_ALIAS );
         final File propFile = getPwmAppPropertiesFile( tomcatConfig );
         properties.store( new FileWriter( propFile ), "auto-generated file" );
     }

+ 1 - 1
server/pom.xml

@@ -265,7 +265,7 @@
                     <dependency>
                         <groupId>com.puppycrawl.tools</groupId>
                         <artifactId>checkstyle</artifactId>
-                        <version>8.7</version>
+                        <version>8.8</version>
                     </dependency>
                 </dependencies>
                 <executions>

+ 294 - 286
server/src/main/java/password/pwm/AppProperty.java

@@ -29,298 +29,297 @@ import java.util.ResourceBundle;
  * by an associated {@code AppProperty.properties} file.  Properties can be overridden by the application administrator in
  * the configuration using the setting {@link password.pwm.config.PwmSetting#APP_PROPERTY_OVERRIDES}.
  */
-public enum AppProperty {
+public enum AppProperty
+{
 
-    APPLICATION_FILELOCK_FILENAME                   ("application.fileLock.filename"),
-    APPLICATION_FILELOCK_WAIT_SECONDS               ("application.fileLock.waitSeconds"),
-    APPLICATION_WORDLIST_RETRY_SECONDS              ("application.wordlistRetryImportSeconds"),
-    AUDIT_EVENTS_EMAILFROM                          ("audit.events.emailFrom"),
-    AUDIT_EVENTS_EMAILSUBJECT                       ("audit.events.emailSubject"),
-    AUDIT_EVENTS_LOCALDB_MAX_BULK_REMOVALS          ("audit.events.localdb.maxBulkRemovals"),
-    AUDIT_SYSLOG_MAX_MESSAGE_LENGTH                 ("audit.syslog.message.length"),
-    AUDIT_SYSLOG_TRUNCATE_MESSAGE                   ("audit.syslog.message.truncateMsg"),
-    BACKUP_LOCATION                                 ("backup.path"),
-    BACKUP_CONFIG_COUNT                             ("backup.config.count"),
-    BACKUP_LOCALDB_COUNT                            ("backup.localdb.count"),
-    CACHE_ENABLE                                    ("cache.enable"),
-    CACHE_MEMORY_MAX_ITEMS                          ("cache.memory.maxItems"),
-    CACHE_PWRULECHECK_LIFETIME_MS                   ("cache.pwRuleCheckLifetimeMS"),
-    CACHE_FORM_UNIQUE_VALUE_LIFETIME_MS             ("cache.uniqueFormValueLifetimeMS"),
-    CLIENT_ACTIVITY_MAX_EPS_RATE                    ("client.ajax.activityMaxEpsRate"),
-    CLIENT_AJAX_PW_WAIT_CHECK_SECONDS               ("client.ajax.changePasswordWaitCheckSeconds"),
-    CLIENT_AJAX_TYPING_TIMEOUT                      ("client.ajax.typingTimeout"),
-    CLIENT_AJAX_TYPING_WAIT                         ("client.ajax.typingWait"),
-    CLIENT_FORM_NONCE_ENABLE                        ("client.formNonce.enable"),
-    CLIENT_FORM_NONCE_LENGTH                        ("client.formNonce.length"),
-    CLIENT_FORM_CLIENT_REGEX_ENABLED                ("client.form.clientRegexEnable"),
-    CLIENT_WARNING_HEADER_SHOW                      ("client.warningHeader.show"),
-    CLIENT_PW_SHOW_REVERT_TIMEOUT                   ("client.pwShowRevertTimeout"),
-    CLIENT_JS_ENABLE_HTML5DIALOG                    ("client.js.enableHtml5Dialog"),
-    CLIENT_JSP_SHOW_ICONS                           ("client.jsp.showIcons"),
-    CONFIG_MAX_JDBC_JAR_SIZE                        ("config.maxJdbcJarSize"),
-    CONFIG_RELOAD_ON_CHANGE                         ("config.reloadOnChange"),
-    CONFIG_MAX_PERSISTENT_LOGIN_SECONDS             ("config.maxPersistentLoginSeconds"),
-    CONFIG_HISTORY_MAX_ITEMS                        ("config.login.history.maxEvents"),
-    CONFIG_FILE_SCAN_FREQUENCY                      ("config.fileScanFrequencyMS"),
-    CONFIG_NEWUSER_PASSWORD_POLICY_CACHE_MS         ("config.newuser.passwordPolicyCacheMS"),
-    CONFIG_THEME                                    ("config.theme"),
-    CONFIG_JBCRYPT_PWLIB_ENABLE                     ("config.enableJbCryptPwLibrary"),
-    CONFIG_EDITOR_BLOCK_OLD_IE                      ("configEditor.blockOldIE"),
-    CONFIG_EDITOR_QUERY_FILTER_TEST_LIMIT           ("configEditor.queryFilter.testLimit"),
-    CONFIG_EDITOR_IDLE_TIMEOUT                      ("configEditor.idleTimeoutSeconds"),
-    CONFIG_GUIDE_IDLE_TIMEOUT                       ("configGuide.idleTimeoutSeconds"),
-    CONFIG_MANAGER_ZIPDEBUG_MAXLOGLINES             ("configManager.zipDebug.maxLogLines"),
-    CONFIG_MANAGER_ZIPDEBUG_MAXLOGSECONDS           ("configManager.zipDebug.maxLogSeconds"),
-    CLUSTER_DB_ENABLE                               ("cluster.db.enable"),
-    CLUSTER_DB_HEARTBEAT_SECONDS                    ("cluster.db.heartbeatSeconds"),
-    CLUSTER_DB_NODE_TIMEOUT_SECONDS                 ("cluster.db.nodeTimeoutSeconds"),
-    CLUSTER_DB_NODE_PURGE_SECONDS                   ("cluster.db.nodePurgeSeconds"),
-    DB_JDBC_LOAD_STRATEGY                           ("db.jdbcLoadStrategy"),
-    DB_CONNECTIONS_MAX                              ("db.connections.max"),
-    DB_CONNECTIONS_TIMEOUT_MS                       ("db.connections.timeoutMs"),
-    DB_CONNECTIONS_WATCHDOG_FREQUENCY_SECONDS       ("db.connections.watchdogFrequencySeconds"),
-    DB_SCHEMA_KEY_LENGTH                            ("db.schema.keyLength"),
-    DOWNLOAD_FILENAME_STATISTICS_CSV                ("download.filename.statistics.csv"),
-    DOWNLOAD_FILENAME_USER_REPORT_SUMMARY_CSV       ("download.filename.reportSummary.csv"),
-    DOWNLOAD_FILENAME_USER_REPORT_RECORDS_CSV       ("download.filename.reportRecords.csv"),
-    DOWNLOAD_FILENAME_AUDIT_RECORDS_CSV             ("download.filename.auditRecords.csv"),
-    DOWNLOAD_FILENAME_LDAP_PERMISSION_CSV           ("download.filename.ldapPermission.csv"),
-    DOWNLOAD_FILENAME_USER_DEBUG_JSON               ("download.filename.userDebug.json"),
-    FORM_EMAIL_REGEX                                ("form.email.regexTest"),
-    HTTP_RESOURCES_MAX_CACHE_ITEMS                  ("http.resources.maxCacheItems"),
-    HTTP_RESOURCES_MAX_CACHE_BYTES                  ("http.resources.maxCacheBytes"),
-    HTTP_RESOURCES_EXPIRATION_SECONDS               ("http.resources.expirationSeconds"),
-    HTTP_RESOURCES_ENABLE_GZIP                      ("http.resources.gzip.enable"),
-    HTTP_RESOURCES_PATH_NONCE_LENGTH                ("http.resources.pathNonce.length"),
-    HTTP_RESOURCES_ENABLE_PATH_NONCE                ("http.resources.pathNonceEnable"),
-    HTTP_RESOURCES_NONCE_PATH_PREFIX                ("http.resources.pathNoncePrefix"),
-    HTTP_RESOURCES_ZIP_FILES                        ("http.resources.zipFiles"),
-    HTTP_COOKIE_DEFAULT_SECURE_FLAG                 ("http.cookie.default.secureFlag"),
-    HTTP_COOKIE_THEME_NAME                          ("http.cookie.theme.name"),
-    HTTP_COOKIE_THEME_AGE                           ("http.cookie.theme.age"),
-    HTTP_COOKIE_LOCALE_NAME                         ("http.cookie.locale.name"),
-    HTTP_COOKIE_AUTHRECORD_NAME                     ("http.cookie.authRecord.name"),
-    HTTP_COOKIE_AUTHRECORD_AGE                      ("http.cookie.authRecord.age"),
-    HTTP_COOKIE_MAX_READ_LENGTH                     ("http.cookie.maxReadLength"),
-    HTTP_COOKIE_CAPTCHA_SKIP_NAME                   ("http.cookie.captchaSkip.name"),
-    HTTP_COOKIE_CAPTCHA_SKIP_AGE                    ("http.cookie.captchaSkip.age"),
-    HTTP_COOKIE_LOGIN_NAME                          ("http.cookie.login.name"),
-    HTTP_BASIC_AUTH_CHARSET                         ("http.basicAuth.charset"),
-    HTTP_BODY_MAXREAD_LENGTH                        ("http.body.maxReadLength"),
-    HTTP_CLIENT_SOCKET_TIMEOUT_MS                   ("http.client.socketTimeoutMs"),
-    HTTP_CLIENT_CONNECT_TIMEOUT_MS                  ("http.client.connectTimeoutMs"),
-    HTTP_CLIENT_REQUEST_TIMEOUT_MS                  ("http.client.requestTimeoutMs"),
-    HTTP_CLIENT_PROMISCUOUS_WORDLIST_ENABLE         ("http.client.promiscuous.wordlist.enable"),
-    HTTP_ENABLE_GZIP                                ("http.gzip.enable"),
-    HTTP_ERRORS_ALLOW_HTML                          ("http.errors.allowHtml"),
-    HTTP_HEADER_SERVER                              ("http.header.server"),
-    HTTP_HEADER_SEND_CONTENT_LANGUAGE               ("http.header.sendContentLanguage"),
-    HTTP_HEADER_SEND_XAMB                           ("http.header.sendXAmb"),
-    HTTP_HEADER_SEND_XINSTANCE                      ("http.header.sendXInstance"),
-    HTTP_HEADER_SEND_XNOISE                         ("http.header.sendXNoise"),
-    HTTP_HEADER_SEND_XSESSIONID                     ("http.header.sendXSessionID"),
-    HTTP_HEADER_SEND_XVERSION                       ("http.header.sendXVersion"),
-    HTTP_HEADER_SEND_XCONTENTTYPEOPTIONS            ("http.header.sendXContentTypeOptions"),
-    HTTP_HEADER_SEND_XXSSPROTECTION                 ("http.header.sendXXSSProtection"),
-    HTTP_HEADER_NOISE_LENGTH                        ("http.header.noise.length"),
-    HTTP_HEADER_CSP_NONCE_BYTES                     ("http.header.csp.nonce.bytes"),
-    HTTP_PARAM_NAME_FORWARD_URL                     ("http.parameter.forward"),
-    HTTP_PARAM_NAME_LOGOUT_URL                      ("http.parameter.logout"),
-    HTTP_PARAM_NAME_THEME                           ("http.parameter.theme"),
-    HTTP_PARAM_NAME_LOCALE                          ("http.parameter.locale"),
-    HTTP_PARAM_NAME_PASSWORD_EXPIRED                ("http.parameter.passwordExpired"),
-    HTTP_PARAM_NAME_SSO_OVERRIDE                    ("http.parameter.ssoOverride"),
-    HTTP_PARAM_MAX_READ_LENGTH                      ("http.parameter.maxReadLength"),
-    HTTP_PARAM_SESSION_VERIFICATION                 ("http.parameter.sessionVerification"),
-    HTTP_PARAM_OAUTH_ACCESS_TOKEN                   ("http.parameter.oauth.accessToken"),
-    HTTP_PARAM_OAUTH_ATTRIBUTES                     ("http.parameter.oauth.attributes"),
-    HTTP_PARAM_OAUTH_CLIENT_ID                      ("http.parameter.oauth.clientID"),
-    HTTP_PARAM_OAUTH_CODE                           ("http.parameter.oauth.code"),
-    HTTP_PARAM_OAUTH_EXPIRES                        ("http.parameter.oauth.expires"),
-    HTTP_PARAM_OAUTH_RESPONSE_TYPE                  ("http.parameter.oauth.responseType"),
-    HTTP_PARAM_OAUTH_REDIRECT_URI                   ("http.parameter.oauth.redirectUri"),
-    HTTP_PARAM_OAUTH_REFRESH_TOKEN                  ("http.parameter.oauth.refreshToken"),
-    HTTP_PARAM_OAUTH_STATE                          ("http.parameter.oauth.state"),
-    HTTP_PARAM_OAUTH_GRANT_TYPE                     ("http.parameter.oauth.grantType"),
-    HTTP_DOWNLOAD_BUFFER_SIZE                       ("http.download.buffer.size"),
-    HTTP_SESSION_RECYCLE_AT_AUTH                    ("http.session.recycleAtAuth"),
-    HTTP_SESSION_VALIDATION_KEY_LENGTH              ("http.session.validationKeyLength"),
-    HTTP_SERVLET_ENABLE_POST_REDIRECT_GET           ("http.servlet.enablePostRedirectGet"),
-    LOCALDB_AGGRESSIVE_COMPACT_ENABLED              ("localdb.aggressiveCompact.enabled"),
-    LOCALDB_IMPLEMENTATION                          ("localdb.implementation"),
-    LOCALDB_INIT_STRING                             ("localdb.initParameters"),
-    LOCALDB_LOCATION                                ("localdb.location"),
-    LOCALDB_LOGWRITER_BUFFER_SIZE                   ("localdb.logWriter.bufferSize"),
-    LOCALDB_LOGWRITER_MAX_BUFFER_WAIT_MS            ("localdb.logWriter.maxBufferWaitMs"),
-    LOCALDB_LOGWRITER_MAX_TRIM_SIZE                 ("localdb.logWriter.maxTrimSize"),
-    MACRO_RANDOM_CHAR_MAX_LENGTH                    ("macro.randomChar.maxLength"),
-    MACRO_LDAP_ATTR_CHAR_MAX_LENGTH                 ("macro.ldapAttr.maxLength"),
+    APPLICATION_FILELOCK_FILENAME                   ( "application.fileLock.filename" ),
+    APPLICATION_FILELOCK_WAIT_SECONDS               ( "application.fileLock.waitSeconds" ),
+    APPLICATION_WORDLIST_RETRY_SECONDS              ( "application.wordlistRetryImportSeconds" ),
+    AUDIT_EVENTS_EMAILFROM                          ( "audit.events.emailFrom" ),
+    AUDIT_EVENTS_EMAILSUBJECT                       ( "audit.events.emailSubject" ),
+    AUDIT_EVENTS_LOCALDB_MAX_BULK_REMOVALS          ( "audit.events.localdb.maxBulkRemovals" ),
+    AUDIT_SYSLOG_MAX_MESSAGE_LENGTH                 ( "audit.syslog.message.length" ),
+    AUDIT_SYSLOG_TRUNCATE_MESSAGE                   ( "audit.syslog.message.truncateMsg" ),
+    BACKUP_LOCATION                                 ( "backup.path" ),
+    BACKUP_CONFIG_COUNT                             ( "backup.config.count" ),
+    BACKUP_LOCALDB_COUNT                            ( "backup.localdb.count" ),
+    CACHE_ENABLE                                    ( "cache.enable" ),
+    CACHE_MEMORY_MAX_ITEMS                          ( "cache.memory.maxItems" ),
+    CACHE_PWRULECHECK_LIFETIME_MS                   ( "cache.pwRuleCheckLifetimeMS" ),
+    CACHE_FORM_UNIQUE_VALUE_LIFETIME_MS             ( "cache.uniqueFormValueLifetimeMS" ),
+    CLIENT_ACTIVITY_MAX_EPS_RATE                    ( "client.ajax.activityMaxEpsRate" ),
+    CLIENT_AJAX_PW_WAIT_CHECK_SECONDS               ( "client.ajax.changePasswordWaitCheckSeconds" ),
+    CLIENT_AJAX_TYPING_TIMEOUT                      ( "client.ajax.typingTimeout" ),
+    CLIENT_AJAX_TYPING_WAIT                         ( "client.ajax.typingWait" ),
+    CLIENT_FORM_NONCE_ENABLE                        ( "client.formNonce.enable" ),
+    CLIENT_FORM_NONCE_LENGTH                        ( "client.formNonce.length" ),
+    CLIENT_FORM_CLIENT_REGEX_ENABLED                ( "client.form.clientRegexEnable" ),
+    CLIENT_WARNING_HEADER_SHOW                      ( "client.warningHeader.show" ),
+    CLIENT_PW_SHOW_REVERT_TIMEOUT                   ( "client.pwShowRevertTimeout" ),
+    CLIENT_JS_ENABLE_HTML5DIALOG                    ( "client.js.enableHtml5Dialog" ),
+    CLIENT_JSP_SHOW_ICONS                           ( "client.jsp.showIcons" ),
+    CONFIG_MAX_JDBC_JAR_SIZE                        ( "config.maxJdbcJarSize" ),
+    CONFIG_RELOAD_ON_CHANGE                         ( "config.reloadOnChange" ),
+    CONFIG_MAX_PERSISTENT_LOGIN_SECONDS             ( "config.maxPersistentLoginSeconds" ),
+    CONFIG_HISTORY_MAX_ITEMS                        ( "config.login.history.maxEvents" ),
+    CONFIG_FILE_SCAN_FREQUENCY                      ( "config.fileScanFrequencyMS" ),
+    CONFIG_NEWUSER_PASSWORD_POLICY_CACHE_MS         ( "config.newuser.passwordPolicyCacheMS" ),
+    CONFIG_THEME                                    ( "config.theme" ),
+    CONFIG_JBCRYPT_PWLIB_ENABLE                     ( "config.enableJbCryptPwLibrary" ),
+    CONFIG_EDITOR_BLOCK_OLD_IE                      ( "configEditor.blockOldIE" ),
+    CONFIG_EDITOR_QUERY_FILTER_TEST_LIMIT           ( "configEditor.queryFilter.testLimit" ),
+    CONFIG_EDITOR_IDLE_TIMEOUT                      ( "configEditor.idleTimeoutSeconds" ),
+    CONFIG_GUIDE_IDLE_TIMEOUT                       ( "configGuide.idleTimeoutSeconds" ),
+    CONFIG_MANAGER_ZIPDEBUG_MAXLOGLINES             ( "configManager.zipDebug.maxLogLines" ),
+    CONFIG_MANAGER_ZIPDEBUG_MAXLOGSECONDS           ( "configManager.zipDebug.maxLogSeconds" ),
+    CLUSTER_DB_ENABLE                               ( "cluster.db.enable" ),
+    CLUSTER_DB_HEARTBEAT_SECONDS                    ( "cluster.db.heartbeatSeconds" ),
+    CLUSTER_DB_NODE_TIMEOUT_SECONDS                 ( "cluster.db.nodeTimeoutSeconds" ),
+    CLUSTER_DB_NODE_PURGE_SECONDS                   ( "cluster.db.nodePurgeSeconds" ),
+    DB_JDBC_LOAD_STRATEGY                           ( "db.jdbcLoadStrategy" ),
+    DB_CONNECTIONS_MAX                              ( "db.connections.max" ),
+    DB_CONNECTIONS_TIMEOUT_MS                       ( "db.connections.timeoutMs" ),
+    DB_CONNECTIONS_WATCHDOG_FREQUENCY_SECONDS       ( "db.connections.watchdogFrequencySeconds" ),
+    DB_SCHEMA_KEY_LENGTH                            ( "db.schema.keyLength" ),
+    DOWNLOAD_FILENAME_STATISTICS_CSV                ( "download.filename.statistics.csv" ),
+    DOWNLOAD_FILENAME_USER_REPORT_SUMMARY_CSV       ( "download.filename.reportSummary.csv" ),
+    DOWNLOAD_FILENAME_USER_REPORT_RECORDS_CSV       ( "download.filename.reportRecords.csv" ),
+    DOWNLOAD_FILENAME_AUDIT_RECORDS_CSV             ( "download.filename.auditRecords.csv" ),
+    DOWNLOAD_FILENAME_LDAP_PERMISSION_CSV           ( "download.filename.ldapPermission.csv" ),
+    DOWNLOAD_FILENAME_USER_DEBUG_JSON               ( "download.filename.userDebug.json" ),
+    FORM_EMAIL_REGEX                                ( "form.email.regexTest" ),
+    HTTP_RESOURCES_MAX_CACHE_ITEMS                  ( "http.resources.maxCacheItems" ),
+    HTTP_RESOURCES_MAX_CACHE_BYTES                  ( "http.resources.maxCacheBytes" ),
+    HTTP_RESOURCES_EXPIRATION_SECONDS               ( "http.resources.expirationSeconds" ),
+    HTTP_RESOURCES_ENABLE_GZIP                      ( "http.resources.gzip.enable" ),
+    HTTP_RESOURCES_PATH_NONCE_LENGTH                ( "http.resources.pathNonce.length" ),
+    HTTP_RESOURCES_ENABLE_PATH_NONCE                ( "http.resources.pathNonceEnable" ),
+    HTTP_RESOURCES_NONCE_PATH_PREFIX                ( "http.resources.pathNoncePrefix" ),
+    HTTP_RESOURCES_ZIP_FILES                        ( "http.resources.zipFiles" ),
+    HTTP_COOKIE_DEFAULT_SECURE_FLAG                 ( "http.cookie.default.secureFlag" ),
+    HTTP_COOKIE_THEME_NAME                          ( "http.cookie.theme.name" ),
+    HTTP_COOKIE_THEME_AGE                           ( "http.cookie.theme.age" ),
+    HTTP_COOKIE_LOCALE_NAME                         ( "http.cookie.locale.name" ),
+    HTTP_COOKIE_AUTHRECORD_NAME                     ( "http.cookie.authRecord.name" ),
+    HTTP_COOKIE_AUTHRECORD_AGE                      ( "http.cookie.authRecord.age" ),
+    HTTP_COOKIE_MAX_READ_LENGTH                     ( "http.cookie.maxReadLength" ),
+    HTTP_COOKIE_CAPTCHA_SKIP_NAME                   ( "http.cookie.captchaSkip.name" ),
+    HTTP_COOKIE_CAPTCHA_SKIP_AGE                    ( "http.cookie.captchaSkip.age" ),
+    HTTP_COOKIE_LOGIN_NAME                          ( "http.cookie.login.name" ),
+    HTTP_BASIC_AUTH_CHARSET                         ( "http.basicAuth.charset" ),
+    HTTP_BODY_MAXREAD_LENGTH                        ( "http.body.maxReadLength" ),
+    HTTP_CLIENT_SOCKET_TIMEOUT_MS                   ( "http.client.socketTimeoutMs" ),
+    HTTP_CLIENT_CONNECT_TIMEOUT_MS                  ( "http.client.connectTimeoutMs" ),
+    HTTP_CLIENT_REQUEST_TIMEOUT_MS                  ( "http.client.requestTimeoutMs" ),
+    HTTP_CLIENT_PROMISCUOUS_WORDLIST_ENABLE         ( "http.client.promiscuous.wordlist.enable" ),
+    HTTP_ENABLE_GZIP                                ( "http.gzip.enable" ),
+    HTTP_ERRORS_ALLOW_HTML                          ( "http.errors.allowHtml" ),
+    HTTP_HEADER_SERVER                              ( "http.header.server" ),
+    HTTP_HEADER_SEND_CONTENT_LANGUAGE               ( "http.header.sendContentLanguage" ),
+    HTTP_HEADER_SEND_XAMB                           ( "http.header.sendXAmb" ),
+    HTTP_HEADER_SEND_XINSTANCE                      ( "http.header.sendXInstance" ),
+    HTTP_HEADER_SEND_XNOISE                         ( "http.header.sendXNoise" ),
+    HTTP_HEADER_SEND_XSESSIONID                     ( "http.header.sendXSessionID" ),
+    HTTP_HEADER_SEND_XVERSION                       ( "http.header.sendXVersion" ),
+    HTTP_HEADER_SEND_XCONTENTTYPEOPTIONS            ( "http.header.sendXContentTypeOptions" ),
+    HTTP_HEADER_SEND_XXSSPROTECTION                 ( "http.header.sendXXSSProtection" ),
+    HTTP_HEADER_NOISE_LENGTH                        ( "http.header.noise.length" ),
+    HTTP_HEADER_CSP_NONCE_BYTES                     ( "http.header.csp.nonce.bytes" ),
+    HTTP_PARAM_NAME_FORWARD_URL                     ( "http.parameter.forward" ),
+    HTTP_PARAM_NAME_LOGOUT_URL                      ( "http.parameter.logout" ),
+    HTTP_PARAM_NAME_THEME                           ( "http.parameter.theme" ),
+    HTTP_PARAM_NAME_LOCALE                          ( "http.parameter.locale" ),
+    HTTP_PARAM_NAME_PASSWORD_EXPIRED                ( "http.parameter.passwordExpired" ),
+    HTTP_PARAM_NAME_SSO_OVERRIDE                    ( "http.parameter.ssoOverride" ),
+    HTTP_PARAM_MAX_READ_LENGTH                      ( "http.parameter.maxReadLength" ),
+    HTTP_PARAM_SESSION_VERIFICATION                 ( "http.parameter.sessionVerification" ),
+    HTTP_PARAM_OAUTH_ACCESS_TOKEN                   ( "http.parameter.oauth.accessToken" ),
+    HTTP_PARAM_OAUTH_ATTRIBUTES                     ( "http.parameter.oauth.attributes" ),
+    HTTP_PARAM_OAUTH_CLIENT_ID                      ( "http.parameter.oauth.clientID" ),
+    HTTP_PARAM_OAUTH_CODE                           ( "http.parameter.oauth.code" ),
+    HTTP_PARAM_OAUTH_EXPIRES                        ( "http.parameter.oauth.expires" ),
+    HTTP_PARAM_OAUTH_RESPONSE_TYPE                  ( "http.parameter.oauth.responseType" ),
+    HTTP_PARAM_OAUTH_REDIRECT_URI                   ( "http.parameter.oauth.redirectUri" ),
+    HTTP_PARAM_OAUTH_REFRESH_TOKEN                  ( "http.parameter.oauth.refreshToken" ),
+    HTTP_PARAM_OAUTH_STATE                          ( "http.parameter.oauth.state" ),
+    HTTP_PARAM_OAUTH_GRANT_TYPE                     ( "http.parameter.oauth.grantType" ),
+    HTTP_DOWNLOAD_BUFFER_SIZE                       ( "http.download.buffer.size" ),
+    HTTP_SESSION_RECYCLE_AT_AUTH                    ( "http.session.recycleAtAuth" ),
+    HTTP_SESSION_VALIDATION_KEY_LENGTH              ( "http.session.validationKeyLength" ),
+    HTTP_SERVLET_ENABLE_POST_REDIRECT_GET           ( "http.servlet.enablePostRedirectGet" ),
+    LOCALDB_AGGRESSIVE_COMPACT_ENABLED              ( "localdb.aggressiveCompact.enabled" ),
+    LOCALDB_IMPLEMENTATION                          ( "localdb.implementation" ),
+    LOCALDB_INIT_STRING                             ( "localdb.initParameters" ),
+    LOCALDB_LOCATION                                ( "localdb.location" ),
+    LOCALDB_LOGWRITER_BUFFER_SIZE                   ( "localdb.logWriter.bufferSize" ),
+    LOCALDB_LOGWRITER_MAX_BUFFER_WAIT_MS            ( "localdb.logWriter.maxBufferWaitMs" ),
+    LOCALDB_LOGWRITER_MAX_TRIM_SIZE                 ( "localdb.logWriter.maxTrimSize" ),
+    MACRO_RANDOM_CHAR_MAX_LENGTH                    ( "macro.randomChar.maxLength" ),
+    MACRO_LDAP_ATTR_CHAR_MAX_LENGTH                 ( "macro.ldapAttr.maxLength" ),
 
 
     /** Time intruder records exist in the intruder table before being deleted. */
-    INTRUDER_RETENTION_TIME_MS                      ("intruder.retentionTimeMS"),
+    INTRUDER_RETENTION_TIME_MS                      ( "intruder.retentionTimeMS" ),
 
     /** How often to cleanup the intruder table. */
-    INTRUDER_CLEANUP_FREQUENCY_MS                   ("intruder.cleanupFrequencyMS"),
-    INTRUDER_MIN_DELAY_PENALTY_MS                   ("intruder.minimumDelayPenaltyMS"),
-    INTRUDER_MAX_DELAY_PENALTY_MS                   ("intruder.maximumDelayPenaltyMS"),
-    INTRUDER_DELAY_PER_COUNT_MS                     ("intruder.delayPerCountMS"),
-    INTRUDER_DELAY_MAX_JITTER_MS                    ("intruder.delayMaxJitterMS"),
-    HEALTHCHECK_ENABLED                             ("healthCheck.enabled"),
-    HEALTHCHECK_NOMINAL_CHECK_INTERVAL              ("healthCheck.nominalCheckIntervalSeconds"),
-    HEALTHCHECK_MIN_CHECK_INTERVAL                  ("healthCheck.minimumCheckIntervalSeconds"),
-    HEALTHCHECK_MAX_RECORD_AGE                      ("healthCheck.maximumRecordAgeSeconds"),
-    HEALTHCHECK_MAX_FORCE_WAIT                      ("healthCheck.maximumForceCheckWaitSeconds"),
-    HEALTH_CERTIFICATE_WARN_SECONDS                 ("health.certificate.warnSeconds"),
-    HEALTH_LDAP_CAUTION_DURATION_MS                 ("health.ldap.cautionDurationMS"),
-    HEALTH_JAVA_MAX_THREADS                         ("health.java.maxThreads"),
-    HEALTH_JAVA_MIN_HEAP_BYTES                      ("health.java.minHeapBytes"),
-    HELPDESK_TOKEN_MAX_AGE                          ("helpdesk.token.maxAgeSeconds"),
-    HELPDESK_TOKEN_VALUE                            ("helpdesk.token.value"),
-    HELPDESK_VERIFICATION_INVALID_DELAY_MS          ("helpdesk.verification.invalid.delayMs"),
-    HELPDESK_VERIFICATION_TIMEOUT_SECONDS           ("helpdesk.verification.timeoutSeconds"),
-    LDAP_RESOLVE_CANONICAL_DN                       ("ldap.resolveCanonicalDN"),
-    LDAP_CACHE_CANONICAL_ENABLE                     ("ldap.cache.canonical.enable"),
-    LDAP_CACHE_CANONICAL_SECONDS                    ("ldap.cache.canonical.seconds"),
-    LDAP_CACHE_USER_GUID_ENABLE                     ("ldap.cache.userGuid.enable"),
-    LDAP_CACHE_USER_GUID_SECONDS                    ("ldap.cache.userGuid.seconds"),
-    LDAP_CHAI_SETTINGS                              ("ldap.chaiSettings"),
-    LDAP_PROXY_CONNECTION_PER_PROFILE               ("ldap.proxy.connectionsPerProfile"),
-    LDAP_PROXY_MAX_CONNECTIONS                      ("ldap.proxy.maxConnections"),
-    LDAP_EXTENSIONS_NMAS_ENABLE                     ("ldap.extensions.nmas.enable"),
-    LDAP_CONNECTION_TIMEOUT                         ("ldap.connection.timeoutMS"),
-    LDAP_PROFILE_RETRY_DELAY                        ("ldap.profile.retryDelayMS"),
-    LDAP_PROMISCUOUS_ENABLE                         ("ldap.promiscuousEnable"),
-    LDAP_PASSWORD_REPLICA_CHECK_INIT_DELAY_MS       ("ldap.password.replicaCheck.initialDelayMS"),
-    LDAP_PASSWORD_REPLICA_CHECK_CYCLE_DELAY_MS      ("ldap.password.replicaCheck.cycleDelayMS"),
-    LDAP_PASSWORD_CHANGE_SELF_ENABLE                ("ldap.password.change.self.enable"),
-    LDAP_PASSWORD_CHANGE_HELPDESK_ENABLE            ("ldap.password.change.helpdesk.enable"),
-    LDAP_GUID_PATTERN                               ("ldap.guid.pattern"),
-    LDAP_BROWSER_MAX_ENTRIES                        ("ldap.browser.maxEntries"),
-    LDAP_SEARCH_PAGING_ENABLE                       ("ldap.search.paging.enable"),
-    LDAP_SEARCH_PAGING_SIZE                         ("ldap.search.paging.size"),
-    LDAP_SEARCH_PARALLEL_ENABLE                     ("ldap.search.parallel.enable"),
-    LDAP_SEARCH_PARALLEL_FACTOR                     ("ldap.search.parallel.factor"),
-    LDAP_SEARCH_PARALLEL_THREAD_MAX                 ("ldap.search.parallel.threadMax"),
-    LDAP_ORACLE_POST_TEMPPW_USE_CURRENT_TIME        ("ldap.oracle.postTempPasswordUseCurrentTime"),
-    LOGGING_PATTERN                                 ("logging.pattern"),
-    LOGGING_FILE_MAX_SIZE                           ("logging.file.maxSize"),
-    LOGGING_FILE_MAX_ROLLOVER                       ("logging.file.maxRollover"),
-    LOGGING_FILE_PATH                               ("logging.file.path"),
-    LOGGING_DEV_OUTPUT                              ("logging.devOutput.enable"),
-    NEWUSER_LDAP_USE_TEMP_PW                        ("newUser.ldap.useTempPassword"),
-    NEWUSER_TOKEN_ALLOW_PLAIN_PW                    ("newUser.token.allowPlainPassword"),
-    NMAS_THREADS_MAX_COUNT                          ("nmas.threads.maxCount"),
-    NMAS_THREADS_MIN_SECONDS                        ("nmas.threads.minSeconds"),
-    NMAS_THREADS_MAX_SECONDS                        ("nmas.threads.maxSeconds"),
-    NMAS_THREADS_WATCHDOG_FREQUENCY                 ("nmas.threads.watchdogFrequencyMs"),
-    NMAS_THREADS_WATCHDOG_DEBUG                     ("nmas.threads.watchdogDebug"),
-    NMAS_IGNORE_NMASCR_DURING_FORCECHECK            ("nmas.ignoreNmasCrDuringForceSetupCheck"),
-    NMAS_USE_LOCAL_SASL_FACTORY                     ("nmas.useLocalSaslFactory"),
-    NMAS_FORCE_SASL_FACTORY_REGISTRATION            ("nmas.forceSaslFactoryRegistration"),
-    OAUTH_ID_REQUEST_TYPE                           ("oauth.id.requestType"),
-    OAUTH_ID_ACCESS_GRANT_TYPE                      ("oauth.id.accessGrantType"),
-    OAUTH_ID_REFRESH_GRANT_TYPE                     ("oauth.id.refreshGrantType"),
-    OAUTH_ENABLE_TOKEN_REFRESH                      ("oauth.enableTokenRefresh"),
-    OAUTH_RETURN_URL_OVERRIDE                       ("oauth.returnUrlOverride"),
+    INTRUDER_CLEANUP_FREQUENCY_MS                   ( "intruder.cleanupFrequencyMS" ),
+    INTRUDER_MIN_DELAY_PENALTY_MS                   ( "intruder.minimumDelayPenaltyMS" ),
+    INTRUDER_MAX_DELAY_PENALTY_MS                   ( "intruder.maximumDelayPenaltyMS" ),
+    INTRUDER_DELAY_PER_COUNT_MS                     ( "intruder.delayPerCountMS" ),
+    INTRUDER_DELAY_MAX_JITTER_MS                    ( "intruder.delayMaxJitterMS" ),
+    HEALTHCHECK_ENABLED                             ( "healthCheck.enabled" ),
+    HEALTHCHECK_NOMINAL_CHECK_INTERVAL              ( "healthCheck.nominalCheckIntervalSeconds" ),
+    HEALTHCHECK_MIN_CHECK_INTERVAL                  ( "healthCheck.minimumCheckIntervalSeconds" ),
+    HEALTHCHECK_MAX_RECORD_AGE                      ( "healthCheck.maximumRecordAgeSeconds" ),
+    HEALTHCHECK_MAX_FORCE_WAIT                      ( "healthCheck.maximumForceCheckWaitSeconds" ),
+    HEALTH_CERTIFICATE_WARN_SECONDS                 ( "health.certificate.warnSeconds" ),
+    HEALTH_LDAP_CAUTION_DURATION_MS                 ( "health.ldap.cautionDurationMS" ),
+    HEALTH_JAVA_MAX_THREADS                         ( "health.java.maxThreads" ),
+    HEALTH_JAVA_MIN_HEAP_BYTES                      ( "health.java.minHeapBytes" ),
+    HELPDESK_TOKEN_MAX_AGE                          ( "helpdesk.token.maxAgeSeconds" ),
+    HELPDESK_TOKEN_VALUE                            ( "helpdesk.token.value" ),
+    HELPDESK_VERIFICATION_INVALID_DELAY_MS          ( "helpdesk.verification.invalid.delayMs" ),
+    HELPDESK_VERIFICATION_TIMEOUT_SECONDS           ( "helpdesk.verification.timeoutSeconds" ),
+    LDAP_RESOLVE_CANONICAL_DN                       ( "ldap.resolveCanonicalDN" ),
+    LDAP_CACHE_CANONICAL_ENABLE                     ( "ldap.cache.canonical.enable" ),
+    LDAP_CACHE_CANONICAL_SECONDS                    ( "ldap.cache.canonical.seconds" ),
+    LDAP_CACHE_USER_GUID_ENABLE                     ( "ldap.cache.userGuid.enable" ),
+    LDAP_CACHE_USER_GUID_SECONDS                    ( "ldap.cache.userGuid.seconds" ),
+    LDAP_CHAI_SETTINGS                              ( "ldap.chaiSettings" ),
+    LDAP_PROXY_CONNECTION_PER_PROFILE               ( "ldap.proxy.connectionsPerProfile" ),
+    LDAP_PROXY_MAX_CONNECTIONS                      ( "ldap.proxy.maxConnections" ),
+    LDAP_EXTENSIONS_NMAS_ENABLE                     ( "ldap.extensions.nmas.enable" ),
+    LDAP_CONNECTION_TIMEOUT                         ( "ldap.connection.timeoutMS" ),
+    LDAP_PROFILE_RETRY_DELAY                        ( "ldap.profile.retryDelayMS" ),
+    LDAP_PROMISCUOUS_ENABLE                         ( "ldap.promiscuousEnable" ),
+    LDAP_PASSWORD_REPLICA_CHECK_INIT_DELAY_MS       ( "ldap.password.replicaCheck.initialDelayMS" ),
+    LDAP_PASSWORD_REPLICA_CHECK_CYCLE_DELAY_MS      ( "ldap.password.replicaCheck.cycleDelayMS" ),
+    LDAP_PASSWORD_CHANGE_SELF_ENABLE                ( "ldap.password.change.self.enable" ),
+    LDAP_PASSWORD_CHANGE_HELPDESK_ENABLE            ( "ldap.password.change.helpdesk.enable" ),
+    LDAP_GUID_PATTERN                               ( "ldap.guid.pattern" ),
+    LDAP_BROWSER_MAX_ENTRIES                        ( "ldap.browser.maxEntries" ),
+    LDAP_SEARCH_PAGING_ENABLE                       ( "ldap.search.paging.enable" ),
+    LDAP_SEARCH_PAGING_SIZE                         ( "ldap.search.paging.size" ),
+    LDAP_SEARCH_PARALLEL_ENABLE                     ( "ldap.search.parallel.enable" ),
+    LDAP_SEARCH_PARALLEL_FACTOR                     ( "ldap.search.parallel.factor" ),
+    LDAP_SEARCH_PARALLEL_THREAD_MAX                 ( "ldap.search.parallel.threadMax" ),
+    LDAP_ORACLE_POST_TEMPPW_USE_CURRENT_TIME        ( "ldap.oracle.postTempPasswordUseCurrentTime" ),
+    LOGGING_PATTERN                                 ( "logging.pattern" ),
+    LOGGING_FILE_MAX_SIZE                           ( "logging.file.maxSize" ),
+    LOGGING_FILE_MAX_ROLLOVER                       ( "logging.file.maxRollover" ),
+    LOGGING_FILE_PATH                               ( "logging.file.path" ),
+    LOGGING_DEV_OUTPUT                              ( "logging.devOutput.enable" ),
+    NEWUSER_LDAP_USE_TEMP_PW                        ( "newUser.ldap.useTempPassword" ),
+    NEWUSER_TOKEN_ALLOW_PLAIN_PW                    ( "newUser.token.allowPlainPassword" ),
+    NMAS_THREADS_MAX_COUNT                          ( "nmas.threads.maxCount" ),
+    NMAS_THREADS_MIN_SECONDS                        ( "nmas.threads.minSeconds" ),
+    NMAS_THREADS_MAX_SECONDS                        ( "nmas.threads.maxSeconds" ),
+    NMAS_THREADS_WATCHDOG_FREQUENCY                 ( "nmas.threads.watchdogFrequencyMs" ),
+    NMAS_THREADS_WATCHDOG_DEBUG                     ( "nmas.threads.watchdogDebug" ),
+    NMAS_IGNORE_NMASCR_DURING_FORCECHECK            ( "nmas.ignoreNmasCrDuringForceSetupCheck" ),
+    NMAS_USE_LOCAL_SASL_FACTORY                     ( "nmas.useLocalSaslFactory" ),
+    NMAS_FORCE_SASL_FACTORY_REGISTRATION            ( "nmas.forceSaslFactoryRegistration" ),
+    OAUTH_ID_REQUEST_TYPE                           ( "oauth.id.requestType" ),
+    OAUTH_ID_ACCESS_GRANT_TYPE                      ( "oauth.id.accessGrantType" ),
+    OAUTH_ID_REFRESH_GRANT_TYPE                     ( "oauth.id.refreshGrantType" ),
+    OAUTH_ENABLE_TOKEN_REFRESH                      ( "oauth.enableTokenRefresh" ),
+    OAUTH_RETURN_URL_OVERRIDE                       ( "oauth.returnUrlOverride" ),
 
     /* Allows one older TOTP token - compensate for clock out of sync */
-    TOTP_PAST_INTERVALS                             ("otp.totp.pastIntervals"),
+    TOTP_PAST_INTERVALS                             ( "otp.totp.pastIntervals" ),
 
     /* Allows one newer TOTP token - compensate for clock out of sync */
-    TOTP_FUTURE_INTERVALS                           ("otp.totp.futureIntervals"),
+    TOTP_FUTURE_INTERVALS                           ( "otp.totp.futureIntervals" ),
 
-    TOTP_INTERVAL                                   ("otp.totp.intervalSeconds"),
-    OTP_TOKEN_LENGTH                                ("otp.token.length"),
-    OTP_SALT_CHARLENGTH                             ("otp.salt.charLength"),
-    OTP_RECOVERY_TOKEN_MACRO                        ("otp.recovery.macro"),
-    OTP_RECOVERY_HASH_COUNT                         ("otp.recoveryHash.iterations"),
-    OTP_RECOVERY_HASH_METHOD                        ("otp.recoveryHash.method"),
-    OTP_QR_IMAGE_HEIGHT                             ("otp.qrImage.height"),
-    OTP_QR_IMAGE_WIDTH                              ("otp.qrImage.width"),
-    OTP_ENCRYPTION_ALG                              ("otp.encryptionAlg"),
-    PASSWORD_RANDOMGEN_MAX_ATTEMPTS                 ("password.randomGenerator.maxAttempts"),
-    PASSWORD_RANDOMGEN_MAX_LENGTH                   ("password.randomGenerator.maxLength"),
-    PASSWORD_RANDOMGEN_JITTER_COUNT                 ("password.randomGenerator.jitter.count"),
+    TOTP_INTERVAL                                   ( "otp.totp.intervalSeconds" ),
+    OTP_TOKEN_LENGTH                                ( "otp.token.length" ),
+    OTP_SALT_CHARLENGTH                             ( "otp.salt.charLength" ),
+    OTP_RECOVERY_TOKEN_MACRO                        ( "otp.recovery.macro" ),
+    OTP_RECOVERY_HASH_COUNT                         ( "otp.recoveryHash.iterations" ),
+    OTP_RECOVERY_HASH_METHOD                        ( "otp.recoveryHash.method" ),
+    OTP_QR_IMAGE_HEIGHT                             ( "otp.qrImage.height" ),
+    OTP_QR_IMAGE_WIDTH                              ( "otp.qrImage.width" ),
+    OTP_ENCRYPTION_ALG                              ( "otp.encryptionAlg" ),
+    PASSWORD_RANDOMGEN_MAX_ATTEMPTS                 ( "password.randomGenerator.maxAttempts" ),
+    PASSWORD_RANDOMGEN_MAX_LENGTH                   ( "password.randomGenerator.maxLength" ),
+    PASSWORD_RANDOMGEN_JITTER_COUNT                 ( "password.randomGenerator.jitter.count" ),
 
     /* Strength thresholds, introduced by the addition of the zxcvbn strength meter library (since it has 5 levels) */
-    PASSWORD_STRENGTH_THRESHOLD_VERY_STRONG         ("password.strength.threshold.veryStrong"),
-    PASSWORD_STRENGTH_THRESHOLD_STRONG              ("password.strength.threshold.strong"),
-    PASSWORD_STRENGTH_THRESHOLD_GOOD                ("password.strength.threshold.good"),
-    PASSWORD_STRENGTH_THRESHOLD_WEAK                ("password.strength.threshold.weak"),
-    PASSWORD_STRENGTH_THRESHOLD_VERY_WEAK           ("password.strength.threshold.veryWeak"),
+    PASSWORD_STRENGTH_THRESHOLD_VERY_STRONG         ( "password.strength.threshold.veryStrong" ),
+    PASSWORD_STRENGTH_THRESHOLD_STRONG              ( "password.strength.threshold.strong" ),
+    PASSWORD_STRENGTH_THRESHOLD_GOOD                ( "password.strength.threshold.good" ),
+    PASSWORD_STRENGTH_THRESHOLD_WEAK                ( "password.strength.threshold.weak" ),
+    PASSWORD_STRENGTH_THRESHOLD_VERY_WEAK           ( "password.strength.threshold.veryWeak" ),
 
-    PEOPLESEARCH_MAX_VALUE_VERIFYUSERDN             ("peoplesearch.values.verifyUserDN"),
-    PEOPLESEARCH_VALUE_MAXCOUNT                     ("peoplesearch.values.maxCount"),
-    PEOPLESEARCH_VIEW_DETAIL_LINKS                  ("peoplesearch.view.detail.links"),
-    PEOPLESEARCH_ORGCHART_ENABLE_CHILD_COUNT        ("peoplesearch.orgChart.enableChildCount"),
-    PEOPLESEARCH_ORGCHART_MAX_PARENTS               ("peoplesearch.orgChart.maxParents"),
-    QUEUE_EMAIL_RETRY_TIMEOUT_MS                    ("queue.email.retryTimeoutMs"),
-    QUEUE_EMAIL_MAX_COUNT                           ("queue.email.maxCount"),
-    QUEUE_EMAIL_MAX_THREADS                         ("queue.email.maxThreads"),
-    QUEUE_SMS_RETRY_TIMEOUT_MS                      ("queue.sms.retryTimeoutMs"),
-    QUEUE_SMS_MAX_COUNT                             ("queue.sms.maxCount"),
-    QUEUE_SYSLOG_RETRY_TIMEOUT_MS                   ("queue.syslog.retryTimeoutMs"),
-    QUEUE_SYSLOG_MAX_AGE_MS                         ("queue.syslog.maxAgeMs"),
-    QUEUE_SYSLOG_MAX_COUNT                          ("queue.syslog.maxCount"),
-    RECAPTCHA_CLIENT_JS_URL                         ("recaptcha.clientJsUrl"),
-    RECAPTCHA_CLIENT_IFRAME_URL                     ("recaptcha.clientIframeUrl"),
-    RECAPTCHA_VALIDATE_URL                          ("recaptcha.validateUrl"),
-    REPORTING_LDAP_SEARCH_TIMEOUT                   ("reporting.ldap.searchTimeoutMs"),
-    REPORTING_LDAP_SEARCH_THREADS                   ("reporting.ldap.searchThreads"),
-    SECURITY_STRIP_INLINE_JAVASCRIPT                ("security.html.stripInlineJavascript"),
-    SECURITY_HTTP_FORCE_REQUEST_SEQUENCING          ("security.http.forceRequestSequencing"),
-    SECURITY_HTTP_STRIP_HEADER_REGEX                ("security.http.stripHeaderRegex"),
-    SECURITY_HTTP_PERFORM_CSRF_HEADER_CHECKS        ("security.http.performCsrfHeaderChecks"),
-    SECURITY_HTTP_PROMISCUOUS_ENABLE                ("security.http.promiscuousEnable"),
-    SECURITY_HTTP_CONFIG_CSP_HEADER                 ("security.http.config.cspHeader"),
-    SECURITY_HTTPSSERVER_SELF_FUTURESECONDS         ("security.httpsServer.selfCert.futureSeconds"),
-    SECURITY_HTTPSSERVER_SELF_ALG                   ("security.httpsServer.selfCert.alg"),
-    SECURITY_HTTPSSERVER_SELF_KEY_SIZE              ("security.httpsServer.selfCert.keySize"),
-    SECURITY_LOGIN_HIDDEN_ERROR_TYPES               ("security.login.hiddenErrorTypes"),
-    SECURITY_RESPONSES_HASH_ITERATIONS              ("security.responses.hashIterations"),
-    SECURITY_INPUT_TRIM                             ("security.input.trim"),
-    SECURITY_INPUT_PASSWORD_TRIM                    ("security.input.password.trim"),
-    SECURITY_INPUT_THEME_MATCH_REGEX                ("security.input.themeMatchRegex"),
-    SECURITY_WS_REST_SERVER_SECRET_HEADER           ("security.ws.rest.server.secretKeyHeader"),
-    SECURITY_SHAREDHISTORY_HASH_ITERATIONS          ("security.sharedHistory.hashIterations"),
-    SECURITY_SHAREDHISTORY_HASH_NAME                ("security.sharedHistory.hashName"),
-    SECURITY_SHAREDHISTORY_CASE_INSENSITIVE         ("security.sharedHistory.caseInsensitive"),
-    SECURITY_SHAREDHISTORY_SALT_LENGTH              ("security.sharedHistory.saltLength"),
-    SECURITY_CERTIFICATES_VALIDATE_TIMESTAMPS       ("security.certs.validateTimestamps"),
-    SECURITY_CONFIG_MIN_SECURITY_KEY_LENGTH         ("security.config.minSecurityKeyLength"),
-    SECURITY_DEFAULT_EPHEMERAL_BLOCK_ALG            ("security.defaultEphemeralBlockAlg"),
-    SECURITY_DEFAULT_EPHEMERAL_HASH_ALG             ("security.defaultEphemeralHashAlg"),
-    SEEDLIST_BUILTIN_PATH                           ("seedlist.builtin.path"),
-    SMTP_SUBJECT_ENCODING_CHARSET                   ("smtp.subjectEncodingCharset"),
-    TOKEN_CLEANER_INTERVAL_SECONDS                  ("token.cleaner.intervalSeconds"),
-    TOKEN_MASK_EMAIL_REGEX                          ("token.mask.email.regex"),
-    TOKEN_MASK_EMAIL_REPLACE                        ("token.mask.email.replace"),
-    TOKEN_MASK_SHOW_SELECTION                       ("token.mask.showSelection"),
-    TOKEN_MASK_SMS_REGEX                            ("token.mask.sms.regex"),
-    TOKEN_MASK_SMS_REPLACE                          ("token.mask.sms.replace"),
-    TOKEN_MAX_UNIQUE_CREATE_ATTEMPTS                ("token.maxUniqueCreateAttempts"),
-    TOKEN_RESEND_DELAY_MS                           ("token.resend.delayMS"),
-    TOKEN_REMOVE_ON_CLAIM                           ("token.removeOnClaim"),
-    TOKEN_VERIFY_PW_MODIFY_TIME                     ("token.verifyPwModifyTime"),
-    TOKEN_STORAGE_MAX_KEY_LENGTH                    ("token.storage.maxKeyLength"),
-    TELEMETRY_SENDER_IMPLEMENTATION                 ("telemetry.senderImplementation"),
-    TELEMETRY_SENDER_SETTINGS                       ("telemetry.senderSettings"),
-    TELEMETRY_SEND_FREQUENCY_SECONDS                ("telemetry.sendFrequencySeconds"),
-    TELEMETRY_MIN_AUTHENTICATIONS                   ("telemetry.minimumAuthentications"),
+    PEOPLESEARCH_MAX_VALUE_VERIFYUSERDN             ( "peoplesearch.values.verifyUserDN" ),
+    PEOPLESEARCH_VALUE_MAXCOUNT                     ( "peoplesearch.values.maxCount" ),
+    PEOPLESEARCH_VIEW_DETAIL_LINKS                  ( "peoplesearch.view.detail.links" ),
+    PEOPLESEARCH_ORGCHART_ENABLE_CHILD_COUNT        ( "peoplesearch.orgChart.enableChildCount" ),
+    PEOPLESEARCH_ORGCHART_MAX_PARENTS               ( "peoplesearch.orgChart.maxParents" ),
+    QUEUE_EMAIL_RETRY_TIMEOUT_MS                    ( "queue.email.retryTimeoutMs" ),
+    QUEUE_EMAIL_MAX_COUNT                           ( "queue.email.maxCount" ),
+    QUEUE_EMAIL_MAX_THREADS                         ( "queue.email.maxThreads" ),
+    QUEUE_SMS_RETRY_TIMEOUT_MS                      ( "queue.sms.retryTimeoutMs" ),
+    QUEUE_SMS_MAX_COUNT                             ( "queue.sms.maxCount" ),
+    QUEUE_SYSLOG_RETRY_TIMEOUT_MS                   ( "queue.syslog.retryTimeoutMs" ),
+    QUEUE_SYSLOG_MAX_AGE_MS                         ( "queue.syslog.maxAgeMs" ),
+    QUEUE_SYSLOG_MAX_COUNT                          ( "queue.syslog.maxCount" ),
+    RECAPTCHA_CLIENT_JS_URL                         ( "recaptcha.clientJsUrl" ),
+    RECAPTCHA_CLIENT_IFRAME_URL                     ( "recaptcha.clientIframeUrl" ),
+    RECAPTCHA_VALIDATE_URL                          ( "recaptcha.validateUrl" ),
+    REPORTING_LDAP_SEARCH_TIMEOUT                   ( "reporting.ldap.searchTimeoutMs" ),
+    REPORTING_LDAP_SEARCH_THREADS                   ( "reporting.ldap.searchThreads" ),
+    SECURITY_STRIP_INLINE_JAVASCRIPT                ( "security.html.stripInlineJavascript" ),
+    SECURITY_HTTP_FORCE_REQUEST_SEQUENCING          ( "security.http.forceRequestSequencing" ),
+    SECURITY_HTTP_STRIP_HEADER_REGEX                ( "security.http.stripHeaderRegex" ),
+    SECURITY_HTTP_PERFORM_CSRF_HEADER_CHECKS        ( "security.http.performCsrfHeaderChecks" ),
+    SECURITY_HTTP_PROMISCUOUS_ENABLE                ( "security.http.promiscuousEnable" ),
+    SECURITY_HTTP_CONFIG_CSP_HEADER                 ( "security.http.config.cspHeader" ),
+    SECURITY_HTTPSSERVER_SELF_FUTURESECONDS         ( "security.httpsServer.selfCert.futureSeconds" ),
+    SECURITY_HTTPSSERVER_SELF_ALG                   ( "security.httpsServer.selfCert.alg" ),
+    SECURITY_HTTPSSERVER_SELF_KEY_SIZE              ( "security.httpsServer.selfCert.keySize" ),
+    SECURITY_LOGIN_HIDDEN_ERROR_TYPES               ( "security.login.hiddenErrorTypes" ),
+    SECURITY_RESPONSES_HASH_ITERATIONS              ( "security.responses.hashIterations" ),
+    SECURITY_INPUT_TRIM                             ( "security.input.trim" ),
+    SECURITY_INPUT_PASSWORD_TRIM                    ( "security.input.password.trim" ),
+    SECURITY_INPUT_THEME_MATCH_REGEX                ( "security.input.themeMatchRegex" ),
+    SECURITY_WS_REST_SERVER_SECRET_HEADER           ( "security.ws.rest.server.secretKeyHeader" ),
+    SECURITY_SHAREDHISTORY_HASH_ITERATIONS          ( "security.sharedHistory.hashIterations" ),
+    SECURITY_SHAREDHISTORY_HASH_NAME                ( "security.sharedHistory.hashName" ),
+    SECURITY_SHAREDHISTORY_CASE_INSENSITIVE         ( "security.sharedHistory.caseInsensitive" ),
+    SECURITY_SHAREDHISTORY_SALT_LENGTH              ( "security.sharedHistory.saltLength" ),
+    SECURITY_CERTIFICATES_VALIDATE_TIMESTAMPS       ( "security.certs.validateTimestamps" ),
+    SECURITY_CONFIG_MIN_SECURITY_KEY_LENGTH         ( "security.config.minSecurityKeyLength" ),
+    SECURITY_DEFAULT_EPHEMERAL_BLOCK_ALG            ( "security.defaultEphemeralBlockAlg" ),
+    SECURITY_DEFAULT_EPHEMERAL_HASH_ALG             ( "security.defaultEphemeralHashAlg" ),
+    SEEDLIST_BUILTIN_PATH                           ( "seedlist.builtin.path" ),
+    SMTP_SUBJECT_ENCODING_CHARSET                   ( "smtp.subjectEncodingCharset" ),
+    TOKEN_CLEANER_INTERVAL_SECONDS                  ( "token.cleaner.intervalSeconds" ),
+    TOKEN_MASK_EMAIL_REGEX                          ( "token.mask.email.regex" ),
+    TOKEN_MASK_EMAIL_REPLACE                        ( "token.mask.email.replace" ),
+    TOKEN_MASK_SHOW_SELECTION                       ( "token.mask.showSelection" ),
+    TOKEN_MASK_SMS_REGEX                            ( "token.mask.sms.regex" ),
+    TOKEN_MASK_SMS_REPLACE                          ( "token.mask.sms.replace" ),
+    TOKEN_MAX_UNIQUE_CREATE_ATTEMPTS                ( "token.maxUniqueCreateAttempts" ),
+    TOKEN_RESEND_DELAY_MS                           ( "token.resend.delayMS" ),
+    TOKEN_REMOVE_ON_CLAIM                           ( "token.removeOnClaim" ),
+    TOKEN_VERIFY_PW_MODIFY_TIME                     ( "token.verifyPwModifyTime" ),
+    TOKEN_STORAGE_MAX_KEY_LENGTH                    ( "token.storage.maxKeyLength" ),
+    TELEMETRY_SENDER_IMPLEMENTATION                 ( "telemetry.senderImplementation" ),
+    TELEMETRY_SENDER_SETTINGS                       ( "telemetry.senderSettings" ),
+    TELEMETRY_SEND_FREQUENCY_SECONDS                ( "telemetry.sendFrequencySeconds" ),
+    TELEMETRY_MIN_AUTHENTICATIONS                   ( "telemetry.minimumAuthentications" ),
 
 
 
     /** Regular expression to be used for matching URLs to be shortened by the URL Shortening Service Class. */
-    URL_SHORTNER_URL_REGEX                          ("urlshortener.url.regex"),
-    WORDLIST_BUILTIN_PATH                           ("wordlist.builtin.path"),
-    WORDLIST_CHAR_LENGTH_MAX                        ("wordlist.maxCharLength"),
-    WORDLIST_CHAR_LENGTH_MIN                        ("wordlist.minCharLength"),
-    WS_REST_CLIENT_PWRULE_HALTONERROR               ("ws.restClient.pwRule.haltOnError"),
-    WS_REST_SERVER_SIGNING_FORM_TIMEOUT_SECONDS     ("ws.restServer.signing.form.timeoutSeconds"),
-    ALLOW_MACRO_IN_REGEX_SETTING                    ("password.policy.allowMacroInRegexSetting"),
-
-    ;
+    URL_SHORTNER_URL_REGEX                          ( "urlshortener.url.regex" ),
+    WORDLIST_BUILTIN_PATH                           ( "wordlist.builtin.path" ),
+    WORDLIST_CHAR_LENGTH_MAX                        ( "wordlist.maxCharLength" ),
+    WORDLIST_CHAR_LENGTH_MIN                        ( "wordlist.minCharLength" ),
+    WS_REST_CLIENT_PWRULE_HALTONERROR               ( "ws.restClient.pwRule.haltOnError" ),
+    WS_REST_SERVER_SIGNING_FORM_TIMEOUT_SECONDS     ( "ws.restServer.signing.form.timeoutSeconds" ),
+    ALLOW_MACRO_IN_REGEX_SETTING                    ( "password.policy.allowMacroInRegexSetting" ),;
 
     public static final String VALUE_SEPARATOR = ";;;";
     private static final String DESCRIPTION_SUFFIX = "_description";
@@ -328,35 +327,44 @@ public enum AppProperty {
     private final String key;
     private String defaultValue;
 
-    AppProperty(final String key) {
+    AppProperty( final String key )
+    {
         this.key = key;
     }
 
-    public String getKey() {
+    public String getKey( )
+    {
         return key;
     }
 
-    public static AppProperty forKey(final String key) {
-        for (final AppProperty appProperty : AppProperty.values()) {
-            if (appProperty.getKey().equals(key)) {
+    public static AppProperty forKey( final String key )
+    {
+        for ( final AppProperty appProperty : AppProperty.values() )
+        {
+            if ( appProperty.getKey().equals( key ) )
+            {
                 return appProperty;
             }
         }
         return null;
     }
 
-    public String getDefaultValue() {
-        if (defaultValue == null) {
-            defaultValue = readAppPropertiesBundle(this.getKey());
+    public String getDefaultValue( )
+    {
+        if ( defaultValue == null )
+        {
+            defaultValue = readAppPropertiesBundle( this.getKey() );
         }
         return defaultValue;
     }
 
-    public String getDescription() {
-        return readAppPropertiesBundle(this.getKey() + DESCRIPTION_SUFFIX);
+    public String getDescription( )
+    {
+        return readAppPropertiesBundle( this.getKey() + DESCRIPTION_SUFFIX );
     }
 
-    private static String readAppPropertiesBundle(final String key) {
-        return ResourceBundle.getBundle(AppProperty.class.getName()).getString(key);
+    private static String readAppPropertiesBundle( final String key )
+    {
+        return ResourceBundle.getBundle( AppProperty.class.getName() ).getString( key );
     }
 }

+ 488 - 331
server/src/main/java/password/pwm/PwmApplication.java

@@ -102,40 +102,40 @@ import java.util.Map;
  *
  * @author Jason D. Rivard
  */
-public class PwmApplication {
+public class PwmApplication
+{
 
-    private static final PwmLogger LOGGER = PwmLogger.forClass(PwmApplication.class);
+    private static final PwmLogger LOGGER = PwmLogger.forClass( PwmApplication.class );
     private static final String DEFAULT_INSTANCE_ID = "-1";
 
-    public enum AppAttribute {
-        INSTANCE_ID("context_instanceID"),
-        INSTALL_DATE("DB_KEY_INSTALL_DATE"),
-        CONFIG_HASH("configurationSettingHash"),
-        LAST_LDAP_ERROR("lastLdapError"),
-        TOKEN_COUNTER("tokenCounter"),
-        REPORT_STATUS("reporting.status"),
+    public enum AppAttribute
+    {
+        INSTANCE_ID( "context_instanceID" ),
+        INSTALL_DATE( "DB_KEY_INSTALL_DATE" ),
+        CONFIG_HASH( "configurationSettingHash" ),
+        LAST_LDAP_ERROR( "lastLdapError" ),
+        TOKEN_COUNTER( "tokenCounter" ),
+        REPORT_STATUS( "reporting.status" ),
         // REPORT_CLEAN_FLAG("reporting.cleanFlag"), deprecated
-        SMS_ITEM_COUNTER("smsQueue.itemCount"),
-        EMAIL_ITEM_COUNTER("itemQueue.itemCount"),
-        LOCALDB_IMPORT_STATUS("localDB.import.status"),
-        WORDLIST_METADATA("wordlist.metadata"),
-        SEEDLIST_METADATA("seedlist.metadata"),
-        HTTPS_SELF_CERT("https.selfCert"),
-        CONFIG_LOGIN_HISTORY("config.loginHistory"),
-        LOCALDB_LOGGER_STORAGE_FORMAT("localdb.logger.storage.format"),
-
-        TELEMETRY_LAST_PUBLISH_TIMESTAMP("telemetry.lastPublish.timestamp")
+        SMS_ITEM_COUNTER( "smsQueue.itemCount" ),
+        EMAIL_ITEM_COUNTER( "itemQueue.itemCount" ),
+        LOCALDB_IMPORT_STATUS( "localDB.import.status" ),
+        WORDLIST_METADATA( "wordlist.metadata" ),
+        SEEDLIST_METADATA( "seedlist.metadata" ),
+        HTTPS_SELF_CERT( "https.selfCert" ),
+        CONFIG_LOGIN_HISTORY( "config.loginHistory" ),
+        LOCALDB_LOGGER_STORAGE_FORMAT( "localdb.logger.storage.format" ),
 
-        ;
+        TELEMETRY_LAST_PUBLISH_TIMESTAMP( "telemetry.lastPublish.timestamp" );
 
         private final String key;
 
-        AppAttribute(final String key)
+        AppAttribute( final String key )
         {
             this.key = key;
         }
 
-        public String getKey()
+        public String getKey( )
         {
             return key;
         }
@@ -154,35 +154,40 @@ public class PwmApplication {
 
     private final PwmEnvironment pwmEnvironment;
 
-    private final PwmServiceManager pwmServiceManager = new PwmServiceManager(this);
+    private final PwmServiceManager pwmServiceManager = new PwmServiceManager( this );
 
-    public PwmApplication(final PwmEnvironment pwmEnvironment)
+    public PwmApplication( final PwmEnvironment pwmEnvironment )
             throws PwmUnrecoverableException
     {
         pwmEnvironment.verifyIfApplicationPathIsSetProperly();
         this.pwmEnvironment = pwmEnvironment;
 
-        try {
+        try
+        {
             initialize();
-        } catch (PwmUnrecoverableException e) {
-            LOGGER.fatal(e.getMessage());
+        }
+        catch ( PwmUnrecoverableException e )
+        {
+            LOGGER.fatal( e.getMessage() );
             throw e;
         }
     }
 
-    private void initialize()
+    private void initialize( )
             throws PwmUnrecoverableException
     {
         final Instant startTime = Instant.now();
 
         // initialize log4j
-        if (!pwmEnvironment.isInternalRuntimeInstance() && !pwmEnvironment.getFlags().contains(PwmEnvironment.ApplicationFlag.CommandLineInstance)) {
-            final String log4jFileName = pwmEnvironment.getConfig().readSettingAsString(PwmSetting.EVENTS_JAVA_LOG4JCONFIG_FILE);
-            final File log4jFile = FileSystemUtility.figureFilepath(log4jFileName, pwmEnvironment.getApplicationPath());
+        if ( !pwmEnvironment.isInternalRuntimeInstance() && !pwmEnvironment.getFlags().contains( PwmEnvironment.ApplicationFlag.CommandLineInstance ) )
+        {
+            final String log4jFileName = pwmEnvironment.getConfig().readSettingAsString( PwmSetting.EVENTS_JAVA_LOG4JCONFIG_FILE );
+            final File log4jFile = FileSystemUtility.figureFilepath( log4jFileName, pwmEnvironment.getApplicationPath() );
             final String consoleLevel;
             final String fileLevel;
 
-            switch (getApplicationMode()) {
+            switch ( getApplicationMode() )
+            {
                 case ERROR:
                 case NEW:
                     consoleLevel = PwmLogLevel.TRACE.toString();
@@ -190,216 +195,264 @@ public class PwmApplication {
                     break;
 
                 default:
-                    consoleLevel = pwmEnvironment.getConfig().readSettingAsString(PwmSetting.EVENTS_JAVA_STDOUT_LEVEL);
-                    fileLevel = pwmEnvironment.getConfig().readSettingAsString(PwmSetting.EVENTS_FILE_LEVEL);
+                    consoleLevel = pwmEnvironment.getConfig().readSettingAsString( PwmSetting.EVENTS_JAVA_STDOUT_LEVEL );
+                    fileLevel = pwmEnvironment.getConfig().readSettingAsString( PwmSetting.EVENTS_FILE_LEVEL );
                     break;
             }
 
-            PwmLogManager.initializeLogger(this, pwmEnvironment.getConfig(), log4jFile, consoleLevel, pwmEnvironment.getApplicationPath(), fileLevel);
+            PwmLogManager.initializeLogger( this, pwmEnvironment.getConfig(), log4jFile, consoleLevel, pwmEnvironment.getApplicationPath(), fileLevel );
 
-            switch (getApplicationMode()) {
+            switch ( getApplicationMode() )
+            {
                 case RUNNING:
                     break;
 
                 case ERROR:
-                    LOGGER.fatal("starting up in ERROR mode! Check log or health check information for cause");
+                    LOGGER.fatal( "starting up in ERROR mode! Check log or health check information for cause" );
                     break;
 
                 default:
-                    LOGGER.trace("setting log level to TRACE because application mode is " + getApplicationMode());
+                    LOGGER.trace( "setting log level to TRACE because application mode is " + getApplicationMode() );
                     break;
             }
         }
 
         // get file lock
-        if (!pwmEnvironment.isInternalRuntimeInstance()) {
+        if ( !pwmEnvironment.isInternalRuntimeInstance() )
+        {
             pwmEnvironment.waitForFileLock();
         }
 
         // clear temp dir
-        if (!pwmEnvironment.isInternalRuntimeInstance()) {
+        if ( !pwmEnvironment.isInternalRuntimeInstance() )
+        {
             final File tempFileDirectory = getTempDirectory();
-            try {
-                FileSystemUtility.deleteDirectoryContents(tempFileDirectory);
-            } catch (Exception e) {
-                throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_STARTUP_ERROR,
-                        "unable to clear temp file directory '"+ tempFileDirectory.getAbsolutePath() + "', error: " + e.getMessage()
-                ));
+            try
+            {
+                FileSystemUtility.deleteDirectoryContents( tempFileDirectory );
+            }
+            catch ( Exception e )
+            {
+                throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_STARTUP_ERROR,
+                        "unable to clear temp file directory '" + tempFileDirectory.getAbsolutePath() + "', error: " + e.getMessage()
+                ) );
             }
         }
 
-        LOGGER.info("initializing, application mode=" + getApplicationMode()
-                + ", applicationPath=" + (pwmEnvironment.getApplicationPath() == null ? "null" : pwmEnvironment.getApplicationPath().getAbsolutePath())
-                + ", configFile=" + (pwmEnvironment.getConfigurationFile() == null ? "null" : pwmEnvironment.getConfigurationFile().getAbsolutePath())
+        LOGGER.info( "initializing, application mode=" + getApplicationMode()
+                + ", applicationPath=" + ( pwmEnvironment.getApplicationPath() == null ? "null" : pwmEnvironment.getApplicationPath().getAbsolutePath() )
+                + ", configFile=" + ( pwmEnvironment.getConfigurationFile() == null ? "null" : pwmEnvironment.getConfigurationFile().getAbsolutePath() )
         );
 
-        if (!pwmEnvironment.isInternalRuntimeInstance()) {
-            if (getApplicationMode() == PwmApplicationMode.ERROR || getApplicationMode() == PwmApplicationMode.NEW) {
-                LOGGER.warn("skipping LocalDB open due to application mode " + getApplicationMode());
-            } else {
-                this.localDB = Initializer.initializeLocalDB(this);
+        if ( !pwmEnvironment.isInternalRuntimeInstance() )
+        {
+            if ( getApplicationMode() == PwmApplicationMode.ERROR || getApplicationMode() == PwmApplicationMode.NEW )
+            {
+                LOGGER.warn( "skipping LocalDB open due to application mode " + getApplicationMode() );
+            }
+            else
+            {
+                this.localDB = Initializer.initializeLocalDB( this );
             }
         }
 
-        this.localDBLogger = PwmLogManager.initializeLocalDBLogger(this);
+        this.localDBLogger = PwmLogManager.initializeLocalDBLogger( this );
 
         // log the loaded configuration
-        LOGGER.debug("configuration load completed");
+        LOGGER.debug( "configuration load completed" );
 
         // read the pwm servlet instance id
-        instanceID = fetchInstanceID(localDB, this);
-        LOGGER.debug("using '" + getInstanceID() + "' for instance's ID (instanceID)");
+        instanceID = fetchInstanceID( localDB, this );
+        LOGGER.debug( "using '" + getInstanceID() + "' for instance's ID (instanceID)" );
 
         // read the pwm installation date
-        installTime = fetchInstallDate(startupTime);
-        LOGGER.debug("this application instance first installed on " + JavaHelper.toIsoDate(installTime));
+        installTime = fetchInstallDate( startupTime );
+        LOGGER.debug( "this application instance first installed on " + JavaHelper.toIsoDate( installTime ) );
 
-        LOGGER.debug("application environment flags: " + JsonUtil.serializeCollection(pwmEnvironment.getFlags()));
-        LOGGER.debug("application environment parameters: " + JsonUtil.serializeMap(pwmEnvironment.getParameters()));
+        LOGGER.debug( "application environment flags: " + JsonUtil.serializeCollection( pwmEnvironment.getFlags() ) );
+        LOGGER.debug( "application environment parameters: " + JsonUtil.serializeMap( pwmEnvironment.getParameters() ) );
 
         pwmServiceManager.initAllServices();
 
         final boolean skipPostInit = pwmEnvironment.isInternalRuntimeInstance()
-                || pwmEnvironment.getFlags().contains(PwmEnvironment.ApplicationFlag.CommandLineInstance);
+                || pwmEnvironment.getFlags().contains( PwmEnvironment.ApplicationFlag.CommandLineInstance );
 
-        if (!skipPostInit) {
-            final TimeDuration totalTime = TimeDuration.fromCurrent(startTime);
-            LOGGER.info(PwmConstants.PWM_APP_NAME + " " + PwmConstants.SERVLET_VERSION + " open for bidness! (" + totalTime.asCompactString() + ")");
-            StatisticsManager.incrementStat(this, Statistic.PWM_STARTUPS);
-            LOGGER.debug("buildTime=" + PwmConstants.BUILD_TIME + ", javaLocale=" + Locale.getDefault() + ", DefaultLocale=" + PwmConstants.DEFAULT_LOCALE);
-
-            final Thread postInitThread = new Thread(() -> postInitTasks());
-            postInitThread.setDaemon(true);
-            postInitThread.setName(JavaHelper.makeThreadName(this, PwmApplication.class));
+        if ( !skipPostInit )
+        {
+            final TimeDuration totalTime = TimeDuration.fromCurrent( startTime );
+            LOGGER.info( PwmConstants.PWM_APP_NAME + " " + PwmConstants.SERVLET_VERSION + " open for bidness! (" + totalTime.asCompactString() + ")" );
+            StatisticsManager.incrementStat( this, Statistic.PWM_STARTUPS );
+            LOGGER.debug( "buildTime=" + PwmConstants.BUILD_TIME + ", javaLocale=" + Locale.getDefault() + ", DefaultLocale=" + PwmConstants.DEFAULT_LOCALE );
+
+            final Thread postInitThread = new Thread( ( ) -> postInitTasks() );
+            postInitThread.setDaemon( true );
+            postInitThread.setName( JavaHelper.makeThreadName( this, PwmApplication.class ) );
             postInitThread.start();
         }
     }
 
-    private void postInitTasks()
+    private void postInitTasks( )
     {
         final Instant startTime = Instant.now();
 
-        LOGGER.debug("loaded configuration: " + pwmEnvironment.getConfig().toDebugString());
+        LOGGER.debug( "loaded configuration: " + pwmEnvironment.getConfig().toDebugString() );
 
         // detect if config has been modified since previous startup
-        try {
-            final String previousHash = readAppAttribute(AppAttribute.CONFIG_HASH, String.class);
+        try
+        {
+            final String previousHash = readAppAttribute( AppAttribute.CONFIG_HASH, String.class );
             final String currentHash = pwmEnvironment.getConfig().configurationHash();
-            if (previousHash == null || !previousHash.equals(currentHash)) {
-                writeAppAttribute(AppAttribute.CONFIG_HASH, currentHash);
-                LOGGER.warn("configuration checksum does not match previously seen checksum, configuration has been modified since last startup");
-                if (this.getAuditManager() != null) {
+            if ( previousHash == null || !previousHash.equals( currentHash ) )
+            {
+                writeAppAttribute( AppAttribute.CONFIG_HASH, currentHash );
+                LOGGER.warn( "configuration checksum does not match previously seen checksum, configuration has been modified since last startup" );
+                if ( this.getAuditManager() != null )
+                {
                     final String modifyMessage = "configuration was modified directly (not using ConfigEditor UI)";
-                    this.getAuditManager().submit(new AuditRecordFactory(this).createUserAuditRecord(
+                    this.getAuditManager().submit( new AuditRecordFactory( this ).createUserAuditRecord(
                             AuditEvent.MODIFY_CONFIGURATION,
                             null,
                             null,
                             modifyMessage
-                    ));
+                    ) );
                 }
             }
-        } catch (Exception e) {
-            LOGGER.debug("unable to detect if configuration has been modified since previous startup: " + e.getMessage());
+        }
+        catch ( Exception e )
+        {
+            LOGGER.debug( "unable to detect if configuration has been modified since previous startup: " + e.getMessage() );
         }
 
-        if (this.getConfig() != null) {
-            final Map<AppProperty,String> nonDefaultProperties = getConfig().readAllNonDefaultAppProperties();
-            if (nonDefaultProperties != null && !nonDefaultProperties.isEmpty()) {
-                final Map<String,String> tempMap = new LinkedHashMap<>();
-                for (final Map.Entry<AppProperty,String> entry : nonDefaultProperties.entrySet()) {
-                    tempMap.put(entry.getKey().getKey(), entry.getValue());
+        if ( this.getConfig() != null )
+        {
+            final Map<AppProperty, String> nonDefaultProperties = getConfig().readAllNonDefaultAppProperties();
+            if ( nonDefaultProperties != null && !nonDefaultProperties.isEmpty() )
+            {
+                final Map<String, String> tempMap = new LinkedHashMap<>();
+                for ( final Map.Entry<AppProperty, String> entry : nonDefaultProperties.entrySet() )
+                {
+                    tempMap.put( entry.getKey().getKey(), entry.getValue() );
                 }
-                LOGGER.trace("non-default app properties read from configuration: " + JsonUtil.serializeMap(tempMap));
-            } else {
-                LOGGER.trace("no non-default app properties in configuration");
+                LOGGER.trace( "non-default app properties read from configuration: " + JsonUtil.serializeMap( tempMap ) );
+            }
+            else
+            {
+                LOGGER.trace( "no non-default app properties in configuration" );
             }
         }
 
         // send system audit event
-        try {
-            final SystemAuditRecord auditRecord = new AuditRecordFactory(this).createSystemAuditRecord(
+        try
+        {
+            final SystemAuditRecord auditRecord = new AuditRecordFactory( this ).createSystemAuditRecord(
                     AuditEvent.STARTUP,
                     null
             );
-            getAuditManager().submit(auditRecord);
-        } catch (PwmException e) {
-            LOGGER.warn("unable to submit start alert event " + e.getMessage());
+            getAuditManager().submit( auditRecord );
+        }
+        catch ( PwmException e )
+        {
+            LOGGER.warn( "unable to submit start alert event " + e.getMessage() );
         }
 
-        try {
-            final Map<PwmAboutProperty,String> infoMap = PwmAboutProperty.makeInfoBean(this);
-            LOGGER.trace("application info: " + JsonUtil.serializeMap(infoMap));
-        } catch (Exception e) {
-            LOGGER.error("error generating about application bean: " + e.getMessage(), e);
+        try
+        {
+            final Map<PwmAboutProperty, String> infoMap = PwmAboutProperty.makeInfoBean( this );
+            LOGGER.trace( "application info: " + JsonUtil.serializeMap( infoMap ) );
+        }
+        catch ( Exception e )
+        {
+            LOGGER.error( "error generating about application bean: " + e.getMessage(), e );
         }
 
-        try {
-            this.getIntruderManager().clear(RecordType.USERNAME, PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME);
-        } catch (Exception e) {
-            LOGGER.warn("error while clearing configmanager-intruder-username from intruder table: " + e.getMessage());
+        try
+        {
+            this.getIntruderManager().clear( RecordType.USERNAME, PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME );
+        }
+        catch ( Exception e )
+        {
+            LOGGER.warn( "error while clearing configmanager-intruder-username from intruder table: " + e.getMessage() );
         }
 
-        if (!pwmEnvironment.isInternalRuntimeInstance()) {
-            try {
-                outputKeystore(this);
-            } catch (Exception e) {
-                LOGGER.debug("error while generating keystore output: " + e.getMessage());
+        if ( !pwmEnvironment.isInternalRuntimeInstance() )
+        {
+            try
+            {
+                outputKeystore( this );
+            }
+            catch ( Exception e )
+            {
+                LOGGER.debug( "error while generating keystore output: " + e.getMessage() );
             }
 
-            try {
-                outputTomcatConf(this);
-            } catch (Exception e) {
-                LOGGER.debug("error while generating tomcat conf output: " + e.getMessage());
+            try
+            {
+                outputTomcatConf( this );
+            }
+            catch ( Exception e )
+            {
+                LOGGER.debug( "error while generating tomcat conf output: " + e.getMessage() );
             }
         }
 
-        LOGGER.trace("completed post init tasks in " + TimeDuration.fromCurrent(startTime).asCompactString());
+        LOGGER.trace( "completed post init tasks in " + TimeDuration.fromCurrent( startTime ).asCompactString() );
     }
 
-    private static void outputKeystore(final PwmApplication pwmApplication) throws Exception
+    private static void outputKeystore( final PwmApplication pwmApplication ) throws Exception
     {
         final Map<PwmEnvironment.ApplicationParameter, String> applicationParams = pwmApplication.getPwmEnvironment().getParameters();
-        final String keystoreFileString = applicationParams.get(PwmEnvironment.ApplicationParameter.AutoExportHttpsKeyStoreFile);
-        if (keystoreFileString != null && !keystoreFileString.isEmpty()) {
-            LOGGER.trace("attempting to output keystore as configured by environment parameters to " + keystoreFileString);
-            final File keyStoreFile = new File(keystoreFileString);
-            final String password = applicationParams.get(PwmEnvironment.ApplicationParameter.AutoExportHttpsKeyStorePassword);
-            final String alias = applicationParams.get(PwmEnvironment.ApplicationParameter.AutoExportHttpsKeyStoreAlias);
-            final KeyStore keyStore = HttpsServerCertificateManager.keyStoreForApplication(pwmApplication, new PasswordData(password), alias);
+        final String keystoreFileString = applicationParams.get( PwmEnvironment.ApplicationParameter.AutoExportHttpsKeyStoreFile );
+        if ( keystoreFileString != null && !keystoreFileString.isEmpty() )
+        {
+            LOGGER.trace( "attempting to output keystore as configured by environment parameters to " + keystoreFileString );
+            final File keyStoreFile = new File( keystoreFileString );
+            final String password = applicationParams.get( PwmEnvironment.ApplicationParameter.AutoExportHttpsKeyStorePassword );
+            final String alias = applicationParams.get( PwmEnvironment.ApplicationParameter.AutoExportHttpsKeyStoreAlias );
+            final KeyStore keyStore = HttpsServerCertificateManager.keyStoreForApplication( pwmApplication, new PasswordData( password ), alias );
             final ByteArrayOutputStream outputContents = new ByteArrayOutputStream();
-            keyStore.store(outputContents, password.toCharArray());
-            if (keyStoreFile.exists()) {
-                LOGGER.trace("deleting existing keystore file " + keyStoreFile.getAbsolutePath());
-                if (keyStoreFile.delete()) {
-                    LOGGER.trace("deleted existing keystore file: " + keyStoreFile.getAbsolutePath());
+            keyStore.store( outputContents, password.toCharArray() );
+            if ( keyStoreFile.exists() )
+            {
+                LOGGER.trace( "deleting existing keystore file " + keyStoreFile.getAbsolutePath() );
+                if ( keyStoreFile.delete() )
+                {
+                    LOGGER.trace( "deleted existing keystore file: " + keyStoreFile.getAbsolutePath() );
                 }
             }
 
-            try (FileOutputStream fileOutputStream = new FileOutputStream(keyStoreFile)) {
-                fileOutputStream.write(outputContents.toByteArray());
+            try ( FileOutputStream fileOutputStream = new FileOutputStream( keyStoreFile ) )
+            {
+                fileOutputStream.write( outputContents.toByteArray() );
             }
 
-            LOGGER.info("successfully exported application https key to keystore file " + keyStoreFile.getAbsolutePath());
+            LOGGER.info( "successfully exported application https key to keystore file " + keyStoreFile.getAbsolutePath() );
         }
     }
 
-    private static void outputTomcatConf(final PwmApplication pwmApplication) throws IOException {
+    private static void outputTomcatConf( final PwmApplication pwmApplication ) throws IOException
+    {
         final Map<PwmEnvironment.ApplicationParameter, String> applicationParams = pwmApplication.getPwmEnvironment().getParameters();
-        final String tomcatOutputFileStr = applicationParams.get(PwmEnvironment.ApplicationParameter.AutoWriteTomcatConfOutputFile);
-        if (tomcatOutputFileStr != null && !tomcatOutputFileStr.isEmpty()) {
-            LOGGER.trace("attempting to output tomcat configuration file as configured by environment parameters to " + tomcatOutputFileStr);
-            final File tomcatOutputFile = new File(tomcatOutputFileStr);
+        final String tomcatOutputFileStr = applicationParams.get( PwmEnvironment.ApplicationParameter.AutoWriteTomcatConfOutputFile );
+        if ( tomcatOutputFileStr != null && !tomcatOutputFileStr.isEmpty() )
+        {
+            LOGGER.trace( "attempting to output tomcat configuration file as configured by environment parameters to " + tomcatOutputFileStr );
+            final File tomcatOutputFile = new File( tomcatOutputFileStr );
             final File tomcatSourceFile;
             {
-                final String tomcatSourceFileStr = applicationParams.get(PwmEnvironment.ApplicationParameter.AutoWriteTomcatConfSourceFile);
-                if (tomcatSourceFileStr != null && !tomcatSourceFileStr.isEmpty()) {
-                    tomcatSourceFile = new File(tomcatSourceFileStr);
-                    if (!tomcatSourceFile.exists()) {
-                        LOGGER.error("can not output tomcat configuration file, source file does not exist: " + tomcatSourceFile.getAbsolutePath());
+                final String tomcatSourceFileStr = applicationParams.get( PwmEnvironment.ApplicationParameter.AutoWriteTomcatConfSourceFile );
+                if ( tomcatSourceFileStr != null && !tomcatSourceFileStr.isEmpty() )
+                {
+                    tomcatSourceFile = new File( tomcatSourceFileStr );
+                    if ( !tomcatSourceFile.exists() )
+                    {
+                        LOGGER.error( "can not output tomcat configuration file, source file does not exist: " + tomcatSourceFile.getAbsolutePath() );
                         return;
                     }
-                } else {
-                    LOGGER.error("can not output tomcat configuration file, source file parameter '" + PwmEnvironment.ApplicationParameter.AutoWriteTomcatConfSourceFile.toString() + "' is not specified.");
+                }
+                else
+                {
+                    LOGGER.error( "can not output tomcat configuration file, source file parameter '"
+                            + PwmEnvironment.ApplicationParameter.AutoWriteTomcatConfSourceFile.toString() + "' is not specified." );
                     return;
                 }
             }
@@ -407,217 +460,261 @@ public class PwmApplication {
             final ByteArrayOutputStream outputContents = new ByteArrayOutputStream();
             ExportHttpsTomcatConfigCommand.TomcatConfigWriter.writeOutputFile(
                     pwmApplication.getConfig(),
-                    new FileInputStream(tomcatSourceFile),
+                    new FileInputStream( tomcatSourceFile ),
                     outputContents
             );
-            if (tomcatOutputFile.exists()) {
-                LOGGER.trace("deleting existing tomcat configuration file " + tomcatOutputFile.getAbsolutePath());
-                if (tomcatOutputFile.delete()) {
-                    LOGGER.trace("deleted existing tomcat configuration file: " + tomcatOutputFile.getAbsolutePath());
+            if ( tomcatOutputFile.exists() )
+            {
+                LOGGER.trace( "deleting existing tomcat configuration file " + tomcatOutputFile.getAbsolutePath() );
+                if ( tomcatOutputFile.delete() )
+                {
+                    LOGGER.trace( "deleted existing tomcat configuration file: " + tomcatOutputFile.getAbsolutePath() );
                 }
             }
 
-            try (FileOutputStream fileOutputStream = new FileOutputStream(tomcatOutputFile)) {
-                fileOutputStream.write(outputContents.toByteArray());
+            try ( FileOutputStream fileOutputStream = new FileOutputStream( tomcatOutputFile ) )
+            {
+                fileOutputStream.write( outputContents.toByteArray() );
             }
 
-            LOGGER.info("successfully wrote tomcat configuration to file " + tomcatOutputFile.getAbsolutePath());
+            LOGGER.info( "successfully wrote tomcat configuration to file " + tomcatOutputFile.getAbsolutePath() );
         }
     }
 
-    public String getInstanceID()
+    public String getInstanceID( )
     {
         return instanceID;
     }
 
-    public SharedHistoryManager getSharedHistoryManager()
+    public SharedHistoryManager getSharedHistoryManager( )
     {
-        return (SharedHistoryManager)pwmServiceManager.getService(SharedHistoryManager.class);
+        return ( SharedHistoryManager ) pwmServiceManager.getService( SharedHistoryManager.class );
     }
 
-    public IntruderManager getIntruderManager()
+    public IntruderManager getIntruderManager( )
     {
-        return (IntruderManager)pwmServiceManager.getService(IntruderManager.class);
+        return ( IntruderManager ) pwmServiceManager.getService( IntruderManager.class );
     }
 
-    public ChaiUser getProxiedChaiUser(final UserIdentity userIdentity)
+    public ChaiUser getProxiedChaiUser( final UserIdentity userIdentity )
             throws PwmUnrecoverableException
     {
-        try {
-            final ChaiProvider proxiedProvider = getProxyChaiProvider(userIdentity.getLdapProfileID());
-            return proxiedProvider.getEntryFactory().newChaiUser(userIdentity.getUserDN());
-        } catch (ChaiUnavailableException e) {
-            throw PwmUnrecoverableException.fromChaiException(e);
+        try
+        {
+            final ChaiProvider proxiedProvider = getProxyChaiProvider( userIdentity.getLdapProfileID() );
+            return proxiedProvider.getEntryFactory().newChaiUser( userIdentity.getUserDN() );
+        }
+        catch ( ChaiUnavailableException e )
+        {
+            throw PwmUnrecoverableException.fromChaiException( e );
         }
     }
 
-    public ChaiProvider getProxyChaiProvider(final String identifier)
+    public ChaiProvider getProxyChaiProvider( final String identifier )
             throws PwmUnrecoverableException
     {
-        return getLdapConnectionService().getProxyChaiProvider(identifier);
+        return getLdapConnectionService().getProxyChaiProvider( identifier );
     }
 
-    public LocalDBLogger getLocalDBLogger()
+    public LocalDBLogger getLocalDBLogger( )
     {
         return localDBLogger;
     }
 
-    public HealthMonitor getHealthMonitor()
+    public HealthMonitor getHealthMonitor( )
     {
-        return (HealthMonitor)pwmServiceManager.getService(HealthMonitor.class);
+        return ( HealthMonitor ) pwmServiceManager.getService( HealthMonitor.class );
     }
 
-    public List<PwmService> getPwmServices() {
+    public List<PwmService> getPwmServices( )
+    {
         final List<PwmService> pwmServices = new ArrayList<>();
-        pwmServices.add(this.localDBLogger);
-        pwmServices.addAll(this.pwmServiceManager.getRunningServices());
-        pwmServices.remove(null);
-        return Collections.unmodifiableList(pwmServices);
+        pwmServices.add( this.localDBLogger );
+        pwmServices.addAll( this.pwmServiceManager.getRunningServices() );
+        pwmServices.remove( null );
+        return Collections.unmodifiableList( pwmServices );
     }
 
-    public WordlistManager getWordlistManager() {
-        return (WordlistManager)pwmServiceManager.getService(WordlistManager.class);
+    public WordlistManager getWordlistManager( )
+    {
+        return ( WordlistManager ) pwmServiceManager.getService( WordlistManager.class );
     }
 
-    public SeedlistManager getSeedlistManager() {
-        return (SeedlistManager)pwmServiceManager.getService(SeedlistManager.class);
+    public SeedlistManager getSeedlistManager( )
+    {
+        return ( SeedlistManager ) pwmServiceManager.getService( SeedlistManager.class );
     }
 
-    public ReportService getReportService() {
-        return (ReportService)pwmServiceManager.getService(ReportService.class);
+    public ReportService getReportService( )
+    {
+        return ( ReportService ) pwmServiceManager.getService( ReportService.class );
     }
 
-    public EmailQueueManager getEmailQueue() {
-        return (EmailQueueManager)pwmServiceManager.getService(EmailQueueManager.class);
+    public EmailQueueManager getEmailQueue( )
+    {
+        return ( EmailQueueManager ) pwmServiceManager.getService( EmailQueueManager.class );
     }
 
-    public AuditService getAuditManager() {
-        return (AuditService)pwmServiceManager.getService(AuditService.class);
+    public AuditService getAuditManager( )
+    {
+        return ( AuditService ) pwmServiceManager.getService( AuditService.class );
     }
 
-    public SmsQueueManager getSmsQueue() {
-        return (SmsQueueManager)pwmServiceManager.getService(SmsQueueManager.class);
+    public SmsQueueManager getSmsQueue( )
+    {
+        return ( SmsQueueManager ) pwmServiceManager.getService( SmsQueueManager.class );
     }
 
-    public UrlShortenerService getUrlShortener() {
-        return (UrlShortenerService)pwmServiceManager.getService(UrlShortenerService.class);
+    public UrlShortenerService getUrlShortener( )
+    {
+        return ( UrlShortenerService ) pwmServiceManager.getService( UrlShortenerService.class );
     }
 
-    public UserSearchEngine getUserSearchEngine() {
-        return (UserSearchEngine)pwmServiceManager.getService(UserSearchEngine.class);
+    public UserSearchEngine getUserSearchEngine( )
+    {
+        return ( UserSearchEngine ) pwmServiceManager.getService( UserSearchEngine.class );
     }
 
-    public ClusterService getClusterService() {
-        return (ClusterService) pwmServiceManager.getService(ClusterService.class);
+    public ClusterService getClusterService( )
+    {
+        return ( ClusterService ) pwmServiceManager.getService( ClusterService.class );
     }
 
-    public ErrorInformation getLastLocalDBFailure() {
+    public ErrorInformation getLastLocalDBFailure( )
+    {
         return lastLocalDBFailure;
     }
 
-    public TokenService getTokenService() {
-        return (TokenService)pwmServiceManager.getService(TokenService.class);
+    public TokenService getTokenService( )
+    {
+        return ( TokenService ) pwmServiceManager.getService( TokenService.class );
     }
 
-    public LdapConnectionService getLdapConnectionService() {
-        return (LdapConnectionService)pwmServiceManager.getService(LdapConnectionService.class);
+    public LdapConnectionService getLdapConnectionService( )
+    {
+        return ( LdapConnectionService ) pwmServiceManager.getService( LdapConnectionService.class );
     }
 
-    public SessionTrackService getSessionTrackService() {
-        return (SessionTrackService)pwmServiceManager.getService(SessionTrackService.class);
+    public SessionTrackService getSessionTrackService( )
+    {
+        return ( SessionTrackService ) pwmServiceManager.getService( SessionTrackService.class );
     }
 
-    public ResourceServletService getResourceServletService() {
-        return (ResourceServletService)pwmServiceManager.getService(ResourceServletService.class);
+    public ResourceServletService getResourceServletService( )
+    {
+        return ( ResourceServletService ) pwmServiceManager.getService( ResourceServletService.class );
     }
 
-    public Configuration getConfig() {
+    public Configuration getConfig( )
+    {
         return pwmEnvironment.getConfig();
     }
 
-    public PwmApplicationMode getApplicationMode() {
+    public PwmApplicationMode getApplicationMode( )
+    {
         return pwmEnvironment.getApplicationMode();
     }
 
-    public DatabaseAccessor getDatabaseAccessor()
+    public DatabaseAccessor getDatabaseAccessor( )
 
             throws PwmUnrecoverableException
     {
         return getDatabaseService().getAccessor();
     }
 
-    public DatabaseService getDatabaseService() {
-        return (DatabaseService)pwmServiceManager.getService(DatabaseService.class);
+    public DatabaseService getDatabaseService( )
+    {
+        return ( DatabaseService ) pwmServiceManager.getService( DatabaseService.class );
     }
 
 
-
-    private Instant fetchInstallDate(final Instant startupTime) {
-        if (localDB != null) {
-            try {
-                final String storedDateStr = readAppAttribute(AppAttribute.INSTALL_DATE,String.class);
-                if (storedDateStr == null || storedDateStr.length() < 1) {
-                    writeAppAttribute(AppAttribute.INSTALL_DATE, String.valueOf(startupTime.toEpochMilli()));
-                } else {
-                    return Instant.ofEpochMilli(Long.parseLong(storedDateStr));
+    private Instant fetchInstallDate( final Instant startupTime )
+    {
+        if ( localDB != null )
+        {
+            try
+            {
+                final String storedDateStr = readAppAttribute( AppAttribute.INSTALL_DATE, String.class );
+                if ( storedDateStr == null || storedDateStr.length() < 1 )
+                {
+                    writeAppAttribute( AppAttribute.INSTALL_DATE, String.valueOf( startupTime.toEpochMilli() ) );
                 }
-            } catch (Exception e) {
-                LOGGER.error("error retrieving installation date from localDB: " + e.getMessage());
+                else
+                {
+                    return Instant.ofEpochMilli( Long.parseLong( storedDateStr ) );
+                }
+            }
+            catch ( Exception e )
+            {
+                LOGGER.error( "error retrieving installation date from localDB: " + e.getMessage() );
             }
         }
         return Instant.now();
     }
 
-    private String fetchInstanceID(final LocalDB localDB, final PwmApplication pwmApplication) {
-        String newInstanceID = pwmApplication.getConfig().readSettingAsString(PwmSetting.PWM_INSTANCE_NAME);
+    private String fetchInstanceID( final LocalDB localDB, final PwmApplication pwmApplication )
+    {
+        String newInstanceID = pwmApplication.getConfig().readSettingAsString( PwmSetting.PWM_INSTANCE_NAME );
 
-        if (newInstanceID != null && newInstanceID.trim().length() > 0) {
+        if ( newInstanceID != null && newInstanceID.trim().length() > 0 )
+        {
             return newInstanceID;
         }
 
-        newInstanceID = readAppAttribute(AppAttribute.INSTANCE_ID, String.class);
+        newInstanceID = readAppAttribute( AppAttribute.INSTANCE_ID, String.class );
 
-        if (newInstanceID == null || newInstanceID.length() < 1) {
-            newInstanceID = Long.toHexString(PwmRandom.getInstance().nextLong()).toUpperCase();
-            LOGGER.info("generated new random instanceID " + newInstanceID);
+        if ( newInstanceID == null || newInstanceID.length() < 1 )
+        {
+            newInstanceID = Long.toHexString( PwmRandom.getInstance().nextLong() ).toUpperCase();
+            LOGGER.info( "generated new random instanceID " + newInstanceID );
 
-            if (localDB != null) {
-                writeAppAttribute(AppAttribute.INSTANCE_ID, newInstanceID);
+            if ( localDB != null )
+            {
+                writeAppAttribute( AppAttribute.INSTANCE_ID, newInstanceID );
             }
-        } else {
-            LOGGER.trace("retrieved instanceID " + newInstanceID + "" + " from localDB");
+        }
+        else
+        {
+            LOGGER.trace( "retrieved instanceID " + newInstanceID + "" + " from localDB" );
         }
 
-        if (newInstanceID.length() < 1) {
+        if ( newInstanceID.length() < 1 )
+        {
             newInstanceID = DEFAULT_INSTANCE_ID;
         }
 
         return newInstanceID;
     }
 
-    public StatisticsManager getStatisticsManager() {
-        return (StatisticsManager)pwmServiceManager.getService(StatisticsManager.class);
+    public StatisticsManager getStatisticsManager( )
+    {
+        return ( StatisticsManager ) pwmServiceManager.getService( StatisticsManager.class );
     }
 
-    public OtpService getOtpService() {
-        return (OtpService)pwmServiceManager.getService(OtpService.class);
+    public OtpService getOtpService( )
+    {
+        return ( OtpService ) pwmServiceManager.getService( OtpService.class );
     }
 
-    public CrService getCrService() {
-        return (CrService)pwmServiceManager.getService(CrService.class);
+    public CrService getCrService( )
+    {
+        return ( CrService ) pwmServiceManager.getService( CrService.class );
     }
 
-    public SessionStateService getSessionStateService() {
-        return (SessionStateService)pwmServiceManager.getService(SessionStateService.class);
+    public SessionStateService getSessionStateService( )
+    {
+        return ( SessionStateService ) pwmServiceManager.getService( SessionStateService.class );
     }
 
 
-    public CacheService getCacheService() {
-        return (CacheService)pwmServiceManager.getService(CacheService.class);
+    public CacheService getCacheService( )
+    {
+        return ( CacheService ) pwmServiceManager.getService( CacheService.class );
     }
 
-    public SecureService getSecureService() {
-        return (SecureService)pwmServiceManager.getService(SecureService.class);
+    public SecureService getSecureService( )
+    {
+        return ( SecureService ) pwmServiceManager.getService( SecureService.class );
     }
 
     public void sendSmsUsingQueue(
@@ -625,196 +722,256 @@ public class PwmApplication {
             final String message,
             final SessionLabel sessionLabel,
             final MacroMachine macroMachine
-    ) {
+    )
+    {
         final SmsQueueManager smsQueue = getSmsQueue();
-        if (smsQueue == null) {
-            LOGGER.error(sessionLabel, "SMS queue is unavailable, unable to send SMS to: " + to);
+        if ( smsQueue == null )
+        {
+            LOGGER.error( sessionLabel, "SMS queue is unavailable, unable to send SMS to: " + to );
             return;
         }
 
         final SmsItemBean smsItemBean = new SmsItemBean(
-                macroMachine.expandMacros(to),
-                macroMachine.expandMacros(message),
+                macroMachine.expandMacros( to ),
+                macroMachine.expandMacros( message ),
                 sessionLabel
         );
 
-        try {
-            smsQueue.addSmsToQueue(smsItemBean);
-        } catch (PwmUnrecoverableException e) {
-            LOGGER.warn("unable to add sms to queue: " + e.getMessage());
+        try
+        {
+            smsQueue.addSmsToQueue( smsItemBean );
+        }
+        catch ( PwmUnrecoverableException e )
+        {
+            LOGGER.warn( "unable to add sms to queue: " + e.getMessage() );
         }
     }
 
-    public void shutdown() {
-        LOGGER.warn("shutting down");
+    public void shutdown( )
+    {
+        LOGGER.warn( "shutting down" );
         {
             // send system audit event
-            try {
-                final SystemAuditRecord auditRecord = new AuditRecordFactory(this).createSystemAuditRecord(
+            try
+            {
+                final SystemAuditRecord auditRecord = new AuditRecordFactory( this ).createSystemAuditRecord(
                         AuditEvent.SHUTDOWN,
                         null
                 );
-                if (getAuditManager() != null) {
-                    getAuditManager().submit(auditRecord);
+                if ( getAuditManager() != null )
+                {
+                    getAuditManager().submit( auditRecord );
                 }
-            } catch (PwmException e) {
-                LOGGER.warn("unable to submit shutdown alert event " + e.getMessage());
+            }
+            catch ( PwmException e )
+            {
+                LOGGER.warn( "unable to submit shutdown alert event " + e.getMessage() );
             }
         }
 
         pwmServiceManager.shutdownAllServices();
 
-        if (localDBLogger != null) {
-            try {
+        if ( localDBLogger != null )
+        {
+            try
+            {
                 localDBLogger.close();
-            } catch (Exception e) {
-                LOGGER.error("error closing localDBLogger: " + e.getMessage(),e);
+            }
+            catch ( Exception e )
+            {
+                LOGGER.error( "error closing localDBLogger: " + e.getMessage(), e );
             }
             localDBLogger = null;
         }
 
-        if (localDB != null) {
-            try {
-                LOGGER.trace("beginning close of LocalDB");
+        if ( localDB != null )
+        {
+            try
+            {
+                LOGGER.trace( "beginning close of LocalDB" );
                 localDB.close();
-            } catch (Exception e) {
-                LOGGER.fatal("error closing localDB: " + e, e);
+            }
+            catch ( Exception e )
+            {
+                LOGGER.fatal( "error closing localDB: " + e, e );
             }
             localDB = null;
         }
 
         pwmEnvironment.releaseFileLock();
 
-        LOGGER.info(PwmConstants.PWM_APP_NAME + " " + PwmConstants.SERVLET_VERSION + " closed for bidness, cya!");
+        LOGGER.info( PwmConstants.PWM_APP_NAME + " " + PwmConstants.SERVLET_VERSION + " closed for bidness, cya!" );
     }
 
-    public Instant getStartupTime() {
+    public Instant getStartupTime( )
+    {
         return startupTime;
     }
 
-    public Instant getInstallTime() {
+    public Instant getInstallTime( )
+    {
         return installTime;
     }
 
-    public LocalDB getLocalDB() {
+    public LocalDB getLocalDB( )
+    {
         return localDB;
     }
 
-    private static class Initializer {
+    private static class Initializer
+    {
 
-        public static LocalDB initializeLocalDB(final PwmApplication pwmApplication) throws PwmUnrecoverableException {
+        public static LocalDB initializeLocalDB( final PwmApplication pwmApplication ) throws PwmUnrecoverableException
+        {
             final File databaseDirectory;
             // see if META-INF isn't already there, then use WEB-INF.
-            try {
-                final String localDBLocationSetting = pwmApplication.getConfig().readAppProperty(AppProperty.LOCALDB_LOCATION);
-                databaseDirectory = FileSystemUtility.figureFilepath(localDBLocationSetting, pwmApplication.pwmEnvironment.getApplicationPath());
-            } catch (Exception e) {
-                pwmApplication.lastLocalDBFailure = new ErrorInformation(PwmError.ERROR_LOCALDB_UNAVAILABLE,"error locating configured LocalDB directory: " + e.getMessage());
-                LOGGER.warn(pwmApplication.lastLocalDBFailure.toDebugStr());
-                throw new PwmUnrecoverableException(pwmApplication.lastLocalDBFailure);
+            try
+            {
+                final String localDBLocationSetting = pwmApplication.getConfig().readAppProperty( AppProperty.LOCALDB_LOCATION );
+                databaseDirectory = FileSystemUtility.figureFilepath( localDBLocationSetting, pwmApplication.pwmEnvironment.getApplicationPath() );
+            }
+            catch ( Exception e )
+            {
+                pwmApplication.lastLocalDBFailure = new ErrorInformation( PwmError.ERROR_LOCALDB_UNAVAILABLE, "error locating configured LocalDB directory: " + e.getMessage() );
+                LOGGER.warn( pwmApplication.lastLocalDBFailure.toDebugStr() );
+                throw new PwmUnrecoverableException( pwmApplication.lastLocalDBFailure );
             }
 
-            LOGGER.debug("using localDB path " + databaseDirectory);
+            LOGGER.debug( "using localDB path " + databaseDirectory );
 
             // initialize the localDB
-            try {
+            try
+            {
                 final boolean readOnly = pwmApplication.getApplicationMode() == PwmApplicationMode.READ_ONLY;
-                return LocalDBFactory.getInstance(databaseDirectory, readOnly, pwmApplication, pwmApplication.getConfig());
-            } catch (Exception e) {
-                pwmApplication.lastLocalDBFailure = new ErrorInformation(PwmError.ERROR_LOCALDB_UNAVAILABLE,"unable to initialize LocalDB: " + e.getMessage());
-                LOGGER.warn(pwmApplication.lastLocalDBFailure.toDebugStr());
-                throw new PwmUnrecoverableException(pwmApplication.lastLocalDBFailure);
+                return LocalDBFactory.getInstance( databaseDirectory, readOnly, pwmApplication, pwmApplication.getConfig() );
+            }
+            catch ( Exception e )
+            {
+                pwmApplication.lastLocalDBFailure = new ErrorInformation( PwmError.ERROR_LOCALDB_UNAVAILABLE, "unable to initialize LocalDB: " + e.getMessage() );
+                LOGGER.warn( pwmApplication.lastLocalDBFailure.toDebugStr() );
+                throw new PwmUnrecoverableException( pwmApplication.lastLocalDBFailure );
             }
         }
     }
 
-    public PwmEnvironment getPwmEnvironment() {
+    public PwmEnvironment getPwmEnvironment( )
+    {
         return pwmEnvironment;
     }
 
-    public String getRuntimeNonce() {
+    public String getRuntimeNonce( )
+    {
         return runtimeNonce;
     }
 
-    public <T extends Serializable> T readAppAttribute(final AppAttribute appAttribute, final Class<T> returnClass) {
-        if (localDB == null || localDB.status() != LocalDB.Status.OPEN) {
-            LOGGER.error("error retrieving key '" + appAttribute.getKey() + "', localDB unavailable: ");
+    public <T extends Serializable> T readAppAttribute( final AppAttribute appAttribute, final Class<T> returnClass )
+    {
+        if ( localDB == null || localDB.status() != LocalDB.Status.OPEN )
+        {
+            LOGGER.error( "error retrieving key '" + appAttribute.getKey() + "', localDB unavailable: " );
             return null;
         }
 
-        if (appAttribute == null) {
+        if ( appAttribute == null )
+        {
             return null;
         }
 
-        try {
-            final String strValue = localDB.get(LocalDB.DB.PWM_META, appAttribute.getKey());
-            return JsonUtil.deserialize(strValue, returnClass);
-        } catch (Exception e) {
-            LOGGER.error("error retrieving key '" + appAttribute.getKey() + "' value from localDB: " + e.getMessage());
+        try
+        {
+            final String strValue = localDB.get( LocalDB.DB.PWM_META, appAttribute.getKey() );
+            return JsonUtil.deserialize( strValue, returnClass );
+        }
+        catch ( Exception e )
+        {
+            LOGGER.error( "error retrieving key '" + appAttribute.getKey() + "' value from localDB: " + e.getMessage() );
         }
         return null;
     }
 
-    public void writeAppAttribute(final AppAttribute appAttribute, final Serializable value) {
-        if (localDB == null || localDB.status() != LocalDB.Status.OPEN) {
-            LOGGER.error("error writing key '" + appAttribute.getKey() + "', localDB unavailable: ");
+    public void writeAppAttribute( final AppAttribute appAttribute, final Serializable value )
+    {
+        if ( localDB == null || localDB.status() != LocalDB.Status.OPEN )
+        {
+            LOGGER.error( "error writing key '" + appAttribute.getKey() + "', localDB unavailable: " );
             return;
         }
 
-        if (appAttribute == null) {
+        if ( appAttribute == null )
+        {
             return;
         }
 
-        try {
-            if (value == null) {
-                localDB.remove(LocalDB.DB.PWM_META, appAttribute.getKey());
-            } else {
-                final String jsonValue = JsonUtil.serialize(value);
-                localDB.put(LocalDB.DB.PWM_META, appAttribute.getKey(), jsonValue);
+        try
+        {
+            if ( value == null )
+            {
+                localDB.remove( LocalDB.DB.PWM_META, appAttribute.getKey() );
             }
-        } catch (Exception e) {
-            LOGGER.error("error retrieving key '" + appAttribute.getKey() + "' installation date from localDB: " + e.getMessage());
-            try {
-                localDB.remove(LocalDB.DB.PWM_META, appAttribute.getKey());
-            } catch (Exception e2) {
-                LOGGER.error("error removing bogus appAttribute value for key " + appAttribute.getKey() + ", error: " + localDB);
+            else
+            {
+                final String jsonValue = JsonUtil.serialize( value );
+                localDB.put( LocalDB.DB.PWM_META, appAttribute.getKey(), jsonValue );
+            }
+        }
+        catch ( Exception e )
+        {
+            LOGGER.error( "error retrieving key '" + appAttribute.getKey() + "' installation date from localDB: " + e.getMessage() );
+            try
+            {
+                localDB.remove( LocalDB.DB.PWM_META, appAttribute.getKey() );
+            }
+            catch ( Exception e2 )
+            {
+                LOGGER.error( "error removing bogus appAttribute value for key " + appAttribute.getKey() + ", error: " + localDB );
             }
         }
     }
 
-    public File getTempDirectory() throws PwmUnrecoverableException {
-        if (pwmEnvironment.getApplicationPath() == null) {
+    public File getTempDirectory( ) throws PwmUnrecoverableException
+    {
+        if ( pwmEnvironment.getApplicationPath() == null )
+        {
             final ErrorInformation errorInformation = new ErrorInformation(
                     PwmError.ERROR_STARTUP_ERROR,
                     "unable to establish temp work directory: application path unavailable"
             );
-            throw new PwmUnrecoverableException(errorInformation);
-        }
-        final File tempDirectory = new File(pwmEnvironment.getApplicationPath() + File.separator + "temp");
-        if (!tempDirectory.exists()) {
-            LOGGER.trace("preparing to create temporary directory " + tempDirectory.getAbsolutePath());
-            if (tempDirectory.mkdir()) {
-                LOGGER.debug("created " + tempDirectory.getAbsolutePath());
-            } else {
-                LOGGER.debug("unable to create temporary directory " + tempDirectory.getAbsolutePath());
+            throw new PwmUnrecoverableException( errorInformation );
+        }
+        final File tempDirectory = new File( pwmEnvironment.getApplicationPath() + File.separator + "temp" );
+        if ( !tempDirectory.exists() )
+        {
+            LOGGER.trace( "preparing to create temporary directory " + tempDirectory.getAbsolutePath() );
+            if ( tempDirectory.mkdir() )
+            {
+                LOGGER.debug( "created " + tempDirectory.getAbsolutePath() );
+            }
+            else
+            {
+                LOGGER.debug( "unable to create temporary directory " + tempDirectory.getAbsolutePath() );
                 final ErrorInformation errorInformation = new ErrorInformation(
                         PwmError.ERROR_STARTUP_ERROR,
                         "unable to establish create temp work directory " + tempDirectory.getAbsolutePath()
                 );
-                throw new PwmUnrecoverableException(errorInformation);
+                throw new PwmUnrecoverableException( errorInformation );
             }
         }
         return tempDirectory;
     }
 
-    public boolean determineIfDetailErrorMsgShown() {
+    public boolean determineIfDetailErrorMsgShown( )
+    {
         final PwmApplicationMode mode = this.getApplicationMode();
-        if (mode == PwmApplicationMode.CONFIGURATION || mode == PwmApplicationMode.NEW) {
+        if ( mode == PwmApplicationMode.CONFIGURATION || mode == PwmApplicationMode.NEW )
+        {
             return true;
         }
-        if (mode == PwmApplicationMode.RUNNING) {
-            if (this.getConfig() != null) {
-                if (this.getConfig().readSettingAsBoolean(PwmSetting.DISPLAY_SHOW_DETAILED_ERRORS)) {
+        if ( mode == PwmApplicationMode.RUNNING )
+        {
+            if ( this.getConfig() != null )
+            {
+                if ( this.getConfig().readSettingAsBoolean( PwmSetting.DISPLAY_SHOW_DETAILED_ERRORS ) )
+                {
                     return true;
                 }
             }

+ 1 - 0
server/src/main/java/password/pwm/PwmEnvironment.java

@@ -145,6 +145,7 @@ public class PwmEnvironment
         }
     }
 
+    @SuppressWarnings( "checkstyle:ParameterNumber" )
     private PwmEnvironment(
             final PwmApplicationMode applicationMode,
             final Configuration config,

+ 4 - 3
server/src/main/java/password/pwm/bean/TelemetryPublishBean.java

@@ -33,16 +33,17 @@ import java.util.Map;
 
 @Getter
 @Builder
-public class TelemetryPublishBean implements Serializable {
+public class TelemetryPublishBean implements Serializable
+{
     private final Instant timestamp;
     private final String id;
     private final String instanceHash;
     private final String siteDescription;
     private final Instant installTime;
     private final List<PwmLdapVendor> ldapVendor;
-    private final Map<String,String> statistics;
+    private final Map<String, String> statistics;
     private final List<String> configuredSettings;
     private final String versionBuild;
     private final String versionVersion;
-    private final Map<String,String> about;
+    private final Map<String, String> about;
 }

File diff suppressed because it is too large
+ 488 - 492
server/src/main/java/password/pwm/config/PwmSetting.java


+ 17 - 11
server/src/main/java/password/pwm/config/function/SMSGatewayCertImportFunction.java

@@ -31,28 +31,34 @@ import password.pwm.error.PwmOperationalException;
 
 import java.net.URI;
 
-public class SMSGatewayCertImportFunction extends AbstractUriCertImportFunction {
+public class SMSGatewayCertImportFunction extends AbstractUriCertImportFunction
+{
 
 
     @Override
-    String getUri(final StoredConfigurationImpl storedConfiguration, final PwmSetting pwmSetting, final String profile, final String extraData) throws PwmOperationalException {
+    String getUri( final StoredConfigurationImpl storedConfiguration, final PwmSetting pwmSetting, final String profile, final String extraData ) throws PwmOperationalException
+    {
 
 
         final String uriString;
         final String menuDebugLocation;
 
-        uriString = (String)storedConfiguration.readSetting(PwmSetting.SMS_GATEWAY_URL).toNativeObject();
+        uriString = ( String ) storedConfiguration.readSetting( PwmSetting.SMS_GATEWAY_URL ).toNativeObject();
         menuDebugLocation = PwmSetting.SMS_GATEWAY_URL.toMenuLocationDebug( null, PwmConstants.DEFAULT_LOCALE );
 
-        if (uriString.isEmpty()) {
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR,"Setting " + menuDebugLocation + " must first be configured");
-            throw new PwmOperationalException(errorInformation);
+        if ( uriString.isEmpty() )
+        {
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.CONFIG_FORMAT_ERROR, "Setting " + menuDebugLocation + " must first be configured" );
+            throw new PwmOperationalException( errorInformation );
         }
-        try {
-            URI.create(uriString);
-        } catch (IllegalArgumentException e) {
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR,"Setting " + menuDebugLocation + " has an invalid URL syntax");
-            throw new PwmOperationalException(errorInformation);
+        try
+        {
+            URI.create( uriString );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.CONFIG_FORMAT_ERROR, "Setting " + menuDebugLocation + " has an invalid URL syntax" );
+            throw new PwmOperationalException( errorInformation );
         }
         return uriString;
     }

+ 4 - 1
server/src/main/java/password/pwm/config/option/ConfigurationOption.java

@@ -22,6 +22,9 @@
 
 package password.pwm.config.option;
 
+/**
+ * Marker interface.
+ */
 public interface ConfigurationOption
-{ /* marker interface */
+{
 }

+ 2 - 1
server/src/main/java/password/pwm/config/option/SyslogOutputFormat.java

@@ -1,6 +1,7 @@
 package password.pwm.config.option;
 
-public enum SyslogOutputFormat {
+public enum SyslogOutputFormat
+{
     JSON,
     CEF,
 }

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

@@ -154,6 +154,7 @@ public class LDAPStatusChecker implements HealthChecker
         return returnRecords;
     }
 
+    @SuppressWarnings( "checkstyle:MethodLength" )
     public List<HealthRecord> doLdapTestUserCheck(
             final Configuration config,
             final LdapProfile ldapProfile,
@@ -987,11 +988,11 @@ public class LDAPStatusChecker implements HealthChecker
         {
             return false;
         }
-        final String[] EXAMPLE_SUFFIXES = new String[] {
+        final String[] exampleSuffixes = new String[] {
                 "DC=site,DC=example,DC=net",
                 "ou=groups,o=example",
         };
-        for ( final String suffix : EXAMPLE_SUFFIXES )
+        for ( final String suffix : exampleSuffixes )
         {
             if ( dnValue.endsWith( suffix ) )
             {

+ 112 - 80
server/src/main/java/password/pwm/http/PwmResponse.java

@@ -48,30 +48,33 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
-public class PwmResponse extends PwmHttpResponseWrapper {
-    private static final PwmLogger LOGGER = PwmLogger.forClass(PwmResponse.class);
+public class PwmResponse extends PwmHttpResponseWrapper
+{
+    private static final PwmLogger LOGGER = PwmLogger.forClass( PwmResponse.class );
 
     private final PwmRequest pwmRequest;
 
-    public enum Flag {
+    public enum Flag
+    {
         AlwaysShowMessage,
         ForceLogout,
     }
 
-    public enum RedirectType {
-        Permanent_301(HttpServletResponse.SC_MOVED_PERMANENTLY),
-        Found_302(HttpServletResponse.SC_FOUND),
-        Other_303(303),
-
-        ;
+    public enum RedirectType
+    {
+        Permanent_301( HttpServletResponse.SC_MOVED_PERMANENTLY ),
+        Found_302( HttpServletResponse.SC_FOUND ),
+        Other_303( 303 ),;
 
         private final int code;
 
-        RedirectType(final int code) {
+        RedirectType( final int code )
+        {
             this.code = code;
         }
 
-        public int getCode() {
+        public int getCode( )
+        {
             return code;
         }
     }
@@ -80,18 +83,21 @@ public class PwmResponse extends PwmHttpResponseWrapper {
             final HttpServletResponse response,
             final PwmRequest pwmRequest,
             final Configuration configuration
-    ) {
-        super(pwmRequest.getHttpServletRequest(), response, configuration);
+    )
+    {
+        super( pwmRequest.getHttpServletRequest(), response, configuration );
         this.pwmRequest = pwmRequest;
     }
 
-    @SuppressFBWarnings("DE_MIGHT_IGNORE") // its okay to disappear the exception during logging
+    // its okay to disappear the exception during logging
+    @SuppressFBWarnings( "DE_MIGHT_IGNORE" )
     public void forwardToJsp(
             final JspUrl jspURL
     )
             throws ServletException, IOException, PwmUnrecoverableException
     {
-        if (!pwmRequest.isFlag(PwmRequestFlag.NO_REQ_COUNTER)) {
+        if ( !pwmRequest.isFlag( PwmRequestFlag.NO_REQ_COUNTER ) )
+        {
             pwmRequest.getPwmSession().getSessionManager().incrementRequestCounterKey();
         }
 
@@ -100,46 +106,53 @@ public class PwmResponse extends PwmHttpResponseWrapper {
         final HttpServletRequest httpServletRequest = pwmRequest.getHttpServletRequest();
         final ServletContext servletContext = httpServletRequest.getSession().getServletContext();
         final String url = jspURL.getPath();
-        try {
-            LOGGER.trace(pwmRequest.getSessionLabel(), "forwarding to " + url);
-        } catch (Exception e) {
+        try
+        {
+            LOGGER.trace( pwmRequest.getSessionLabel(), "forwarding to " + url );
+        }
+        catch ( Exception e )
+        {
             /* noop, server may not be up enough to do the log output */
         }
-        servletContext.getRequestDispatcher(url).forward(httpServletRequest, this.getHttpServletResponse());
+        servletContext.getRequestDispatcher( url ).forward( httpServletRequest, this.getHttpServletResponse() );
     }
 
-    public void forwardToSuccessPage(final Message message, final String... field)
+    public void forwardToSuccessPage( final Message message, final String... field )
             throws ServletException, PwmUnrecoverableException, IOException
 
     {
-        final String messageStr = Message.getLocalizedMessage(pwmRequest.getLocale(), message, pwmRequest.getConfig(), field);
-        forwardToSuccessPage(messageStr);
+        final String messageStr = Message.getLocalizedMessage( pwmRequest.getLocale(), message, pwmRequest.getConfig(), field );
+        forwardToSuccessPage( messageStr );
     }
 
-    public void forwardToSuccessPage(final String message, final Flag... flags)
+    public void forwardToSuccessPage( final String message, final Flag... flags )
             throws ServletException, PwmUnrecoverableException, IOException
 
     {
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
         final PwmSession pwmSession = pwmRequest.getPwmSession();
-        this.pwmRequest.setAttribute(PwmRequestAttribute.SuccessMessage, message);
+        this.pwmRequest.setAttribute( PwmRequestAttribute.SuccessMessage, message );
 
-        final boolean showMessage = !pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.DISPLAY_SUCCESS_PAGES)
-                && !Arrays.asList(flags).contains(Flag.AlwaysShowMessage);
+        final boolean showMessage = !pwmApplication.getConfig().readSettingAsBoolean( PwmSetting.DISPLAY_SUCCESS_PAGES )
+                && !Arrays.asList( flags ).contains( Flag.AlwaysShowMessage );
 
-        if (showMessage) {
-            LOGGER.trace(pwmSession, "skipping success page due to configuration setting.");
+        if ( showMessage )
+        {
+            LOGGER.trace( pwmSession, "skipping success page due to configuration setting." );
             final String redirectUrl = pwmRequest.getContextPath()
-                    +  PwmServletDefinition.PublicCommand.servletUrl()
+                    + PwmServletDefinition.PublicCommand.servletUrl()
                     + "?processAction=next";
-            sendRedirect(redirectUrl);
+            sendRedirect( redirectUrl );
             return;
         }
 
-        try {
-            forwardToJsp(JspUrl.SUCCESS);
-        } catch (PwmUnrecoverableException e) {
-            LOGGER.error("unexpected error sending user to success page: " + e.toString());
+        try
+        {
+            forwardToJsp( JspUrl.SUCCESS );
+        }
+        catch ( PwmUnrecoverableException e )
+        {
+            LOGGER.error( "unexpected error sending user to success page: " + e.toString() );
         }
     }
 
@@ -149,111 +162,130 @@ public class PwmResponse extends PwmHttpResponseWrapper {
     )
             throws IOException, ServletException
     {
-        LOGGER.error(pwmRequest.getSessionLabel(), errorInformation);
+        LOGGER.error( pwmRequest.getSessionLabel(), errorInformation );
 
-        pwmRequest.setAttribute(PwmRequestAttribute.PwmErrorInfo, errorInformation);
+        pwmRequest.setAttribute( PwmRequestAttribute.PwmErrorInfo, errorInformation );
 
-        if (JavaHelper.enumArrayContainsValue(flags, Flag.ForceLogout)) {
-            LOGGER.debug(pwmRequest, "forcing logout due to error " + errorInformation.toDebugStr());
-            pwmRequest.getPwmSession().unauthenticateUser(pwmRequest);
+        if ( JavaHelper.enumArrayContainsValue( flags, Flag.ForceLogout ) )
+        {
+            LOGGER.debug( pwmRequest, "forcing logout due to error " + errorInformation.toDebugStr() );
+            pwmRequest.getPwmSession().unauthenticateUser( pwmRequest );
         }
 
-        if (getResponseFlags().contains(PwmResponseFlag.ERROR_RESPONSE_SENT)) {
-            LOGGER.debug(pwmRequest, "response error has been previously set, disregarding new error: " + errorInformation.toDebugStr());
+        if ( getResponseFlags().contains( PwmResponseFlag.ERROR_RESPONSE_SENT ) )
+        {
+            LOGGER.debug( pwmRequest, "response error has been previously set, disregarding new error: " + errorInformation.toDebugStr() );
             return;
         }
 
-        if (isCommitted()) {
+        if ( isCommitted() )
+        {
             final String msg = "cannot respond with error '" + errorInformation.toDebugStr() + "', response is already committed";
-            LOGGER.warn(pwmRequest.getSessionLabel(), ExceptionUtils.getStackTrace(new Throwable(msg)));
+            LOGGER.warn( pwmRequest.getSessionLabel(), ExceptionUtils.getStackTrace( new Throwable( msg ) ) );
             return;
         }
 
-        if (pwmRequest.isJsonRequest()) {
-            outputJsonResult(RestResultBean.fromError(errorInformation, pwmRequest));
-        } else if (pwmRequest.isHtmlRequest()) {
-            try {
-                forwardToJsp(JspUrl.ERROR);
-            } catch (PwmUnrecoverableException e) {
-                LOGGER.error("unexpected error sending user to error page: " + e.toString());
+        if ( pwmRequest.isJsonRequest() )
+        {
+            outputJsonResult( RestResultBean.fromError( errorInformation, pwmRequest ) );
+        }
+        else if ( pwmRequest.isHtmlRequest() )
+        {
+            try
+            {
+                forwardToJsp( JspUrl.ERROR );
+            }
+            catch ( PwmUnrecoverableException e )
+            {
+                LOGGER.error( "unexpected error sending user to error page: " + e.toString() );
             }
-        } else {
+        }
+        else
+        {
             final boolean showDetail = pwmRequest.getPwmApplication().determineIfDetailErrorMsgShown();
             final String errorStatusText = showDetail
                     ? errorInformation.toDebugStr()
-                    : errorInformation.toUserStr(pwmRequest.getPwmSession(),pwmRequest.getPwmApplication());
-            getHttpServletResponse().sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, errorStatusText);
+                    : errorInformation.toUserStr( pwmRequest.getPwmSession(), pwmRequest.getPwmApplication() );
+            getHttpServletResponse().sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, errorStatusText );
         }
 
-        setResponseFlag(PwmResponseFlag.ERROR_RESPONSE_SENT);
+        setResponseFlag( PwmResponseFlag.ERROR_RESPONSE_SENT );
     }
 
 
     public void outputJsonResult(
             final RestResultBean restResultBean
     )
-            throws IOException {
+            throws IOException
+    {
         preCommitActions();
         final HttpServletResponse resp = this.getHttpServletResponse();
         final String outputString = restResultBean.toJson();
-        resp.setContentType(HttpContentType.json.getHeaderValue());
-        resp.getWriter().print(outputString);
+        resp.setContentType( HttpContentType.json.getHeaderValue() );
+        resp.getWriter().print( outputString );
         resp.getWriter().close();
     }
 
 
-    public void writeEncryptedCookie(final String cookieName, final Serializable cookieValue, final CookiePath path)
+    public void writeEncryptedCookie( final String cookieName, final Serializable cookieValue, final CookiePath path )
             throws PwmUnrecoverableException
     {
-        writeEncryptedCookie(cookieName, cookieValue, -1, path);
+        writeEncryptedCookie( cookieName, cookieValue, -1, path );
     }
 
-    public void writeEncryptedCookie(final String cookieName, final Serializable cookieValue, final int seconds, final CookiePath path)
+    public void writeEncryptedCookie( final String cookieName, final Serializable cookieValue, final int seconds, final CookiePath path )
             throws PwmUnrecoverableException
     {
-        final String jsonValue = JsonUtil.serialize(cookieValue);
-        final String encryptedValue = pwmRequest.getPwmApplication().getSecureService().encryptToString(jsonValue);
-        writeCookie(cookieName, encryptedValue, seconds, path, PwmHttpResponseWrapper.Flag.BypassSanitation);
+        final String jsonValue = JsonUtil.serialize( cookieValue );
+        final String encryptedValue = pwmRequest.getPwmApplication().getSecureService().encryptToString( jsonValue );
+        writeCookie( cookieName, encryptedValue, seconds, path, PwmHttpResponseWrapper.Flag.BypassSanitation );
     }
 
-    public void markAsDownload(final HttpContentType contentType, final String filename) {
-        this.setHeader(HttpHeader.ContentDisposition,"attachment; fileName=" + filename);
-        this.setContentType(contentType);
+    public void markAsDownload( final HttpContentType contentType, final String filename )
+    {
+        this.setHeader( HttpHeader.ContentDisposition, "attachment; fileName=" + filename );
+        this.setContentType( contentType );
     }
 
-    public void sendRedirect(final String url)
+    public void sendRedirect( final String url )
             throws IOException
     {
-        sendRedirect(url, RedirectType.Found_302);
+        sendRedirect( url, RedirectType.Found_302 );
     }
 
-    public void sendRedirect(final String url, final RedirectType redirectType)
+    public void sendRedirect( final String url, final RedirectType redirectType )
             throws IOException
     {
         preCommitActions();
 
         final HttpServletResponse resp = pwmRequest.getPwmResponse().getHttpServletResponse();
-        resp.setStatus(redirectType.getCode()); // http "other" redirect
-        resp.setHeader(HttpHeader.Location.getHttpName(), url);
-        LOGGER.trace(pwmRequest, "sending " + redirectType.getCode() + " redirect to " + url);
+        resp.setStatus( redirectType.getCode() );
+
+        // http "other" redirect
+        resp.setHeader( HttpHeader.Location.getHttpName(), url );
+        LOGGER.trace( pwmRequest, "sending " + redirectType.getCode() + " redirect to " + url );
     }
 
-    private void preCommitActions() {
-        if (pwmRequest.getPwmResponse().isCommitted()) {
+    private void preCommitActions( )
+    {
+        if ( pwmRequest.getPwmResponse().isCommitted() )
+        {
             return;
         }
 
-        pwmRequest.getPwmApplication().getSessionStateService().saveLoginSessionState(pwmRequest);
-        pwmRequest.getPwmApplication().getSessionStateService().saveSessionBeans(pwmRequest);
+        pwmRequest.getPwmApplication().getSessionStateService().saveLoginSessionState( pwmRequest );
+        pwmRequest.getPwmApplication().getSessionStateService().saveSessionBeans( pwmRequest );
     }
 
     private final Set<PwmResponseFlag> pwmResponseFlags = new HashSet<>();
 
-    private Collection<PwmResponseFlag> getResponseFlags() {
-        return Collections.unmodifiableSet(pwmResponseFlags);
+    private Collection<PwmResponseFlag> getResponseFlags( )
+    {
+        return Collections.unmodifiableSet( pwmResponseFlags );
     }
 
-    private void setResponseFlag(final PwmResponseFlag flag) {
-        pwmResponseFlags.add(flag);
+    private void setResponseFlag( final PwmResponseFlag flag )
+    {
+        pwmResponseFlags.add( flag );
     }
 }

+ 180 - 120
server/src/main/java/password/pwm/http/filter/ConfigAccessFilter.java

@@ -62,39 +62,49 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-public class ConfigAccessFilter extends AbstractPwmFilter {
-    private static final PwmLogger LOGGER = PwmLogger.forClass(ConfigAccessFilter.class);
+public class ConfigAccessFilter extends AbstractPwmFilter
+{
+    private static final PwmLogger LOGGER = PwmLogger.forClass( ConfigAccessFilter.class );
 
 
     @Override
-    void processFilter(final PwmApplicationMode mode, final PwmRequest pwmRequest, final PwmFilterChain filterChain) throws PwmException, IOException, ServletException {
+    void processFilter( final PwmApplicationMode mode, final PwmRequest pwmRequest, final PwmFilterChain filterChain ) throws PwmException, IOException, ServletException
+    {
         final PwmApplicationMode appMode = pwmRequest.getPwmApplication().getApplicationMode();
-        if (appMode == PwmApplicationMode.NEW) {
+        if ( appMode == PwmApplicationMode.NEW )
+        {
             filterChain.doFilter();
             return;
         }
 
         final boolean blockOldIE = Boolean.parseBoolean( pwmRequest.getPwmApplication().getConfig().readAppProperty( AppProperty.CONFIG_EDITOR_BLOCK_OLD_IE ) );
-        if (blockOldIE) {
-            try {
+        if ( blockOldIE )
+        {
+            try
+            {
                 UserAgentUtils.checkIfPreIE11( pwmRequest );
-            } catch ( PwmException e ) {
+            }
+            catch ( PwmException e )
+            {
                 pwmRequest.respondWithError( e.getErrorInformation() );
                 return;
             }
         }
 
-        final ConfigManagerBean configManagerBean = pwmRequest.getPwmApplication().getSessionStateService().getBean(pwmRequest, ConfigManagerBean.class);
-        if (checkAuthentication(pwmRequest, configManagerBean) == ProcessStatus.Continue) {
+        final ConfigManagerBean configManagerBean = pwmRequest.getPwmApplication().getSessionStateService().getBean( pwmRequest, ConfigManagerBean.class );
+        if ( checkAuthentication( pwmRequest, configManagerBean ) == ProcessStatus.Continue )
+        {
             filterChain.doFilter();
         }
     }
 
     @Override
-    boolean isInterested(final PwmApplicationMode mode, final PwmURL pwmURL) {
+    boolean isInterested( final PwmApplicationMode mode, final PwmURL pwmURL )
+    {
         return pwmURL.isConfigManagerURL();
     }
 
+    @SuppressWarnings( "checkstyle:MethodLength" )
     static ProcessStatus checkAuthentication(
             final PwmRequest pwmRequest,
             final ConfigManagerBean configManagerBean
@@ -103,187 +113,226 @@ public class ConfigAccessFilter extends AbstractPwmFilter {
     {
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
         final PwmSession pwmSession = pwmRequest.getPwmSession();
-        final ConfigurationReader runningConfigReader = ContextManager.getContextManager(pwmRequest.getHttpServletRequest().getSession()).getConfigReader();
+        final ConfigurationReader runningConfigReader = ContextManager.getContextManager( pwmRequest.getHttpServletRequest().getSession() ).getConfigReader();
         final StoredConfigurationImpl storedConfig = runningConfigReader.getStoredConfiguration();
 
         boolean authRequired = false;
-        if (storedConfig.hasPassword()) {
+        if ( storedConfig.hasPassword() )
+        {
             authRequired = true;
         }
 
-        if (PwmApplicationMode.RUNNING == pwmRequest.getPwmApplication().getApplicationMode()) {
-            if (!pwmRequest.isAuthenticated()) {
-                throw new PwmUnrecoverableException(PwmError.ERROR_AUTHENTICATION_REQUIRED);
+        if ( PwmApplicationMode.RUNNING == pwmRequest.getPwmApplication().getApplicationMode() )
+        {
+            if ( !pwmRequest.isAuthenticated() )
+            {
+                throw new PwmUnrecoverableException( PwmError.ERROR_AUTHENTICATION_REQUIRED );
             }
 
-            if (!pwmRequest.getPwmSession().getSessionManager().checkPermission(pwmRequest.getPwmApplication(), Permission.PWMADMIN)) {
-                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNAUTHORIZED);
-                denyAndError(pwmRequest, errorInformation);
+            if ( !pwmRequest.getPwmSession().getSessionManager().checkPermission( pwmRequest.getPwmApplication(), Permission.PWMADMIN ) )
+            {
+                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_UNAUTHORIZED );
+                denyAndError( pwmRequest, errorInformation );
                 return ProcessStatus.Halt;
             }
         }
 
-        if (PwmApplicationMode.CONFIGURATION != pwmRequest.getPwmApplication().getApplicationMode()) {
+        if ( PwmApplicationMode.CONFIGURATION != pwmRequest.getPwmApplication().getApplicationMode() )
+        {
             authRequired = true;
         }
 
-        if (!authRequired) {
+        if ( !authRequired )
+        {
             return ProcessStatus.Continue;
         }
 
-        if (!storedConfig.hasPassword()) {
+        if ( !storedConfig.hasPassword() )
+        {
             final String errorMsg = "config file does not have a configuration password";
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR,errorMsg,new String[]{errorMsg});
-            return denyAndError(pwmRequest, errorInformation);
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.CONFIG_FORMAT_ERROR, errorMsg, new String[]
+                    {
+                            errorMsg,
+                    }
+                    );
+            return denyAndError( pwmRequest, errorInformation );
         }
 
-        if (configManagerBean.isPasswordVerified()) {
+        if ( configManagerBean.isPasswordVerified() )
+        {
             return ProcessStatus.Continue;
         }
 
         String persistentLoginValue = null;
         boolean persistentLoginAccepted = false;
         boolean persistentLoginEnabled = false;
-        if (pwmRequest.getConfig().isDefaultValue(PwmSetting.PWM_SECURITY_KEY)) {
-            LOGGER.debug(pwmRequest, "security not available, persistent login not possible.");
-        } else {
+        if ( pwmRequest.getConfig().isDefaultValue( PwmSetting.PWM_SECURITY_KEY ) )
+        {
+            LOGGER.debug( pwmRequest, "security not available, persistent login not possible." );
+        }
+        else
+        {
             persistentLoginEnabled = true;
             final PwmSecurityKey securityKey = pwmRequest.getConfig().getSecurityKey();
 
-            if (PwmApplicationMode.RUNNING == pwmRequest.getPwmApplication().getApplicationMode()) {
+            if ( PwmApplicationMode.RUNNING == pwmRequest.getPwmApplication().getApplicationMode() )
+            {
                 persistentLoginValue = SecureEngine.hash(
-                        storedConfig.readConfigProperty(ConfigurationProperty.PASSWORD_HASH)
+                        storedConfig.readConfigProperty( ConfigurationProperty.PASSWORD_HASH )
                                 + pwmSession.getUserInfo().getUserIdentity().toDelimitedKey(),
-                        PwmHashAlgorithm.SHA512);
+                        PwmHashAlgorithm.SHA512 );
 
-            } else {
+            }
+            else
+            {
                 persistentLoginValue = SecureEngine.hash(
-                        storedConfig.readConfigProperty(ConfigurationProperty.PASSWORD_HASH),
-                        PwmHashAlgorithm.SHA512);
+                        storedConfig.readConfigProperty( ConfigurationProperty.PASSWORD_HASH ),
+                        PwmHashAlgorithm.SHA512 );
             }
 
             {
-                final String cookieStr = pwmRequest.readCookie(PwmConstants.COOKIE_PERSISTENT_CONFIG_LOGIN);
-                if (securityKey != null && cookieStr != null && !cookieStr.isEmpty()) {
-                    try {
-                        final String jsonStr = pwmApplication.getSecureService().decryptStringValue(cookieStr);
-                        final PersistentLoginInfo persistentLoginInfo = JsonUtil.deserialize(jsonStr, PersistentLoginInfo.class);
-                        if (persistentLoginInfo != null && persistentLoginValue != null) {
-                            if (persistentLoginInfo.getExpireDate().isAfter(Instant.now())) {
-                                if (persistentLoginValue.equals(persistentLoginInfo.getPassword())) {
+                final String cookieStr = pwmRequest.readCookie( PwmConstants.COOKIE_PERSISTENT_CONFIG_LOGIN );
+                if ( securityKey != null && cookieStr != null && !cookieStr.isEmpty() )
+                {
+                    try
+                    {
+                        final String jsonStr = pwmApplication.getSecureService().decryptStringValue( cookieStr );
+                        final PersistentLoginInfo persistentLoginInfo = JsonUtil.deserialize( jsonStr, PersistentLoginInfo.class );
+                        if ( persistentLoginInfo != null && persistentLoginValue != null )
+                        {
+                            if ( persistentLoginInfo.getExpireDate().isAfter( Instant.now() ) )
+                            {
+                                if ( persistentLoginValue.equals( persistentLoginInfo.getPassword() ) )
+                                {
                                     persistentLoginAccepted = true;
-                                    LOGGER.debug(pwmRequest, "accepting persistent config login from cookie (expires "
-                                                    + JavaHelper.toIsoDate(persistentLoginInfo.getExpireDate())
-                                                    + ")"
+                                    LOGGER.debug( pwmRequest, "accepting persistent config login from cookie (expires "
+                                            + JavaHelper.toIsoDate( persistentLoginInfo.getExpireDate() )
+                                            + ")"
                                     );
                                 }
                             }
                         }
-                    } catch (Exception e) {
-                        LOGGER.error(pwmRequest, "error examining persistent config login cookie: " + e.getMessage());
                     }
-                    if (!persistentLoginAccepted) {
-                        pwmRequest.getPwmResponse().removeCookie(PwmConstants.COOKIE_PERSISTENT_CONFIG_LOGIN, null);
-                        LOGGER.debug(pwmRequest, "removing non-working persistent config login cookie");
+                    catch ( Exception e )
+                    {
+                        LOGGER.error( pwmRequest, "error examining persistent config login cookie: " + e.getMessage() );
+                    }
+                    if ( !persistentLoginAccepted )
+                    {
+                        pwmRequest.getPwmResponse().removeCookie( PwmConstants.COOKIE_PERSISTENT_CONFIG_LOGIN, null );
+                        LOGGER.debug( pwmRequest, "removing non-working persistent config login cookie" );
                     }
                 }
             }
         }
 
 
-        final String password = pwmRequest.readParameterAsString("password");
+        final String password = pwmRequest.readParameterAsString( "password" );
         boolean passwordAccepted = false;
-        if (!persistentLoginAccepted) {
-            if (password != null && password.length() > 0) {
-                if (storedConfig.verifyPassword(password, pwmRequest.getConfig())) {
+        if ( !persistentLoginAccepted )
+        {
+            if ( password != null && password.length() > 0 )
+            {
+                if ( storedConfig.verifyPassword( password, pwmRequest.getConfig() ) )
+                {
                     passwordAccepted = true;
-                    LOGGER.trace(pwmRequest, "valid configuration password accepted");
-                    updateLoginHistory(pwmRequest,pwmRequest.getUserInfoIfLoggedIn(), true);
-                } else{
-                    LOGGER.trace(pwmRequest, "configuration password is not correct");
-                    pwmApplication.getIntruderManager().convenience().markAddressAndSession(pwmSession);
-                    pwmApplication.getIntruderManager().mark(RecordType.USERNAME, PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME, pwmSession.getLabel());
-                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_PASSWORD_ONLY_BAD);
-                    updateLoginHistory(pwmRequest,pwmRequest.getUserInfoIfLoggedIn(), false);
-                    return denyAndError(pwmRequest, errorInformation);
+                    LOGGER.trace( pwmRequest, "valid configuration password accepted" );
+                    updateLoginHistory( pwmRequest, pwmRequest.getUserInfoIfLoggedIn(), true );
+                }
+                else
+                {
+                    LOGGER.trace( pwmRequest, "configuration password is not correct" );
+                    pwmApplication.getIntruderManager().convenience().markAddressAndSession( pwmSession );
+                    pwmApplication.getIntruderManager().mark( RecordType.USERNAME, PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME, pwmSession.getLabel() );
+                    final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_PASSWORD_ONLY_BAD );
+                    updateLoginHistory( pwmRequest, pwmRequest.getUserInfoIfLoggedIn(), false );
+                    return denyAndError( pwmRequest, errorInformation );
                 }
             }
         }
 
-        if ((persistentLoginAccepted || passwordAccepted)) {
-            configManagerBean.setPasswordVerified(true);
-            pwmApplication.getIntruderManager().convenience().clearAddressAndSession(pwmSession);
-            pwmApplication.getIntruderManager().clear(RecordType.USERNAME, PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME);
-            if (persistentLoginEnabled && !persistentLoginAccepted && "on".equals(pwmRequest.readParameterAsString("remember"))) {
-                final int persistentSeconds = figureMaxLoginSeconds(pwmRequest);
-                if (persistentSeconds > 0) {
-                    final Instant expirationDate = Instant.ofEpochMilli(System.currentTimeMillis() + (persistentSeconds * 1000));
-                    final PersistentLoginInfo persistentLoginInfo = new PersistentLoginInfo(expirationDate, persistentLoginValue);
-                    final String jsonPersistentLoginInfo = JsonUtil.serialize(persistentLoginInfo);
-                    final String cookieValue = pwmApplication.getSecureService().encryptToString(jsonPersistentLoginInfo);
+        if ( ( persistentLoginAccepted || passwordAccepted ) )
+        {
+            configManagerBean.setPasswordVerified( true );
+            pwmApplication.getIntruderManager().convenience().clearAddressAndSession( pwmSession );
+            pwmApplication.getIntruderManager().clear( RecordType.USERNAME, PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME );
+            if ( persistentLoginEnabled && !persistentLoginAccepted && "on".equals( pwmRequest.readParameterAsString( "remember" ) ) )
+            {
+                final int persistentSeconds = figureMaxLoginSeconds( pwmRequest );
+                if ( persistentSeconds > 0 )
+                {
+                    final Instant expirationDate = Instant.ofEpochMilli( System.currentTimeMillis() + ( persistentSeconds * 1000 ) );
+                    final PersistentLoginInfo persistentLoginInfo = new PersistentLoginInfo( expirationDate, persistentLoginValue );
+                    final String jsonPersistentLoginInfo = JsonUtil.serialize( persistentLoginInfo );
+                    final String cookieValue = pwmApplication.getSecureService().encryptToString( jsonPersistentLoginInfo );
                     pwmRequest.getPwmResponse().writeCookie(
                             PwmConstants.COOKIE_PERSISTENT_CONFIG_LOGIN,
                             cookieValue,
                             persistentSeconds
                     );
-                    LOGGER.debug(pwmRequest, "set persistent config login cookie (expires "
-                                    + JavaHelper.toIsoDate(expirationDate)
-                                    + ")"
+                    LOGGER.debug( pwmRequest, "set persistent config login cookie (expires "
+                            + JavaHelper.toIsoDate( expirationDate )
+                            + ")"
                     );
                 }
             }
 
-            if (configManagerBean.getPrePasswordEntryUrl() != null) {
+            if ( configManagerBean.getPrePasswordEntryUrl() != null )
+            {
                 final String originalUrl = configManagerBean.getPrePasswordEntryUrl();
-                configManagerBean.setPrePasswordEntryUrl(null);
-                pwmRequest.getPwmResponse().sendRedirect(originalUrl);
+                configManagerBean.setPrePasswordEntryUrl( null );
+                pwmRequest.getPwmResponse().sendRedirect( originalUrl );
                 return ProcessStatus.Halt;
             }
             return ProcessStatus.Continue;
         }
 
-        if (configManagerBean.getPrePasswordEntryUrl() == null) {
-            configManagerBean.setPrePasswordEntryUrl(pwmRequest.getHttpServletRequest().getRequestURL().toString());
+        if ( configManagerBean.getPrePasswordEntryUrl() == null )
+        {
+            configManagerBean.setPrePasswordEntryUrl( pwmRequest.getHttpServletRequest().getRequestURL().toString() );
         }
 
-        forwardToJsp(pwmRequest);
+        forwardToJsp( pwmRequest );
         return ProcessStatus.Halt;
     }
 
-    private static void forwardToJsp(final PwmRequest pwmRequest)
+    private static void forwardToJsp( final PwmRequest pwmRequest )
             throws ServletException, PwmUnrecoverableException, IOException
     {
-        final int persistentSeconds = figureMaxLoginSeconds(pwmRequest);
-        final String time = new TimeDuration(persistentSeconds * 1000).asLongString(pwmRequest.getLocale());
+        final int persistentSeconds = figureMaxLoginSeconds( pwmRequest );
+        final String time = new TimeDuration( persistentSeconds * 1000 ).asLongString( pwmRequest.getLocale() );
 
-        final ConfigLoginHistory configLoginHistory = readConfigLoginHistory(pwmRequest);
+        final ConfigLoginHistory configLoginHistory = readConfigLoginHistory( pwmRequest );
 
-        pwmRequest.setAttribute(PwmRequestAttribute.ConfigLoginHistory, configLoginHistory);
-        pwmRequest.setAttribute(PwmRequestAttribute.ConfigPasswordRememberTime,time);
-        pwmRequest.forwardToJsp(JspUrl.CONFIG_MANAGER_LOGIN);
+        pwmRequest.setAttribute( PwmRequestAttribute.ConfigLoginHistory, configLoginHistory );
+        pwmRequest.setAttribute( PwmRequestAttribute.ConfigPasswordRememberTime, time );
+        pwmRequest.forwardToJsp( JspUrl.CONFIG_MANAGER_LOGIN );
 
     }
 
-    private static ConfigLoginHistory readConfigLoginHistory(final PwmRequest pwmRequest) {
-        final ConfigLoginHistory configLoginHistory = pwmRequest.getPwmApplication().readAppAttribute(PwmApplication.AppAttribute.CONFIG_LOGIN_HISTORY, ConfigLoginHistory.class);
+    private static ConfigLoginHistory readConfigLoginHistory( final PwmRequest pwmRequest )
+    {
+        final ConfigLoginHistory configLoginHistory = pwmRequest.getPwmApplication().readAppAttribute( PwmApplication.AppAttribute.CONFIG_LOGIN_HISTORY, ConfigLoginHistory.class );
         return configLoginHistory == null
                 ? new ConfigLoginHistory()
                 : configLoginHistory;
     }
 
-    private static void updateLoginHistory(final PwmRequest pwmRequest, final UserIdentity userIdentity, final boolean successful) {
-        final ConfigLoginHistory configLoginHistory = readConfigLoginHistory(pwmRequest);
+    private static void updateLoginHistory( final PwmRequest pwmRequest, final UserIdentity userIdentity, final boolean successful )
+    {
+        final ConfigLoginHistory configLoginHistory = readConfigLoginHistory( pwmRequest );
         final ConfigLoginEvent event = new ConfigLoginEvent(
                 userIdentity == null ? "n/a" : userIdentity.toDisplayString(),
                 Instant.now(),
                 pwmRequest.getPwmSession().getSessionStateBean().getSrcAddress()
         );
-        final int maxEvents = Integer.parseInt(pwmRequest.getPwmApplication().getConfig().readAppProperty(AppProperty.CONFIG_HISTORY_MAX_ITEMS));
-        configLoginHistory.addEvent(event, maxEvents, successful);
-        pwmRequest.getPwmApplication().writeAppAttribute(PwmApplication.AppAttribute.CONFIG_LOGIN_HISTORY, configLoginHistory);
+        final int maxEvents = Integer.parseInt( pwmRequest.getPwmApplication().getConfig().readAppProperty( AppProperty.CONFIG_HISTORY_MAX_ITEMS ) );
+        configLoginHistory.addEvent( event, maxEvents, successful );
+        pwmRequest.getPwmApplication().writeAppAttribute( PwmApplication.AppAttribute.CONFIG_LOGIN_HISTORY, configLoginHistory );
     }
 
-    private static class PersistentLoginInfo implements Serializable {
+    private static class PersistentLoginInfo implements Serializable
+    {
         private Instant expireDate;
         private String password;
 
@@ -296,76 +345,87 @@ public class ConfigAccessFilter extends AbstractPwmFilter {
             this.password = password;
         }
 
-        public Instant getExpireDate()
+        public Instant getExpireDate( )
         {
             return expireDate;
         }
 
-        public String getPassword()
+        public String getPassword( )
         {
             return password;
         }
     }
 
 
-
-    public static class ConfigLoginHistory implements Serializable {
+    public static class ConfigLoginHistory implements Serializable
+    {
         private final List<ConfigLoginEvent> successEvents = new ArrayList<>();
         private final List<ConfigLoginEvent> failedEvents = new ArrayList<>();
 
-        void addEvent(final ConfigLoginEvent event, final int maxEvents, final boolean successful) {
+        void addEvent( final ConfigLoginEvent event, final int maxEvents, final boolean successful )
+        {
             final List<ConfigLoginEvent> events = successful ? successEvents : failedEvents;
-            events.add(event);
-            if (maxEvents > 0) {
-                while (events.size() > maxEvents) {
-                    events.remove(0);
+            events.add( event );
+            if ( maxEvents > 0 )
+            {
+                while ( events.size() > maxEvents )
+                {
+                    events.remove( 0 );
                 }
             }
         }
 
-        public List<ConfigLoginEvent> successEvents() {
-            return Collections.unmodifiableList(successEvents);
+        public List<ConfigLoginEvent> successEvents( )
+        {
+            return Collections.unmodifiableList( successEvents );
         }
 
-        public List<ConfigLoginEvent> failedEvents() {
-            return Collections.unmodifiableList(failedEvents);
+        public List<ConfigLoginEvent> failedEvents( )
+        {
+            return Collections.unmodifiableList( failedEvents );
         }
     }
 
-    public static class ConfigLoginEvent implements Serializable {
+    public static class ConfigLoginEvent implements Serializable
+    {
         private final String userIdentity;
         private final Instant date;
         private final String networkAddress;
 
-        public ConfigLoginEvent(final String userIdentity, final Instant date, final String networkAddress) {
+        public ConfigLoginEvent( final String userIdentity, final Instant date, final String networkAddress )
+        {
             this.userIdentity = userIdentity;
             this.date = date;
             this.networkAddress = networkAddress;
         }
 
-        public String getUserIdentity() {
+        public String getUserIdentity( )
+        {
             return userIdentity;
         }
 
-        public Instant getDate() {
+        public Instant getDate( )
+        {
             return date;
         }
 
-        public String getNetworkAddress() {
+        public String getNetworkAddress( )
+        {
             return networkAddress;
         }
     }
 
-    static int figureMaxLoginSeconds(final PwmRequest pwmRequest) {
-        return Integer.parseInt(pwmRequest.getConfig().readAppProperty(AppProperty.CONFIG_MAX_PERSISTENT_LOGIN_SECONDS));
+    static int figureMaxLoginSeconds( final PwmRequest pwmRequest )
+    {
+        return Integer.parseInt( pwmRequest.getConfig().readAppProperty( AppProperty.CONFIG_MAX_PERSISTENT_LOGIN_SECONDS ) );
     }
 
 
-    private static ProcessStatus denyAndError(final PwmRequest pwmRequest, final ErrorInformation errorInformation)
+    private static ProcessStatus denyAndError( final PwmRequest pwmRequest, final ErrorInformation errorInformation )
             throws ServletException, PwmUnrecoverableException, IOException
     {
-        pwmRequest.setAttribute(PwmRequestAttribute.PwmErrorInfo, errorInformation);
-        forwardToJsp(pwmRequest);
+        pwmRequest.setAttribute( PwmRequestAttribute.PwmErrorInfo, errorInformation );
+        forwardToJsp( pwmRequest );
         return ProcessStatus.Halt;
     }
 }

+ 29 - 17
server/src/main/java/password/pwm/http/filter/GZIPFilter.java

@@ -43,52 +43,64 @@ import java.io.IOException;
  * GZip Filter Wrapper.  This filter must be invoked _before_ a PwmRequest object is instantiated, else
  * it will cache a reference to the original response and break the application.
  */
-public class GZIPFilter implements Filter {
-    private static final PwmLogger LOGGER = PwmLogger.forClass(GZIPFilter.class);
+public class GZIPFilter implements Filter
+{
+    private static final PwmLogger LOGGER = PwmLogger.forClass( GZIPFilter.class );
 
     private final CompressingFilter compressingFilter = new CompressingFilter();
     private boolean enabled = false;
 
-    public void init(final FilterConfig filterConfig)
+    public void init( final FilterConfig filterConfig )
             throws ServletException
     {
         final PwmApplication pwmApplication;
-        try {
+        try
+        {
             pwmApplication = ContextManager.getPwmApplication( filterConfig.getServletContext() );
-            enabled = Boolean.parseBoolean(pwmApplication.getConfig().readAppProperty(AppProperty.HTTP_ENABLE_GZIP));
-        } catch (PwmUnrecoverableException e) {
+            enabled = Boolean.parseBoolean( pwmApplication.getConfig().readAppProperty( AppProperty.HTTP_ENABLE_GZIP ) );
+        }
+        catch ( PwmUnrecoverableException e )
+        {
             LOGGER.warn( "unable to load application configuration, defaulting to disabled" );
         }
 
         compressingFilter.init( filterConfig );
     }
 
-    public void destroy()
+    public void destroy( )
     {
         compressingFilter.destroy();
     }
 
     @Override
-    public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain)
+    public void doFilter( final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain )
             throws IOException, ServletException
     {
-        if ( enabled && interestInRequest( servletRequest )) {
+        if ( enabled && interestInRequest( servletRequest ) )
+        {
             compressingFilter.doFilter( servletRequest, servletResponse, filterChain );
-        } else {
-            filterChain.doFilter(servletRequest, servletResponse);
+        }
+        else
+        {
+            filterChain.doFilter( servletRequest, servletResponse );
         }
     }
 
-    private boolean interestInRequest( final ServletRequest servletRequest) {
-        try {
-            final PwmURL pwmURL = new PwmURL((HttpServletRequest) servletRequest);
+    private boolean interestInRequest( final ServletRequest servletRequest )
+    {
+        try
+        {
+            final PwmURL pwmURL = new PwmURL( ( HttpServletRequest ) servletRequest );
 
             // resource servlet does its own gzip compression with fancy server-side caching
-            if (pwmURL.isResourceURL()) {
+            if ( pwmURL.isResourceURL() )
+            {
                 return false;
             }
-        } catch (Exception e) {
-            LOGGER.error("unable to parse request url, defaulting to non-gzip: " + e.getMessage());
+        }
+        catch ( Exception e )
+        {
+            LOGGER.error( "unable to parse request url, defaulting to non-gzip: " + e.getMessage() );
         }
 
         return true;

+ 417 - 279
server/src/main/java/password/pwm/http/filter/RequestInitializationFilter.java

@@ -76,67 +76,90 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
-public class RequestInitializationFilter implements Filter {
+public class RequestInitializationFilter implements Filter
+{
 
-    private static final PwmLogger LOGGER = PwmLogger.forClass(RequestInitializationFilter.class);
+    private static final PwmLogger LOGGER = PwmLogger.forClass( RequestInitializationFilter.class );
 
     @Override
-    public void init(final FilterConfig filterConfig)
+    public void init( final FilterConfig filterConfig )
             throws ServletException
     {
     }
 
     @Override
-    public void destroy()
+    public void destroy( )
     {
     }
 
     public void doFilter(
             final ServletRequest servletRequest,
             final ServletResponse servletResponse,
-            final FilterChain filterChain) throws IOException, ServletException {
+            final FilterChain filterChain ) throws IOException, ServletException
+    {
 
-        final HttpServletRequest req = (HttpServletRequest)servletRequest;
-        final HttpServletResponse resp = (HttpServletResponse)servletResponse;
-        final PwmApplicationMode mode = PwmApplicationMode.determineMode(req);
-        final PwmURL pwmURL = new PwmURL(req);
+        final HttpServletRequest req = ( HttpServletRequest ) servletRequest;
+        final HttpServletResponse resp = ( HttpServletResponse ) servletResponse;
+        final PwmApplicationMode mode = PwmApplicationMode.determineMode( req );
+        final PwmURL pwmURL = new PwmURL( req );
 
         PwmApplication testPwmApplicationLoad = null;
-        try { testPwmApplicationLoad = ContextManager.getPwmApplication(req); } catch (PwmException e) {}
+        try
+        {
+            testPwmApplicationLoad = ContextManager.getPwmApplication( req );
+        }
+        catch ( PwmException e )
+        {
+        }
 
-        if (testPwmApplicationLoad != null && mode == PwmApplicationMode.RUNNING) {
-            if (testPwmApplicationLoad.getStatisticsManager() != null) {
-                testPwmApplicationLoad.getStatisticsManager().updateEps(EpsStatistic.REQUESTS, 1);
+        if ( testPwmApplicationLoad != null && mode == PwmApplicationMode.RUNNING )
+        {
+            if ( testPwmApplicationLoad.getStatisticsManager() != null )
+            {
+                testPwmApplicationLoad.getStatisticsManager().updateEps( EpsStatistic.REQUESTS, 1 );
             }
         }
 
-        if (testPwmApplicationLoad == null && pwmURL.isResourceURL()) {
-            filterChain.doFilter(req, resp);
-        } else if (pwmURL.isRestService()) {
-            filterChain.doFilter(req, resp);
-        } else {
-            if (mode == PwmApplicationMode.ERROR) {
-                try {
-                    final ContextManager contextManager = ContextManager.getContextManager(req.getServletContext());
-                    if (contextManager != null) {
+        if ( testPwmApplicationLoad == null && pwmURL.isResourceURL() )
+        {
+            filterChain.doFilter( req, resp );
+        }
+        else if ( pwmURL.isRestService() )
+        {
+            filterChain.doFilter( req, resp );
+        }
+        else
+        {
+            if ( mode == PwmApplicationMode.ERROR )
+            {
+                try
+                {
+                    final ContextManager contextManager = ContextManager.getContextManager( req.getServletContext() );
+                    if ( contextManager != null )
+                    {
                         final ErrorInformation startupError = contextManager.getStartupErrorInformation();
-                        servletRequest.setAttribute(PwmRequestAttribute.PwmErrorInfo.toString(), startupError);
+                        servletRequest.setAttribute( PwmRequestAttribute.PwmErrorInfo.toString(), startupError );
                     }
-                } catch (Exception e) {
-                    if (pwmURL.isResourceURL()) {
-                        filterChain.doFilter(servletRequest, servletResponse);
+                }
+                catch ( Exception e )
+                {
+                    if ( pwmURL.isResourceURL() )
+                    {
+                        filterChain.doFilter( servletRequest, servletResponse );
                         return;
                     }
 
-                    LOGGER.error("error while trying to detect application status: " + e.getMessage());
+                    LOGGER.error( "error while trying to detect application status: " + e.getMessage() );
                 }
 
-                LOGGER.error("unable to satisfy incoming request, application is not available");
-                resp.setStatus(500);
+                LOGGER.error( "unable to satisfy incoming request, application is not available" );
+                resp.setStatus( 500 );
                 final String url = JspUrl.APP_UNAVAILABLE.getPath();
-                servletRequest.getServletContext().getRequestDispatcher(url).forward(servletRequest, servletResponse);
-            } else {
-                initializeServletRequest(req, resp, filterChain);
+                servletRequest.getServletContext().getRequestDispatcher( url ).forward( servletRequest, servletResponse );
+            }
+            else
+            {
+                initializeServletRequest( req, resp, filterChain );
             }
         }
     }
@@ -149,144 +172,172 @@ public class RequestInitializationFilter implements Filter {
     )
             throws IOException, ServletException
     {
-        try {
-            checkAndInitSessionState(req);
-            PwmRequest.forRequest(req,resp);
-        } catch (Throwable e) {
-            LOGGER.error("can't load application: " + e.getMessage(),e);
-            if (!(new PwmURL(req).isResourceURL())) {
-                respondWithUnavailableError(req, resp);
+        try
+        {
+            checkAndInitSessionState( req );
+            PwmRequest.forRequest( req, resp );
+        }
+        catch ( Throwable e )
+        {
+            LOGGER.error( "can't load application: " + e.getMessage(), e );
+            if ( !( new PwmURL( req ).isResourceURL() ) )
+            {
+                respondWithUnavailableError( req, resp );
                 return;
             }
             return;
         }
 
-        try {
-            final PwmRequest pwmRequest = PwmRequest.forRequest(req,resp);
+        try
+        {
+            final PwmRequest pwmRequest = PwmRequest.forRequest( req, resp );
 
-            checkIfSessionRecycleNeeded(pwmRequest);
+            checkIfSessionRecycleNeeded( pwmRequest );
 
-            handleRequestInitialization(pwmRequest);
+            handleRequestInitialization( pwmRequest );
 
-            addPwmResponseHeaders(pwmRequest);
+            addPwmResponseHeaders( pwmRequest );
 
-            checkIdleTimeout(pwmRequest);
+            checkIdleTimeout( pwmRequest );
 
-            try {
-                handleRequestSecurityChecks(pwmRequest);
-            } catch (PwmUnrecoverableException e) {
-                LOGGER.error(pwmRequest, e.getErrorInformation());
-                pwmRequest.respondWithError(e.getErrorInformation());
-                if (PwmError.ERROR_INTRUDER_SESSION != e.getError()) {
+            try
+            {
+                handleRequestSecurityChecks( pwmRequest );
+            }
+            catch ( PwmUnrecoverableException e )
+            {
+                LOGGER.error( pwmRequest, e.getErrorInformation() );
+                pwmRequest.respondWithError( e.getErrorInformation() );
+                if ( PwmError.ERROR_INTRUDER_SESSION != e.getError() )
+                {
                     pwmRequest.invalidateSession();
                 }
                 return;
             }
 
-        } catch (Throwable e) {
+        }
+        catch ( Throwable e )
+        {
             final String logMsg = "can't init request: " + e.getMessage();
-            if (e instanceof PwmException && ((PwmException) e).getError() != PwmError.ERROR_UNKNOWN) {
-                LOGGER.error(logMsg);
-            } else {
-                LOGGER.error(logMsg,e);
+            if ( e instanceof PwmException && ( ( PwmException ) e ).getError() != PwmError.ERROR_UNKNOWN )
+            {
+                LOGGER.error( logMsg );
+            }
+            else
+            {
+                LOGGER.error( logMsg, e );
             }
-            if (!(new PwmURL(req).isResourceURL())) {
-                respondWithUnavailableError(req, resp);
+            if ( !( new PwmURL( req ).isResourceURL() ) )
+            {
+                respondWithUnavailableError( req, resp );
                 return;
             }
             return;
         }
 
-        filterChain.doFilter(req, resp);
+        filterChain.doFilter( req, resp );
     }
 
-    private void respondWithUnavailableError( final HttpServletRequest req, final HttpServletResponse resp)
+    private void respondWithUnavailableError( final HttpServletRequest req, final HttpServletResponse resp )
             throws ServletException, IOException
     {
-        ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_APP_UNAVAILABLE);
-        try {
-            final ContextManager contextManager = ContextManager.getContextManager(req.getServletContext());
-            if (contextManager != null && contextManager.getStartupErrorInformation() != null) {
+        ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_APP_UNAVAILABLE );
+        try
+        {
+            final ContextManager contextManager = ContextManager.getContextManager( req.getServletContext() );
+            if ( contextManager != null && contextManager.getStartupErrorInformation() != null )
+            {
                 errorInformation = contextManager.getStartupErrorInformation();
             }
-        } catch (PwmUnrecoverableException e2) {
-            LOGGER.error("error reading session context from servlet container: " + e2.getMessage());
+        }
+        catch ( PwmUnrecoverableException e2 )
+        {
+            LOGGER.error( "error reading session context from servlet container: " + e2.getMessage() );
         }
 
-        req.setAttribute(PwmRequestAttribute.PwmErrorInfo.toString(),errorInformation);
+        req.setAttribute( PwmRequestAttribute.PwmErrorInfo.toString(), errorInformation );
         final String url = JspUrl.APP_UNAVAILABLE.getPath();
-        req.getServletContext().getRequestDispatcher(url).forward(req, resp);
+        req.getServletContext().getRequestDispatcher( url ).forward( req, resp );
     }
 
-    private void checkAndInitSessionState(final HttpServletRequest request)
+    private void checkAndInitSessionState( final HttpServletRequest request )
             throws PwmUnrecoverableException
     {
-        final ContextManager contextManager = ContextManager.getContextManager(request.getSession());
+        final ContextManager contextManager = ContextManager.getContextManager( request.getSession() );
         final PwmApplication pwmApplication = contextManager.getPwmApplication();
 
-        { // destroy any outdated sessions
-            final HttpSession httpSession = request.getSession(false);
-            if (httpSession != null) {
-                final String sessionPwmAppNonce = (String) httpSession.getAttribute(PwmConstants.SESSION_ATTR_PWM_APP_NONCE);
-                if (sessionPwmAppNonce == null || !sessionPwmAppNonce.equals(pwmApplication.getRuntimeNonce())) {
-                    LOGGER.debug("invalidating http session created with non-current servlet context");
+        {
+            // destroy any outdated sessions
+            final HttpSession httpSession = request.getSession( false );
+            if ( httpSession != null )
+            {
+                final String sessionPwmAppNonce = ( String ) httpSession.getAttribute( PwmConstants.SESSION_ATTR_PWM_APP_NONCE );
+                if ( sessionPwmAppNonce == null || !sessionPwmAppNonce.equals( pwmApplication.getRuntimeNonce() ) )
+                {
+                    LOGGER.debug( "invalidating http session created with non-current servlet context" );
                     httpSession.invalidate();
                 }
             }
         }
 
-        { // handle pwmSession init and assignment.
+        {
+            // handle pwmSession init and assignment.
             final HttpSession httpSession = request.getSession();
-            if (httpSession.getAttribute(PwmConstants.SESSION_ATTR_PWM_SESSION) == null) {
-                final PwmSession pwmSession = PwmSession.createPwmSession(pwmApplication);
-                PwmSessionWrapper.sessionMerge(pwmApplication, pwmSession, httpSession);
+            if ( httpSession.getAttribute( PwmConstants.SESSION_ATTR_PWM_SESSION ) == null )
+            {
+                final PwmSession pwmSession = PwmSession.createPwmSession( pwmApplication );
+                PwmSessionWrapper.sessionMerge( pwmApplication, pwmSession, httpSession );
             }
         }
 
     }
 
-    private void checkIfSessionRecycleNeeded(final PwmRequest pwmRequest)
+    private void checkIfSessionRecycleNeeded( final PwmRequest pwmRequest )
             throws IOException, ServletException
     {
-        if (!pwmRequest.getPwmSession().getSessionStateBean().isSessionIdRecycleNeeded()) {
+        if ( !pwmRequest.getPwmSession().getSessionStateBean().isSessionIdRecycleNeeded() )
+        {
             return;
         }
 
-        final boolean recycleEnabled = Boolean.parseBoolean( pwmRequest.getConfig().readAppProperty(AppProperty.HTTP_SESSION_RECYCLE_AT_AUTH));
+        final boolean recycleEnabled = Boolean.parseBoolean( pwmRequest.getConfig().readAppProperty( AppProperty.HTTP_SESSION_RECYCLE_AT_AUTH ) );
 
-        if (!recycleEnabled) {
+        if ( !recycleEnabled )
+        {
             return;
         }
-        LOGGER.debug(pwmRequest,"forcing new http session due to authentication");
+        LOGGER.debug( pwmRequest, "forcing new http session due to authentication" );
 
         final HttpServletRequest req = pwmRequest.getHttpServletRequest();
 
         // read the old session data
-        final HttpSession oldSession = req.getSession(true);
+        final HttpSession oldSession = req.getSession( true );
         final int oldMaxInactiveInterval = oldSession.getMaxInactiveInterval();
-        final Map<String,Object> sessionAttributes = new HashMap<>();
+        final Map<String, Object> sessionAttributes = new HashMap<>();
         final Enumeration oldSessionAttrNames = oldSession.getAttributeNames();
-        while (oldSessionAttrNames.hasMoreElements()) {
-            final String attrName = (String)oldSessionAttrNames.nextElement();
-            sessionAttributes.put(attrName, oldSession.getAttribute(attrName));
+        while ( oldSessionAttrNames.hasMoreElements() )
+        {
+            final String attrName = ( String ) oldSessionAttrNames.nextElement();
+            sessionAttributes.put( attrName, oldSession.getAttribute( attrName ) );
         }
 
-        for (final String attrName : sessionAttributes.keySet()) {
-            oldSession.removeAttribute(attrName);
+        for ( final String attrName : sessionAttributes.keySet() )
+        {
+            oldSession.removeAttribute( attrName );
         }
 
         //invalidate the old session
         oldSession.invalidate();
 
         // make a new session
-        final HttpSession newSession = req.getSession(true);
+        final HttpSession newSession = req.getSession( true );
 
         // write back all the session data
-        sessionAttributes.keySet().forEach(attrName -> newSession.setAttribute(attrName, sessionAttributes.get(attrName)));
+        sessionAttributes.keySet().forEach( attrName -> newSession.setAttribute( attrName, sessionAttributes.get( attrName ) ) );
 
-        newSession.setMaxInactiveInterval(oldMaxInactiveInterval);
+        newSession.setMaxInactiveInterval( oldMaxInactiveInterval );
 
-        pwmRequest.getPwmSession().getSessionStateBean().setSessionIdRecycleNeeded(false);
+        pwmRequest.getPwmSession().getSessionStateBean().setSessionIdRecycleNeeded( false );
     }
 
     public static void addPwmResponseHeaders(
@@ -295,7 +346,8 @@ public class RequestInitializationFilter implements Filter {
             throws PwmUnrecoverableException
     {
 
-        if (pwmRequest == null) {
+        if ( pwmRequest == null )
+        {
             return;
         }
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
@@ -303,103 +355,124 @@ public class RequestInitializationFilter implements Filter {
         final Configuration config = pwmApplication.getConfig();
         final PwmResponse resp = pwmRequest.getPwmResponse();
 
-        if (resp.isCommitted()) {
+        if ( resp.isCommitted() )
+        {
             return;
         }
 
-        final boolean includeXSessionID = Boolean.parseBoolean(config.readAppProperty(AppProperty.HTTP_HEADER_SEND_XSESSIONID));
-        if (includeXSessionID && pwmSession != null) {
-            resp.setHeader(HttpHeader.XSessionID, pwmSession.getSessionStateBean().getSessionID());
+        final boolean includeXSessionID = Boolean.parseBoolean( config.readAppProperty( AppProperty.HTTP_HEADER_SEND_XSESSIONID ) );
+        if ( includeXSessionID && pwmSession != null )
+        {
+            resp.setHeader( HttpHeader.XSessionID, pwmSession.getSessionStateBean().getSessionID() );
         }
 
-        final boolean includeContentLanguage = Boolean.parseBoolean(config.readAppProperty(AppProperty.HTTP_HEADER_SEND_CONTENT_LANGUAGE));
-        if (includeContentLanguage) {
-            resp.setHeader(HttpHeader.Content_Language, pwmRequest.getLocale().toLanguageTag());
+        final boolean includeContentLanguage = Boolean.parseBoolean( config.readAppProperty( AppProperty.HTTP_HEADER_SEND_CONTENT_LANGUAGE ) );
+        if ( includeContentLanguage )
+        {
+            resp.setHeader( HttpHeader.Content_Language, pwmRequest.getLocale().toLanguageTag() );
         }
 
         addStaticResponseHeaders( pwmApplication, resp.getHttpServletResponse() );
 
 
-        if (pwmSession != null) {
+        if ( pwmSession != null )
+        {
             final String contentPolicy;
-            if (pwmRequest.getURL().isConfigGuideURL() || pwmRequest.getURL().isConfigManagerURL()) {
-                contentPolicy = config.readAppProperty(AppProperty.SECURITY_HTTP_CONFIG_CSP_HEADER);
-            } else {
-                contentPolicy = config.readSettingAsString(PwmSetting.SECURITY_CSP_HEADER);
+            if ( pwmRequest.getURL().isConfigGuideURL() || pwmRequest.getURL().isConfigManagerURL() )
+            {
+                contentPolicy = config.readAppProperty( AppProperty.SECURITY_HTTP_CONFIG_CSP_HEADER );
+            }
+            else
+            {
+                contentPolicy = config.readSettingAsString( PwmSetting.SECURITY_CSP_HEADER );
             }
 
-            if (contentPolicy != null && !contentPolicy.isEmpty()) {
+            if ( contentPolicy != null && !contentPolicy.isEmpty() )
+            {
                 final String nonce = pwmRequest.getCspNonce();
-                final String expandedPolicy = contentPolicy.replace("%NONCE%", nonce);
-                resp.setHeader(HttpHeader.ContentSecurityPolicy, expandedPolicy);
+                final String expandedPolicy = contentPolicy.replace( "%NONCE%", nonce );
+                resp.setHeader( HttpHeader.ContentSecurityPolicy, expandedPolicy );
             }
         }
     }
 
-    public static void addStaticResponseHeaders(final PwmApplication pwmApplication, final HttpServletResponse resp) throws PwmUnrecoverableException
+    public static void addStaticResponseHeaders( final PwmApplication pwmApplication, final HttpServletResponse resp ) throws PwmUnrecoverableException
     {
         final Configuration config = pwmApplication.getConfig();
 
-        final String serverHeader = config.readAppProperty(AppProperty.HTTP_HEADER_SERVER);
-        final boolean includeXInstance = Boolean.parseBoolean(config.readAppProperty(AppProperty.HTTP_HEADER_SEND_XINSTANCE));
-        final boolean includeXVersion = Boolean.parseBoolean(config.readAppProperty(AppProperty.HTTP_HEADER_SEND_XVERSION));
-        final boolean includeXContentTypeOptions = Boolean.parseBoolean(config.readAppProperty(AppProperty.HTTP_HEADER_SEND_XCONTENTTYPEOPTIONS));
-        final boolean includeXXSSProtection = Boolean.parseBoolean(config.readAppProperty(AppProperty.HTTP_HEADER_SEND_XXSSPROTECTION));
-        final boolean includeXFrameDeny = config.readSettingAsBoolean(PwmSetting.SECURITY_PREVENT_FRAMING);
-        final boolean includeXAmb = Boolean.parseBoolean(config.readAppProperty(AppProperty.HTTP_HEADER_SEND_XAMB));
+        final String serverHeader = config.readAppProperty( AppProperty.HTTP_HEADER_SERVER );
+        final boolean includeXInstance = Boolean.parseBoolean( config.readAppProperty( AppProperty.HTTP_HEADER_SEND_XINSTANCE ) );
+        final boolean includeXVersion = Boolean.parseBoolean( config.readAppProperty( AppProperty.HTTP_HEADER_SEND_XVERSION ) );
+        final boolean includeXContentTypeOptions = Boolean.parseBoolean( config.readAppProperty( AppProperty.HTTP_HEADER_SEND_XCONTENTTYPEOPTIONS ) );
+        final boolean includeXXSSProtection = Boolean.parseBoolean( config.readAppProperty( AppProperty.HTTP_HEADER_SEND_XXSSPROTECTION ) );
+        final boolean includeXFrameDeny = config.readSettingAsBoolean( PwmSetting.SECURITY_PREVENT_FRAMING );
+        final boolean includeXAmb = Boolean.parseBoolean( config.readAppProperty( AppProperty.HTTP_HEADER_SEND_XAMB ) );
 
         {
             final String noiseHeader = makeNoiseHeader( config );
-            if (noiseHeader != null) {
+            if ( noiseHeader != null )
+            {
                 resp.setHeader( HttpHeader.XNoise.getHttpName(), noiseHeader );
             }
         }
 
-        if (includeXVersion) {
-            resp.setHeader(HttpHeader.XVersion.getHttpName(), PwmConstants.SERVLET_VERSION);
+        if ( includeXVersion )
+        {
+            resp.setHeader( HttpHeader.XVersion.getHttpName(), PwmConstants.SERVLET_VERSION );
         }
 
-        if (includeXContentTypeOptions) {
-            resp.setHeader(HttpHeader.XContentTypeOptions.getHttpName(), "nosniff");
+        if ( includeXContentTypeOptions )
+        {
+            resp.setHeader( HttpHeader.XContentTypeOptions.getHttpName(), "nosniff" );
         }
 
-        if (includeXXSSProtection) {
-            resp.setHeader(HttpHeader.XXSSProtection.getHttpName(), "1");
+        if ( includeXXSSProtection )
+        {
+            resp.setHeader( HttpHeader.XXSSProtection.getHttpName(), "1" );
         }
 
-        if (includeXInstance) {
-            resp.setHeader(HttpHeader.XInstance.getHttpName(), String.valueOf(pwmApplication.getInstanceID()));
+        if ( includeXInstance )
+        {
+            resp.setHeader( HttpHeader.XInstance.getHttpName(), String.valueOf( pwmApplication.getInstanceID() ) );
         }
 
-        if (serverHeader != null && !serverHeader.isEmpty()) {
-            final String value = MacroMachine.forNonUserSpecific(pwmApplication, null).expandMacros(serverHeader);
-            resp.setHeader(HttpHeader.Server.getHttpName(), value);
+        if ( serverHeader != null && !serverHeader.isEmpty() )
+        {
+            final String value = MacroMachine.forNonUserSpecific( pwmApplication, null ).expandMacros( serverHeader );
+            resp.setHeader( HttpHeader.Server.getHttpName(), value );
         }
 
-        if (includeXFrameDeny) {
-            resp.setHeader(HttpHeader.XFrameOptions.getHttpName(), "DENY");
+        if ( includeXFrameDeny )
+        {
+            resp.setHeader( HttpHeader.XFrameOptions.getHttpName(), "DENY" );
         }
 
-        if (includeXAmb) {
-            resp.setHeader(HttpHeader.XAmb.getHttpName(), PwmConstants.X_AMB_HEADER.get(
-                    PwmRandom.getInstance().nextInt(PwmConstants.X_AMB_HEADER.size())
-            ));
+        if ( includeXAmb )
+        {
+            resp.setHeader( HttpHeader.XAmb.getHttpName(), PwmConstants.X_AMB_HEADER.get(
+                    PwmRandom.getInstance().nextInt( PwmConstants.X_AMB_HEADER.size() )
+            ) );
         }
 
-        resp.setHeader(HttpHeader.Cache_Control.getHttpName(), "no-cache, no-store, must-revalidate, proxy-revalidate");
+        resp.setHeader( HttpHeader.Cache_Control.getHttpName(), "no-cache, no-store, must-revalidate, proxy-revalidate" );
     }
 
 
-    public static String readUserHostname(final HttpServletRequest request, final Configuration config) throws PwmUnrecoverableException {
-        if (config != null && !config.readSettingAsBoolean(PwmSetting.REVERSE_DNS_ENABLE)) {
+    public static String readUserHostname( final HttpServletRequest request, final Configuration config ) throws PwmUnrecoverableException
+    {
+        if ( config != null && !config.readSettingAsBoolean( PwmSetting.REVERSE_DNS_ENABLE ) )
+        {
             return "";
         }
 
-        final String userIPAddress = readUserIPAddress(request, config);
-        try {
-            return InetAddress.getByName(userIPAddress).getCanonicalHostName();
-        } catch (UnknownHostException e) {
-            LOGGER.trace("unknown host while trying to compute hostname for src request: " + e.getMessage());
+        final String userIPAddress = readUserIPAddress( request, config );
+        try
+        {
+            return InetAddress.getByName( userIPAddress ).getCanonicalHostName();
+        }
+        catch ( UnknownHostException e )
+        {
+            LOGGER.trace( "unknown host while trying to compute hostname for src request: " + e.getMessage() );
         }
         return "";
     }
@@ -410,30 +483,37 @@ public class RequestInitializationFilter implements Filter {
      *
      * @return String containing the textual representation of the source IP address, or null if the request is invalid.
      */
-    public static String readUserIPAddress(final HttpServletRequest request, final Configuration config) throws PwmUnrecoverableException {
-        final boolean useXForwardedFor = config != null && config.readSettingAsBoolean(PwmSetting.USE_X_FORWARDED_FOR_HEADER);
+    public static String readUserIPAddress( final HttpServletRequest request, final Configuration config ) throws PwmUnrecoverableException
+    {
+        final boolean useXForwardedFor = config != null && config.readSettingAsBoolean( PwmSetting.USE_X_FORWARDED_FOR_HEADER );
 
         String userIP = "";
 
-        if (useXForwardedFor) {
-            userIP = request.getHeader(HttpHeader.XForwardedFor.getHttpName());
-            if (!StringUtil.isEmpty(userIP)) {
-                final int commaIndex = userIP.indexOf(',');
-                if (commaIndex > -1) {
-                    userIP = userIP.substring(0, commaIndex);
+        if ( useXForwardedFor )
+        {
+            userIP = request.getHeader( HttpHeader.XForwardedFor.getHttpName() );
+            if ( !StringUtil.isEmpty( userIP ) )
+            {
+                final int commaIndex = userIP.indexOf( ',' );
+                if ( commaIndex > -1 )
+                {
+                    userIP = userIP.substring( 0, commaIndex );
                 }
             }
 
-            if (!StringUtil.isEmpty(userIP)) {
-                if (!InetAddressValidator.getInstance().isValid(userIP)) {
-                    LOGGER.warn("discarding bogus network address '" + userIP + "' in "
-                            + HttpHeader.XForwardedFor.getHttpName() + " header");
+            if ( !StringUtil.isEmpty( userIP ) )
+            {
+                if ( !InetAddressValidator.getInstance().isValid( userIP ) )
+                {
+                    LOGGER.warn( "discarding bogus network address '" + userIP + "' in "
+                            + HttpHeader.XForwardedFor.getHttpName() + " header" );
                     userIP = null;
                 }
             }
         }
 
-        if (StringUtil.isEmpty(userIP)) {
+        if ( StringUtil.isEmpty( userIP ) )
+        {
             userIP = request.getRemoteAddr();
         }
 
@@ -450,33 +530,38 @@ public class RequestInitializationFilter implements Filter {
         final PwmURL pwmURL = pwmRequest.getURL();
 
         // mark if first request
-        if (ssBean.getSessionCreationTime() == null) {
-            ssBean.setSessionCreationTime(Instant.now());
-            ssBean.setSessionLastAccessedTime(Instant.now());
+        if ( ssBean.getSessionCreationTime() == null )
+        {
+            ssBean.setSessionCreationTime( Instant.now() );
+            ssBean.setSessionLastAccessedTime( Instant.now() );
         }
 
         // mark session ip address
-        if (ssBean.getSrcAddress() == null) {
-            ssBean.setSrcAddress(readUserIPAddress(pwmRequest.getHttpServletRequest(), pwmRequest.getConfig()));
+        if ( ssBean.getSrcAddress() == null )
+        {
+            ssBean.setSrcAddress( readUserIPAddress( pwmRequest.getHttpServletRequest(), pwmRequest.getConfig() ) );
         }
 
         // mark the user's hostname in the session bean
-        if (ssBean.getSrcHostname() == null) {
-            ssBean.setSrcHostname(readUserHostname(pwmRequest.getHttpServletRequest(), pwmRequest.getConfig()));
+        if ( ssBean.getSrcHostname() == null )
+        {
+            ssBean.setSrcHostname( readUserHostname( pwmRequest.getHttpServletRequest(), pwmRequest.getConfig() ) );
         }
 
         // update the privateUrlAccessed flag
-        if (pwmURL.isPrivateUrl()) {
-            ssBean.setPrivateUrlAccessed(true);
+        if ( pwmURL.isPrivateUrl() )
+        {
+            ssBean.setPrivateUrlAccessed( true );
         }
 
         // initialize the session's locale
-        if (ssBean.getLocale() == null) {
-            initializeLocaleAndTheme(pwmRequest);
+        if ( ssBean.getLocale() == null )
+        {
+            initializeLocaleAndTheme( pwmRequest );
         }
 
         // set idle timeout
-        PwmSessionWrapper.setHttpSessionIdleTimeout(pwmRequest.getPwmApplication(), pwmRequest.getPwmSession(), pwmRequest.getHttpServletRequest().getSession());
+        PwmSessionWrapper.setHttpSessionIdleTimeout( pwmRequest.getPwmApplication(), pwmRequest.getPwmSession(), pwmRequest.getHttpServletRequest().getSession() );
     }
 
     private static void initializeLocaleAndTheme(
@@ -484,28 +569,34 @@ public class RequestInitializationFilter implements Filter {
     )
             throws PwmUnrecoverableException
     {
-        final String localeCookieName = pwmRequest.getConfig().readAppProperty(AppProperty.HTTP_COOKIE_LOCALE_NAME);
-        final String localeCookie = pwmRequest.readCookie(localeCookieName);
-        if (localeCookieName.length() > 0 && localeCookie != null) {
-            LOGGER.debug(pwmRequest, "detected locale cookie in request, setting locale to " + localeCookie);
-            pwmRequest.getPwmSession().setLocale(pwmRequest.getPwmApplication(), localeCookie);
-        } else {
+        final String localeCookieName = pwmRequest.getConfig().readAppProperty( AppProperty.HTTP_COOKIE_LOCALE_NAME );
+        final String localeCookie = pwmRequest.readCookie( localeCookieName );
+        if ( localeCookieName.length() > 0 && localeCookie != null )
+        {
+            LOGGER.debug( pwmRequest, "detected locale cookie in request, setting locale to " + localeCookie );
+            pwmRequest.getPwmSession().setLocale( pwmRequest.getPwmApplication(), localeCookie );
+        }
+        else
+        {
             final List<Locale> knownLocales = pwmRequest.getConfig().getKnownLocales();
-            final Locale userLocale = LocaleHelper.localeResolver(pwmRequest.getHttpServletRequest().getLocale(), knownLocales);
-            pwmRequest.getPwmSession().getSessionStateBean().setLocale(userLocale == null ? PwmConstants.DEFAULT_LOCALE : userLocale);
-            LOGGER.trace(pwmRequest, "user locale set to '" + pwmRequest.getLocale() + "'");
+            final Locale userLocale = LocaleHelper.localeResolver( pwmRequest.getHttpServletRequest().getLocale(), knownLocales );
+            pwmRequest.getPwmSession().getSessionStateBean().setLocale( userLocale == null ? PwmConstants.DEFAULT_LOCALE : userLocale );
+            LOGGER.trace( pwmRequest, "user locale set to '" + pwmRequest.getLocale() + "'" );
         }
 
-        final String themeCookieName = pwmRequest.getConfig().readAppProperty(AppProperty.HTTP_COOKIE_THEME_NAME);
-        final String themeCookie = pwmRequest.readCookie(themeCookieName);
-        if (localeCookieName.length() > 0 && themeCookie != null && themeCookie.length() > 0) {
-            if (pwmRequest.getPwmApplication().getResourceServletService().checkIfThemeExists(pwmRequest, themeCookie)) {
-                LOGGER.debug(pwmRequest, "detected theme cookie in request, setting theme to " + themeCookie);
-                pwmRequest.getPwmSession().getSessionStateBean().setTheme(themeCookie);
+        final String themeCookieName = pwmRequest.getConfig().readAppProperty( AppProperty.HTTP_COOKIE_THEME_NAME );
+        final String themeCookie = pwmRequest.readCookie( themeCookieName );
+        if ( localeCookieName.length() > 0 && themeCookie != null && themeCookie.length() > 0 )
+        {
+            if ( pwmRequest.getPwmApplication().getResourceServletService().checkIfThemeExists( pwmRequest, themeCookie ) )
+            {
+                LOGGER.debug( pwmRequest, "detected theme cookie in request, setting theme to " + themeCookie );
+                pwmRequest.getPwmSession().getSessionStateBean().setTheme( themeCookie );
             }
         }
     }
 
+    @SuppressWarnings( "checkstyle:MethodLength" )
     public static void handleRequestSecurityChecks(
             final PwmRequest pwmRequest
     )
@@ -514,49 +605,61 @@ public class RequestInitializationFilter implements Filter {
         final LocalSessionStateBean ssBean = pwmRequest.getPwmSession().getSessionStateBean();
 
         // check the user's IP address
-        if (!pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.MULTI_IP_SESSION_ALLOWED)) {
-            final String remoteAddress = readUserIPAddress(pwmRequest.getHttpServletRequest(), pwmRequest.getConfig());
-            if (!ssBean.getSrcAddress().equals(remoteAddress)) {
+        if ( !pwmRequest.getConfig().readSettingAsBoolean( PwmSetting.MULTI_IP_SESSION_ALLOWED ) )
+        {
+            final String remoteAddress = readUserIPAddress( pwmRequest.getHttpServletRequest(), pwmRequest.getConfig() );
+            if ( !ssBean.getSrcAddress().equals( remoteAddress ) )
+            {
                 final String errorMsg = "current network address '" + remoteAddress + "' has changed from original network address '" + ssBean.getSrcAddress() + "'";
-                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SECURITY_VIOLATION,errorMsg);
-                throw new PwmUnrecoverableException(errorInformation);
+                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_SECURITY_VIOLATION, errorMsg );
+                throw new PwmUnrecoverableException( errorInformation );
             }
         }
 
         // check total time.
         {
-            if (ssBean.getSessionCreationTime() != null) {
-                final Long maxSessionSeconds = pwmRequest.getConfig().readSettingAsLong(PwmSetting.SESSION_MAX_SECONDS);
-                final TimeDuration sessionAge = TimeDuration.fromCurrent(ssBean.getSessionCreationTime());
-                if (sessionAge.getTotalSeconds() > maxSessionSeconds) {
+            if ( ssBean.getSessionCreationTime() != null )
+            {
+                final Long maxSessionSeconds = pwmRequest.getConfig().readSettingAsLong( PwmSetting.SESSION_MAX_SECONDS );
+                final TimeDuration sessionAge = TimeDuration.fromCurrent( ssBean.getSessionCreationTime() );
+                if ( sessionAge.getTotalSeconds() > maxSessionSeconds )
+                {
                     final String errorMsg = "session age (" + sessionAge.asCompactString() + ") is longer than maximum permitted age";
-                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SECURITY_VIOLATION,errorMsg);
-                    throw new PwmUnrecoverableException(errorInformation);
+                    final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_SECURITY_VIOLATION, errorMsg );
+                    throw new PwmUnrecoverableException( errorInformation );
                 }
             }
         }
 
         // check headers
         {
-            final List<String> requiredHeaders = pwmRequest.getConfig().readSettingAsStringArray(PwmSetting.REQUIRED_HEADERS);
-            if (requiredHeaders != null && !requiredHeaders.isEmpty()) {
-                final Map<String, String> configuredValues  = StringUtil.convertStringListToNameValuePair(requiredHeaders, "=");
+            final List<String> requiredHeaders = pwmRequest.getConfig().readSettingAsStringArray( PwmSetting.REQUIRED_HEADERS );
+            if ( requiredHeaders != null && !requiredHeaders.isEmpty() )
+            {
+                final Map<String, String> configuredValues = StringUtil.convertStringListToNameValuePair( requiredHeaders, "=" );
 
-                for (final Map.Entry<String,String> entry : configuredValues.entrySet()) {
+                for ( final Map.Entry<String, String> entry : configuredValues.entrySet() )
+                {
                     final String key = entry.getKey();
-                    if (key != null && key.length() > 0) {
+                    if ( key != null && key.length() > 0 )
+                    {
                         final String requiredValue = entry.getValue();
-                        if (requiredValue != null && requiredValue.length() > 0) {
-                            final String value = pwmRequest.readHeaderValueAsString(key);
-                            if (value == null || value.length() < 1) {
+                        if ( requiredValue != null && requiredValue.length() > 0 )
+                        {
+                            final String value = pwmRequest.readHeaderValueAsString( key );
+                            if ( value == null || value.length() < 1 )
+                            {
                                 final String errorMsg = "request is missing required value for header '" + key + "'";
-                                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SECURITY_VIOLATION,errorMsg);
-                                throw new PwmUnrecoverableException(errorInformation);
-                            } else {
-                                if (!requiredValue.equals(value)) {
+                                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_SECURITY_VIOLATION, errorMsg );
+                                throw new PwmUnrecoverableException( errorInformation );
+                            }
+                            else
+                            {
+                                if ( !requiredValue.equals( value ) )
+                                {
                                     final String errorMsg = "request has incorrect required value for header '" + key + "'";
-                                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SECURITY_VIOLATION,errorMsg);
-                                    throw new PwmUnrecoverableException(errorInformation);
+                                    final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_SECURITY_VIOLATION, errorMsg );
+                                    throw new PwmUnrecoverableException( errorInformation );
                                 }
                             }
                         }
@@ -567,132 +670,167 @@ public class RequestInitializationFilter implements Filter {
 
         // check permitted source IP address
         {
-            final List<String> requiredHeaders = pwmRequest.getConfig().readSettingAsStringArray(PwmSetting.IP_PERMITTED_RANGE);
-            if (requiredHeaders != null && !requiredHeaders.isEmpty()) {
+            final List<String> requiredHeaders = pwmRequest.getConfig().readSettingAsStringArray( PwmSetting.IP_PERMITTED_RANGE );
+            if ( requiredHeaders != null && !requiredHeaders.isEmpty() )
+            {
                 boolean match = false;
                 final String requestAddress = pwmRequest.getHttpServletRequest().getRemoteAddr();
-                for (int i = 0; i < requiredHeaders.size() && !match; i++) {
-                    final String ipMatchString = requiredHeaders.get(i);
-                    try {
-                        final IPMatcher ipMatcher = new IPMatcher(ipMatchString);
-                        try {
-                            if (ipMatcher.match(requestAddress)) {
+                for ( int i = 0; i < requiredHeaders.size() && !match; i++ )
+                {
+                    final String ipMatchString = requiredHeaders.get( i );
+                    try
+                    {
+                        final IPMatcher ipMatcher = new IPMatcher( ipMatchString );
+                        try
+                        {
+                            if ( ipMatcher.match( requestAddress ) )
+                            {
                                 match = true;
                             }
-                        } catch (IPMatcher.IPMatcherException e) {
-                            LOGGER.error("error while attempting to match permitted address range '" + ipMatchString + "', error: " + e);
                         }
-                    } catch (IPMatcher.IPMatcherException e) {
-                        LOGGER.error("error parsing permitted address range '" + ipMatchString + "', error: " + e);
+                        catch ( IPMatcher.IPMatcherException e )
+                        {
+                            LOGGER.error( "error while attempting to match permitted address range '" + ipMatchString + "', error: " + e );
+                        }
+                    }
+                    catch ( IPMatcher.IPMatcherException e )
+                    {
+                        LOGGER.error( "error parsing permitted address range '" + ipMatchString + "', error: " + e );
                     }
                 }
-                if (!match) {
+                if ( !match )
+                {
                     final String errorMsg = "request network address '" + requestAddress + "' does not match any configured permitted source address";
-                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SECURITY_VIOLATION,errorMsg);
-                    throw new PwmUnrecoverableException(errorInformation);
+                    final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_SECURITY_VIOLATION, errorMsg );
+                    throw new PwmUnrecoverableException( errorInformation );
                 }
             }
         }
 
         //  csrf cross-site request forgery checks
-        final boolean performCsrfHeaderChecks = Boolean.parseBoolean(pwmRequest.getConfig().readAppProperty(AppProperty.SECURITY_HTTP_PERFORM_CSRF_HEADER_CHECKS));
+        final boolean performCsrfHeaderChecks = Boolean.parseBoolean( pwmRequest.getConfig().readAppProperty( AppProperty.SECURITY_HTTP_PERFORM_CSRF_HEADER_CHECKS ) );
         if (
                 performCsrfHeaderChecks
                         && !pwmRequest.getMethod().isIdempotent()
                         && !pwmRequest.getURL().isRestService()
                 )
         {
-            final String originValue = pwmRequest.readHeaderValueAsString(HttpHeader.Origin);
-            final String referrerValue = pwmRequest.readHeaderValueAsString(HttpHeader.Referer);
-            final String siteUrl = pwmRequest.getPwmApplication().getConfig().readSettingAsString(PwmSetting.PWM_SITE_URL);
+            final String originValue = pwmRequest.readHeaderValueAsString( HttpHeader.Origin );
+            final String referrerValue = pwmRequest.readHeaderValueAsString( HttpHeader.Referer );
+            final String siteUrl = pwmRequest.getPwmApplication().getConfig().readSettingAsString( PwmSetting.PWM_SITE_URL );
 
             final String targetValue = pwmRequest.getHttpServletRequest().getRequestURL().toString();
-            if (StringUtil.isEmpty(targetValue)) {
+            if ( StringUtil.isEmpty( targetValue ) )
+            {
                 final String msg = "malformed request instance, missing target uri value";
-                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SECURITY_VIOLATION, msg);
-                LOGGER.debug(pwmRequest, errorInformation.toDebugStr() + " [" + makeHeaderDebugStr(pwmRequest) + "]");
-                throw new PwmUnrecoverableException(errorInformation);
+                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_SECURITY_VIOLATION, msg );
+                LOGGER.debug( pwmRequest, errorInformation.toDebugStr() + " [" + makeHeaderDebugStr( pwmRequest ) + "]" );
+                throw new PwmUnrecoverableException( errorInformation );
             }
 
             final boolean originHeaderEvaluated;
-            if (!StringUtil.isEmpty(originValue)) {
-                if (!PwmURL.compareUriBase(originValue, targetValue)) {
+            if ( !StringUtil.isEmpty( originValue ) )
+            {
+                if ( !PwmURL.compareUriBase( originValue, targetValue ) )
+                {
                     final String msg = "cross-origin request not permitted: origin header does not match incoming target url"
-                            + " [" + makeHeaderDebugStr(pwmRequest) + "]";
-                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SECURITY_VIOLATION, msg);
-                    LOGGER.debug(pwmRequest, errorInformation.toDebugStr());
-                    throw new PwmUnrecoverableException(errorInformation);
+                            + " [" + makeHeaderDebugStr( pwmRequest ) + "]";
+                    final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_SECURITY_VIOLATION, msg );
+                    LOGGER.debug( pwmRequest, errorInformation.toDebugStr() );
+                    throw new PwmUnrecoverableException( errorInformation );
                 }
                 originHeaderEvaluated = true;
-            } else {
+            }
+            else
+            {
                 originHeaderEvaluated = false;
             }
 
             final boolean referrerHeaderEvaluated;
-            if (!StringUtil.isEmpty(referrerValue)) {
-                if (!PwmURL.compareUriBase(referrerValue, targetValue) && !PwmURL.compareUriBase(referrerValue, siteUrl)) {
+            if ( !StringUtil.isEmpty( referrerValue ) )
+            {
+                if ( !PwmURL.compareUriBase( referrerValue, targetValue ) && !PwmURL.compareUriBase( referrerValue, siteUrl ) )
+                {
                     final String msg = "cross-origin request not permitted: referrer header does not match incoming target url"
-                            + " [" + makeHeaderDebugStr(pwmRequest) + "]";
-                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SECURITY_VIOLATION, msg);
-                    LOGGER.debug(pwmRequest, errorInformation.toDebugStr());
-                    throw new PwmUnrecoverableException(errorInformation);
+                            + " [" + makeHeaderDebugStr( pwmRequest ) + "]";
+                    final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_SECURITY_VIOLATION, msg );
+                    LOGGER.debug( pwmRequest, errorInformation.toDebugStr() );
+                    throw new PwmUnrecoverableException( errorInformation );
                 }
                 referrerHeaderEvaluated = true;
-            } else {
+            }
+            else
+            {
                 referrerHeaderEvaluated = false;
             }
 
-            if (!referrerHeaderEvaluated && !originHeaderEvaluated && !PwmURL.compareUriBase(originValue, siteUrl)) {
+            if ( !referrerHeaderEvaluated && !originHeaderEvaluated && !PwmURL.compareUriBase( originValue, siteUrl ) )
+            {
                 final String msg = "neither referer nor origin header request are present on non-idempotent request";
-                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SECURITY_VIOLATION, msg);
-                LOGGER.debug(pwmRequest, errorInformation.toDebugStr() + " [" + makeHeaderDebugStr(pwmRequest) + "]");
-                throw new PwmUnrecoverableException(errorInformation);
+                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_SECURITY_VIOLATION, msg );
+                LOGGER.debug( pwmRequest, errorInformation.toDebugStr() + " [" + makeHeaderDebugStr( pwmRequest ) + "]" );
+                throw new PwmUnrecoverableException( errorInformation );
             }
         }
 
         // check trial
-        if (PwmConstants.TRIAL_MODE) {
-            final String currentAuthString = pwmRequest.getPwmApplication().getStatisticsManager().getStatBundleForKey(StatisticsManager.KEY_CURRENT).getStatistic(Statistic.AUTHENTICATIONS);
-            if (new BigInteger(currentAuthString).compareTo(BigInteger.valueOf(PwmConstants.TRIAL_MAX_AUTHENTICATIONS)) > 0) {
-                throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_TRIAL_VIOLATION,"maximum usage per server startup exceeded"));
+        if ( PwmConstants.TRIAL_MODE )
+        {
+            final StatisticsManager statisticsManager = pwmRequest.getPwmApplication().getStatisticsManager();
+            final String currentAuthString = statisticsManager.getStatBundleForKey( StatisticsManager.KEY_CURRENT ).getStatistic( Statistic.AUTHENTICATIONS );
+            if ( new BigInteger( currentAuthString ).compareTo( BigInteger.valueOf( PwmConstants.TRIAL_MAX_AUTHENTICATIONS ) ) > 0 )
+            {
+                throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_TRIAL_VIOLATION, "maximum usage per server startup exceeded" ) );
             }
 
-            final String totalAuthString = pwmRequest.getPwmApplication().getStatisticsManager().getStatBundleForKey(StatisticsManager.KEY_CUMULATIVE).getStatistic(Statistic.AUTHENTICATIONS);
-            if (new BigInteger(totalAuthString).compareTo(BigInteger.valueOf(PwmConstants.TRIAL_MAX_TOTAL_AUTH)) > 0) {
-                throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_TRIAL_VIOLATION,"maximum usage for this server has been exceeded"));
+            final String totalAuthString = statisticsManager.getStatBundleForKey( StatisticsManager.KEY_CUMULATIVE ).getStatistic( Statistic.AUTHENTICATIONS );
+            if ( new BigInteger( totalAuthString ).compareTo( BigInteger.valueOf( PwmConstants.TRIAL_MAX_TOTAL_AUTH ) ) > 0 )
+            {
+                throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_TRIAL_VIOLATION, "maximum usage for this server has been exceeded" ) );
             }
         }
 
         // check intruder
-        pwmRequest.getPwmApplication().getIntruderManager().convenience().checkAddressAndSession(pwmRequest.getPwmSession());
+        pwmRequest.getPwmApplication().getIntruderManager().convenience().checkAddressAndSession( pwmRequest.getPwmSession() );
     }
 
-    private void checkIdleTimeout(final PwmRequest pwmRequest) throws PwmUnrecoverableException {
-        final TimeDuration maxDurationForRequest = IdleTimeoutCalculator.idleTimeoutForRequest(pwmRequest);
-        final TimeDuration currentDuration = TimeDuration.fromCurrent(pwmRequest.getHttpServletRequest().getSession().getLastAccessedTime());
-        if (currentDuration.isLongerThan(maxDurationForRequest)) {
-            LOGGER.debug("unauthenticated session due to idle time, max for request is " + maxDurationForRequest.asCompactString()
-                    + ", session idle time is " + currentDuration.asCompactString());
-            pwmRequest.getPwmSession().unauthenticateUser(pwmRequest);
+    private void checkIdleTimeout( final PwmRequest pwmRequest ) throws PwmUnrecoverableException
+    {
+        final TimeDuration maxDurationForRequest = IdleTimeoutCalculator.idleTimeoutForRequest( pwmRequest );
+        final TimeDuration currentDuration = TimeDuration.fromCurrent( pwmRequest.getHttpServletRequest().getSession().getLastAccessedTime() );
+        if ( currentDuration.isLongerThan( maxDurationForRequest ) )
+        {
+            LOGGER.debug( "unauthenticated session due to idle time, max for request is " + maxDurationForRequest.asCompactString()
+                    + ", session idle time is " + currentDuration.asCompactString() );
+            pwmRequest.getPwmSession().unauthenticateUser( pwmRequest );
         }
     }
 
-    private static String makeHeaderDebugStr(final PwmRequest pwmRequest) {
-        final Map<String,String> values = new LinkedHashMap<>();
-        for (final HttpHeader header : new HttpHeader[]{HttpHeader.Referer, HttpHeader.Origin}) {
-            values.put(header.getHttpName(), pwmRequest.readHeaderValueAsString(header));
+    private static String makeHeaderDebugStr( final PwmRequest pwmRequest )
+    {
+        final Map<String, String> values = new LinkedHashMap<>();
+        for ( final HttpHeader header : new HttpHeader[]
+                {
+                        HttpHeader.Referer,
+                        HttpHeader.Origin,
+                }
+                )
+        {
+            values.put( header.getHttpName(), pwmRequest.readHeaderValueAsString( header ) );
         }
-        values.put("target", pwmRequest.getHttpServletRequest().getRequestURL().toString());
-        values.put("siteUrl", pwmRequest.getPwmApplication().getConfig().readSettingAsString(PwmSetting.PWM_SITE_URL));
-        return StringUtil.mapToString(values);
+        values.put( "target", pwmRequest.getHttpServletRequest().getRequestURL().toString() );
+        values.put( "siteUrl", pwmRequest.getPwmApplication().getConfig().readSettingAsString( PwmSetting.PWM_SITE_URL ) );
+        return StringUtil.mapToString( values );
     }
 
-    private static String makeNoiseHeader(final Configuration configuration) {
-        final boolean sendNoise = Boolean.parseBoolean(configuration.readAppProperty(AppProperty.HTTP_HEADER_SEND_XNOISE));
+    private static String makeNoiseHeader( final Configuration configuration )
+    {
+        final boolean sendNoise = Boolean.parseBoolean( configuration.readAppProperty( AppProperty.HTTP_HEADER_SEND_XNOISE ) );
 
-        if (sendNoise) {
-            final int noiseLength = Integer.parseInt(configuration.readAppProperty(AppProperty.HTTP_HEADER_NOISE_LENGTH));
-            return PwmRandom.getInstance().alphaNumericString(PwmRandom.getInstance().nextInt(noiseLength)+11);
+        if ( sendNoise )
+        {
+            final int noiseLength = Integer.parseInt( configuration.readAppProperty( AppProperty.HTTP_HEADER_NOISE_LENGTH ) );
+            return PwmRandom.getInstance().alphaNumericString( PwmRandom.getInstance().nextInt( noiseLength ) + 11 );
         }
 
         return null;

+ 374 - 277
server/src/main/java/password/pwm/http/servlet/ActivateUserServlet.java

@@ -94,12 +94,12 @@ import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
 /**
- * User interaction servlet for creating new users (self registration)
+ * User interaction servlet for creating new users (self registration).
  *
  * @author Jason D. Rivard
  */
 @WebServlet(
-        name="ActivateUserServlet",
+        name = "ActivateUserServlet",
         urlPatterns = {
                 PwmConstants.URL_PREFIX_PUBLIC + "/activate",
                 PwmConstants.URL_PREFIX_PUBLIC + "/activate/*",
@@ -107,43 +107,46 @@ import java.util.concurrent.TimeUnit;
                 PwmConstants.URL_PREFIX_PUBLIC + "/ActivateUser/*",
         }
 )
-public class ActivateUserServlet extends AbstractPwmServlet {
+public class ActivateUserServlet extends AbstractPwmServlet
+{
 
-    private static final PwmLogger LOGGER = PwmLogger.forClass(ActivateUserServlet.class);
+    private static final PwmLogger LOGGER = PwmLogger.forClass( ActivateUserServlet.class );
 
-    public enum ActivateUserAction implements AbstractPwmServlet.ProcessAction {
-        activate(HttpMethod.POST),
-        enterCode(HttpMethod.POST, HttpMethod.GET),
-        reset(HttpMethod.POST),
-        agree(HttpMethod.POST),
-
-        ;
+    public enum ActivateUserAction implements AbstractPwmServlet.ProcessAction
+    {
+        activate( HttpMethod.POST ),
+        enterCode( HttpMethod.POST, HttpMethod.GET ),
+        reset( HttpMethod.POST ),
+        agree( HttpMethod.POST ),;
 
         private final Collection<HttpMethod> method;
 
-        ActivateUserAction(final HttpMethod... method)
+        ActivateUserAction( final HttpMethod... method )
         {
-            this.method = Collections.unmodifiableList(Arrays.asList(method));
+            this.method = Collections.unmodifiableList( Arrays.asList( method ) );
         }
 
-        public Collection<HttpMethod> permittedMethods()
+        public Collection<HttpMethod> permittedMethods( )
         {
             return method;
         }
     }
 
-    protected ActivateUserAction readProcessAction(final PwmRequest request)
+    protected ActivateUserAction readProcessAction( final PwmRequest request )
             throws PwmUnrecoverableException
     {
-        try {
-            return ActivateUserAction.valueOf(request.readParameterAsString(PwmConstants.PARAM_ACTION_REQUEST));
-        } catch (IllegalArgumentException e) {
+        try
+        {
+            return ActivateUserAction.valueOf( request.readParameterAsString( PwmConstants.PARAM_ACTION_REQUEST ) );
+        }
+        catch ( IllegalArgumentException e )
+        {
             return null;
         }
     }
 
 
-    protected void processAction(final PwmRequest pwmRequest)
+    protected void processAction( final PwmRequest pwmRequest )
             throws ServletException, ChaiUnavailableException, IOException, PwmUnrecoverableException
     {
         //Fetch the session state bean.
@@ -152,59 +155,67 @@ public class ActivateUserServlet extends AbstractPwmServlet {
 
         final Configuration config = pwmApplication.getConfig();
 
-        final ActivateUserBean activateUserBean = pwmApplication.getSessionStateService().getBean(pwmRequest, ActivateUserBean.class);
+        final ActivateUserBean activateUserBean = pwmApplication.getSessionStateService().getBean( pwmRequest, ActivateUserBean.class );
 
-        if (!config.readSettingAsBoolean(PwmSetting.ACTIVATE_USER_ENABLE)) {
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE,"activate user is not enabled");
-            pwmRequest.respondWithError(errorInformation);
+        if ( !config.readSettingAsBoolean( PwmSetting.ACTIVATE_USER_ENABLE ) )
+        {
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_SERVICE_NOT_AVAILABLE, "activate user is not enabled" );
+            pwmRequest.respondWithError( errorInformation );
             return;
         }
 
-        if (pwmSession.isAuthenticated()) {
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_USERAUTHENTICATED);
-            pwmRequest.respondWithError(errorInformation);
+        if ( pwmSession.isAuthenticated() )
+        {
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_USERAUTHENTICATED );
+            pwmRequest.respondWithError( errorInformation );
             return;
         }
 
-        final ActivateUserAction action = readProcessAction(pwmRequest);
+        final ActivateUserAction action = readProcessAction( pwmRequest );
 
         // convert a url command like /pwm/public/NewUserServlet/12321321 to redirect with a process action.
-        if (action == null) {
-            if (pwmRequest.convertURLtokenCommand(PwmServletDefinition.ActivateUser, ActivateUserAction.enterCode)) {
+        if ( action == null )
+        {
+            if ( pwmRequest.convertURLtokenCommand( PwmServletDefinition.ActivateUser, ActivateUserAction.enterCode ) )
+            {
                 return;
             }
-        } else {
-            switch (action) {
+        }
+        else
+        {
+            switch ( action )
+            {
                 case activate:
-                    handleActivationRequest(pwmRequest);
+                    handleActivationRequest( pwmRequest );
                     break;
 
                 case enterCode:
-                    handleEnterTokenCode(pwmRequest);
+                    handleEnterTokenCode( pwmRequest );
                     break;
 
                 case reset:
-                    pwmApplication.getSessionStateService().clearBean(pwmRequest, ActivateUserBean.class);
-                    forwardToActivateUserForm(pwmRequest);
+                    pwmApplication.getSessionStateService().clearBean( pwmRequest, ActivateUserBean.class );
+                    forwardToActivateUserForm( pwmRequest );
                     return;
 
                 case agree:
-                    handleAgreeRequest(pwmRequest, activateUserBean);
-                    advanceToNextStage(pwmRequest);
+                    handleAgreeRequest( pwmRequest, activateUserBean );
+                    advanceToNextStage( pwmRequest );
                     break;
 
                 default:
-                    JavaHelper.unhandledSwitchStatement(action);
+                    JavaHelper.unhandledSwitchStatement( action );
 
             }
         }
 
-        if (!pwmRequest.getPwmResponse().isCommitted()) {
-            this.advanceToNextStage(pwmRequest);
+        if ( !pwmRequest.getPwmResponse().isCommitted() )
+        {
+            this.advanceToNextStage( pwmRequest );
         }
     }
 
-    public void handleActivationRequest(final PwmRequest pwmRequest)
+    public void handleActivationRequest( final PwmRequest pwmRequest )
             throws PwmUnrecoverableException, ChaiUnavailableException, IOException, ServletException
     {
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
@@ -212,78 +223,84 @@ public class ActivateUserServlet extends AbstractPwmServlet {
         final Configuration config = pwmApplication.getConfig();
         final LocalSessionStateBean ssBean = pwmSession.getSessionStateBean();
 
-        if (CaptchaUtility.captchaEnabledForRequest(pwmRequest)) {
-            if (!CaptchaUtility.verifyReCaptcha(pwmRequest)) {
-                final ErrorInformation errorInfo = new ErrorInformation(PwmError.ERROR_BAD_CAPTCHA_RESPONSE);
-                LOGGER.debug(pwmRequest, errorInfo);
-                setLastError(pwmRequest, errorInfo);
+        if ( CaptchaUtility.captchaEnabledForRequest( pwmRequest ) )
+        {
+            if ( !CaptchaUtility.verifyReCaptcha( pwmRequest ) )
+            {
+                final ErrorInformation errorInfo = new ErrorInformation( PwmError.ERROR_BAD_CAPTCHA_RESPONSE );
+                LOGGER.debug( pwmRequest, errorInfo );
+                setLastError( pwmRequest, errorInfo );
                 return;
             }
         }
 
 
-        pwmApplication.getSessionStateService().clearBean(pwmRequest, ActivateUserBean.class);
-        final List<FormConfiguration> configuredActivationForm = config.readSettingAsForm(PwmSetting.ACTIVATE_USER_FORM);
+        pwmApplication.getSessionStateService().clearBean( pwmRequest, ActivateUserBean.class );
+        final List<FormConfiguration> configuredActivationForm = config.readSettingAsForm( PwmSetting.ACTIVATE_USER_FORM );
 
-        Map<FormConfiguration,String> formValues = new HashMap<>();
-        try {
+        Map<FormConfiguration, String> formValues = new HashMap<>();
+        try
+        {
             //read the values from the request
-            formValues = FormUtility.readFormValuesFromRequest(pwmRequest, configuredActivationForm,
-                    ssBean.getLocale());
+            formValues = FormUtility.readFormValuesFromRequest( pwmRequest, configuredActivationForm,
+                    ssBean.getLocale() );
 
             // check for intruders
-            pwmApplication.getIntruderManager().convenience().checkAttributes(formValues);
+            pwmApplication.getIntruderManager().convenience().checkAttributes( formValues );
 
             // read the context attr
-            final String contextParam = pwmRequest.readParameterAsString(PwmConstants.PARAM_CONTEXT);
+            final String contextParam = pwmRequest.readParameterAsString( PwmConstants.PARAM_CONTEXT );
 
             // read the profile attr
-            final String ldapProfile = pwmRequest.readParameterAsString(PwmConstants.PARAM_LDAP_PROFILE);
+            final String ldapProfile = pwmRequest.readParameterAsString( PwmConstants.PARAM_LDAP_PROFILE );
 
             // see if the values meet the configured form requirements.
-            FormUtility.validateFormValues(config, formValues, ssBean.getLocale());
+            FormUtility.validateFormValues( config, formValues, ssBean.getLocale() );
 
-            final String searchFilter = figureLdapSearchFilter(pwmRequest);
+            final String searchFilter = figureLdapSearchFilter( pwmRequest );
 
             // read an ldap user object based on the params
             final UserIdentity userIdentity;
             {
                 final UserSearchEngine userSearchEngine = pwmApplication.getUserSearchEngine();
                 final SearchConfiguration searchConfiguration = SearchConfiguration.builder()
-                        .contexts(Collections.singletonList(contextParam))
-                        .filter(searchFilter)
-                        .formValues(formValues)
-                        .ldapProfile(ldapProfile)
+                        .contexts( Collections.singletonList( contextParam ) )
+                        .filter( searchFilter )
+                        .formValues( formValues )
+                        .ldapProfile( ldapProfile )
                         .build();
 
-                userIdentity = userSearchEngine.performSingleUserSearch(searchConfiguration, pwmRequest.getSessionLabel());
+                userIdentity = userSearchEngine.performSingleUserSearch( searchConfiguration, pwmRequest.getSessionLabel() );
             }
 
-            validateParamsAgainstLDAP(pwmRequest, formValues, userIdentity);
+            validateParamsAgainstLDAP( pwmRequest, formValues, userIdentity );
 
-            final List<UserPermission> userPermissions = config.readSettingAsUserPermission(PwmSetting.ACTIVATE_USER_QUERY_MATCH);
-            if (!LdapPermissionTester.testUserPermissions(pwmApplication, pwmSession.getLabel(), userIdentity, userPermissions)) {
+            final List<UserPermission> userPermissions = config.readSettingAsUserPermission( PwmSetting.ACTIVATE_USER_QUERY_MATCH );
+            if ( !LdapPermissionTester.testUserPermissions( pwmApplication, pwmSession.getLabel(), userIdentity, userPermissions ) )
+            {
                 final String errorMsg = "user " + userIdentity + " attempted activation, but does not match query string";
-                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_ACTIVATE_NO_PERMISSION, errorMsg);
-                pwmApplication.getIntruderManager().convenience().markUserIdentity(userIdentity, pwmSession);
-                pwmApplication.getIntruderManager().convenience().markAddressAndSession(pwmSession);
-                throw new PwmUnrecoverableException(errorInformation);
+                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_ACTIVATE_NO_PERMISSION, errorMsg );
+                pwmApplication.getIntruderManager().convenience().markUserIdentity( userIdentity, pwmSession );
+                pwmApplication.getIntruderManager().convenience().markAddressAndSession( pwmSession );
+                throw new PwmUnrecoverableException( errorInformation );
             }
 
-            final ActivateUserBean activateUserBean = pwmApplication.getSessionStateService().getBean(pwmRequest, ActivateUserBean.class);
-            activateUserBean.setUserIdentity(userIdentity);
-            activateUserBean.setFormValidated(true);
-            pwmApplication.getIntruderManager().convenience().clearAttributes(formValues);
-            pwmApplication.getIntruderManager().convenience().clearAddressAndSession(pwmSession);
-        } catch (PwmOperationalException e) {
-            pwmApplication.getIntruderManager().convenience().markAttributes(formValues, pwmSession);
-            pwmApplication.getIntruderManager().convenience().markAddressAndSession(pwmSession);
-            setLastError(pwmRequest, e.getErrorInformation());
-            LOGGER.debug(pwmSession.getLabel(),e.getErrorInformation().toDebugStr());
+            final ActivateUserBean activateUserBean = pwmApplication.getSessionStateService().getBean( pwmRequest, ActivateUserBean.class );
+            activateUserBean.setUserIdentity( userIdentity );
+            activateUserBean.setFormValidated( true );
+            pwmApplication.getIntruderManager().convenience().clearAttributes( formValues );
+            pwmApplication.getIntruderManager().convenience().clearAddressAndSession( pwmSession );
+        }
+        catch ( PwmOperationalException e )
+        {
+            pwmApplication.getIntruderManager().convenience().markAttributes( formValues, pwmSession );
+            pwmApplication.getIntruderManager().convenience().markAddressAndSession( pwmSession );
+            setLastError( pwmRequest, e.getErrorInformation() );
+            LOGGER.debug( pwmSession.getLabel(), e.getErrorInformation().toDebugStr() );
         }
 
         // redirect user to change password screen.
-        advanceToNextStage(pwmRequest);
+        advanceToNextStage( pwmRequest );
     }
 
     private void handleAgreeRequest(
@@ -292,49 +309,57 @@ public class ActivateUserServlet extends AbstractPwmServlet {
     )
             throws ServletException, IOException, PwmUnrecoverableException, ChaiUnavailableException
     {
-        LOGGER.debug(pwmRequest, "user accepted agreement");
+        LOGGER.debug( pwmRequest, "user accepted agreement" );
 
-        if (!activateUserBean.isAgreementPassed()) {
-            activateUserBean.setAgreementPassed(true);
-            final AuditRecord auditRecord = new AuditRecordFactory(pwmRequest).createUserAuditRecord(
+        if ( !activateUserBean.isAgreementPassed() )
+        {
+            activateUserBean.setAgreementPassed( true );
+            final AuditRecord auditRecord = new AuditRecordFactory( pwmRequest ).createUserAuditRecord(
                     AuditEvent.AGREEMENT_PASSED,
                     pwmRequest.getUserInfoIfLoggedIn(),
                     pwmRequest.getSessionLabel(),
                     "ActivateUser"
             );
-            pwmRequest.getPwmApplication().getAuditManager().submit(auditRecord);
+            pwmRequest.getPwmApplication().getAuditManager().submit( auditRecord );
         }
     }
 
 
-    private void advanceToNextStage(final PwmRequest pwmRequest)
+    private void advanceToNextStage( final PwmRequest pwmRequest )
             throws PwmUnrecoverableException, IOException, ServletException, ChaiUnavailableException
     {
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
         final PwmSession pwmSession = pwmRequest.getPwmSession();
         final Configuration config = pwmApplication.getConfig();
-        final ActivateUserBean activateUserBean = pwmApplication.getSessionStateService().getBean(pwmRequest, ActivateUserBean.class);
+        final ActivateUserBean activateUserBean = pwmApplication.getSessionStateService().getBean( pwmRequest, ActivateUserBean.class );
 
-        if (!activateUserBean.isFormValidated() || activateUserBean.getUserIdentity() == null) {
-            forwardToActivateUserForm(pwmRequest);
+        if ( !activateUserBean.isFormValidated() || activateUserBean.getUserIdentity() == null )
+        {
+            forwardToActivateUserForm( pwmRequest );
             return;
         }
 
-        final boolean tokenRequired = MessageSendMethod.NONE != MessageSendMethod.valueOf(config.readSettingAsString(PwmSetting.ACTIVATE_TOKEN_SEND_METHOD));
-        if (tokenRequired) {
-            if (!activateUserBean.isTokenIssued()) {
-                try {
+        final boolean tokenRequired = MessageSendMethod.NONE != MessageSendMethod.valueOf( config.readSettingAsString( PwmSetting.ACTIVATE_TOKEN_SEND_METHOD ) );
+        if ( tokenRequired )
+        {
+            if ( !activateUserBean.isTokenIssued() )
+            {
+                try
+                {
                     final Locale locale = pwmSession.getSessionStateBean().getLocale();
-                    initializeToken(pwmRequest, locale, activateUserBean.getUserIdentity());
-                } catch (PwmOperationalException e) {
-                    setLastError(pwmRequest, e.getErrorInformation());
-                    forwardToActivateUserForm(pwmRequest);
+                    initializeToken( pwmRequest, locale, activateUserBean.getUserIdentity() );
+                }
+                catch ( PwmOperationalException e )
+                {
+                    setLastError( pwmRequest, e.getErrorInformation() );
+                    forwardToActivateUserForm( pwmRequest );
                     return;
                 }
             }
 
-            if (!activateUserBean.isTokenPassed()) {
-                pwmRequest.forwardToJsp(JspUrl.ACTIVATE_USER_ENTER_CODE);
+            if ( !activateUserBean.isTokenPassed() )
+            {
+                pwmRequest.forwardToJsp( JspUrl.ACTIVATE_USER_ENTER_CODE );
                 return;
             }
         }
@@ -343,24 +368,29 @@ public class ActivateUserServlet extends AbstractPwmServlet {
                 PwmSetting.ACTIVATE_AGREEMENT_MESSAGE,
                 pwmSession.getSessionStateBean().getLocale()
         );
-        if (agreementText != null && agreementText.length() > 0 && !activateUserBean.isAgreementPassed()) {
-            if (activateUserBean.getAgreementText() == null) {
-                final MacroMachine macroMachine = MacroMachine.forUser(pwmRequest, activateUserBean.getUserIdentity());
-                final String expandedText = macroMachine.expandMacros(agreementText);
-                activateUserBean.setAgreementText(expandedText);
+        if ( agreementText != null && agreementText.length() > 0 && !activateUserBean.isAgreementPassed() )
+        {
+            if ( activateUserBean.getAgreementText() == null )
+            {
+                final MacroMachine macroMachine = MacroMachine.forUser( pwmRequest, activateUserBean.getUserIdentity() );
+                final String expandedText = macroMachine.expandMacros( agreementText );
+                activateUserBean.setAgreementText( expandedText );
             }
-            pwmRequest.forwardToJsp(JspUrl.ACTIVATE_USER_AGREEMENT);
+            pwmRequest.forwardToJsp( JspUrl.ACTIVATE_USER_AGREEMENT );
             return;
         }
 
-        try {
-            activateUser(pwmRequest, activateUserBean.getUserIdentity());
-            pwmRequest.getPwmResponse().forwardToSuccessPage(Message.Success_ActivateUser);
-        } catch (PwmOperationalException e) {
-            LOGGER.debug(pwmRequest, e.getErrorInformation());
-            pwmApplication.getIntruderManager().convenience().markUserIdentity(activateUserBean.getUserIdentity(),pwmSession);
-            pwmApplication.getIntruderManager().convenience().markAddressAndSession(pwmSession);
-            pwmRequest.respondWithError(e.getErrorInformation());
+        try
+        {
+            activateUser( pwmRequest, activateUserBean.getUserIdentity() );
+            pwmRequest.getPwmResponse().forwardToSuccessPage( Message.Success_ActivateUser );
+        }
+        catch ( PwmOperationalException e )
+        {
+            LOGGER.debug( pwmRequest, e.getErrorInformation() );
+            pwmApplication.getIntruderManager().convenience().markUserIdentity( activateUserBean.getUserIdentity(), pwmSession );
+            pwmApplication.getIntruderManager().convenience().markAddressAndSession( pwmSession );
+            pwmRequest.respondWithError( e.getErrorInformation() );
         }
     }
 
@@ -373,95 +403,116 @@ public class ActivateUserServlet extends AbstractPwmServlet {
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
         final PwmSession pwmSession = pwmRequest.getPwmSession();
         final Configuration config = pwmApplication.getConfig();
-        final ChaiUser theUser = pwmApplication.getProxiedChaiUser(userIdentity);
-        if (config.readSettingAsBoolean(PwmSetting.ACTIVATE_USER_UNLOCK)) {
-            try {
+        final ChaiUser theUser = pwmApplication.getProxiedChaiUser( userIdentity );
+        if ( config.readSettingAsBoolean( PwmSetting.ACTIVATE_USER_UNLOCK ) )
+        {
+            try
+            {
                 theUser.unlockPassword();
-            } catch (ChaiOperationException e) {
+            }
+            catch ( ChaiOperationException e )
+            {
                 final String errorMsg = "error unlocking user " + userIdentity + ": " + e.getMessage();
-                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_ACTIVATION_FAILURE, errorMsg);
-                throw new PwmOperationalException(errorInformation);
+                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_ACTIVATION_FAILURE, errorMsg );
+                throw new PwmOperationalException( errorInformation );
             }
         }
 
-        try {
-            {  // execute configured actions
-                LOGGER.debug(pwmSession.getLabel(), "executing configured pre-actions to user " + theUser.getEntryDN());
-                final List<ActionConfiguration> configValues = config.readSettingAsAction(PwmSetting.ACTIVATE_USER_PRE_WRITE_ATTRIBUTES);
-                if (configValues != null && !configValues.isEmpty()) {
-                    final MacroMachine macroMachine = MacroMachine.forUser(pwmRequest, userIdentity);
-
-                    final ActionExecutor actionExecutor = new ActionExecutor.ActionExecutorSettings(pwmApplication, userIdentity)
-                            .setExpandPwmMacros(true)
-                            .setMacroMachine(macroMachine)
+        try
+        {
+            {
+                // execute configured actions
+                LOGGER.debug( pwmSession.getLabel(), "executing configured pre-actions to user " + theUser.getEntryDN() );
+                final List<ActionConfiguration> configValues = config.readSettingAsAction( PwmSetting.ACTIVATE_USER_PRE_WRITE_ATTRIBUTES );
+                if ( configValues != null && !configValues.isEmpty() )
+                {
+                    final MacroMachine macroMachine = MacroMachine.forUser( pwmRequest, userIdentity );
+
+                    final ActionExecutor actionExecutor = new ActionExecutor.ActionExecutorSettings( pwmApplication, userIdentity )
+                            .setExpandPwmMacros( true )
+                            .setMacroMachine( macroMachine )
                             .createActionExecutor();
 
-                    actionExecutor.executeActions(configValues, pwmRequest.getSessionLabel());
+                    actionExecutor.executeActions( configValues, pwmRequest.getSessionLabel() );
                 }
             }
 
             //authenticate the pwm session
-            final SessionAuthenticator sessionAuthenticator = new SessionAuthenticator(pwmApplication, pwmSession, PwmAuthenticationSource.USER_ACTIVATION);
-            sessionAuthenticator.authUserWithUnknownPassword(userIdentity,AuthenticationType.AUTH_FROM_PUBLIC_MODULE);
+            final SessionAuthenticator sessionAuthenticator = new SessionAuthenticator( pwmApplication, pwmSession, PwmAuthenticationSource.USER_ACTIVATION );
+            sessionAuthenticator.authUserWithUnknownPassword( userIdentity, AuthenticationType.AUTH_FROM_PUBLIC_MODULE );
 
             //ensure a change password is triggered
-            pwmSession.getLoginInfoBean().setType(AuthenticationType.AUTH_FROM_PUBLIC_MODULE);
-            pwmSession.getLoginInfoBean().getAuthFlags().add(AuthenticationType.AUTH_FROM_PUBLIC_MODULE);
-            pwmSession.getLoginInfoBean().getLoginFlags().add(LoginInfoBean.LoginFlag.forcePwChange);
+            pwmSession.getLoginInfoBean().setType( AuthenticationType.AUTH_FROM_PUBLIC_MODULE );
+            pwmSession.getLoginInfoBean().getAuthFlags().add( AuthenticationType.AUTH_FROM_PUBLIC_MODULE );
+            pwmSession.getLoginInfoBean().getLoginFlags().add( LoginInfoBean.LoginFlag.forcePwChange );
 
 
             // mark the event log
-            pwmApplication.getAuditManager().submit(AuditEvent.ACTIVATE_USER, pwmSession.getUserInfo(), pwmSession);
+            pwmApplication.getAuditManager().submit( AuditEvent.ACTIVATE_USER, pwmSession.getUserInfo(), pwmSession );
 
             // update the stats bean
-            pwmApplication.getStatisticsManager().incrementValue(Statistic.ACTIVATED_USERS);
+            pwmApplication.getStatisticsManager().incrementValue( Statistic.ACTIVATED_USERS );
 
             // send email or sms
-            sendPostActivationNotice(pwmRequest);
+            sendPostActivationNotice( pwmRequest );
 
             // setup post-change attributes
-            final PostChangePasswordAction postAction = new PostChangePasswordAction() {
+            final PostChangePasswordAction postAction = new PostChangePasswordAction()
+            {
 
-                public String getLabel() {
+                public String getLabel( )
+                {
                     return "ActivateUser write attributes";
                 }
 
-                public boolean doAction(final PwmSession pwmSession, final String newPassword)
-                        throws PwmUnrecoverableException {
-                    try {
-                        {  // execute configured actions
-                            LOGGER.debug(pwmSession.getLabel(), "executing post-activate configured actions to user " + userIdentity.toDisplayString());
-
-                            final MacroMachine macroMachine = pwmSession.getSessionManager().getMacroMachine(pwmApplication);
-                            final List<ActionConfiguration> configValues = pwmApplication.getConfig().readSettingAsAction(PwmSetting.ACTIVATE_USER_POST_WRITE_ATTRIBUTES);
-
-                            final ActionExecutor actionExecutor = new ActionExecutor.ActionExecutorSettings(pwmApplication, userIdentity)
-                                    .setExpandPwmMacros(true)
-                                    .setMacroMachine(macroMachine)
+                public boolean doAction( final PwmSession pwmSession, final String newPassword )
+                        throws PwmUnrecoverableException
+                {
+                    try
+                    {
+                        {
+                            // execute configured actions
+                            LOGGER.debug( pwmSession.getLabel(), "executing post-activate configured actions to user " + userIdentity.toDisplayString() );
+
+                            final MacroMachine macroMachine = pwmSession.getSessionManager().getMacroMachine( pwmApplication );
+                            final List<ActionConfiguration> configValues = pwmApplication.getConfig().readSettingAsAction( PwmSetting.ACTIVATE_USER_POST_WRITE_ATTRIBUTES );
+
+                            final ActionExecutor actionExecutor = new ActionExecutor.ActionExecutorSettings( pwmApplication, userIdentity )
+                                    .setExpandPwmMacros( true )
+                                    .setMacroMachine( macroMachine )
                                     .createActionExecutor();
-                            actionExecutor.executeActions(configValues, pwmRequest.getSessionLabel());
+                            actionExecutor.executeActions( configValues, pwmRequest.getSessionLabel() );
                         }
-                    } catch (PwmOperationalException e) {
-                        final ErrorInformation info = new ErrorInformation(PwmError.ERROR_ACTIVATION_FAILURE, e.getErrorInformation().getDetailedErrorMsg(), e.getErrorInformation().getFieldValues());
-                        final PwmUnrecoverableException newException = new PwmUnrecoverableException(info);
-                        newException.initCause(e);
+                    }
+                    catch ( PwmOperationalException e )
+                    {
+                        final ErrorInformation info = new ErrorInformation(
+                                PwmError.ERROR_ACTIVATION_FAILURE,
+                                e.getErrorInformation().getDetailedErrorMsg(), e.getErrorInformation().getFieldValues()
+                        );
+                        final PwmUnrecoverableException newException = new PwmUnrecoverableException( info );
+                        newException.initCause( e );
                         throw newException;
-                    } catch (ChaiUnavailableException e) {
+                    }
+                    catch ( ChaiUnavailableException e )
+                    {
                         final String errorMsg = "unable to reach ldap server while writing post-activate attributes: " + e.getMessage();
-                        final ErrorInformation info = new ErrorInformation(PwmError.ERROR_ACTIVATION_FAILURE, errorMsg);
-                        final PwmUnrecoverableException newException = new PwmUnrecoverableException(info);
-                        newException.initCause(e);
+                        final ErrorInformation info = new ErrorInformation( PwmError.ERROR_ACTIVATION_FAILURE, errorMsg );
+                        final PwmUnrecoverableException newException = new PwmUnrecoverableException( info );
+                        newException.initCause( e );
                         throw newException;
                     }
                     return true;
                 }
             };
 
-            pwmSession.getUserSessionDataCacheBean().addPostChangePasswordActions("activateUserWriteAttributes", postAction);
-        } catch (ImpossiblePasswordPolicyException e) {
-            final ErrorInformation info = new ErrorInformation(PwmError.ERROR_UNKNOWN, "unexpected ImpossiblePasswordPolicyException error while activating user");
-            LOGGER.warn(pwmSession, info, e);
-            throw new PwmOperationalException(info);
+            pwmSession.getUserSessionDataCacheBean().addPostChangePasswordActions( "activateUserWriteAttributes", postAction );
+        }
+        catch ( ImpossiblePasswordPolicyException e )
+        {
+            final ErrorInformation info = new ErrorInformation( PwmError.ERROR_UNKNOWN, "unexpected ImpossiblePasswordPolicyException error while activating user" );
+            LOGGER.warn( pwmSession, info, e );
+            throw new PwmOperationalException( info );
         }
     }
 
@@ -474,29 +525,47 @@ public class ActivateUserServlet extends AbstractPwmServlet {
     {
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
         final PwmSession pwmSession = pwmRequest.getPwmSession();
-        final String searchFilter = figureLdapSearchFilter(pwmRequest);
-        final ChaiProvider chaiProvider = pwmApplication.getProxyChaiProvider(userIdentity.getLdapProfileID());
-        final ChaiUser chaiUser = chaiProvider.getEntryFactory().newChaiUser(userIdentity.getUserDN());
+        final String searchFilter = figureLdapSearchFilter( pwmRequest );
+        final ChaiProvider chaiProvider = pwmApplication.getProxyChaiProvider( userIdentity.getLdapProfileID() );
+        final ChaiUser chaiUser = chaiProvider.getEntryFactory().newChaiUser( userIdentity.getUserDN() );
 
-        for (final Map.Entry<FormConfiguration, String> entry : formValues.entrySet()) {
+        for ( final Map.Entry<FormConfiguration, String> entry : formValues.entrySet() )
+        {
             final FormConfiguration formItem = entry.getKey();
             final String attrName = formItem.getName();
             final String tokenizedAttrName = "%" + attrName + "%";
-            if (searchFilter.contains(tokenizedAttrName)) {
-                LOGGER.trace(pwmSession, "skipping validation of ldap value for '" + attrName + "' because it is in search filter");
-            } else {
+            if ( searchFilter.contains( tokenizedAttrName ) )
+            {
+                LOGGER.trace( pwmSession, "skipping validation of ldap value for '" + attrName + "' because it is in search filter" );
+            }
+            else
+            {
                 final String value = entry.getValue();
-                try {
-                    if (!chaiUser.compareStringAttribute(attrName, value)) {
+                try
+                {
+                    if ( !chaiUser.compareStringAttribute( attrName, value ) )
+                    {
                         final String errorMsg = "incorrect value for '" + attrName + "'";
-                        final ErrorInformation errorInfo = new ErrorInformation(PwmError.ERROR_ACTIVATION_VALIDATIONFAIL, errorMsg, new String[]{attrName});
-                        LOGGER.debug(pwmSession.getLabel(), errorInfo.toDebugStr());
-                        throw new PwmDataValidationException(errorInfo);
+                        final ErrorInformation errorInfo = new ErrorInformation( PwmError.ERROR_ACTIVATION_VALIDATIONFAIL, errorMsg, new String[]
+                                {
+                                        attrName,
+                                }
+                        );
+                        LOGGER.debug( pwmSession.getLabel(), errorInfo.toDebugStr() );
+                        throw new PwmDataValidationException( errorInfo );
                     }
-                    LOGGER.trace(pwmSession.getLabel(), "successful validation of ldap value for '" + attrName + "'");
-                } catch (ChaiOperationException e) {
-                    LOGGER.error(pwmSession.getLabel(), "error during param validation of '" + attrName + "', error: " + e.getMessage());
-                    throw new PwmDataValidationException(new ErrorInformation(PwmError.ERROR_ACTIVATION_VALIDATIONFAIL, "ldap error testing value for '" + attrName + "'", new String[]{attrName}));
+                    LOGGER.trace( pwmSession.getLabel(), "successful validation of ldap value for '" + attrName + "'" );
+                }
+                catch ( ChaiOperationException e )
+                {
+                    LOGGER.error( pwmSession.getLabel(), "error during param validation of '" + attrName + "', error: " + e.getMessage() );
+                    throw new PwmDataValidationException( new ErrorInformation(
+                            PwmError.ERROR_ACTIVATION_VALIDATIONFAIL,
+                            "ldap error testing value for '" + attrName + "'", new String[]
+                            {
+                                    attrName,
+                            }
+                    ) );
                 }
             }
         }
@@ -511,22 +580,24 @@ public class ActivateUserServlet extends AbstractPwmServlet {
         final PwmSession pwmSession = pwmRequest.getPwmSession();
         final Configuration config = pwmApplication.getConfig();
         final UserInfo userInfo = pwmSession.getUserInfo();
-        final MessageSendMethod pref = MessageSendMethod.valueOf(config.readSettingAsString(PwmSetting.ACTIVATE_TOKEN_SEND_METHOD));
+        final MessageSendMethod pref = MessageSendMethod.valueOf( config.readSettingAsString( PwmSetting.ACTIVATE_TOKEN_SEND_METHOD ) );
 
         final boolean success;
-        switch (pref) {
+        switch ( pref )
+        {
             case SMSONLY:
                 // Only try SMS
-                success = sendPostActivationSms(pwmRequest);
+                success = sendPostActivationSms( pwmRequest );
                 break;
             case EMAILONLY:
             default:
                 // Only try email
-                success = sendPostActivationEmail(pwmRequest);
+                success = sendPostActivationEmail( pwmRequest );
                 break;
         }
-        if (!success) {
-            LOGGER.warn(pwmSession, "skipping send activation message for '" + userInfo.getUserIdentity() + "' no email or SMS number configured");
+        if ( !success )
+        {
+            LOGGER.warn( pwmSession, "skipping send activation message for '" + userInfo.getUserIdentity() + "' no email or SMS number configured" );
         }
     }
 
@@ -540,22 +611,23 @@ public class ActivateUserServlet extends AbstractPwmServlet {
         final UserInfo userInfo = pwmSession.getUserInfo();
         final Configuration config = pwmApplication.getConfig();
         final Locale locale = pwmSession.getSessionStateBean().getLocale();
-        final EmailItemBean configuredEmailSetting = config.readSettingAsEmail(PwmSetting.EMAIL_ACTIVATION, locale);
+        final EmailItemBean configuredEmailSetting = config.readSettingAsEmail( PwmSetting.EMAIL_ACTIVATION, locale );
 
-        if (configuredEmailSetting == null) {
-            LOGGER.debug(pwmSession, "skipping send activation email for '" + userInfo.getUserIdentity() + "' no email configured");
+        if ( configuredEmailSetting == null )
+        {
+            LOGGER.debug( pwmSession, "skipping send activation email for '" + userInfo.getUserIdentity() + "' no email configured" );
             return false;
         }
 
         pwmApplication.getEmailQueue().submitEmail(
                 configuredEmailSetting,
                 pwmSession.getUserInfo(),
-                pwmSession.getSessionManager().getMacroMachine(pwmApplication)
+                pwmSession.getSessionManager().getMacroMachine( pwmApplication )
         );
         return true;
     }
 
-    private Boolean sendPostActivationSms(final PwmRequest pwmRequest)
+    private Boolean sendPostActivationSms( final PwmRequest pwmRequest )
             throws PwmUnrecoverableException, ChaiUnavailableException
     {
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
@@ -563,20 +635,24 @@ public class ActivateUserServlet extends AbstractPwmServlet {
         final Configuration config = pwmApplication.getConfig();
         final UserInfo userInfo = pwmSession.getUserInfo();
         final Locale locale = pwmSession.getSessionStateBean().getLocale();
-        final LdapProfile ldapProfile = userInfo.getUserIdentity().getLdapProfile(config);
+        final LdapProfile ldapProfile = userInfo.getUserIdentity().getLdapProfile( config );
 
-        final String message = config.readSettingAsLocalizedString(PwmSetting.SMS_ACTIVATION_TEXT, locale);
+        final String message = config.readSettingAsLocalizedString( PwmSetting.SMS_ACTIVATION_TEXT, locale );
 
         final String toSmsNumber;
-        try {
-            toSmsNumber = userInfo.readStringAttribute(ldapProfile.readSettingAsString(PwmSetting.SMS_USER_PHONE_ATTRIBUTE));
-        } catch (Exception e) {
-            LOGGER.debug(pwmSession.getLabel(), "error reading SMS attribute from user '" + pwmSession.getUserInfo().getUserIdentity() + "': " + e.getMessage());
+        try
+        {
+            toSmsNumber = userInfo.readStringAttribute( ldapProfile.readSettingAsString( PwmSetting.SMS_USER_PHONE_ATTRIBUTE ) );
+        }
+        catch ( Exception e )
+        {
+            LOGGER.debug( pwmSession.getLabel(), "error reading SMS attribute from user '" + pwmSession.getUserInfo().getUserIdentity() + "': " + e.getMessage() );
             return false;
         }
 
-        if (toSmsNumber == null || toSmsNumber.length() < 1) {
-            LOGGER.debug(pwmSession.getLabel(), "skipping send activation SMS for '" + pwmSession.getUserInfo().getUserIdentity() + "' no SMS number configured");
+        if ( toSmsNumber == null || toSmsNumber.length() < 1 )
+        {
+            LOGGER.debug( pwmSession.getLabel(), "skipping send activation SMS for '" + pwmSession.getUserInfo().getUserIdentity() + "' no SMS number configured" );
             return false;
         }
 
@@ -584,7 +660,7 @@ public class ActivateUserServlet extends AbstractPwmServlet {
                 toSmsNumber,
                 message,
                 pwmRequest.getSessionLabel(),
-                pwmSession.getSessionManager().getMacroMachine(pwmApplication)
+                pwmSession.getSessionManager().getMacroMachine( pwmApplication )
         );
         return true;
     }
@@ -599,80 +675,92 @@ public class ActivateUserServlet extends AbstractPwmServlet {
     {
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
         final PwmSession pwmSession = pwmRequest.getPwmSession();
-        final ActivateUserBean activateUserBean = pwmApplication.getSessionStateService().getBean(pwmRequest, ActivateUserBean.class);
+        final ActivateUserBean activateUserBean = pwmApplication.getSessionStateService().getBean( pwmRequest, ActivateUserBean.class );
         final Configuration config = pwmApplication.getConfig();
 
         final RestTokenDataClient.TokenDestinationData inputTokenDestData;
         {
             final String toAddress;
             {
-                final EmailItemBean emailItemBean = config.readSettingAsEmail(PwmSetting.EMAIL_ACTIVATION_VERIFICATION, locale);
-                final MacroMachine macroMachine = MacroMachine.forUser(pwmRequest, userIdentity);
-                toAddress = macroMachine.expandMacros(emailItemBean.getTo());
+                final EmailItemBean emailItemBean = config.readSettingAsEmail( PwmSetting.EMAIL_ACTIVATION_VERIFICATION, locale );
+                final MacroMachine macroMachine = MacroMachine.forUser( pwmRequest, userIdentity );
+                toAddress = macroMachine.expandMacros( emailItemBean.getTo() );
             }
 
             final String toSmsNumber;
-            try {
-                final UserInfo userInfo = UserInfoFactory.newUserInfoUsingProxy(pwmApplication, pwmSession.getLabel(), userIdentity, pwmRequest.getLocale());
-                final LdapProfile ldapProfile = userIdentity.getLdapProfile(config);
-                toSmsNumber = userInfo.readStringAttribute(ldapProfile.readSettingAsString(PwmSetting.SMS_USER_PHONE_ATTRIBUTE));
-            } catch (Exception e) {
+            try
+            {
+                final UserInfo userInfo = UserInfoFactory.newUserInfoUsingProxy( pwmApplication, pwmSession.getLabel(), userIdentity, pwmRequest.getLocale() );
+                final LdapProfile ldapProfile = userIdentity.getLdapProfile( config );
+                toSmsNumber = userInfo.readStringAttribute( ldapProfile.readSettingAsString( PwmSetting.SMS_USER_PHONE_ATTRIBUTE ) );
+            }
+            catch ( Exception e )
+            {
                 final String errorMsg = "unable to read user SMS attribute due to ldap error, unable to send token: " + e.getMessage();
-                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_ACTIVATION_FAILURE, errorMsg);
-                LOGGER.error(pwmSession.getLabel(), errorInformation);
-                throw new PwmOperationalException(errorInformation);
+                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_ACTIVATION_FAILURE, errorMsg );
+                LOGGER.error( pwmSession.getLabel(), errorInformation );
+                throw new PwmOperationalException( errorInformation );
             }
-            inputTokenDestData = new RestTokenDataClient.TokenDestinationData(toAddress,toSmsNumber,null);
+            inputTokenDestData = new RestTokenDataClient.TokenDestinationData( toAddress, toSmsNumber, null );
         }
 
-        final RestTokenDataClient restTokenDataClient = new RestTokenDataClient(pwmApplication);
+        final RestTokenDataClient restTokenDataClient = new RestTokenDataClient( pwmApplication );
         final RestTokenDataClient.TokenDestinationData outputDestTokenData = restTokenDataClient.figureDestTokenDisplayString(
                 pwmSession.getLabel(),
                 inputTokenDestData,
                 activateUserBean.getUserIdentity(),
-                pwmSession.getSessionStateBean().getLocale());
+                pwmSession.getSessionStateBean().getLocale() );
 
         final Set<String> destinationValues = new HashSet<>();
-        if (outputDestTokenData.getEmail() != null) {
-            destinationValues.add(outputDestTokenData.getEmail());
+        if ( outputDestTokenData.getEmail() != null )
+        {
+            destinationValues.add( outputDestTokenData.getEmail() );
         }
-        if (outputDestTokenData.getSms() != null) {
-            destinationValues.add(outputDestTokenData.getSms());
+        if ( outputDestTokenData.getSms() != null )
+        {
+            destinationValues.add( outputDestTokenData.getSms() );
         }
 
 
-        final Map<String,String> tokenMapData = new HashMap<>();
+        final Map<String, String> tokenMapData = new HashMap<>();
 
-        try {
+        try
+        {
             final Instant userLastPasswordChange = PasswordUtility.determinePwdLastModified(
                     pwmApplication,
                     pwmSession.getLabel(),
-                    activateUserBean.getUserIdentity());
-            if (userLastPasswordChange != null) {
-                tokenMapData.put(PwmConstants.TOKEN_KEY_PWD_CHG_DATE, JavaHelper.toIsoDate(userLastPasswordChange));
+                    activateUserBean.getUserIdentity() );
+            if ( userLastPasswordChange != null )
+            {
+                tokenMapData.put( PwmConstants.TOKEN_KEY_PWD_CHG_DATE, JavaHelper.toIsoDate( userLastPasswordChange ) );
             }
-        } catch (ChaiUnavailableException e) {
-            LOGGER.error(pwmSession.getLabel(), "unexpected error reading user's last password change time");
+        }
+        catch ( ChaiUnavailableException e )
+        {
+            LOGGER.error( pwmSession.getLabel(), "unexpected error reading user's last password change time" );
         }
 
         final String tokenKey;
         final TokenPayload tokenPayload;
-        try {
+        try
+        {
             tokenPayload = pwmApplication.getTokenService().createTokenPayload(
                     TokenType.ACTIVATION,
-                    new TimeDuration(config.readSettingAsLong(PwmSetting.TOKEN_LIFETIME), TimeUnit.SECONDS),
+                    new TimeDuration( config.readSettingAsLong( PwmSetting.TOKEN_LIFETIME ), TimeUnit.SECONDS ),
                     tokenMapData,
                     userIdentity,
                     destinationValues
             );
-            tokenKey = pwmApplication.getTokenService().generateNewToken(tokenPayload, pwmRequest.getSessionLabel());
-        } catch (PwmOperationalException e) {
-            throw new PwmUnrecoverableException(e.getErrorInformation());
+            tokenKey = pwmApplication.getTokenService().generateNewToken( tokenPayload, pwmRequest.getSessionLabel() );
+        }
+        catch ( PwmOperationalException e )
+        {
+            throw new PwmUnrecoverableException( e.getErrorInformation() );
         }
 
-        final String displayValue = sendToken(pwmRequest, userIdentity, locale, outputDestTokenData.getEmail(), outputDestTokenData.getSms(), tokenKey);
-        activateUserBean.setTokenDisplayText(displayValue);
-        activateUserBean.setTokenIssued(true);
+        final String displayValue = sendToken( pwmRequest, userIdentity, locale, outputDestTokenData.getEmail(), outputDestTokenData.getSms(), tokenKey );
+        activateUserBean.setTokenDisplayText( displayValue );
+        activateUserBean.setTokenIssued( true );
     }
 
     private void handleEnterTokenCode(
@@ -682,36 +770,42 @@ public class ActivateUserServlet extends AbstractPwmServlet {
     {
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
         final PwmSession pwmSession = pwmRequest.getPwmSession();
-        final ActivateUserBean activateUserBean = pwmApplication.getSessionStateService().getBean(pwmRequest, ActivateUserBean.class);
-        final String userEnteredCode = pwmRequest.readParameterAsString(PwmConstants.PARAM_TOKEN);
+        final ActivateUserBean activateUserBean = pwmApplication.getSessionStateService().getBean( pwmRequest, ActivateUserBean.class );
+        final String userEnteredCode = pwmRequest.readParameterAsString( PwmConstants.PARAM_TOKEN );
 
         ErrorInformation errorInformation = null;
-        try {
+        try
+        {
             final TokenPayload tokenPayload = pwmApplication.getTokenService().processUserEnteredCode(
                     pwmSession,
                     activateUserBean.getUserIdentity(),
                     TokenType.ACTIVATION,
                     userEnteredCode
             );
-            if (tokenPayload != null) {
-                activateUserBean.setUserIdentity(tokenPayload.getUserIdentity());
-                activateUserBean.setTokenPassed(true);
-                activateUserBean.setFormValidated(true);
+            if ( tokenPayload != null )
+            {
+                activateUserBean.setUserIdentity( tokenPayload.getUserIdentity() );
+                activateUserBean.setTokenPassed( true );
+                activateUserBean.setFormValidated( true );
             }
-        } catch (PwmOperationalException e) {
+        }
+        catch ( PwmOperationalException e )
+        {
             final String errorMsg = "token incorrect: " + e.getMessage();
-            errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_INCORRECT,errorMsg);
+            errorInformation = new ErrorInformation( PwmError.ERROR_TOKEN_INCORRECT, errorMsg );
         }
 
-        if (!activateUserBean.isTokenPassed()) {
-            if (errorInformation == null) {
-                errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_INCORRECT);
+        if ( !activateUserBean.isTokenPassed() )
+        {
+            if ( errorInformation == null )
+            {
+                errorInformation = new ErrorInformation( PwmError.ERROR_TOKEN_INCORRECT );
             }
-            LOGGER.debug(pwmSession.getLabel(), errorInformation.toDebugStr());
-            setLastError(pwmRequest, errorInformation);
+            LOGGER.debug( pwmSession.getLabel(), errorInformation.toDebugStr() );
+            setLastError( pwmRequest, errorInformation );
         }
 
-        this.advanceToNextStage(pwmRequest);
+        this.advanceToNextStage( pwmRequest );
     }
 
     private static String sendToken(
@@ -726,25 +820,25 @@ public class ActivateUserServlet extends AbstractPwmServlet {
     {
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
         final Configuration config = pwmApplication.getConfig();
-        final MessageSendMethod pref = MessageSendMethod.valueOf(config.readSettingAsString(PwmSetting.ACTIVATE_TOKEN_SEND_METHOD));
-        final EmailItemBean emailItemBean = config.readSettingAsEmail(PwmSetting.EMAIL_ACTIVATION_VERIFICATION, userLocale);
-        final String smsMessage = config.readSettingAsLocalizedString(PwmSetting.SMS_ACTIVATION_VERIFICATION_TEXT, userLocale);
+        final MessageSendMethod pref = MessageSendMethod.valueOf( config.readSettingAsString( PwmSetting.ACTIVATE_TOKEN_SEND_METHOD ) );
+        final EmailItemBean emailItemBean = config.readSettingAsEmail( PwmSetting.EMAIL_ACTIVATION_VERIFICATION, userLocale );
+        final String smsMessage = config.readSettingAsLocalizedString( PwmSetting.SMS_ACTIVATION_VERIFICATION_TEXT, userLocale );
 
-        final MacroMachine macroMachine = MacroMachine.forUser(pwmRequest, userIdentity);
+        final MacroMachine macroMachine = MacroMachine.forUser( pwmRequest, userIdentity );
 
         final List<TokenDestinationItem.Type> sentTypes = TokenService.TokenSender.sendToken(
                 TokenService.TokenSendInfo.builder()
-                .pwmApplication( pwmApplication )
-                .userInfo( null )
-                .macroMachine( macroMachine )
-                .configuredEmailSetting( emailItemBean )
-                .tokenSendMethod( pref )
-                .emailAddress( toAddress )
-                .smsNumber( toSmsNumber )
-                .smsMessage( smsMessage )
-                .tokenKey( tokenKey )
-                .sessionLabel( pwmRequest.getSessionLabel() )
-                .build()
+                        .pwmApplication( pwmApplication )
+                        .userInfo( null )
+                        .macroMachine( macroMachine )
+                        .configuredEmailSetting( emailItemBean )
+                        .tokenSendMethod( pref )
+                        .emailAddress( toAddress )
+                        .smsNumber( toSmsNumber )
+                        .smsMessage( smsMessage )
+                        .tokenKey( tokenKey )
+                        .sessionLabel( pwmRequest.getSessionLabel() )
+                        .build()
         );
 
         return TokenService.TokenSender.figureDisplayString(
@@ -752,31 +846,34 @@ public class ActivateUserServlet extends AbstractPwmServlet {
                 sentTypes,
                 toAddress,
                 toSmsNumber
-                );
+        );
     }
 
-    private static String figureLdapSearchFilter(final PwmRequest pwmRequest)
+    private static String figureLdapSearchFilter( final PwmRequest pwmRequest )
             throws PwmUnrecoverableException
     {
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
         final Configuration config = pwmApplication.getConfig();
-        final List<FormConfiguration> configuredActivationForm = config.readSettingAsForm(PwmSetting.ACTIVATE_USER_FORM);
+        final List<FormConfiguration> configuredActivationForm = config.readSettingAsForm( PwmSetting.ACTIVATE_USER_FORM );
 
-        final String configuredSearchFilter = config.readSettingAsString(PwmSetting.ACTIVATE_USER_SEARCH_FILTER);
+        final String configuredSearchFilter = config.readSettingAsString( PwmSetting.ACTIVATE_USER_SEARCH_FILTER );
         final String searchFilter;
-        if (configuredSearchFilter == null || configuredSearchFilter.isEmpty()) {
-            searchFilter = FormUtility.ldapSearchFilterForForm(pwmApplication,configuredActivationForm);
-            LOGGER.trace(pwmRequest,"auto generated search filter based on activation form: " + searchFilter);
-        } else {
+        if ( configuredSearchFilter == null || configuredSearchFilter.isEmpty() )
+        {
+            searchFilter = FormUtility.ldapSearchFilterForForm( pwmApplication, configuredActivationForm );
+            LOGGER.trace( pwmRequest, "auto generated search filter based on activation form: " + searchFilter );
+        }
+        else
+        {
             searchFilter = configuredSearchFilter;
         }
         return searchFilter;
     }
 
-    private static void forwardToActivateUserForm(final PwmRequest pwmRequest)
+    private static void forwardToActivateUserForm( final PwmRequest pwmRequest )
             throws ServletException, PwmUnrecoverableException, IOException
     {
-        pwmRequest.addFormInfoToRequestAttr(PwmSetting.ACTIVATE_USER_FORM,false,false);
-        pwmRequest.forwardToJsp(JspUrl.ACTIVATE_USER);
+        pwmRequest.addFormInfoToRequestAttr( PwmSetting.ACTIVATE_USER_FORM, false, false );
+        pwmRequest.forwardToJsp( JspUrl.ACTIVATE_USER );
     }
 }

+ 1 - 1
server/src/main/java/password/pwm/http/servlet/ClientApiServlet.java

@@ -70,7 +70,7 @@ public class ClientApiServlet extends ControlledPwmServlet
     @Data
     public static class AppData implements Serializable
     {
-        @SuppressWarnings( "CheckStyle:MemberName" )
+        @SuppressWarnings( "checkstyle:MemberName" )
         public Map<String, Object> PWM_GLOBAL;
     }
 

+ 118 - 95
server/src/main/java/password/pwm/http/servlet/ForgottenUsernameServlet.java

@@ -63,61 +63,68 @@ import java.util.Locale;
 import java.util.Map;
 
 @WebServlet(
-        name="ForgottenUsernameServlet",
+        name = "ForgottenUsernameServlet",
         urlPatterns = {
                 PwmConstants.URL_PREFIX_PUBLIC + "/forgottenusername",
                 PwmConstants.URL_PREFIX_PUBLIC + "/ForgottenUsername",
 
         }
 )
-public class ForgottenUsernameServlet extends AbstractPwmServlet {
-    private static final PwmLogger LOGGER = PwmLogger.forClass(ForgottenUsernameServlet.class);
+public class ForgottenUsernameServlet extends AbstractPwmServlet
+{
+    private static final PwmLogger LOGGER = PwmLogger.forClass( ForgottenUsernameServlet.class );
 
-    public enum ForgottenUsernameAction implements AbstractPwmServlet.ProcessAction {
-        search,
-        ;
+    public enum ForgottenUsernameAction implements AbstractPwmServlet.ProcessAction
+    {
+        search,;
 
-        public Collection<HttpMethod> permittedMethods()
+        public Collection<HttpMethod> permittedMethods( )
         {
-            return Collections.singletonList(HttpMethod.POST);
+            return Collections.singletonList( HttpMethod.POST );
         }
     }
 
-    protected ForgottenUsernameAction readProcessAction(final PwmRequest request)
+    protected ForgottenUsernameAction readProcessAction( final PwmRequest request )
             throws PwmUnrecoverableException
     {
-        try {
-            return ForgottenUsernameAction.valueOf(request.readParameterAsString(PwmConstants.PARAM_ACTION_REQUEST));
-        } catch (IllegalArgumentException e) {
+        try
+        {
+            return ForgottenUsernameAction.valueOf( request.readParameterAsString( PwmConstants.PARAM_ACTION_REQUEST ) );
+        }
+        catch ( IllegalArgumentException e )
+        {
             return null;
         }
     }
 
-    protected void processAction(final PwmRequest pwmRequest)
+    protected void processAction( final PwmRequest pwmRequest )
             throws ServletException, IOException, PwmUnrecoverableException
     {
         final Configuration config = pwmRequest.getConfig();
 
-        if (!config.readSettingAsBoolean(PwmSetting.FORGOTTEN_USERNAME_ENABLE)) {
-            pwmRequest.respondWithError(PwmError.ERROR_SERVICE_NOT_AVAILABLE.toInfo());
+        if ( !config.readSettingAsBoolean( PwmSetting.FORGOTTEN_USERNAME_ENABLE ) )
+        {
+            pwmRequest.respondWithError( PwmError.ERROR_SERVICE_NOT_AVAILABLE.toInfo() );
             return;
         }
 
-        final ForgottenUsernameAction action = readProcessAction(pwmRequest);
+        final ForgottenUsernameAction action = readProcessAction( pwmRequest );
 
-        if (action != null) {
+        if ( action != null )
+        {
             pwmRequest.validatePwmFormID();
-            switch (action) {
+            switch ( action )
+            {
                 case search:
-                    handleSearchRequest(pwmRequest);
+                    handleSearchRequest( pwmRequest );
                     return;
 
                 default:
-                    JavaHelper.unhandledSwitchStatement(action);
+                    JavaHelper.unhandledSwitchStatement( action );
             }
         }
 
-        forwardToFormJsp(pwmRequest);
+        forwardToFormJsp( pwmRequest );
     }
 
     public void handleSearchRequest(
@@ -129,40 +136,46 @@ public class ForgottenUsernameServlet extends AbstractPwmServlet {
         final PwmSession pwmSession = pwmRequest.getPwmSession();
         final LocalSessionStateBean ssBean = pwmSession.getSessionStateBean();
 
-        if (CaptchaUtility.captchaEnabledForRequest(pwmRequest)) {
-            if (!CaptchaUtility.verifyReCaptcha(pwmRequest)) {
-                final ErrorInformation errorInfo = new ErrorInformation(PwmError.ERROR_BAD_CAPTCHA_RESPONSE);
-                LOGGER.debug(pwmRequest, errorInfo);
-                setLastError(pwmRequest, errorInfo);
-                forwardToFormJsp(pwmRequest);
+        if ( CaptchaUtility.captchaEnabledForRequest( pwmRequest ) )
+        {
+            if ( !CaptchaUtility.verifyReCaptcha( pwmRequest ) )
+            {
+                final ErrorInformation errorInfo = new ErrorInformation( PwmError.ERROR_BAD_CAPTCHA_RESPONSE );
+                LOGGER.debug( pwmRequest, errorInfo );
+                setLastError( pwmRequest, errorInfo );
+                forwardToFormJsp( pwmRequest );
                 return;
             }
         }
 
-        final String contextParam = pwmRequest.readParameterAsString(PwmConstants.PARAM_CONTEXT);
-        final String ldapProfile = pwmRequest.readParameterAsString(PwmConstants.PARAM_LDAP_PROFILE);
+        final String contextParam = pwmRequest.readParameterAsString( PwmConstants.PARAM_CONTEXT );
+        final String ldapProfile = pwmRequest.readParameterAsString( PwmConstants.PARAM_LDAP_PROFILE );
 
-        final List<FormConfiguration> forgottenUsernameForm = pwmApplication.getConfig().readSettingAsForm(PwmSetting.FORGOTTEN_USERNAME_FORM);
+        final List<FormConfiguration> forgottenUsernameForm = pwmApplication.getConfig().readSettingAsForm( PwmSetting.FORGOTTEN_USERNAME_FORM );
 
         //read the values from the request
         Map<FormConfiguration, String> formValues = new HashMap<>();
-        try {
-            formValues = FormUtility.readFormValuesFromRequest(pwmRequest,
-                    forgottenUsernameForm, ssBean.getLocale());
+        try
+        {
+            formValues = FormUtility.readFormValuesFromRequest( pwmRequest,
+                    forgottenUsernameForm, ssBean.getLocale() );
 
             // check for intruder search
-            pwmApplication.getIntruderManager().convenience().checkAttributes(formValues);
+            pwmApplication.getIntruderManager().convenience().checkAttributes( formValues );
 
             // see if the values meet the configured form requirements.
-            FormUtility.validateFormValues(pwmRequest.getConfig(), formValues, ssBean.getLocale());
+            FormUtility.validateFormValues( pwmRequest.getConfig(), formValues, ssBean.getLocale() );
 
             final String searchFilter;
             {
-                final String configuredSearchFilter = pwmApplication.getConfig().readSettingAsString(PwmSetting.FORGOTTEN_USERNAME_SEARCH_FILTER);
-                if (configuredSearchFilter == null || configuredSearchFilter.isEmpty()) {
-                    searchFilter = FormUtility.ldapSearchFilterForForm(pwmApplication, forgottenUsernameForm);
-                    LOGGER.trace(pwmSession,"auto generated ldap search filter: " + searchFilter);
-                } else {
+                final String configuredSearchFilter = pwmApplication.getConfig().readSettingAsString( PwmSetting.FORGOTTEN_USERNAME_SEARCH_FILTER );
+                if ( configuredSearchFilter == null || configuredSearchFilter.isEmpty() )
+                {
+                    searchFilter = FormUtility.ldapSearchFilterForForm( pwmApplication, forgottenUsernameForm );
+                    LOGGER.trace( pwmSession, "auto generated ldap search filter: " + searchFilter );
+                }
+                else
+                {
                     searchFilter = configuredSearchFilter;
                 }
             }
@@ -171,24 +184,25 @@ public class ForgottenUsernameServlet extends AbstractPwmServlet {
             {
                 final UserSearchEngine userSearchEngine = pwmApplication.getUserSearchEngine();
                 final SearchConfiguration searchConfiguration = SearchConfiguration.builder()
-                        .filter(searchFilter)
-                        .formValues(formValues)
-                        .ldapProfile(ldapProfile)
-                        .contexts(Collections.singletonList(contextParam))
+                        .filter( searchFilter )
+                        .formValues( formValues )
+                        .ldapProfile( ldapProfile )
+                        .contexts( Collections.singletonList( contextParam ) )
                         .build();
-                userIdentity = userSearchEngine.performSingleUserSearch(searchConfiguration, pwmSession.getLabel());
+                userIdentity = userSearchEngine.performSingleUserSearch( searchConfiguration, pwmSession.getLabel() );
             }
 
-            if (userIdentity == null) {
-                pwmApplication.getIntruderManager().convenience().markAddressAndSession(pwmSession);
-                pwmApplication.getStatisticsManager().incrementValue(Statistic.FORGOTTEN_USERNAME_FAILURES);
-                setLastError(pwmRequest, PwmError.ERROR_CANT_MATCH_USER.toInfo());
-                forwardToFormJsp(pwmRequest);
+            if ( userIdentity == null )
+            {
+                pwmApplication.getIntruderManager().convenience().markAddressAndSession( pwmSession );
+                pwmApplication.getStatisticsManager().incrementValue( Statistic.FORGOTTEN_USERNAME_FAILURES );
+                setLastError( pwmRequest, PwmError.ERROR_CANT_MATCH_USER.toInfo() );
+                forwardToFormJsp( pwmRequest );
                 return;
             }
 
             // make sure the user isn't locked.
-            pwmApplication.getIntruderManager().convenience().checkUserIdentity(userIdentity);
+            pwmApplication.getIntruderManager().convenience().checkUserIdentity( userIdentity );
 
             final UserInfo forgottenUserInfo = UserInfoFactory.newUserInfoUsingProxy(
                     pwmApplication,
@@ -197,30 +211,32 @@ public class ForgottenUsernameServlet extends AbstractPwmServlet {
             );
 
             // send username
-            sendUsername(pwmApplication, pwmSession, forgottenUserInfo);
+            sendUsername( pwmApplication, pwmSession, forgottenUserInfo );
 
-            pwmApplication.getIntruderManager().convenience().clearAddressAndSession(pwmSession);
-            pwmApplication.getIntruderManager().convenience().clearAttributes(formValues);
+            pwmApplication.getIntruderManager().convenience().clearAddressAndSession( pwmSession );
+            pwmApplication.getIntruderManager().convenience().clearAttributes( formValues );
 
-            pwmApplication.getStatisticsManager().incrementValue(Statistic.FORGOTTEN_USERNAME_SUCCESSES);
+            pwmApplication.getStatisticsManager().incrementValue( Statistic.FORGOTTEN_USERNAME_SUCCESSES );
 
             // redirect user to success page.
-            forwardToCompletePage(pwmRequest, userIdentity);
+            forwardToCompletePage( pwmRequest, userIdentity );
             return;
 
-        } catch (PwmOperationalException e) {
+        }
+        catch ( PwmOperationalException e )
+        {
             final ErrorInformation errorInfo;
             errorInfo = e.getError() == PwmError.ERROR_UNKNOWN
-                    ? new ErrorInformation(PwmError.ERROR_CANT_MATCH_USER,e.getErrorInformation().getDetailedErrorMsg(),
-                    e.getErrorInformation().getFieldValues())
+                    ? new ErrorInformation( PwmError.ERROR_CANT_MATCH_USER, e.getErrorInformation().getDetailedErrorMsg(),
+                    e.getErrorInformation().getFieldValues() )
                     : e.getErrorInformation();
-            setLastError(pwmRequest, errorInfo);
-            pwmApplication.getIntruderManager().convenience().markAddressAndSession(pwmSession);
-            pwmApplication.getIntruderManager().convenience().markAttributes(formValues, pwmSession);
+            setLastError( pwmRequest, errorInfo );
+            pwmApplication.getIntruderManager().convenience().markAddressAndSession( pwmSession );
+            pwmApplication.getIntruderManager().convenience().markAttributes( formValues, pwmSession );
         }
 
-        pwmApplication.getStatisticsManager().incrementValue(Statistic.FORGOTTEN_USERNAME_FAILURES);
-        forwardToFormJsp(pwmRequest);
+        pwmApplication.getStatisticsManager().incrementValue( Statistic.FORGOTTEN_USERNAME_FAILURES );
+        forwardToFormJsp( pwmRequest );
     }
 
 
@@ -233,11 +249,12 @@ public class ForgottenUsernameServlet extends AbstractPwmServlet {
     {
         final Locale userLocale = pwmSession.getSessionStateBean().getLocale();
         final Configuration configuration = pwmApplication.getConfig();
-        final MessageSendMethod messageSendMethod = configuration.readSettingAsEnum(PwmSetting.FORGOTTEN_USERNAME_SEND_USERNAME_METHOD, MessageSendMethod.class);
-        final EmailItemBean emailItemBean = configuration.readSettingAsEmail(PwmSetting.EMAIL_SEND_USERNAME, userLocale);
-        final String smsMessage = configuration.readSettingAsLocalizedString(PwmSetting.SMS_FORGOTTEN_USERNAME_TEXT, userLocale);
+        final MessageSendMethod messageSendMethod = configuration.readSettingAsEnum( PwmSetting.FORGOTTEN_USERNAME_SEND_USERNAME_METHOD, MessageSendMethod.class );
+        final EmailItemBean emailItemBean = configuration.readSettingAsEmail( PwmSetting.EMAIL_SEND_USERNAME, userLocale );
+        final String smsMessage = configuration.readSettingAsLocalizedString( PwmSetting.SMS_FORGOTTEN_USERNAME_TEXT, userLocale );
 
-        if (messageSendMethod == null || messageSendMethod == MessageSendMethod.NONE) {
+        if ( messageSendMethod == null || messageSendMethod == MessageSendMethod.NONE )
+        {
             return;
         }
 
@@ -262,31 +279,35 @@ public class ForgottenUsernameServlet extends AbstractPwmServlet {
     )
             throws PwmOperationalException, PwmUnrecoverableException
     {
-        if (pwmApplication == null) {
-            throw new IllegalArgumentException("pwmApplication can not be null");
+        if ( pwmApplication == null )
+        {
+            throw new IllegalArgumentException( "pwmApplication can not be null" );
         }
 
-        if (userInfo == null) {
-            throw new IllegalArgumentException("userInfoBean can not be null");
+        if ( userInfo == null )
+        {
+            throw new IllegalArgumentException( "userInfoBean can not be null" );
         }
 
         ErrorInformation error = null;
-        switch (messageSendMethod) {
+        switch ( messageSendMethod )
+        {
             case NONE:
                 break;
 
             case SMSONLY:
                 // Only try SMS
-                error = sendSmsViaMethod(pwmApplication, sessionLabel, userInfo, smsMessage);
+                error = sendSmsViaMethod( pwmApplication, sessionLabel, userInfo, smsMessage );
                 break;
             case EMAILONLY:
             default:
                 // Only try email
-                error = sendEmailViaMethod(pwmApplication, sessionLabel, userInfo, emailItemBean);
+                error = sendEmailViaMethod( pwmApplication, sessionLabel, userInfo, emailItemBean );
                 break;
         }
-        if (error != null) {
-            throw new PwmOperationalException(error);
+        if ( error != null )
+        {
+            throw new PwmOperationalException( error );
         }
     }
 
@@ -299,14 +320,15 @@ public class ForgottenUsernameServlet extends AbstractPwmServlet {
             throws PwmOperationalException, PwmUnrecoverableException
     {
         final String toNumber = userInfo.getUserSmsNumber();
-        if (toNumber == null || toNumber.length() < 1) {
-            final String errorMsg = String.format("unable to send new password email for '%s'; no SMS number available in ldap", userInfo.getUserIdentity());
-            return new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg);
+        if ( toNumber == null || toNumber.length() < 1 )
+        {
+            final String errorMsg = String.format( "unable to send new password email for '%s'; no SMS number available in ldap", userInfo.getUserIdentity() );
+            return new ErrorInformation( PwmError.ERROR_UNKNOWN, errorMsg );
         }
 
-        final MacroMachine macroMachine = new MacroMachine(pwmApplication, sessionLabel, userInfo, null);
+        final MacroMachine macroMachine = new MacroMachine( pwmApplication, sessionLabel, userInfo, null );
 
-        pwmApplication.sendSmsUsingQueue(toNumber, smsMessage, sessionLabel, macroMachine);
+        pwmApplication.sendSmsUsingQueue( toNumber, smsMessage, sessionLabel, macroMachine );
         return null;
     }
 
@@ -318,34 +340,35 @@ public class ForgottenUsernameServlet extends AbstractPwmServlet {
     )
             throws PwmUnrecoverableException
     {
-        if (emailItemBean == null) {
+        if ( emailItemBean == null )
+        {
             final String errorMsg = "emailItemBean is null";
-            return new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg);
+            return new ErrorInformation( PwmError.ERROR_UNKNOWN, errorMsg );
         }
 
-        final MacroMachine macroMachine = new MacroMachine(pwmApplication, sessionLabel, userInfo, null);
+        final MacroMachine macroMachine = new MacroMachine( pwmApplication, sessionLabel, userInfo, null );
 
-        pwmApplication.getEmailQueue().submitEmail(emailItemBean, userInfo, macroMachine);
+        pwmApplication.getEmailQueue().submitEmail( emailItemBean, userInfo, macroMachine );
 
         return null;
     }
 
-    private void forwardToFormJsp(final PwmRequest pwmRequest)
+    private void forwardToFormJsp( final PwmRequest pwmRequest )
             throws ServletException, PwmUnrecoverableException, IOException
     {
-        pwmRequest.addFormInfoToRequestAttr(PwmSetting.FORGOTTEN_USERNAME_FORM,false,false);
-        pwmRequest.forwardToJsp(JspUrl.FORGOTTEN_USERNAME);
+        pwmRequest.addFormInfoToRequestAttr( PwmSetting.FORGOTTEN_USERNAME_FORM, false, false );
+        pwmRequest.forwardToJsp( JspUrl.FORGOTTEN_USERNAME );
     }
 
-    private static void forwardToCompletePage(final PwmRequest pwmRequest, final UserIdentity userIdentity)
+    private static void forwardToCompletePage( final PwmRequest pwmRequest, final UserIdentity userIdentity )
             throws PwmUnrecoverableException, ServletException, IOException
     {
         final Locale locale = pwmRequest.getLocale();
-        final String completeMessage = pwmRequest.getConfig().readSettingAsLocalizedString(PwmSetting.FORGOTTEN_USERNAME_MESSAGE,locale);
-        final MacroMachine macroMachine = MacroMachine.forUser(pwmRequest.getPwmApplication(), pwmRequest.getLocale(), pwmRequest.getSessionLabel(), userIdentity);
-        final String expandedText = macroMachine.expandMacros(completeMessage);
-        pwmRequest.setAttribute(PwmRequestAttribute.CompleteText, expandedText);
-        pwmRequest.forwardToJsp(JspUrl.FORGOTTEN_USERNAME_COMPLETE);
+        final String completeMessage = pwmRequest.getConfig().readSettingAsLocalizedString( PwmSetting.FORGOTTEN_USERNAME_MESSAGE, locale );
+        final MacroMachine macroMachine = MacroMachine.forUser( pwmRequest.getPwmApplication(), pwmRequest.getLocale(), pwmRequest.getSessionLabel(), userIdentity );
+        final String expandedText = macroMachine.expandMacros( completeMessage );
+        pwmRequest.setAttribute( PwmRequestAttribute.CompleteText, expandedText );
+        pwmRequest.forwardToJsp( JspUrl.FORGOTTEN_USERNAME_COMPLETE );
     }
 
 }

+ 369 - 289
server/src/main/java/password/pwm/http/servlet/UpdateProfileServlet.java

@@ -84,225 +84,246 @@ import java.util.Map;
 import java.util.Set;
 
 /**
- * User interaction servlet for updating user attributes
+ * User interaction servlet for updating user attributes.
  *
  * @author Jason D. Rivard
  */
 @WebServlet(
-        name="UpdateProfileServlet",
+        name = "UpdateProfileServlet",
         urlPatterns = {
                 PwmConstants.URL_PREFIX_PRIVATE + "/updateprofile",
                 PwmConstants.URL_PREFIX_PRIVATE + "/UpdateProfile"
         }
 )
-public class UpdateProfileServlet extends ControlledPwmServlet {
+public class UpdateProfileServlet extends ControlledPwmServlet
+{
 
-    private static final PwmLogger LOGGER = PwmLogger.forClass(UpdateProfileServlet.class);
+    private static final PwmLogger LOGGER = PwmLogger.forClass( UpdateProfileServlet.class );
 
     @Data
-    public static class ValidateResponse implements Serializable {
+    public static class ValidateResponse implements Serializable
+    {
         private String message;
         private boolean success;
     }
 
-    public enum UpdateProfileAction implements AbstractPwmServlet.ProcessAction {
-        updateProfile(HttpMethod.POST),
-        agree(HttpMethod.POST),
-        confirm(HttpMethod.POST),
-        unConfirm(HttpMethod.POST),
-        validate(HttpMethod.POST),
-        enterCode(HttpMethod.POST),
-
-        ;
+    public enum UpdateProfileAction implements AbstractPwmServlet.ProcessAction
+    {
+        updateProfile( HttpMethod.POST ),
+        agree( HttpMethod.POST ),
+        confirm( HttpMethod.POST ),
+        unConfirm( HttpMethod.POST ),
+        validate( HttpMethod.POST ),
+        enterCode( HttpMethod.POST ),;
 
         private final HttpMethod method;
 
-        UpdateProfileAction(final HttpMethod method)
+        UpdateProfileAction( final HttpMethod method )
         {
             this.method = method;
         }
 
-        public Collection<HttpMethod> permittedMethods()
+        public Collection<HttpMethod> permittedMethods( )
         {
-            return Collections.singletonList(method);
+            return Collections.singletonList( method );
         }
     }
 
     @Override
-    public Class<? extends ProcessAction> getProcessActionsClass() {
+    public Class<? extends ProcessAction> getProcessActionsClass( )
+    {
         return UpdateProfileAction.class;
     }
 
-    private static UpdateAttributesProfile getProfile(final PwmRequest pwmRequest) throws PwmUnrecoverableException
+    private static UpdateAttributesProfile getProfile( final PwmRequest pwmRequest ) throws PwmUnrecoverableException
     {
-        return pwmRequest.getPwmSession().getSessionManager().getUpdateAttributeProfile(pwmRequest.getPwmApplication());
+        return pwmRequest.getPwmSession().getSessionManager().getUpdateAttributeProfile( pwmRequest.getPwmApplication() );
     }
 
-    private static UpdateProfileBean getBean(final PwmRequest pwmRequest) throws PwmUnrecoverableException {
-        return pwmRequest.getPwmApplication().getSessionStateService().getBean(pwmRequest, UpdateProfileBean.class);
+    private static UpdateProfileBean getBean( final PwmRequest pwmRequest ) throws PwmUnrecoverableException
+    {
+        return pwmRequest.getPwmApplication().getSessionStateService().getBean( pwmRequest, UpdateProfileBean.class );
     }
 
-    @ActionHandler(action = "enterCode")
+    @ActionHandler( action = "enterCode" )
     ProcessStatus handleEnterCodeRequest(
             final PwmRequest pwmRequest
     )
             throws PwmUnrecoverableException, IOException, ServletException, ChaiUnavailableException
     {
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
-        final UpdateProfileBean updateProfileBean = getBean(pwmRequest);
+        final UpdateProfileBean updateProfileBean = getBean( pwmRequest );
         final PwmSession pwmSession = pwmRequest.getPwmSession();
-        final String userEnteredCode = pwmRequest.readParameterAsString(PwmConstants.PARAM_TOKEN);
+        final String userEnteredCode = pwmRequest.readParameterAsString( PwmConstants.PARAM_TOKEN );
 
         boolean tokenPassed = false;
         ErrorInformation errorInformation = null;
-        try {
+        try
+        {
             final TokenPayload tokenPayload = pwmApplication.getTokenService().processUserEnteredCode(
                     pwmSession,
                     pwmRequest.getUserInfoIfLoggedIn(),
                     null,
                     userEnteredCode
             );
-            if (tokenPayload != null) {
-                if (TokenType.UPDATE_EMAIL.matchesName(tokenPayload.getName())) {
-                    LOGGER.debug(pwmRequest, "email token passed");
-
-                    updateProfileBean.getTokenVerificationProgress().getPassedTokens().add(TokenVerificationProgress.TokenChannel.EMAIL);
-                    updateProfileBean.getTokenVerificationProgress().getIssuedTokens().add(TokenVerificationProgress.TokenChannel.EMAIL);
-                    updateProfileBean.getTokenVerificationProgress().setPhase(null);
+            if ( tokenPayload != null )
+            {
+                if ( TokenType.UPDATE_EMAIL.matchesName( tokenPayload.getName() ) )
+                {
+                    LOGGER.debug( pwmRequest, "email token passed" );
+
+                    updateProfileBean.getTokenVerificationProgress().getPassedTokens().add( TokenVerificationProgress.TokenChannel.EMAIL );
+                    updateProfileBean.getTokenVerificationProgress().getIssuedTokens().add( TokenVerificationProgress.TokenChannel.EMAIL );
+                    updateProfileBean.getTokenVerificationProgress().setPhase( null );
                     tokenPassed = true;
-                } else if (TokenType.UPDATE_SMS.matchesName(tokenPayload.getName())) {
-                    LOGGER.debug(pwmRequest, "SMS token passed");
-                    updateProfileBean.getTokenVerificationProgress().getPassedTokens().add(TokenVerificationProgress.TokenChannel.SMS);
-                    updateProfileBean.getTokenVerificationProgress().getIssuedTokens().add(TokenVerificationProgress.TokenChannel.SMS);
-                    updateProfileBean.getTokenVerificationProgress().setPhase(null);
+                }
+                else if ( TokenType.UPDATE_SMS.matchesName( tokenPayload.getName() ) )
+                {
+                    LOGGER.debug( pwmRequest, "SMS token passed" );
+                    updateProfileBean.getTokenVerificationProgress().getPassedTokens().add( TokenVerificationProgress.TokenChannel.SMS );
+                    updateProfileBean.getTokenVerificationProgress().getIssuedTokens().add( TokenVerificationProgress.TokenChannel.SMS );
+                    updateProfileBean.getTokenVerificationProgress().setPhase( null );
                     tokenPassed = true;
-                } else {
+                }
+                else
+                {
                     final String errorMsg = "token name/type is not recognized: " + tokenPayload.getName();
-                    errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_INCORRECT,errorMsg);
+                    errorInformation = new ErrorInformation( PwmError.ERROR_TOKEN_INCORRECT, errorMsg );
                 }
             }
-        } catch (PwmOperationalException e) {
+        }
+        catch ( PwmOperationalException e )
+        {
             final String errorMsg = "token incorrect: " + e.getMessage();
-            errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_INCORRECT, errorMsg);
+            errorInformation = new ErrorInformation( PwmError.ERROR_TOKEN_INCORRECT, errorMsg );
         }
 
 
-        if (!tokenPassed) {
-            if (errorInformation == null) {
-                errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_INCORRECT);
+        if ( !tokenPassed )
+        {
+            if ( errorInformation == null )
+            {
+                errorInformation = new ErrorInformation( PwmError.ERROR_TOKEN_INCORRECT );
             }
-            LOGGER.debug(pwmSession, errorInformation.toDebugStr());
-            setLastError(pwmRequest, errorInformation);
+            LOGGER.debug( pwmSession, errorInformation.toDebugStr() );
+            setLastError( pwmRequest, errorInformation );
         }
 
         return ProcessStatus.Continue;
     }
 
-    @ActionHandler(action = "validate")
+    @ActionHandler( action = "validate" )
     ProcessStatus restValidateForm(
             final PwmRequest pwmRequest
     )
             throws IOException, ServletException, PwmUnrecoverableException, ChaiUnavailableException
     {
-        final UpdateProfileBean updateProfileBean = getBean(pwmRequest);
-        final UpdateAttributesProfile updateAttributesProfile = getProfile(pwmRequest);
+        final UpdateProfileBean updateProfileBean = getBean( pwmRequest );
+        final UpdateAttributesProfile updateAttributesProfile = getProfile( pwmRequest );
 
         boolean success = true;
-        String userMessage = Message.getLocalizedMessage(pwmRequest.getLocale(), Message.Success_UpdateForm, pwmRequest.getConfig());
+        String userMessage = Message.getLocalizedMessage( pwmRequest.getLocale(), Message.Success_UpdateForm, pwmRequest.getConfig() );
 
-        try {
+        try
+        {
             // read in the responses from the request
-            final Map<FormConfiguration,String> formValues = readFromJsonRequest(pwmRequest, updateAttributesProfile, updateProfileBean);
+            final Map<FormConfiguration, String> formValues = readFromJsonRequest( pwmRequest, updateAttributesProfile, updateProfileBean );
 
             // verify form meets the form requirements
-            verifyFormAttributes(pwmRequest.getPwmApplication(), pwmRequest.getUserInfoIfLoggedIn(), pwmRequest.getLocale(), formValues, true);
+            verifyFormAttributes( pwmRequest.getPwmApplication(), pwmRequest.getUserInfoIfLoggedIn(), pwmRequest.getLocale(), formValues, true );
 
-            updateProfileBean.getFormData().putAll(FormUtility.asStringMap(formValues));
-        } catch (PwmOperationalException e) {
+            updateProfileBean.getFormData().putAll( FormUtility.asStringMap( formValues ) );
+        }
+        catch ( PwmOperationalException e )
+        {
             success = false;
-            userMessage = e.getErrorInformation().toUserStr(pwmRequest.getPwmSession(), pwmRequest.getPwmApplication());
+            userMessage = e.getErrorInformation().toUserStr( pwmRequest.getPwmSession(), pwmRequest.getPwmApplication() );
         }
 
         final ValidateResponse response = new ValidateResponse();
-        response.setMessage(userMessage);
-        response.setSuccess(success);
-        pwmRequest.outputJsonResult(RestResultBean.withData(response));
+        response.setMessage( userMessage );
+        response.setSuccess( success );
+        pwmRequest.outputJsonResult( RestResultBean.withData( response ) );
         return ProcessStatus.Halt;
     }
 
-    @ActionHandler(action = "unConfirm")
+    @ActionHandler( action = "unConfirm" )
     ProcessStatus handleUnconfirm(
             final PwmRequest pwmRequest
     )
             throws PwmUnrecoverableException
     {
-        final UpdateProfileBean updateProfileBean = getBean(pwmRequest);
+        final UpdateProfileBean updateProfileBean = getBean( pwmRequest );
 
-        updateProfileBean.setFormSubmitted(false);
-        updateProfileBean.setConfirmationPassed(false);
+        updateProfileBean.setFormSubmitted( false );
+        updateProfileBean.setConfirmationPassed( false );
         updateProfileBean.clearTokenVerificationProgress();
 
         return ProcessStatus.Continue;
     }
 
-    @ActionHandler(action = "agree")
-    ProcessStatus handleAgreeRequest(final PwmRequest pwmRequest)
+    @ActionHandler( action = "agree" )
+    ProcessStatus handleAgreeRequest( final PwmRequest pwmRequest )
             throws ServletException, IOException, PwmUnrecoverableException, ChaiUnavailableException
     {
-        LOGGER.debug(pwmRequest, "user accepted agreement");
+        LOGGER.debug( pwmRequest, "user accepted agreement" );
 
-        final UpdateProfileBean updateProfileBean = getBean(pwmRequest);
-        if (!updateProfileBean.isAgreementPassed()) {
-            updateProfileBean.setAgreementPassed(true);
-            final AuditRecord auditRecord = new AuditRecordFactory(pwmRequest).createUserAuditRecord(
+        final UpdateProfileBean updateProfileBean = getBean( pwmRequest );
+        if ( !updateProfileBean.isAgreementPassed() )
+        {
+            updateProfileBean.setAgreementPassed( true );
+            final AuditRecord auditRecord = new AuditRecordFactory( pwmRequest ).createUserAuditRecord(
                     AuditEvent.AGREEMENT_PASSED,
                     pwmRequest.getUserInfoIfLoggedIn(),
                     pwmRequest.getSessionLabel(),
                     "UpdateProfile"
             );
-            pwmRequest.getPwmApplication().getAuditManager().submit(auditRecord);
+            pwmRequest.getPwmApplication().getAuditManager().submit( auditRecord );
         }
 
         return ProcessStatus.Continue;
     }
 
-    @ActionHandler(action = "confirm")
-    ProcessStatus handleConfirmRequest(final PwmRequest pwmRequest)
+    @ActionHandler( action = "confirm" )
+    ProcessStatus handleConfirmRequest( final PwmRequest pwmRequest )
             throws PwmUnrecoverableException
     {
-        final UpdateProfileBean updateProfileBean = getBean(pwmRequest);
-        updateProfileBean.setConfirmationPassed(true);
+        final UpdateProfileBean updateProfileBean = getBean( pwmRequest );
+        updateProfileBean.setConfirmationPassed( true );
 
         return ProcessStatus.Continue;
     }
 
-    @ActionHandler(action = "updateProfile")
+    @ActionHandler( action = "updateProfile" )
     ProcessStatus handleUpdateProfileRequest(
             final PwmRequest pwmRequest
     )
             throws PwmUnrecoverableException, ChaiUnavailableException, IOException, ServletException
     {
-        final UpdateProfileBean updateProfileBean = getBean(pwmRequest);
-        final UpdateAttributesProfile updateAttributesProfile = getProfile(pwmRequest);
+        final UpdateProfileBean updateProfileBean = getBean( pwmRequest );
+        final UpdateAttributesProfile updateAttributesProfile = getProfile( pwmRequest );
 
-        try {
-            readFormParametersFromRequest(pwmRequest, updateAttributesProfile, updateProfileBean);
-        } catch (PwmOperationalException e) {
-            LOGGER.error(pwmRequest, e.getMessage());
-            setLastError(pwmRequest, e.getErrorInformation());
+        try
+        {
+            readFormParametersFromRequest( pwmRequest, updateAttributesProfile, updateProfileBean );
+        }
+        catch ( PwmOperationalException e )
+        {
+            LOGGER.error( pwmRequest, e.getMessage() );
+            setLastError( pwmRequest, e.getErrorInformation() );
         }
 
-        updateProfileBean.setFormSubmitted(true);
+        updateProfileBean.setFormSubmitted( true );
 
         return ProcessStatus.Continue;
     }
 
-    protected void nextStep(final PwmRequest pwmRequest)
+    protected void nextStep( final PwmRequest pwmRequest )
             throws IOException, ServletException, PwmUnrecoverableException, ChaiUnavailableException
     {
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
-        final UpdateProfileBean updateProfileBean = getBean(pwmRequest);
-        final UpdateAttributesProfile updateAttributesProfile = getProfile(pwmRequest);
+        final UpdateProfileBean updateProfileBean = getBean( pwmRequest );
+        final UpdateAttributesProfile updateAttributesProfile = getProfile( pwmRequest );
         final PwmSession pwmSession = pwmRequest.getPwmSession();
 
         final String updateProfileAgreementText = updateAttributesProfile.readSettingAsLocalizedString(
@@ -310,117 +331,141 @@ public class UpdateProfileServlet extends ControlledPwmServlet {
                 pwmSession.getSessionStateBean().getLocale()
         );
 
-        if (updateProfileAgreementText != null && updateProfileAgreementText.length() > 0) {
-            if (!updateProfileBean.isAgreementPassed()) {
-                final MacroMachine macroMachine = pwmRequest.getPwmSession().getSessionManager().getMacroMachine(pwmRequest.getPwmApplication());
-                final String expandedText = macroMachine.expandMacros(updateProfileAgreementText);
-                pwmRequest.setAttribute(PwmRequestAttribute.AgreementText, expandedText);
-                pwmRequest.forwardToJsp(JspUrl.UPDATE_ATTRIBUTES_AGREEMENT);
+        if ( updateProfileAgreementText != null && updateProfileAgreementText.length() > 0 )
+        {
+            if ( !updateProfileBean.isAgreementPassed() )
+            {
+                final MacroMachine macroMachine = pwmRequest.getPwmSession().getSessionManager().getMacroMachine( pwmRequest.getPwmApplication() );
+                final String expandedText = macroMachine.expandMacros( updateProfileAgreementText );
+                pwmRequest.setAttribute( PwmRequestAttribute.AgreementText, expandedText );
+                pwmRequest.forwardToJsp( JspUrl.UPDATE_ATTRIBUTES_AGREEMENT );
                 return;
             }
         }
 
         //make sure there is form data in the bean.
-        if (!updateProfileBean.isFormLdapLoaded()) {
+        if ( !updateProfileBean.isFormLdapLoaded() )
+        {
             updateProfileBean.getFormData().clear();
-            updateProfileBean.getFormData().putAll((formDataFromLdap(pwmRequest, updateAttributesProfile)));
-            updateProfileBean.setFormLdapLoaded(true);
-            forwardToForm(pwmRequest, updateAttributesProfile, updateProfileBean);
+            updateProfileBean.getFormData().putAll( ( formDataFromLdap( pwmRequest, updateAttributesProfile ) ) );
+            updateProfileBean.setFormLdapLoaded( true );
+            forwardToForm( pwmRequest, updateAttributesProfile, updateProfileBean );
             return;
         }
 
-        if (!updateProfileBean.isFormSubmitted()) {
-            forwardToForm(pwmRequest, updateAttributesProfile, updateProfileBean);
+        if ( !updateProfileBean.isFormSubmitted() )
+        {
+            forwardToForm( pwmRequest, updateAttributesProfile, updateProfileBean );
             return;
         }
 
 
         // validate the form data.
-        try {
+        try
+        {
             // verify form meets the form requirements
-            final List<FormConfiguration> formFields = updateAttributesProfile.readSettingAsForm(PwmSetting.UPDATE_PROFILE_FORM);
-            final Map<FormConfiguration, String> formValues = FormUtility.readFormValuesFromMap(updateProfileBean.getFormData(), formFields, pwmRequest.getLocale());
-            verifyFormAttributes(pwmRequest.getPwmApplication(), pwmRequest.getUserInfoIfLoggedIn(), pwmRequest.getLocale(), formValues, true);
-        } catch (PwmException e) {
-            LOGGER.error(pwmSession, e.getMessage());
-            setLastError(pwmRequest, e.getErrorInformation());
-            forwardToForm(pwmRequest, updateAttributesProfile, updateProfileBean);
+            final List<FormConfiguration> formFields = updateAttributesProfile.readSettingAsForm( PwmSetting.UPDATE_PROFILE_FORM );
+            final Map<FormConfiguration, String> formValues = FormUtility.readFormValuesFromMap( updateProfileBean.getFormData(), formFields, pwmRequest.getLocale() );
+            verifyFormAttributes( pwmRequest.getPwmApplication(), pwmRequest.getUserInfoIfLoggedIn(), pwmRequest.getLocale(), formValues, true );
+        }
+        catch ( PwmException e )
+        {
+            LOGGER.error( pwmSession, e.getMessage() );
+            setLastError( pwmRequest, e.getErrorInformation() );
+            forwardToForm( pwmRequest, updateAttributesProfile, updateProfileBean );
             return;
         }
 
-        final boolean requireConfirmation = updateAttributesProfile.readSettingAsBoolean(PwmSetting.UPDATE_PROFILE_SHOW_CONFIRMATION);
-        if (requireConfirmation && !updateProfileBean.isConfirmationPassed()) {
-            forwardToConfirmForm(pwmRequest, updateAttributesProfile, updateProfileBean);
+        final boolean requireConfirmation = updateAttributesProfile.readSettingAsBoolean( PwmSetting.UPDATE_PROFILE_SHOW_CONFIRMATION );
+        if ( requireConfirmation && !updateProfileBean.isConfirmationPassed() )
+        {
+            forwardToConfirmForm( pwmRequest, updateAttributesProfile, updateProfileBean );
             return;
         }
 
-        final Set<TokenVerificationProgress.TokenChannel> requiredVerifications = determineTokenPhaseRequired(pwmRequest, updateProfileBean, updateAttributesProfile);
-        if (requiredVerifications != null) {
-            for (final TokenVerificationProgress.TokenChannel tokenChannel : requiredVerifications) {
-                if (requiredVerifications.contains(tokenChannel)) {
-                    if (!updateProfileBean.getTokenVerificationProgress().getIssuedTokens().contains(tokenChannel)) {
-                        initializeToken(pwmRequest, updateProfileBean, tokenChannel);
+        final Set<TokenVerificationProgress.TokenChannel> requiredVerifications = determineTokenPhaseRequired( pwmRequest, updateProfileBean, updateAttributesProfile );
+        if ( requiredVerifications != null )
+        {
+            for ( final TokenVerificationProgress.TokenChannel tokenChannel : requiredVerifications )
+            {
+                if ( requiredVerifications.contains( tokenChannel ) )
+                {
+                    if ( !updateProfileBean.getTokenVerificationProgress().getIssuedTokens().contains( tokenChannel ) )
+                    {
+                        initializeToken( pwmRequest, updateProfileBean, tokenChannel );
                     }
 
-                    if (!updateProfileBean.getTokenVerificationProgress().getPassedTokens().contains(tokenChannel)) {
-                        updateProfileBean.getTokenVerificationProgress().setPhase(tokenChannel);
-                        pwmRequest.forwardToJsp(JspUrl.UPDATE_ATTRIBUTES_ENTER_CODE);
+                    if ( !updateProfileBean.getTokenVerificationProgress().getPassedTokens().contains( tokenChannel ) )
+                    {
+                        updateProfileBean.getTokenVerificationProgress().setPhase( tokenChannel );
+                        pwmRequest.forwardToJsp( JspUrl.UPDATE_ATTRIBUTES_ENTER_CODE );
                         return;
                     }
                 }
             }
         }
 
-        try {
+        try
+        {
             // write the form values
-            final ChaiUser theUser = pwmSession.getSessionManager().getActor(pwmApplication);
+            final ChaiUser theUser = pwmSession.getSessionManager().getActor( pwmApplication );
             doProfileUpdate(
                     pwmRequest.getPwmApplication(),
                     pwmRequest.getSessionLabel(),
                     pwmRequest.getLocale(),
                     pwmSession.getUserInfo(),
-                    pwmSession.getSessionManager().getMacroMachine(pwmApplication),
+                    pwmSession.getSessionManager().getMacroMachine( pwmApplication ),
                     updateAttributesProfile,
                     updateProfileBean.getFormData(),
                     theUser
             );
 
             // re-populate the uiBean because we have changed some values.
-            pwmSession.reloadUserInfoBean(pwmApplication);
+            pwmSession.reloadUserInfoBean( pwmApplication );
 
             // clear cached read attributes.
-            pwmRequest.getPwmSession().reloadUserInfoBean(pwmApplication);
+            pwmRequest.getPwmSession().reloadUserInfoBean( pwmApplication );
 
             // mark the event log
-            pwmApplication.getAuditManager().submit(AuditEvent.UPDATE_PROFILE, pwmSession.getUserInfo(), pwmSession);
+            pwmApplication.getAuditManager().submit( AuditEvent.UPDATE_PROFILE, pwmSession.getUserInfo(), pwmSession );
 
             // clear the bean
-            pwmApplication.getSessionStateService().clearBean(pwmRequest, UpdateProfileBean.class);
+            pwmApplication.getSessionStateService().clearBean( pwmRequest, UpdateProfileBean.class );
 
-            pwmRequest.getPwmResponse().forwardToSuccessPage(Message.Success_UpdateProfile);
+            pwmRequest.getPwmResponse().forwardToSuccessPage( Message.Success_UpdateProfile );
             return;
-        } catch (PwmException e) {
-            LOGGER.error(pwmSession, e.getMessage());
-            setLastError(pwmRequest, e.getErrorInformation());
-        } catch (ChaiException e) {
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UPDATE_ATTRS_FAILURE,e.toString());
-            LOGGER.error(pwmSession, errorInformation.toDebugStr());
-            setLastError(pwmRequest, errorInformation);
+        }
+        catch ( PwmException e )
+        {
+            LOGGER.error( pwmSession, e.getMessage() );
+            setLastError( pwmRequest, e.getErrorInformation() );
+        }
+        catch ( ChaiException e )
+        {
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_UPDATE_ATTRS_FAILURE, e.toString() );
+            LOGGER.error( pwmSession, errorInformation.toDebugStr() );
+            setLastError( pwmRequest, errorInformation );
         }
 
-        forwardToForm(pwmRequest, updateAttributesProfile, updateProfileBean);
+        forwardToForm( pwmRequest, updateAttributesProfile, updateProfileBean );
     }
 
     @Override
-    public ProcessStatus preProcessCheck(final PwmRequest pwmRequest) throws PwmUnrecoverableException, IOException, ServletException {
-        if (!pwmRequest.getPwmApplication().getConfig().readSettingAsBoolean(PwmSetting.UPDATE_PROFILE_ENABLE)) {
-            pwmRequest.respondWithError(new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE, "Setting " + PwmSetting.UPDATE_PROFILE_ENABLE.toMenuLocationDebug(null,null) + " is not enabled."));
+    public ProcessStatus preProcessCheck( final PwmRequest pwmRequest ) throws PwmUnrecoverableException, IOException, ServletException
+    {
+        if ( !pwmRequest.getPwmApplication().getConfig().readSettingAsBoolean( PwmSetting.UPDATE_PROFILE_ENABLE ) )
+        {
+            pwmRequest.respondWithError( new ErrorInformation(
+                    PwmError.ERROR_SERVICE_NOT_AVAILABLE,
+                    "Setting " + PwmSetting.UPDATE_PROFILE_ENABLE.toMenuLocationDebug( null, null ) + " is not enabled." )
+            );
             return ProcessStatus.Halt;
         }
 
-        final UpdateAttributesProfile updateAttributesProfile = getProfile(pwmRequest);
-        if (updateAttributesProfile == null) {
-            pwmRequest.respondWithError(new ErrorInformation(PwmError.ERROR_NO_PROFILE_ASSIGNED));
+        final UpdateAttributesProfile updateAttributesProfile = getProfile( pwmRequest );
+        if ( updateAttributesProfile == null )
+        {
+            pwmRequest.respondWithError( new ErrorInformation( PwmError.ERROR_NO_PROFILE_ASSIGNED ) );
             return ProcessStatus.Halt;
         }
 
@@ -428,60 +473,63 @@ public class UpdateProfileServlet extends ControlledPwmServlet {
     }
 
 
-
-
-    final Map<FormConfiguration,String> readFormParametersFromRequest(
+    final Map<FormConfiguration, String> readFormParametersFromRequest(
             final PwmRequest pwmRequest,
             final UpdateAttributesProfile updateAttributesProfile,
             final UpdateProfileBean updateProfileBean
     )
             throws PwmUnrecoverableException, PwmDataValidationException, ChaiUnavailableException
     {
-        final List<FormConfiguration> formFields = updateAttributesProfile.readSettingAsForm(PwmSetting.UPDATE_PROFILE_FORM);
+        final List<FormConfiguration> formFields = updateAttributesProfile.readSettingAsForm( PwmSetting.UPDATE_PROFILE_FORM );
 
         //read the values from the request
-        final Map<FormConfiguration,String> formValueMap = FormUtility.readFormValuesFromRequest(pwmRequest, formFields, pwmRequest.getLocale());
+        final Map<FormConfiguration, String> formValueMap = FormUtility.readFormValuesFromRequest( pwmRequest, formFields, pwmRequest.getLocale() );
 
-        return updateBeanFormData(formFields, formValueMap, updateProfileBean);
+        return updateBeanFormData( formFields, formValueMap, updateProfileBean );
     }
 
-    static Map<FormConfiguration,String> readFromJsonRequest(
+    static Map<FormConfiguration, String> readFromJsonRequest(
             final PwmRequest pwmRequest,
             final UpdateAttributesProfile updateAttributesProfile,
             final UpdateProfileBean updateProfileBean
     )
             throws PwmDataValidationException, PwmUnrecoverableException, IOException
     {
-        final List<FormConfiguration> formFields = updateAttributesProfile.readSettingAsForm(PwmSetting.UPDATE_PROFILE_FORM);
+        final List<FormConfiguration> formFields = updateAttributesProfile.readSettingAsForm( PwmSetting.UPDATE_PROFILE_FORM );
 
-        final Map<FormConfiguration,String> formValueMap = FormUtility.readFormValuesFromMap(pwmRequest.readBodyAsJsonStringMap(), formFields, pwmRequest.getLocale());
+        final Map<FormConfiguration, String> formValueMap = FormUtility.readFormValuesFromMap( pwmRequest.readBodyAsJsonStringMap(), formFields, pwmRequest.getLocale() );
 
-        return updateBeanFormData(formFields, formValueMap, updateProfileBean);
+        return updateBeanFormData( formFields, formValueMap, updateProfileBean );
     }
 
-    static Map<FormConfiguration,String> updateBeanFormData(
+    static Map<FormConfiguration, String> updateBeanFormData(
             final List<FormConfiguration> formFields,
-            final Map<FormConfiguration,String> formValueMap,
+            final Map<FormConfiguration, String> formValueMap,
             final UpdateProfileBean updateProfileBean
-    ) {
-        final LinkedHashMap<FormConfiguration,String> newFormValueMap = new LinkedHashMap<>();
-        for (final FormConfiguration formConfiguration : formFields) {
-            if (formConfiguration.isReadonly()) {
-                final String existingValue = updateProfileBean.getFormData().get(formConfiguration.getName());
-                newFormValueMap.put(formConfiguration, existingValue);
-            } else {
-                newFormValueMap.put(formConfiguration, formValueMap.get(formConfiguration));
+    )
+    {
+        final LinkedHashMap<FormConfiguration, String> newFormValueMap = new LinkedHashMap<>();
+        for ( final FormConfiguration formConfiguration : formFields )
+        {
+            if ( formConfiguration.isReadonly() )
+            {
+                final String existingValue = updateProfileBean.getFormData().get( formConfiguration.getName() );
+                newFormValueMap.put( formConfiguration, existingValue );
+            }
+            else
+            {
+                newFormValueMap.put( formConfiguration, formValueMap.get( formConfiguration ) );
             }
         }
 
         updateProfileBean.getFormData().clear();
-        updateProfileBean.getFormData().putAll(FormUtility.asStringMap(newFormValueMap));
+        updateProfileBean.getFormData().putAll( FormUtility.asStringMap( newFormValueMap ) );
 
         return newFormValueMap;
     }
 
 
-
+    @SuppressWarnings( "checkstyle:ParameterNumber" )
     public static void doProfileUpdate(
             final PwmApplication pwmApplication,
             final SessionLabel sessionLabel,
@@ -489,42 +537,44 @@ public class UpdateProfileServlet extends ControlledPwmServlet {
             final UserInfo userInfo,
             final MacroMachine macroMachine,
             final UpdateAttributesProfile updateAttributesProfile,
-            final Map<String,String> formValues,
+            final Map<String, String> formValues,
             final ChaiUser theUser
     )
             throws PwmUnrecoverableException, ChaiUnavailableException, PwmOperationalException
     {
-        final List<FormConfiguration> formFields = updateAttributesProfile.readSettingAsForm(PwmSetting.UPDATE_PROFILE_FORM);
-        final Map<FormConfiguration, String> formMap = FormUtility.readFormValuesFromMap(formValues, formFields, locale);
+        final List<FormConfiguration> formFields = updateAttributesProfile.readSettingAsForm( PwmSetting.UPDATE_PROFILE_FORM );
+        final Map<FormConfiguration, String> formMap = FormUtility.readFormValuesFromMap( formValues, formFields, locale );
 
         // verify form meets the form requirements (may be redundant, but shouldn't hurt)
-        verifyFormAttributes(pwmApplication, userInfo.getUserIdentity(), locale, formMap, false);
+        verifyFormAttributes( pwmApplication, userInfo.getUserIdentity(), locale, formMap, false );
 
         // write values.
-        LOGGER.info("updating profile for " + userInfo.getUserIdentity());
+        LOGGER.info( "updating profile for " + userInfo.getUserIdentity() );
 
-        LdapOperationsHelper.writeFormValuesToLdap(pwmApplication, macroMachine, theUser, formMap, false);
+        LdapOperationsHelper.writeFormValuesToLdap( pwmApplication, macroMachine, theUser, formMap, false );
 
         final UserIdentity userIdentity = userInfo.getUserIdentity();
 
-        {  // execute configured actions
-            final List<ActionConfiguration> actions = updateAttributesProfile.readSettingAsAction(PwmSetting.UPDATE_PROFILE_WRITE_ATTRIBUTES);
-            if (actions != null && !actions.isEmpty()) {
-                LOGGER.debug(sessionLabel, "executing configured actions to user " + userIdentity);
+        {
+            // execute configured actions
+            final List<ActionConfiguration> actions = updateAttributesProfile.readSettingAsAction( PwmSetting.UPDATE_PROFILE_WRITE_ATTRIBUTES );
+            if ( actions != null && !actions.isEmpty() )
+            {
+                LOGGER.debug( sessionLabel, "executing configured actions to user " + userIdentity );
 
 
-                final ActionExecutor actionExecutor = new ActionExecutor.ActionExecutorSettings(pwmApplication, userIdentity)
-                        .setExpandPwmMacros(true)
-                        .setMacroMachine(macroMachine)
+                final ActionExecutor actionExecutor = new ActionExecutor.ActionExecutorSettings( pwmApplication, userIdentity )
+                        .setExpandPwmMacros( true )
+                        .setMacroMachine( macroMachine )
                         .createActionExecutor();
 
-                actionExecutor.executeActions(actions, sessionLabel);
+                actionExecutor.executeActions( actions, sessionLabel );
             }
         }
-        sendProfileUpdateEmailNotice(pwmApplication, macroMachine, userInfo, locale, sessionLabel);
+        sendProfileUpdateEmailNotice( pwmApplication, macroMachine, userInfo, locale, sessionLabel );
 
         // success, so forward to success page
-        pwmApplication.getStatisticsManager().incrementValue(Statistic.UPDATE_ATTRIBUTES);
+        pwmApplication.getStatisticsManager().incrementValue( Statistic.UPDATE_ATTRIBUTES );
     }
 
     private static void verifyFormAttributes(
@@ -537,11 +587,12 @@ public class UpdateProfileServlet extends ControlledPwmServlet {
             throws PwmOperationalException, PwmUnrecoverableException
     {
         // see if the values meet form requirements.
-        FormUtility.validateFormValues(pwmApplication.getConfig(), formValues, userLocale);
+        FormUtility.validateFormValues( pwmApplication.getConfig(), formValues, userLocale );
 
         final List<FormUtility.ValidationFlag> validationFlags = new ArrayList<>();
-        if (allowResultCaching) {
-            validationFlags.add(FormUtility.ValidationFlag.allowResultCaching);
+        if ( allowResultCaching )
+        {
+            validationFlags.add( FormUtility.ValidationFlag.allowResultCaching );
         }
 
         // check unique fields against ldap
@@ -549,8 +600,8 @@ public class UpdateProfileServlet extends ControlledPwmServlet {
                 pwmApplication,
                 formValues,
                 userLocale,
-                Collections.singletonList(userIdentity),
-                validationFlags.toArray(new FormUtility.ValidationFlag[validationFlags.size()])
+                Collections.singletonList( userIdentity ),
+                validationFlags.toArray( new FormUtility.ValidationFlag[ validationFlags.size() ] )
         );
     }
 
@@ -565,36 +616,37 @@ public class UpdateProfileServlet extends ControlledPwmServlet {
     {
         final Configuration config = pwmApplication.getConfig();
 
-        final EmailItemBean configuredEmailSetting = config.readSettingAsEmail(PwmSetting.EMAIL_UPDATEPROFILE, locale);
+        final EmailItemBean configuredEmailSetting = config.readSettingAsEmail( PwmSetting.EMAIL_UPDATEPROFILE, locale );
         pwmApplication.getEmailQueue().submitEmail(
                 configuredEmailSetting,
                 userInfo,
                 macroMachine
         );
 
-        if (configuredEmailSetting == null) {
-            LOGGER.debug(sessionLabel, "skipping send profile update email for '" + userInfo.getUserIdentity().toDisplayString() + "' no email configured");
+        if ( configuredEmailSetting == null )
+        {
+            LOGGER.debug( sessionLabel, "skipping send profile update email for '" + userInfo.getUserIdentity().toDisplayString() + "' no email configured" );
         }
     }
 
-    private static void forwardToForm(final PwmRequest pwmRequest, final UpdateAttributesProfile updateAttributesProfile, final UpdateProfileBean updateProfileBean)
+    private static void forwardToForm( final PwmRequest pwmRequest, final UpdateAttributesProfile updateAttributesProfile, final UpdateProfileBean updateProfileBean )
             throws ServletException, PwmUnrecoverableException, IOException
     {
-        final List<FormConfiguration> form = updateAttributesProfile.readSettingAsForm(PwmSetting.UPDATE_PROFILE_FORM);
-        final Map<FormConfiguration,String> formValueMap = formMapFromBean(updateAttributesProfile, updateProfileBean);
-        pwmRequest.addFormInfoToRequestAttr(form, formValueMap, false, false);
-        final List<FormConfiguration> links = updateAttributesProfile.readSettingAsForm(PwmSetting.UPDATE_PROFILE_CUSTOMLINKS);
-        pwmRequest.setAttribute(PwmRequestAttribute.FormCustomLinks,new ArrayList<>(links));
-        pwmRequest.forwardToJsp(JspUrl.UPDATE_ATTRIBUTES);
+        final List<FormConfiguration> form = updateAttributesProfile.readSettingAsForm( PwmSetting.UPDATE_PROFILE_FORM );
+        final Map<FormConfiguration, String> formValueMap = formMapFromBean( updateAttributesProfile, updateProfileBean );
+        pwmRequest.addFormInfoToRequestAttr( form, formValueMap, false, false );
+        final List<FormConfiguration> links = updateAttributesProfile.readSettingAsForm( PwmSetting.UPDATE_PROFILE_CUSTOMLINKS );
+        pwmRequest.setAttribute( PwmRequestAttribute.FormCustomLinks, new ArrayList<>( links ) );
+        pwmRequest.forwardToJsp( JspUrl.UPDATE_ATTRIBUTES );
     }
 
-    private static void forwardToConfirmForm(final PwmRequest pwmRequest, final UpdateAttributesProfile updateAttributesProfile, final UpdateProfileBean updateProfileBean)
+    private static void forwardToConfirmForm( final PwmRequest pwmRequest, final UpdateAttributesProfile updateAttributesProfile, final UpdateProfileBean updateProfileBean )
             throws ServletException, PwmUnrecoverableException, IOException
     {
-        final List<FormConfiguration> form = updateAttributesProfile.readSettingAsForm(PwmSetting.UPDATE_PROFILE_FORM);
-        final Map<FormConfiguration,String> formValueMap = formMapFromBean(updateAttributesProfile, updateProfileBean);
-        pwmRequest.addFormInfoToRequestAttr(form, formValueMap, true, false);
-        pwmRequest.forwardToJsp(JspUrl.UPDATE_ATTRIBUTES_CONFIRM);
+        final List<FormConfiguration> form = updateAttributesProfile.readSettingAsForm( PwmSetting.UPDATE_PROFILE_FORM );
+        final Map<FormConfiguration, String> formValueMap = formMapFromBean( updateAttributesProfile, updateProfileBean );
+        pwmRequest.addFormInfoToRequestAttr( form, formValueMap, true, false );
+        pwmRequest.forwardToJsp( JspUrl.UPDATE_ATTRIBUTES_CONFIRM );
     }
 
     private static Map<FormConfiguration, String> formMapFromBean(
@@ -604,27 +656,28 @@ public class UpdateProfileServlet extends ControlledPwmServlet {
             throws PwmUnrecoverableException
     {
 
-        final List<FormConfiguration> form = updateAttributesProfile.readSettingAsForm(PwmSetting.UPDATE_PROFILE_FORM);
+        final List<FormConfiguration> form = updateAttributesProfile.readSettingAsForm( PwmSetting.UPDATE_PROFILE_FORM );
         final Map<FormConfiguration, String> formValueMap = new LinkedHashMap<>();
-        for (final FormConfiguration formConfiguration : form) {
+        for ( final FormConfiguration formConfiguration : form )
+        {
             formValueMap.put(
                     formConfiguration,
-                    updateProfileBean.getFormData().keySet().contains(formConfiguration.getName())
-                            ? updateProfileBean.getFormData().get(formConfiguration.getName())
+                    updateProfileBean.getFormData().keySet().contains( formConfiguration.getName() )
+                            ? updateProfileBean.getFormData().get( formConfiguration.getName() )
                             : ""
             );
         }
         return formValueMap;
     }
 
-    private static Map<String,String> formDataFromLdap(final PwmRequest pwmRequest, final UpdateAttributesProfile updateAttributesProfile)
+    private static Map<String, String> formDataFromLdap( final PwmRequest pwmRequest, final UpdateAttributesProfile updateAttributesProfile )
             throws PwmUnrecoverableException
     {
         final UserInfo userInfo = pwmRequest.getPwmSession().getUserInfo();
-        final List<FormConfiguration> formFields = updateAttributesProfile.readSettingAsForm(PwmSetting.UPDATE_PROFILE_FORM);
+        final List<FormConfiguration> formFields = updateAttributesProfile.readSettingAsForm( PwmSetting.UPDATE_PROFILE_FORM );
         final Map<FormConfiguration, String> formMap = new LinkedHashMap<>();
-        FormUtility.populateFormMapFromLdap(formFields, pwmRequest.getSessionLabel(), formMap, userInfo);
-        return FormUtility.asStringMap(formMap);
+        FormUtility.populateFormMapFromLdap( formFields, pwmRequest.getSessionLabel(), formMap, userInfo );
+        return FormUtility.asStringMap( formMap );
     }
 
     private static Set<TokenVerificationProgress.TokenChannel> determineTokenPhaseRequired(
@@ -637,37 +690,48 @@ public class UpdateProfileServlet extends ControlledPwmServlet {
     {
         final Set<TokenVerificationProgress.TokenChannel> returnObj = new HashSet<>();
 
-        final LdapProfile ldapProfile = pwmRequest.getUserInfoIfLoggedIn().getLdapProfile(pwmRequest.getConfig());
-        final Map<String,String> userFormData = updateProfileBean.getFormData();
-        Map<String,String> ldapData = null;
+        final LdapProfile ldapProfile = pwmRequest.getUserInfoIfLoggedIn().getLdapProfile( pwmRequest.getConfig() );
+        final Map<String, String> userFormData = updateProfileBean.getFormData();
+        Map<String, String> ldapData = null;
 
-        if (updateAttributesProfile.readSettingAsBoolean(PwmSetting.UPDATE_PROFILE_EMAIL_VERIFICATION)) {
-            final String emailAddressAttribute = ldapProfile.readSettingAsString(PwmSetting.EMAIL_USER_MAIL_ATTRIBUTE);
-            if (userFormData.containsKey(emailAddressAttribute) && !userFormData.get(emailAddressAttribute).isEmpty()) {
-                ldapData = formDataFromLdap(pwmRequest, updateAttributesProfile);
-                if (userFormData.get(emailAddressAttribute) != null && !userFormData.get(emailAddressAttribute).equalsIgnoreCase(ldapData.get(emailAddressAttribute))) {
-                    returnObj.add(TokenVerificationProgress.TokenChannel.EMAIL);
+        if ( updateAttributesProfile.readSettingAsBoolean( PwmSetting.UPDATE_PROFILE_EMAIL_VERIFICATION ) )
+        {
+            final String emailAddressAttribute = ldapProfile.readSettingAsString( PwmSetting.EMAIL_USER_MAIL_ATTRIBUTE );
+            if ( userFormData.containsKey( emailAddressAttribute ) && !userFormData.get( emailAddressAttribute ).isEmpty() )
+            {
+                ldapData = formDataFromLdap( pwmRequest, updateAttributesProfile );
+                if ( userFormData.get( emailAddressAttribute ) != null && !userFormData.get( emailAddressAttribute ).equalsIgnoreCase( ldapData.get( emailAddressAttribute ) ) )
+                {
+                    returnObj.add( TokenVerificationProgress.TokenChannel.EMAIL );
                 }
-            } else {
-                LOGGER.warn(pwmRequest, "email verification enabled, but email attribute '" + emailAddressAttribute + "' is not in update form");
+            }
+            else
+            {
+                LOGGER.warn( pwmRequest, "email verification enabled, but email attribute '" + emailAddressAttribute + "' is not in update form" );
             }
         }
 
-        if (updateAttributesProfile.readSettingAsBoolean(PwmSetting.UPDATE_PROFILE_SMS_VERIFICATION)) {
-            final String phoneNumberAttribute = ldapProfile.readSettingAsString(PwmSetting.SMS_USER_PHONE_ATTRIBUTE);
-            if (userFormData.containsKey(phoneNumberAttribute) && !userFormData.get(phoneNumberAttribute).isEmpty()) {
-                if (ldapData == null) {
-                    ldapData = formDataFromLdap(pwmRequest, updateAttributesProfile);
+        if ( updateAttributesProfile.readSettingAsBoolean( PwmSetting.UPDATE_PROFILE_SMS_VERIFICATION ) )
+        {
+            final String phoneNumberAttribute = ldapProfile.readSettingAsString( PwmSetting.SMS_USER_PHONE_ATTRIBUTE );
+            if ( userFormData.containsKey( phoneNumberAttribute ) && !userFormData.get( phoneNumberAttribute ).isEmpty() )
+            {
+                if ( ldapData == null )
+                {
+                    ldapData = formDataFromLdap( pwmRequest, updateAttributesProfile );
                 }
-                if (userFormData.get(phoneNumberAttribute) != null && !userFormData.get(phoneNumberAttribute).equalsIgnoreCase(ldapData.get(phoneNumberAttribute))) {
-                    returnObj.add(TokenVerificationProgress.TokenChannel.SMS);
+                if ( userFormData.get( phoneNumberAttribute ) != null && !userFormData.get( phoneNumberAttribute ).equalsIgnoreCase( ldapData.get( phoneNumberAttribute ) ) )
+                {
+                    returnObj.add( TokenVerificationProgress.TokenChannel.SMS );
                 }
-            } else {
-                LOGGER.warn(pwmRequest, "sms verification enabled, but phone attribute '" + phoneNumberAttribute + "' is not in update form");
+            }
+            else
+            {
+                LOGGER.warn( pwmRequest, "sms verification enabled, but phone attribute '" + phoneNumberAttribute + "' is not in update form" );
             }
         }
 
-        LOGGER.trace(pwmRequest, "determined required verification phases: " + StringUtil.collectionToString(returnObj,","));
+        LOGGER.trace( pwmRequest, "determined required verification phases: " + StringUtil.collectionToString( returnObj, "," ) );
 
         return returnObj;
     }
@@ -682,116 +746,132 @@ public class UpdateProfileServlet extends ControlledPwmServlet {
         final PwmSession pwmSession = pwmRequest.getPwmSession();
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
 
-        if (pwmApplication.getConfig().getTokenStorageMethod() == TokenStorageMethod.STORE_LDAP) {
-            throw new PwmUnrecoverableException(new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR,null,new String[]{
+        if ( pwmApplication.getConfig().getTokenStorageMethod() == TokenStorageMethod.STORE_LDAP )
+        {
+            throw new PwmUnrecoverableException( new ErrorInformation( PwmError.CONFIG_FORMAT_ERROR, null, new String[] {
                     "cannot generate new user tokens when storage type is configured as STORE_LDAP.",
-            }));
+            } ) );
         }
 
-        final UpdateAttributesProfile profile = getProfile(pwmRequest);
-        final MacroMachine macroMachine = pwmRequest.getPwmSession().getSessionManager().getMacroMachine(pwmApplication);
+        final UpdateAttributesProfile profile = getProfile( pwmRequest );
+        final MacroMachine macroMachine = pwmRequest.getPwmSession().getSessionManager().getMacroMachine( pwmApplication );
         final Configuration config = pwmApplication.getConfig();
-        final LdapProfile ldapProfile = pwmRequest.getUserInfoIfLoggedIn().getLdapProfile(pwmRequest.getConfig());
+        final LdapProfile ldapProfile = pwmRequest.getUserInfoIfLoggedIn().getLdapProfile( pwmRequest.getConfig() );
 
-        switch (tokenType) {
-            case SMS: {
-                final String telephoneNumberAttribute = ldapProfile.readSettingAsString(PwmSetting.SMS_USER_PHONE_ATTRIBUTE);
-                final String toNum = updateProfileBean.getFormData().get(telephoneNumberAttribute);
+        switch ( tokenType )
+        {
+            case SMS:
+            {
+                final String telephoneNumberAttribute = ldapProfile.readSettingAsString( PwmSetting.SMS_USER_PHONE_ATTRIBUTE );
+                final String toNum = updateProfileBean.getFormData().get( telephoneNumberAttribute );
                 final String tokenKey;
-                try {
+                try
+                {
                     final TokenPayload tokenPayload = pwmApplication.getTokenService().createTokenPayload(
                             TokenType.UPDATE_SMS,
-                            profile.getTokenDurationSMS(config),
+                            profile.getTokenDurationSMS( config ),
                             Collections.emptyMap(),
                             pwmRequest.getUserInfoIfLoggedIn(),
-                            Collections.singleton(toNum)
+                            Collections.singleton( toNum )
                     );
-                    tokenKey = pwmApplication.getTokenService().generateNewToken(tokenPayload,
-                            pwmRequest.getSessionLabel());
-                } catch (PwmOperationalException e) {
-                    throw new PwmUnrecoverableException(e.getErrorInformation());
+                    tokenKey = pwmApplication.getTokenService().generateNewToken( tokenPayload,
+                            pwmRequest.getSessionLabel() );
+                }
+                catch ( PwmOperationalException e )
+                {
+                    throw new PwmUnrecoverableException( e.getErrorInformation() );
                 }
 
-                final String message = config.readSettingAsLocalizedString(PwmSetting.SMS_UPDATE_PROFILE_TOKEN_TEXT,
-                        pwmSession.getSessionStateBean().getLocale());
+                final String message = config.readSettingAsLocalizedString( PwmSetting.SMS_UPDATE_PROFILE_TOKEN_TEXT,
+                        pwmSession.getSessionStateBean().getLocale() );
 
-                try {
+                try
+                {
                     TokenService.TokenSender.sendSmsToken(
                             TokenService.TokenSendInfo.builder()
-                            .pwmApplication( pwmApplication )
-                            .userInfo( null )
-                            .macroMachine( macroMachine )
-                            .smsNumber( toNum )
-                            .smsMessage( message )
-                            .tokenKey( tokenKey )
-                            .sessionLabel( pwmSession.getLabel() )
-                            .build()
+                                    .pwmApplication( pwmApplication )
+                                    .userInfo( null )
+                                    .macroMachine( macroMachine )
+                                    .smsNumber( toNum )
+                                    .smsMessage( message )
+                                    .tokenKey( tokenKey )
+                                    .sessionLabel( pwmSession.getLabel() )
+                                    .build()
                     );
-                } catch (Exception e) {
-                    throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_UNKNOWN));
+                }
+                catch ( Exception e )
+                {
+                    throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_UNKNOWN ) );
                 }
 
-                updateProfileBean.getTokenVerificationProgress().getIssuedTokens().add(TokenVerificationProgress.TokenChannel.SMS);
-                updateProfileBean.getTokenVerificationProgress().setTokenDisplayText(toNum);
-                updateProfileBean.getTokenVerificationProgress().setPhase(TokenVerificationProgress.TokenChannel.SMS);
+                updateProfileBean.getTokenVerificationProgress().getIssuedTokens().add( TokenVerificationProgress.TokenChannel.SMS );
+                updateProfileBean.getTokenVerificationProgress().setTokenDisplayText( toNum );
+                updateProfileBean.getTokenVerificationProgress().setPhase( TokenVerificationProgress.TokenChannel.SMS );
             }
             break;
 
-            case EMAIL: {
+            case EMAIL:
+            {
                 final EmailItemBean configuredEmailSetting = config.readSettingAsEmail(
                         PwmSetting.EMAIL_UPDATEPROFILE_VERIFICATION,
                         pwmRequest.getLocale()
                 );
-                final String emailAddressAttribute = ldapProfile.readSettingAsString(PwmSetting.EMAIL_USER_MAIL_ATTRIBUTE);
-                final String toAddress = updateProfileBean.getFormData().get(emailAddressAttribute);
+                final String emailAddressAttribute = ldapProfile.readSettingAsString( PwmSetting.EMAIL_USER_MAIL_ATTRIBUTE );
+                final String toAddress = updateProfileBean.getFormData().get( emailAddressAttribute );
 
                 final String tokenKey;
-                try {
+                try
+                {
                     final TokenPayload tokenPayload = pwmApplication.getTokenService().createTokenPayload(
                             TokenType.UPDATE_EMAIL,
-                            profile.getTokenDurationEmail(config),
+                            profile.getTokenDurationEmail( config ),
                             Collections.emptyMap(),
                             pwmRequest.getUserInfoIfLoggedIn(),
-                            Collections.singleton(toAddress)
+                            Collections.singleton( toAddress )
                     );
-                    tokenKey = pwmApplication.getTokenService().generateNewToken(tokenPayload,
-                            pwmRequest.getSessionLabel());
-                } catch (PwmOperationalException e) {
-                    throw new PwmUnrecoverableException(e.getErrorInformation());
+                    tokenKey = pwmApplication.getTokenService().generateNewToken( tokenPayload,
+                            pwmRequest.getSessionLabel() );
+                }
+                catch ( PwmOperationalException e )
+                {
+                    throw new PwmUnrecoverableException( e.getErrorInformation() );
                 }
 
-                updateProfileBean.getTokenVerificationProgress().getIssuedTokens().add(TokenVerificationProgress.TokenChannel.EMAIL);
-                updateProfileBean.getTokenVerificationProgress().setPhase(TokenVerificationProgress.TokenChannel.EMAIL);
-                updateProfileBean.getTokenVerificationProgress().setTokenDisplayText(toAddress);
+                updateProfileBean.getTokenVerificationProgress().getIssuedTokens().add( TokenVerificationProgress.TokenChannel.EMAIL );
+                updateProfileBean.getTokenVerificationProgress().setPhase( TokenVerificationProgress.TokenChannel.EMAIL );
+                updateProfileBean.getTokenVerificationProgress().setTokenDisplayText( toAddress );
 
                 final EmailItemBean emailItemBean = new EmailItemBean(
                         toAddress,
                         configuredEmailSetting.getFrom(),
                         configuredEmailSetting.getSubject(),
-                        configuredEmailSetting.getBodyPlain().replace("%TOKEN%", tokenKey),
-                        configuredEmailSetting.getBodyHtml().replace("%TOKEN%", tokenKey));
+                        configuredEmailSetting.getBodyPlain().replace( "%TOKEN%", tokenKey ),
+                        configuredEmailSetting.getBodyHtml().replace( "%TOKEN%", tokenKey ) );
 
-                try {
+                try
+                {
                     TokenService.TokenSender.sendEmailToken(
                             TokenService.TokenSendInfo.builder()
-                            .pwmApplication( pwmApplication )
-                            .userInfo( null )
-                            .macroMachine( macroMachine )
-                            .configuredEmailSetting( emailItemBean )
-                            .emailAddress( toAddress )
-                            .tokenKey( tokenKey )
-                            .sessionLabel( pwmRequest.getSessionLabel() )
+                                    .pwmApplication( pwmApplication )
+                                    .userInfo( null )
+                                    .macroMachine( macroMachine )
+                                    .configuredEmailSetting( emailItemBean )
+                                    .emailAddress( toAddress )
+                                    .tokenKey( tokenKey )
+                                    .sessionLabel( pwmRequest.getSessionLabel() )
                                     .build()
                     );
-                } catch (Exception e) {
-                    throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_UNKNOWN));
+                }
+                catch ( Exception e )
+                {
+                    throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_UNKNOWN ) );
                 }
             }
             break;
 
             default:
-                LOGGER.error("Unimplemented token purpose: " + tokenType);
-                updateProfileBean.getTokenVerificationProgress().setPhase(null);
+                LOGGER.error( "Unimplemented token purpose: " + tokenType );
+                updateProfileBean.getTokenVerificationProgress().setPhase( null );
         }
     }
 

File diff suppressed because it is too large
+ 398 - 309
server/src/main/java/password/pwm/http/servlet/configeditor/ConfigEditorServlet.java


File diff suppressed because it is too large
+ 472 - 342
server/src/main/java/password/pwm/http/servlet/forgottenpw/ForgottenPasswordServlet.java


+ 70 - 52
server/src/main/java/password/pwm/http/servlet/forgottenpw/ForgottenPasswordUtil.java

@@ -539,17 +539,17 @@ class ForgottenPasswordUtil
 
         final List<TokenDestinationItem.Type> sentTypes = TokenService.TokenSender.sendToken(
                 TokenService.TokenSendInfo.builder()
-                .pwmApplication( pwmRequest.getPwmApplication() )
-                .userInfo( userInfo )
-                .macroMachine( macroMachine )
-                .configuredEmailSetting( emailItemBean )
-                .tokenSendMethod( tokenSendMethod )
-                .emailAddress( outputDestrestTokenDataClient.getEmail() )
-                .smsNumber( outputDestrestTokenDataClient.getSms() )
-                .smsMessage( smsMessage )
-                .tokenKey( tokenKey )
-                .sessionLabel( pwmRequest.getSessionLabel() )
-                .build()
+                        .pwmApplication( pwmRequest.getPwmApplication() )
+                        .userInfo( userInfo )
+                        .macroMachine( macroMachine )
+                        .configuredEmailSetting( emailItemBean )
+                        .tokenSendMethod( tokenSendMethod )
+                        .emailAddress( outputDestrestTokenDataClient.getEmail() )
+                        .smsNumber( outputDestrestTokenDataClient.getSms() )
+                        .smsMessage( smsMessage )
+                        .tokenKey( tokenKey )
+                        .sessionLabel( pwmRequest.getSessionLabel() )
+                        .build()
         );
 
         StatisticsManager.incrementStat( pwmRequest, Statistic.RECOVERY_TOKENS_SENT );
@@ -563,36 +563,41 @@ class ForgottenPasswordUtil
         return displayDestAddress;
     }
 
-    static void doActionSendNewPassword( final PwmRequest pwmRequest)
+    static void doActionSendNewPassword( final PwmRequest pwmRequest )
             throws ChaiUnavailableException, IOException, ServletException, PwmUnrecoverableException
     {
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
-        final ForgottenPasswordBean forgottenPasswordBean = ForgottenPasswordServlet.forgottenPasswordBean(pwmRequest);
-        final ForgottenPasswordProfile forgottenPasswordProfile = ForgottenPasswordServlet.forgottenPasswordProfile(pwmRequest);
-        final RecoveryAction recoveryAction = ForgottenPasswordUtil.getRecoveryAction(pwmApplication.getConfig(), forgottenPasswordBean);
+        final ForgottenPasswordBean forgottenPasswordBean = ForgottenPasswordServlet.forgottenPasswordBean( pwmRequest );
+        final ForgottenPasswordProfile forgottenPasswordProfile = ForgottenPasswordServlet.forgottenPasswordProfile( pwmRequest );
+        final RecoveryAction recoveryAction = ForgottenPasswordUtil.getRecoveryAction( pwmApplication.getConfig(), forgottenPasswordBean );
 
-        LOGGER.trace(pwmRequest,"beginning process to send new password to user");
+        LOGGER.trace( pwmRequest, "beginning process to send new password to user" );
 
-        if (!forgottenPasswordBean.getProgress().isAllPassed()) {
+        if ( !forgottenPasswordBean.getProgress().isAllPassed() )
+        {
             return;
         }
 
         final UserIdentity userIdentity = forgottenPasswordBean.getUserIdentity();
-        final ChaiUser theUser = pwmRequest.getPwmApplication().getProxiedChaiUser(userIdentity);
+        final ChaiUser theUser = pwmRequest.getPwmApplication().getProxiedChaiUser( userIdentity );
 
-        try {
+        try
+        {
             // try unlocking user
             theUser.unlockPassword();
-            LOGGER.trace(pwmRequest, "unlock account succeeded");
-        } catch (ChaiOperationException e) {
+            LOGGER.trace( pwmRequest, "unlock account succeeded" );
+        }
+        catch ( ChaiOperationException e )
+        {
             final String errorMsg = "unable to unlock user " + theUser.getEntryDN() + " error: " + e.getMessage();
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNLOCK_FAILURE,errorMsg);
-            LOGGER.error(pwmRequest.getPwmSession(), errorInformation.toDebugStr());
-            pwmRequest.respondWithError(errorInformation);
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_UNLOCK_FAILURE, errorMsg );
+            LOGGER.error( pwmRequest.getPwmSession(), errorInformation.toDebugStr() );
+            pwmRequest.respondWithError( errorInformation );
             return;
         }
 
-        try {
+        try
+        {
             final UserInfo userInfo = UserInfoFactory.newUserInfoUsingProxy(
                     pwmApplication,
                     pwmRequest.getSessionLabel(),
@@ -600,10 +605,10 @@ class ForgottenPasswordUtil
                     pwmRequest.getLocale()
             );
 
-            LOGGER.info(pwmRequest, "user successfully supplied password recovery responses, emailing new password to: " + theUser.getEntryDN());
+            LOGGER.info( pwmRequest, "user successfully supplied password recovery responses, emailing new password to: " + theUser.getEntryDN() );
 
             // add post change actions
-            ForgottenPasswordServlet.addPostChangeAction(pwmRequest, userIdentity);
+            ForgottenPasswordServlet.addPostChangeAction( pwmRequest, userIdentity );
 
             // create new password
             final PasswordData newPassword = RandomPasswordGenerator.createRandomPassword(
@@ -611,35 +616,39 @@ class ForgottenPasswordUtil
                     userInfo.getPasswordPolicy(),
                     pwmApplication
             );
-            LOGGER.trace(pwmRequest, "generated random password value based on password policy for "
-                    + userIdentity.toDisplayString());
+            LOGGER.trace( pwmRequest, "generated random password value based on password policy for "
+                    + userIdentity.toDisplayString() );
 
 
             // set the password
-            try {
-                theUser.setPassword(newPassword.getStringValue());
-                LOGGER.trace(pwmRequest, "set user " + userIdentity.toDisplayString()
-                        + " password to system generated random value");
-            } catch (ChaiException e) {
-                throw PwmUnrecoverableException.fromChaiException(e);
+            try
+            {
+                theUser.setPassword( newPassword.getStringValue() );
+                LOGGER.trace( pwmRequest, "set user " + userIdentity.toDisplayString()
+                        + " password to system generated random value" );
+            }
+            catch ( ChaiException e )
+            {
+                throw PwmUnrecoverableException.fromChaiException( e );
             }
 
-            if (recoveryAction == RecoveryAction.SENDNEWPW_AND_EXPIRE) {
-                LOGGER.debug(pwmRequest, "marking user " + userIdentity.toDisplayString() + " password as expired");
+            if ( recoveryAction == RecoveryAction.SENDNEWPW_AND_EXPIRE )
+            {
+                LOGGER.debug( pwmRequest, "marking user " + userIdentity.toDisplayString() + " password as expired" );
                 theUser.expirePassword();
             }
 
             // mark the event log
             {
-                final AuditRecord auditRecord = new AuditRecordFactory(pwmApplication).createUserAuditRecord(
+                final AuditRecord auditRecord = new AuditRecordFactory( pwmApplication ).createUserAuditRecord(
                         AuditEvent.RECOVER_PASSWORD,
                         userIdentity,
                         pwmRequest.getSessionLabel()
                 );
-                pwmApplication.getAuditManager().submit(auditRecord);
+                pwmApplication.getAuditManager().submit( auditRecord );
             }
 
-            final MessageSendMethod messageSendMethod = forgottenPasswordProfile.readSettingAsEnum(PwmSetting.RECOVERY_SENDNEWPW_METHOD,MessageSendMethod.class);
+            final MessageSendMethod messageSendMethod = forgottenPasswordProfile.readSettingAsEnum( PwmSetting.RECOVERY_SENDNEWPW_METHOD, MessageSendMethod.class );
 
             // send email or SMS
             final String toAddress = PasswordUtility.sendNewPassword(
@@ -650,22 +659,31 @@ class ForgottenPasswordUtil
                     messageSendMethod
             );
 
-            pwmRequest.getPwmResponse().forwardToSuccessPage( Message.Success_PasswordSend, toAddress);
-        } catch (PwmException e) {
-            LOGGER.warn(pwmRequest, "unexpected error setting new password during recovery process for user: " + e.getMessage());
-            pwmRequest.respondWithError(e.getErrorInformation());
-        } catch (ChaiOperationException e) {
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNKNOWN,"unexpected ldap error while processing recovery action " + recoveryAction + ", error: " + e.getMessage());
-            LOGGER.warn(pwmRequest, errorInformation.toDebugStr());
-            pwmRequest.respondWithError(errorInformation);
-        } finally {
-            ForgottenPasswordServlet.clearForgottenPasswordBean(pwmRequest);
+            pwmRequest.getPwmResponse().forwardToSuccessPage( Message.Success_PasswordSend, toAddress );
+        }
+        catch ( PwmException e )
+        {
+            LOGGER.warn( pwmRequest, "unexpected error setting new password during recovery process for user: " + e.getMessage() );
+            pwmRequest.respondWithError( e.getErrorInformation() );
+        }
+        catch ( ChaiOperationException e )
+        {
+            final ErrorInformation errorInformation = new ErrorInformation(
+                    PwmError.ERROR_UNKNOWN,
+                    "unexpected ldap error while processing recovery action " + recoveryAction + ", error: " + e.getMessage()
+            );
+            LOGGER.warn( pwmRequest, errorInformation.toDebugStr() );
+            pwmRequest.respondWithError( errorInformation );
+        }
+        finally
+        {
+            ForgottenPasswordServlet.clearForgottenPasswordBean( pwmRequest );
 
             // the user should not be authenticated, this is a safety method
-            pwmRequest.getPwmSession().unauthenticateUser(pwmRequest);
+            pwmRequest.getPwmSession().unauthenticateUser( pwmRequest );
 
             // the password set flag should not have been set, this is a safety method
-            pwmRequest.getPwmSession().getSessionStateBean().setPasswordModified(false);
+            pwmRequest.getPwmSession().getSessionStateBean().setPasswordModified( false );
         }
     }
 }

+ 142 - 100
server/src/main/java/password/pwm/http/servlet/helpdesk/HelpdeskDetailInfoBean.java

@@ -31,7 +31,6 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.Getter;
 import lombok.Setter;
-
 import password.pwm.bean.ResponseInfoBean;
 import password.pwm.bean.UserIdentity;
 import password.pwm.config.PwmSetting;
@@ -70,9 +69,10 @@ import java.util.Map;
 import java.util.Set;
 
 @Getter
-@Setter(AccessLevel.PRIVATE)
-public class HelpdeskDetailInfoBean implements Serializable {
-    private static final PwmLogger LOGGER = PwmLogger.forClass(HelpdeskDetailInfoBean.class);
+@Setter( AccessLevel.PRIVATE )
+public class HelpdeskDetailInfoBean implements Serializable
+{
+    private static final PwmLogger LOGGER = PwmLogger.forClass( HelpdeskDetailInfoBean.class );
 
     private String userDisplayName;
 
@@ -93,13 +93,15 @@ public class HelpdeskDetailInfoBean implements Serializable {
 
     @Data
     @AllArgsConstructor
-    public static class ButtonInfo implements Serializable {
+    public static class ButtonInfo implements Serializable
+    {
         private String name;
         private String label;
         private String description;
     }
 
-    public enum StandardButton {
+    public enum StandardButton
+    {
         back,
         refresh,
         changePassword,
@@ -110,6 +112,7 @@ public class HelpdeskDetailInfoBean implements Serializable {
         deleteUser,
     }
 
+    @SuppressWarnings( "checkstyle:MethodLength" )
     static HelpdeskDetailInfoBean makeHelpdeskDetailInfo(
             final PwmRequest pwmRequest,
             final HelpdeskProfile helpdeskProfile,
@@ -118,11 +121,12 @@ public class HelpdeskDetailInfoBean implements Serializable {
             throws PwmUnrecoverableException, ChaiUnavailableException
     {
         final Instant startTime = Instant.now();
-        LOGGER.trace(pwmRequest, "beginning to assemble detail data report for user " + userIdentity);
+        LOGGER.trace( pwmRequest, "beginning to assemble detail data report for user " + userIdentity );
         final Locale actorLocale = pwmRequest.getLocale();
-        final ChaiUser theUser = HelpdeskServlet.getChaiUser(pwmRequest, helpdeskProfile, userIdentity);
+        final ChaiUser theUser = HelpdeskServlet.getChaiUser( pwmRequest, helpdeskProfile, userIdentity );
 
-        if (!theUser.exists()) {
+        if ( !theUser.exists() )
+        {
             return null;
         }
 
@@ -134,64 +138,77 @@ public class HelpdeskDetailInfoBean implements Serializable {
                 userIdentity,
                 theUser.getChaiProvider()
         );
-        final MacroMachine macroMachine = new MacroMachine(pwmRequest.getPwmApplication(), pwmRequest.getSessionLabel(), userInfo, null);
+        final MacroMachine macroMachine = new MacroMachine( pwmRequest.getPwmApplication(), pwmRequest.getSessionLabel(), userInfo, null );
 
-        try {
+        try
+        {
             detailInfo.userHistory = AccountInformationBean.makeAuditInfo(
                     pwmRequest.getPwmApplication(),
                     pwmRequest.getSessionLabel(),
                     userInfo,
                     pwmRequest.getLocale()
             );
-        } catch (Exception e) {
-            LOGGER.error(pwmRequest, "unexpected error reading userHistory for user '" + userIdentity + "', " + e.getMessage());
+        }
+        catch ( Exception e )
+        {
+            LOGGER.error( pwmRequest, "unexpected error reading userHistory for user '" + userIdentity + "', " + e.getMessage() );
         }
 
         {
-            final List<FormConfiguration> detailFormConfig = helpdeskProfile.readSettingAsForm(PwmSetting.HELPDESK_DETAIL_FORM);
-            final Map<FormConfiguration, List<String>> formData = FormUtility.populateFormMapFromLdap(detailFormConfig, pwmRequest.getPwmSession().getLabel(), userInfo);
+            final List<FormConfiguration> detailFormConfig = helpdeskProfile.readSettingAsForm( PwmSetting.HELPDESK_DETAIL_FORM );
+            final Map<FormConfiguration, List<String>> formData = FormUtility.populateFormMapFromLdap( detailFormConfig, pwmRequest.getPwmSession().getLabel(), userInfo );
             final List<DisplayElement> profileData = new ArrayList<>();
-            for (final Map.Entry<FormConfiguration, List<String>> entry : formData.entrySet()) {
+            for ( final Map.Entry<FormConfiguration, List<String>> entry : formData.entrySet() )
+            {
                 final FormConfiguration formConfiguration = entry.getKey();
-                if (formConfiguration.isMultivalue()) {
-                    profileData.add(new DisplayElement(
+                if ( formConfiguration.isMultivalue() )
+                {
+                    profileData.add( new DisplayElement(
                             formConfiguration.getName(),
                             DisplayElement.Type.multiString,
-                            formConfiguration.getLabel(actorLocale),
+                            formConfiguration.getLabel( actorLocale ),
                             entry.getValue()
-                    ));
-                } else {
-                    final String value = JavaHelper.isEmpty(entry.getValue())
+                    ) );
+                }
+                else
+                {
+                    final String value = JavaHelper.isEmpty( entry.getValue() )
                             ? ""
                             : entry.getValue().iterator().next();
-                    profileData.add(new DisplayElement(
+                    profileData.add( new DisplayElement(
                             formConfiguration.getName(),
                             DisplayElement.Type.string,
-                            formConfiguration.getLabel(actorLocale),
+                            formConfiguration.getLabel( actorLocale ),
                             value
-                    ));
+                    ) );
                 }
             }
             detailInfo.profileData = profileData;
         }
 
         {
-            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));
+            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));
+            detailInfo.setPasswordPolicyRules( Collections.unmodifiableMap( passwordRules ) );
         }
 
         {
@@ -201,58 +218,68 @@ public class HelpdeskDetailInfoBean implements Serializable {
                     pwmRequest.getLocale(),
                     macroMachine
             );
-            detailInfo.setPasswordRequirements(Collections.unmodifiableList(requirementLines));
+            detailInfo.setPasswordRequirements( Collections.unmodifiableList( requirementLines ) );
         }
 
-        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));
+        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 ) );
         }
 
-        if ((userInfo.getPasswordPolicy() != null)
-                && userInfo.getPasswordPolicy().getIdentifier() != null) {
-            detailInfo.setPasswordPolicyID(userInfo.getPasswordPolicy().getIdentifier());
-        } else {
-            detailInfo.setPasswordPolicyID(LocaleHelper.getLocalizedMessage(Display.Value_NotApplicable, pwmRequest));
+        if ( ( userInfo.getPasswordPolicy() != null )
+                && userInfo.getPasswordPolicy().getIdentifier() != null )
+        {
+            detailInfo.setPasswordPolicyID( userInfo.getPasswordPolicy().getIdentifier() );
+        }
+        else
+        {
+            detailInfo.setPasswordPolicyID( LocaleHelper.getLocalizedMessage( Display.Value_NotApplicable, pwmRequest ) );
         }
 
         {
             final ResponseInfoBean responseInfoBean = userInfo.getResponseInfoBean();
-            if (responseInfoBean != null && responseInfoBean.getHelpdeskCrMap() != null) {
+            if ( responseInfoBean != null && responseInfoBean.getHelpdeskCrMap() != null )
+            {
                 final List<DisplayElement> responseDisplay = new ArrayList<>();
                 int counter = 0;
-                for (final Map.Entry<Challenge, String> entry : responseInfoBean.getHelpdeskCrMap().entrySet()) {
+                for ( final Map.Entry<Challenge, String> entry : responseInfoBean.getHelpdeskCrMap().entrySet() )
+                {
                     counter++;
-                    responseDisplay.add(new DisplayElement(
+                    responseDisplay.add( new DisplayElement(
                             "item_" + counter,
                             DisplayElement.Type.string,
                             entry.getKey().getChallengeText(),
                             entry.getValue()
-                    ));
+                    ) );
                 }
                 detailInfo.helpdeskResponses = responseDisplay;
             }
 
         }
 
-        final String configuredDisplayName = helpdeskProfile.readSettingAsString(PwmSetting.HELPDESK_DETAIL_DISPLAY_NAME);
-        if (configuredDisplayName != null && !configuredDisplayName.isEmpty()) {
-            final String displayName = macroMachine.expandMacros(configuredDisplayName);
-            detailInfo.setUserDisplayName(displayName);
+        final String configuredDisplayName = helpdeskProfile.readSettingAsString( PwmSetting.HELPDESK_DETAIL_DISPLAY_NAME );
+        if ( configuredDisplayName != null && !configuredDisplayName.isEmpty() )
+        {
+            final String displayName = macroMachine.expandMacros( configuredDisplayName );
+            detailInfo.setUserDisplayName( displayName );
         }
 
-        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 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 Set<ViewStatusFields> viewStatusFields = helpdeskProfile.readSettingAsOptionList(PwmSetting.HELPDESK_VIEW_STATUS_VALUES, ViewStatusFields.class);
+            final Set<ViewStatusFields> viewStatusFields = helpdeskProfile.readSettingAsOptionList( PwmSetting.HELPDESK_VIEW_STATUS_VALUES, ViewStatusFields.class );
             detailInfo.statusData = ViewableUserInfoDisplayReader.makeDisplayData(
                     viewStatusFields,
                     pwmRequest.getConfig(),
@@ -262,9 +289,9 @@ public class HelpdeskDetailInfoBean implements Serializable {
             );
         }
 
-        detailInfo.setVisibleButtons(determineVisibleButtons(pwmRequest, helpdeskProfile));
-        detailInfo.setEnabledButtons(determineEnabledButtons(detailInfo.getVisibleButtons(), userInfo));
-        detailInfo.setCustomButtons(determineCustomButtons(helpdeskProfile));
+        detailInfo.setVisibleButtons( determineVisibleButtons( pwmRequest, helpdeskProfile ) );
+        detailInfo.setEnabledButtons( determineEnabledButtons( detailInfo.getVisibleButtons(), userInfo ) );
+        detailInfo.setCustomButtons( determineCustomButtons( helpdeskProfile ) );
 
         return detailInfo;
     }
@@ -276,40 +303,47 @@ public class HelpdeskDetailInfoBean implements Serializable {
     {
         final Set<StandardButton> buttons = new LinkedHashSet<>();
 
-        buttons.add(StandardButton.refresh);
-        buttons.add(StandardButton.back);
+        buttons.add( StandardButton.refresh );
+        buttons.add( StandardButton.back );
 
         {
             final HelpdeskUIMode uiMode =
-                    helpdeskProfile.readSettingAsEnum(PwmSetting.HELPDESK_SET_PASSWORD_MODE, HelpdeskUIMode.class);
-            if (uiMode != HelpdeskUIMode.none) {
-                buttons.add(StandardButton.changePassword);
+                    helpdeskProfile.readSettingAsEnum( PwmSetting.HELPDESK_SET_PASSWORD_MODE, HelpdeskUIMode.class );
+            if ( uiMode != HelpdeskUIMode.none )
+            {
+                buttons.add( StandardButton.changePassword );
             }
         }
 
-        if (helpdeskProfile.readSettingAsBoolean(PwmSetting.HELPDESK_ENABLE_UNLOCK)) {
-            buttons.add(StandardButton.unlock);
+        if ( helpdeskProfile.readSettingAsBoolean( PwmSetting.HELPDESK_ENABLE_UNLOCK ) )
+        {
+            buttons.add( StandardButton.unlock );
         }
 
-        if (helpdeskProfile.readSettingAsBoolean(PwmSetting.HELPDESK_CLEAR_RESPONSES_BUTTON)) {
-            buttons.add(StandardButton.clearResponses);
+        if ( helpdeskProfile.readSettingAsBoolean( PwmSetting.HELPDESK_CLEAR_RESPONSES_BUTTON ) )
+        {
+            buttons.add( StandardButton.clearResponses );
         }
 
-        if (pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.OTP_ENABLED)) {
-            if (helpdeskProfile.readSettingAsBoolean(PwmSetting.HELPDESK_CLEAR_OTP_BUTTON)) {
-                buttons.add(StandardButton.clearOtpSecret);
+        if ( pwmRequest.getConfig().readSettingAsBoolean( PwmSetting.OTP_ENABLED ) )
+        {
+            if ( helpdeskProfile.readSettingAsBoolean( PwmSetting.HELPDESK_CLEAR_OTP_BUTTON ) )
+            {
+                buttons.add( StandardButton.clearOtpSecret );
             }
         }
 
-        if (!helpdeskProfile.readOptionalVerificationMethods().isEmpty()) {
-            buttons.add(StandardButton.verification);
+        if ( !helpdeskProfile.readOptionalVerificationMethods().isEmpty() )
+        {
+            buttons.add( StandardButton.verification );
         }
 
-        if (helpdeskProfile.readSettingAsBoolean(PwmSetting.HELPDESK_DELETE_USER_BUTTON)) {
-            buttons.add(StandardButton.deleteUser);
+        if ( helpdeskProfile.readSettingAsBoolean( PwmSetting.HELPDESK_DELETE_USER_BUTTON ) )
+        {
+            buttons.add( StandardButton.deleteUser );
         }
 
-        return Collections.unmodifiableSet(buttons);
+        return Collections.unmodifiableSet( buttons );
     }
 
     static Set<StandardButton> determineEnabledButtons(
@@ -318,51 +352,59 @@ public class HelpdeskDetailInfoBean implements Serializable {
     )
             throws PwmUnrecoverableException
     {
-        final Set<StandardButton> buttons = new LinkedHashSet<>(visibleButtons);
+        final Set<StandardButton> buttons = new LinkedHashSet<>( visibleButtons );
 
-        if (buttons.contains(StandardButton.unlock)) {
+        if ( buttons.contains( StandardButton.unlock ) )
+        {
             final boolean enabled = userInfo.isPasswordLocked();
-            if (!enabled) {
-                buttons.remove(StandardButton.unlock);
+            if ( !enabled )
+            {
+                buttons.remove( StandardButton.unlock );
             }
         }
 
-        if (buttons.contains(StandardButton.clearResponses)) {
+        if ( buttons.contains( StandardButton.clearResponses ) )
+        {
             final boolean enabled = userInfo.getResponseInfoBean() != null;
-            if (!enabled) {
-                buttons.remove(StandardButton.clearResponses);
+            if ( !enabled )
+            {
+                buttons.remove( StandardButton.clearResponses );
             }
         }
 
-        if (buttons.contains(StandardButton.clearOtpSecret)) {
+        if ( buttons.contains( StandardButton.clearOtpSecret ) )
+        {
             final boolean enabled = userInfo.getOtpUserRecord() != null;
-            if (!enabled) {
-                buttons.remove(StandardButton.clearOtpSecret);
+            if ( !enabled )
+            {
+                buttons.remove( StandardButton.clearOtpSecret );
             }
         }
 
-        return Collections.unmodifiableSet(buttons);
+        return Collections.unmodifiableSet( buttons );
     }
 
     static List<ButtonInfo> determineCustomButtons(
             final HelpdeskProfile helpdeskProfile
     )
     {
-        final List<ActionConfiguration> actions = helpdeskProfile.readSettingAsAction(PwmSetting.HELPDESK_ACTIONS);
+        final List<ActionConfiguration> actions = helpdeskProfile.readSettingAsAction( PwmSetting.HELPDESK_ACTIONS );
 
         final List<ButtonInfo> buttons = new ArrayList<>();
-        if (actions != null) {
+        if ( actions != null )
+        {
             int count = 0;
-            for (final ActionConfiguration action : actions) {
-                buttons.add(new ButtonInfo(
+            for ( final ActionConfiguration action : actions )
+            {
+                buttons.add( new ButtonInfo(
                         "custom_" + count++,
                         action.getName(),
                         action.getDescription()
-                ));
+                ) );
             }
         }
 
-        return Collections.unmodifiableList(buttons);
+        return Collections.unmodifiableList( buttons );
 
     }
 

File diff suppressed because it is too large
+ 377 - 295
server/src/main/java/password/pwm/http/servlet/helpdesk/HelpdeskServlet.java


+ 328 - 245
server/src/main/java/password/pwm/http/servlet/newuser/NewUserUtils.java

@@ -86,27 +86,32 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 
-class NewUserUtils {
-    private static PwmLogger LOGGER = password.pwm.util.logging.PwmLogger.forClass(NewUserUtils.class);
+class NewUserUtils
+{
+    private static final PwmLogger LOGGER = password.pwm.util.logging.PwmLogger.forClass( NewUserUtils.class );
 
-    private NewUserUtils() {
+    private NewUserUtils( )
+    {
     }
 
 
-    static void passwordCheckInfoToException(final PasswordUtility.PasswordCheckInfo passwordCheckInfo)
+    static void passwordCheckInfoToException( final PasswordUtility.PasswordCheckInfo passwordCheckInfo )
             throws PwmOperationalException
     {
-        if (!passwordCheckInfo.isPassed()) {
-            final ErrorInformation errorInformation = PwmError.forErrorNumber(passwordCheckInfo.getErrorCode()).toInfo();
-            throw new PwmOperationalException(errorInformation);
+        if ( !passwordCheckInfo.isPassed() )
+        {
+            final ErrorInformation errorInformation = PwmError.forErrorNumber( passwordCheckInfo.getErrorCode() ).toInfo();
+            throw new PwmOperationalException( errorInformation );
         }
-        if (passwordCheckInfo.getMatch() != PasswordUtility.PasswordCheckInfo.MatchStatus.MATCH) {
+        if ( passwordCheckInfo.getMatch() != PasswordUtility.PasswordCheckInfo.MatchStatus.MATCH )
+        {
             final ErrorInformation errorInformation = PwmError.PASSWORD_DOESNOTMATCH.toInfo();
-            throw new PwmOperationalException(errorInformation);
+            throw new PwmOperationalException( errorInformation );
         }
 
     }
 
+    @SuppressWarnings( "checkstyle:MethodLength" )
     static void createUser(
             final NewUserForm newUserForm,
             final PwmRequest pwmRequest,
@@ -126,172 +131,207 @@ class NewUserUtils {
                     newUserForm,
                     false
             );
-            passwordCheckInfoToException(passwordCheckInfo);
+            passwordCheckInfoToException( passwordCheckInfo );
         }
 
-        NewUserUtils.LOGGER.debug(pwmSession, "beginning createUser process for " + newUserDN);
+        NewUserUtils.LOGGER.debug( pwmSession, "beginning createUser process for " + newUserDN );
 
-        final NewUserProfile newUserProfile = NewUserServlet.getNewUserProfile(pwmRequest);
-        final boolean promptForPassword = newUserProfile.readSettingAsBoolean(PwmSetting.NEWUSER_PROMPT_FOR_PASSWORD);
+        final NewUserProfile newUserProfile = NewUserServlet.getNewUserProfile( pwmRequest );
+        final boolean promptForPassword = newUserProfile.readSettingAsBoolean( PwmSetting.NEWUSER_PROMPT_FOR_PASSWORD );
 
         final PasswordData userPassword;
-        if (promptForPassword) {
+        if ( promptForPassword )
+        {
             userPassword = newUserForm.getNewUserPassword();
-        } else {
-            final PwmPasswordPolicy pwmPasswordPolicy = newUserProfile.getNewUserPasswordPolicy(pwmRequest.getPwmApplication(), pwmRequest.getLocale());
-            userPassword = RandomPasswordGenerator.createRandomPassword(pwmRequest.getSessionLabel(), pwmPasswordPolicy, pwmRequest.getPwmApplication());
+        }
+        else
+        {
+            final PwmPasswordPolicy pwmPasswordPolicy = newUserProfile.getNewUserPasswordPolicy( pwmRequest.getPwmApplication(), pwmRequest.getLocale() );
+            userPassword = RandomPasswordGenerator.createRandomPassword( pwmRequest.getSessionLabel(), pwmPasswordPolicy, pwmRequest.getPwmApplication() );
         }
 
         // set up the user creation attributes
-        final Map<String, String> createAttributes = NewUserFormUtils.getLdapDataFromNewUserForm(NewUserServlet.getNewUserProfile(pwmRequest), newUserForm);
+        final Map<String, String> createAttributes = NewUserFormUtils.getLdapDataFromNewUserForm( NewUserServlet.getNewUserProfile( pwmRequest ), newUserForm );
 
         // read the creation object classes from configuration
         final Set<String> createObjectClasses = new LinkedHashSet<>(
-                pwmApplication.getConfig().readSettingAsStringArray(PwmSetting.DEFAULT_OBJECT_CLASSES));
+                pwmApplication.getConfig().readSettingAsStringArray( PwmSetting.DEFAULT_OBJECT_CLASSES ) );
 
         // add the auto-add object classes
         {
             final LdapProfile defaultLDAPProfile = pwmApplication.getConfig().getDefaultLdapProfile();
-            createObjectClasses.addAll(defaultLDAPProfile.readSettingAsStringArray(PwmSetting.AUTO_ADD_OBJECT_CLASSES));
+            createObjectClasses.addAll( defaultLDAPProfile.readSettingAsStringArray( PwmSetting.AUTO_ADD_OBJECT_CLASSES ) );
         }
 
-        final ChaiProvider chaiProvider = pwmApplication.getConfig().getDefaultLdapProfile().getProxyChaiProvider(pwmApplication);
-        try { // create the ldap entry
-            chaiProvider.createEntry(newUserDN, createObjectClasses, createAttributes);
+        final ChaiProvider chaiProvider = pwmApplication.getConfig().getDefaultLdapProfile().getProxyChaiProvider( pwmApplication );
+        try
+        {
+            // create the ldap entry
+            chaiProvider.createEntry( newUserDN, createObjectClasses, createAttributes );
 
-            NewUserUtils.LOGGER.info(pwmSession, "created user entry: " + newUserDN);
-        } catch (ChaiOperationException e) {
+            NewUserUtils.LOGGER.info( pwmSession, "created user entry: " + newUserDN );
+        }
+        catch ( ChaiOperationException e )
+        {
             final String userMessage = "unexpected ldap error creating user entry: " + e.getMessage();
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_NEW_USER_FAILURE,
-                    userMessage);
-            throw new PwmOperationalException(errorInformation);
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_NEW_USER_FAILURE,
+                    userMessage );
+            throw new PwmOperationalException( errorInformation );
         }
 
-        final ChaiUser theUser = chaiProvider.getEntryFactory().newChaiUser(newUserDN);
+        final ChaiUser theUser = chaiProvider.getEntryFactory().newChaiUser( newUserDN );
 
         final boolean useTempPw;
         {
-            final String settingValue = pwmApplication.getConfig().readAppProperty(AppProperty.NEWUSER_LDAP_USE_TEMP_PW);
-            if ("auto".equalsIgnoreCase(settingValue)) {
+            final String settingValue = pwmApplication.getConfig().readAppProperty( AppProperty.NEWUSER_LDAP_USE_TEMP_PW );
+            if ( "auto".equalsIgnoreCase( settingValue ) )
+            {
                 useTempPw = chaiProvider.getDirectoryVendor() == DirectoryVendor.ACTIVE_DIRECTORY;
-            } else {
-                useTempPw = Boolean.parseBoolean(settingValue);
+            }
+            else
+            {
+                useTempPw = Boolean.parseBoolean( settingValue );
             }
         }
 
-        if (useTempPw) {
-            NewUserUtils.LOGGER.trace(pwmSession, "will use temporary password process for new user entry: " + newUserDN);
+        if ( useTempPw )
+        {
+            NewUserUtils.LOGGER.trace( pwmSession, "will use temporary password process for new user entry: " + newUserDN );
             final PasswordData temporaryPassword;
             {
                 final RandomPasswordGenerator.RandomGeneratorConfig randomGeneratorConfig = RandomPasswordGenerator.RandomGeneratorConfig.builder()
-                        .passwordPolicy(newUserProfile.getNewUserPasswordPolicy(pwmApplication, pwmRequest.getLocale()))
+                        .passwordPolicy( newUserProfile.getNewUserPasswordPolicy( pwmApplication, pwmRequest.getLocale() ) )
                         .build();
-                temporaryPassword = RandomPasswordGenerator.createRandomPassword(pwmSession.getLabel(), randomGeneratorConfig, pwmApplication);
+                temporaryPassword = RandomPasswordGenerator.createRandomPassword( pwmSession.getLabel(), randomGeneratorConfig, pwmApplication );
+            }
+            final ChaiUser proxiedUser = chaiProvider.getEntryFactory().newChaiUser( newUserDN );
+            try
+            {
+                //set password as admin
+                proxiedUser.setPassword( temporaryPassword.getStringValue() );
+                NewUserUtils.LOGGER.debug( pwmSession, "set temporary password for new user entry: " + newUserDN );
             }
-            final ChaiUser proxiedUser = chaiProvider.getEntryFactory().newChaiUser(newUserDN);
-            try { //set password as admin
-                proxiedUser.setPassword(temporaryPassword.getStringValue());
-                NewUserUtils.LOGGER.debug(pwmSession, "set temporary password for new user entry: " + newUserDN);
-            } catch (ChaiOperationException e) {
+            catch ( ChaiOperationException e )
+            {
                 final String userMessage = "unexpected ldap error setting temporary password for new user entry: " + e.getMessage();
-                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_NEW_USER_FAILURE,
-                        userMessage);
-                throw new PwmOperationalException(errorInformation);
+                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_NEW_USER_FAILURE,
+                        userMessage );
+                throw new PwmOperationalException( errorInformation );
             }
 
             // add AD-specific attributes
-            if (DirectoryVendor.ACTIVE_DIRECTORY == chaiProvider.getDirectoryVendor()) {
-                try {
-                    NewUserUtils.LOGGER.debug(pwmSession,
-                            "setting userAccountControl attribute to enable account " + theUser.getEntryDN());
-                    theUser.writeStringAttribute("userAccountControl", "512");
-                } catch (ChaiOperationException e) {
+            if ( DirectoryVendor.ACTIVE_DIRECTORY == chaiProvider.getDirectoryVendor() )
+            {
+                try
+                {
+                    NewUserUtils.LOGGER.debug( pwmSession,
+                            "setting userAccountControl attribute to enable account " + theUser.getEntryDN() );
+                    theUser.writeStringAttribute( "userAccountControl", "512" );
+                }
+                catch ( ChaiOperationException e )
+                {
                     final String errorMsg = "error enabling AD account when writing userAccountControl attribute: " + e.getMessage();
-                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_NEW_USER_FAILURE,
-                            errorMsg);
-                    throw new PwmOperationalException(errorInformation);
+                    final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_NEW_USER_FAILURE,
+                            errorMsg );
+                    throw new PwmOperationalException( errorInformation );
                 }
             }
 
-            try { // bind as user
-                NewUserUtils.LOGGER.debug(pwmSession,
-                        "attempting bind as user to then allow changing to requested password for new user entry: " + newUserDN);
-                final ChaiConfiguration chaiConfiguration = ChaiConfiguration.builder(chaiProvider.getChaiConfiguration())
-                        .setSetting(ChaiSetting.BIND_DN, newUserDN)
-                        .setSetting(ChaiSetting.BIND_PASSWORD, temporaryPassword.getStringValue())
+            try
+            {
+                // bind as user
+                NewUserUtils.LOGGER.debug( pwmSession,
+                        "attempting bind as user to then allow changing to requested password for new user entry: " + newUserDN );
+                final ChaiConfiguration chaiConfiguration = ChaiConfiguration.builder( chaiProvider.getChaiConfiguration() )
+                        .setSetting( ChaiSetting.BIND_DN, newUserDN )
+                        .setSetting( ChaiSetting.BIND_PASSWORD, temporaryPassword.getStringValue() )
                         .build();
-                final ChaiProvider bindAsProvider = pwmApplication.getLdapConnectionService().getChaiProviderFactory().newProvider(chaiConfiguration);
-                final ChaiUser bindAsUser = bindAsProvider.getEntryFactory().newChaiUser(newUserDN);
-                bindAsUser.changePassword(temporaryPassword.getStringValue(), userPassword.getStringValue());
-                NewUserUtils.LOGGER.debug(pwmSession, "changed to user requested password for new user entry: " + newUserDN);
+                final ChaiProvider bindAsProvider = pwmApplication.getLdapConnectionService().getChaiProviderFactory().newProvider( chaiConfiguration );
+                final ChaiUser bindAsUser = bindAsProvider.getEntryFactory().newChaiUser( newUserDN );
+                bindAsUser.changePassword( temporaryPassword.getStringValue(), userPassword.getStringValue() );
+                NewUserUtils.LOGGER.debug( pwmSession, "changed to user requested password for new user entry: " + newUserDN );
                 bindAsProvider.close();
-            } catch (ChaiOperationException e) {
+            }
+            catch ( ChaiOperationException e )
+            {
                 final String userMessage = "unexpected ldap error setting user password for new user entry: " + e.getMessage();
-                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_NEW_USER_FAILURE,
-                        userMessage);
-                throw new PwmOperationalException(errorInformation);
+                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_NEW_USER_FAILURE,
+                        userMessage );
+                throw new PwmOperationalException( errorInformation );
+            }
+        }
+        else
+        {
+            try
+            {
+                //set password
+                theUser.setPassword( userPassword.getStringValue() );
+                NewUserUtils.LOGGER.debug( pwmSession, "set user requested password for new user entry: " + newUserDN );
             }
-        } else {
-            try { //set password
-                theUser.setPassword(userPassword.getStringValue());
-                NewUserUtils.LOGGER.debug(pwmSession, "set user requested password for new user entry: " + newUserDN);
-            } catch (ChaiOperationException e) {
+            catch ( ChaiOperationException e )
+            {
                 final String userMessage = "unexpected ldap error setting password for new user entry: " + e.getMessage();
-                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_NEW_USER_FAILURE,
-                        userMessage);
-                throw new PwmOperationalException(errorInformation);
+                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_NEW_USER_FAILURE,
+                        userMessage );
+                throw new PwmOperationalException( errorInformation );
             }
 
             // add AD-specific attributes
-            if (DirectoryVendor.ACTIVE_DIRECTORY == chaiProvider.getDirectoryVendor()) {
-                try {
-                    theUser.writeStringAttribute("userAccountControl", "512");
-                } catch (ChaiOperationException e) {
+            if ( DirectoryVendor.ACTIVE_DIRECTORY == chaiProvider.getDirectoryVendor() )
+            {
+                try
+                {
+                    theUser.writeStringAttribute( "userAccountControl", "512" );
+                }
+                catch ( ChaiOperationException e )
+                {
                     final String errorMsg = "error enabling AD account when writing userAccountControl attribute: " + e.getMessage();
-                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_NEW_USER_FAILURE,
-                            errorMsg);
-                    throw new PwmOperationalException(errorInformation);
+                    final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_NEW_USER_FAILURE,
+                            errorMsg );
+                    throw new PwmOperationalException( errorInformation );
                 }
             }
         }
 
-        NewUserUtils.LOGGER.trace(pwmSession, "new user ldap creation process complete, now authenticating user");
+        NewUserUtils.LOGGER.trace( pwmSession, "new user ldap creation process complete, now authenticating user" );
 
         // write data to remote web service
-        remoteWriteFormData(pwmRequest, newUserForm);
+        remoteWriteFormData( pwmRequest, newUserForm );
 
-        //authenticate the user to pwm
-        final UserIdentity userIdentity = new UserIdentity(newUserDN, pwmApplication.getConfig().getDefaultLdapProfile().getIdentifier());
-        final SessionAuthenticator sessionAuthenticator = new SessionAuthenticator(pwmApplication, pwmSession, PwmAuthenticationSource.NEW_USER_REGISTRATION);
-        sessionAuthenticator.authenticateUser(userIdentity, userPassword);
+        // authenticate the user to pwm
+        final UserIdentity userIdentity = new UserIdentity( newUserDN, pwmApplication.getConfig().getDefaultLdapProfile().getIdentifier() );
+        final SessionAuthenticator sessionAuthenticator = new SessionAuthenticator( pwmApplication, pwmSession, PwmAuthenticationSource.NEW_USER_REGISTRATION );
+        sessionAuthenticator.authenticateUser( userIdentity, userPassword );
 
-        {  // execute configured actions
+        {
+            // execute configured actions
             final List<ActionConfiguration> actions = newUserProfile.readSettingAsAction(
-                    PwmSetting.NEWUSER_WRITE_ATTRIBUTES);
-            if (actions != null && !actions.isEmpty()) {
-                NewUserUtils.LOGGER.debug(pwmSession, "executing configured actions to user " + theUser.getEntryDN());
+                    PwmSetting.NEWUSER_WRITE_ATTRIBUTES );
+            if ( actions != null && !actions.isEmpty() )
+            {
+                NewUserUtils.LOGGER.debug( pwmSession, "executing configured actions to user " + theUser.getEntryDN() );
 
-                final ActionExecutor actionExecutor = new ActionExecutor.ActionExecutorSettings(pwmApplication, userIdentity)
-                        .setExpandPwmMacros(true)
-                        .setMacroMachine(pwmSession.getSessionManager().getMacroMachine(pwmApplication))
+                final ActionExecutor actionExecutor = new ActionExecutor.ActionExecutorSettings( pwmApplication, userIdentity )
+                        .setExpandPwmMacros( true )
+                        .setMacroMachine( pwmSession.getSessionManager().getMacroMachine( pwmApplication ) )
                         .createActionExecutor();
 
-                actionExecutor.executeActions(actions, pwmSession.getLabel());
+                actionExecutor.executeActions( actions, pwmSession.getLabel() );
             }
         }
 
         // send user email
-        sendNewUserEmailConfirmation(pwmRequest);
+        sendNewUserEmailConfirmation( pwmRequest );
 
 
         // add audit record
-        pwmApplication.getAuditManager().submit(AuditEvent.CREATE_USER, pwmSession.getUserInfo(), pwmSession);
+        pwmApplication.getAuditManager().submit( AuditEvent.CREATE_USER, pwmSession.getUserInfo(), pwmSession );
 
         // increment the new user creation statistics
-        pwmApplication.getStatisticsManager().incrementValue(Statistic.NEW_USERS);
+        pwmApplication.getStatisticsManager().incrementValue( Statistic.NEW_USERS );
 
-        NewUserUtils.LOGGER.debug(pwmSession, "completed createUser process for " + newUserDN + " (" + TimeDuration.fromCurrent(
-                startTime).asCompactString() + ")");
+        NewUserUtils.LOGGER.debug( pwmSession, "completed createUser process for " + newUserDN + " (" + TimeDuration.fromCurrent(
+                startTime ).asCompactString() + ")" );
     }
 
     static void deleteUserAccount(
@@ -300,15 +340,18 @@ class NewUserUtils {
     )
             throws PwmUnrecoverableException
     {
-        try {
-            NewUserUtils.LOGGER.warn(pwmRequest, "deleting ldap user account " + userDN);
-            pwmRequest.getConfig().getDefaultLdapProfile().getProxyChaiProvider(pwmRequest.getPwmApplication()).deleteEntry(userDN);
-            NewUserUtils.LOGGER.warn(pwmRequest, "ldap user account " + userDN + " has been deleted");
-        } catch (ChaiUnavailableException | ChaiOperationException e) {
-            NewUserUtils.LOGGER.error(pwmRequest, "error deleting ldap user account " + userDN + ", " + e.getMessage());
+        try
+        {
+            NewUserUtils.LOGGER.warn( pwmRequest, "deleting ldap user account " + userDN );
+            pwmRequest.getConfig().getDefaultLdapProfile().getProxyChaiProvider( pwmRequest.getPwmApplication() ).deleteEntry( userDN );
+            NewUserUtils.LOGGER.warn( pwmRequest, "ldap user account " + userDN + " has been deleted" );
+        }
+        catch ( ChaiUnavailableException | ChaiOperationException e )
+        {
+            NewUserUtils.LOGGER.error( pwmRequest, "error deleting ldap user account " + userDN + ", " + e.getMessage() );
         }
 
-        pwmRequest.getPwmSession().unauthenticateUser(pwmRequest);
+        pwmRequest.getPwmSession().unauthenticateUser( pwmRequest );
     }
 
     static String determineUserDN(
@@ -317,63 +360,71 @@ class NewUserUtils {
     )
             throws PwmUnrecoverableException, ChaiUnavailableException
     {
-        final MacroMachine macroMachine = createMacroMachineForNewUser(pwmRequest.getPwmApplication(), pwmRequest.getSessionLabel(), formValues);
-        final NewUserProfile newUserProfile = NewUserServlet.getNewUserProfile(pwmRequest);
-        final List<String> configuredNames = newUserProfile.readSettingAsStringArray(PwmSetting.NEWUSER_USERNAME_DEFINITION);
+        final MacroMachine macroMachine = createMacroMachineForNewUser( pwmRequest.getPwmApplication(), pwmRequest.getSessionLabel(), formValues );
+        final NewUserProfile newUserProfile = NewUserServlet.getNewUserProfile( pwmRequest );
+        final List<String> configuredNames = newUserProfile.readSettingAsStringArray( PwmSetting.NEWUSER_USERNAME_DEFINITION );
         final List<String> failedValues = new ArrayList<>();
 
-        final String configuredContext = newUserProfile.readSettingAsString(PwmSetting.NEWUSER_CONTEXT);
-        final String expandedContext = macroMachine.expandMacros(configuredContext);
+        final String configuredContext = newUserProfile.readSettingAsString( PwmSetting.NEWUSER_CONTEXT );
+        final String expandedContext = macroMachine.expandMacros( configuredContext );
 
 
-        if (configuredNames == null || configuredNames.isEmpty() || configuredNames.iterator().next().isEmpty()) {
-            final String namingAttribute = pwmRequest.getConfig().getDefaultLdapProfile().readSettingAsString(PwmSetting.LDAP_NAMING_ATTRIBUTE);
+        if ( configuredNames == null || configuredNames.isEmpty() || configuredNames.iterator().next().isEmpty() )
+        {
+            final String namingAttribute = pwmRequest.getConfig().getDefaultLdapProfile().readSettingAsString( PwmSetting.LDAP_NAMING_ATTRIBUTE );
             String namingValue = null;
-            for (final String formKey : formValues.getFormData().keySet()) {
-                if (formKey.equals(namingAttribute)) {
-                    namingValue = formValues.getFormData().get(formKey);
+            for ( final String formKey : formValues.getFormData().keySet() )
+            {
+                if ( formKey.equals( namingAttribute ) )
+                {
+                    namingValue = formValues.getFormData().get( formKey );
                 }
             }
-            if (namingValue == null || namingValue.isEmpty()) {
-                throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_NEW_USER_FAILURE,
-                        "username definition not set, and naming attribute is not present in form"));
+            if ( namingValue == null || namingValue.isEmpty() )
+            {
+                throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_NEW_USER_FAILURE,
+                        "username definition not set, and naming attribute is not present in form" ) );
             }
-            final String escapedName = StringUtil.escapeLdapDN(namingValue);
+            final String escapedName = StringUtil.escapeLdapDN( namingValue );
             final String generatedDN = namingAttribute + "=" + escapedName + "," + expandedContext;
-            NewUserUtils.LOGGER.debug(pwmRequest, "generated dn for new user: " + generatedDN);
+            NewUserUtils.LOGGER.debug( pwmRequest, "generated dn for new user: " + generatedDN );
             return generatedDN;
         }
 
         int attemptCount = 0;
         final String generatedDN;
-        while (attemptCount < configuredNames.size()) {
+        while ( attemptCount < configuredNames.size() )
+        {
             final String expandedName;
             {
                 {
-                    final String configuredName = configuredNames.get(attemptCount);
-                    expandedName = macroMachine.expandMacros(configuredName);
+                    final String configuredName = configuredNames.get( attemptCount );
+                    expandedName = macroMachine.expandMacros( configuredName );
                 }
 
-                if (!testIfEntryNameExists(pwmRequest, expandedName)) {
-                    NewUserUtils.LOGGER.trace(pwmRequest, "generated entry name for new user is unique: " + expandedName);
-                    final String namingAttribute = pwmRequest.getConfig().getDefaultLdapProfile().readSettingAsString(PwmSetting.LDAP_NAMING_ATTRIBUTE);
-                    final String escapedName = StringUtil.escapeLdapDN(expandedName);
+                if ( !testIfEntryNameExists( pwmRequest, expandedName ) )
+                {
+                    NewUserUtils.LOGGER.trace( pwmRequest, "generated entry name for new user is unique: " + expandedName );
+                    final String namingAttribute = pwmRequest.getConfig().getDefaultLdapProfile().readSettingAsString( PwmSetting.LDAP_NAMING_ATTRIBUTE );
+                    final String escapedName = StringUtil.escapeLdapDN( expandedName );
                     generatedDN = namingAttribute + "=" + escapedName + "," + expandedContext;
-                    NewUserUtils.LOGGER.debug(pwmRequest, "generated dn for new user: " + generatedDN);
+                    NewUserUtils.LOGGER.debug( pwmRequest, "generated dn for new user: " + generatedDN );
                     return generatedDN;
-                } else {
-                    failedValues.add(expandedName);
+                }
+                else
+                {
+                    failedValues.add( expandedName );
                 }
             }
 
-            NewUserUtils.LOGGER.debug(pwmRequest, "generated entry name for new user is not unique, will try again");
+            NewUserUtils.LOGGER.debug( pwmRequest, "generated entry name for new user is not unique, will try again" );
             attemptCount++;
         }
-        NewUserUtils.LOGGER.error(pwmRequest,
+        NewUserUtils.LOGGER.error( pwmRequest,
                 "failed to generate new user DN after " + attemptCount + " attempts, failed values: " + JsonUtil.serializeCollection(
-                        failedValues));
-        throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_NEW_USER_FAILURE,
-                "unable to generate a unique DN value"));
+                        failedValues ) );
+        throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_NEW_USER_FAILURE,
+                "unable to generate a unique DN value" ) );
     }
 
     private static boolean testIfEntryNameExists(
@@ -384,17 +435,20 @@ class NewUserUtils {
     {
         final UserSearchEngine userSearchEngine = pwmRequest.getPwmApplication().getUserSearchEngine();
         final SearchConfiguration searchConfiguration = SearchConfiguration.builder()
-                .username(rdnValue)
+                .username( rdnValue )
                 .build();
 
-        try {
+        try
+        {
             final Map<UserIdentity, Map<String, String>> results = userSearchEngine.performMultiUserSearch(
-                    searchConfiguration, 2, Collections.emptyList(), pwmRequest.getSessionLabel());
+                    searchConfiguration, 2, Collections.emptyList(), pwmRequest.getSessionLabel() );
             return results != null && !results.isEmpty();
-        } catch (PwmOperationalException e) {
+        }
+        catch ( PwmOperationalException e )
+        {
             final String msg = "ldap error while searching for duplicate entry names: " + e.getMessage();
-            NewUserUtils.LOGGER.error(pwmRequest, msg);
-            throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_NEW_USER_FAILURE, msg));
+            NewUserUtils.LOGGER.error( pwmRequest, msg );
+            throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_NEW_USER_FAILURE, msg ) );
         }
     }
 
@@ -407,18 +461,19 @@ class NewUserUtils {
         final UserInfo userInfo = pwmSession.getUserInfo();
         final Configuration config = pwmRequest.getConfig();
         final Locale locale = pwmSession.getSessionStateBean().getLocale();
-        final EmailItemBean configuredEmailSetting = config.readSettingAsEmail(PwmSetting.EMAIL_NEWUSER, locale);
+        final EmailItemBean configuredEmailSetting = config.readSettingAsEmail( PwmSetting.EMAIL_NEWUSER, locale );
 
-        if (configuredEmailSetting == null) {
-            NewUserUtils.LOGGER.debug(pwmSession,
-                    "skipping send of new user email for '" + userInfo.getUserIdentity().getUserDN() + "' no email configured");
+        if ( configuredEmailSetting == null )
+        {
+            NewUserUtils.LOGGER.debug( pwmSession,
+                    "skipping send of new user email for '" + userInfo.getUserIdentity().getUserDN() + "' no email configured" );
             return;
         }
 
         pwmRequest.getPwmApplication().getEmailQueue().submitEmail(
                 configuredEmailSetting,
                 pwmSession.getUserInfo(),
-                pwmSession.getSessionManager().getMacroMachine(pwmRequest.getPwmApplication())
+                pwmSession.getSessionManager().getMacroMachine( pwmRequest.getPwmApplication() )
         );
     }
 
@@ -432,22 +487,23 @@ class NewUserUtils {
         final Map<String, String> formValues = newUserForm.getFormData();
 
         final String emailAddressAttribute = pwmApplication.getConfig().getDefaultLdapProfile().readSettingAsString(
-                PwmSetting.EMAIL_USER_MAIL_ATTRIBUTE);
+                PwmSetting.EMAIL_USER_MAIL_ATTRIBUTE );
 
-        final String usernameAttribute = pwmApplication.getConfig().getDefaultLdapProfile().readSettingAsString(PwmSetting.LDAP_USERNAME_ATTRIBUTE);
+        final String usernameAttribute = pwmApplication.getConfig().getDefaultLdapProfile().readSettingAsString( PwmSetting.LDAP_USERNAME_ATTRIBUTE );
 
         final LoginInfoBean stubLoginBean = new LoginInfoBean();
-        stubLoginBean.setUserCurrentPassword(newUserForm.getNewUserPassword());
+        stubLoginBean.setUserCurrentPassword( newUserForm.getNewUserPassword() );
 
         final UserInfoBean stubUserBean = UserInfoBean.builder()
-                .userEmailAddress(formValues.get(emailAddressAttribute))
-                .username(formValues.get(usernameAttribute))
-                .attributes(formValues)
+                .userEmailAddress( formValues.get( emailAddressAttribute ) )
+                .username( formValues.get( usernameAttribute ) )
+                .attributes( formValues )
                 .build();
 
-        return new MacroMachine(pwmApplication, sessionLabel, stubUserBean, stubLoginBean);
+        return new MacroMachine( pwmApplication, sessionLabel, stubUserBean, stubLoginBean );
     }
 
+    @SuppressWarnings( "checkstyle:MethodLength" )
     static void initializeToken(
             final PwmRequest pwmRequest,
             final NewUserBean newUserBean,
@@ -458,130 +514,147 @@ class NewUserUtils {
         final PwmSession pwmSession = pwmRequest.getPwmSession();
         final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
 
-        if (pwmApplication.getConfig().getTokenStorageMethod() == TokenStorageMethod.STORE_LDAP) {
-            throw new PwmUnrecoverableException(new ErrorInformation(PwmError.CONFIG_FORMAT_ERROR,null,new String[]{
+        if ( pwmApplication.getConfig().getTokenStorageMethod() == TokenStorageMethod.STORE_LDAP )
+        {
+            throw new PwmUnrecoverableException( new ErrorInformation( PwmError.CONFIG_FORMAT_ERROR, null, new String[] {
                     "cannot generate new user tokens when storage type is configured as STORE_LDAP.",
-            }));
+            } ) );
         }
 
-        final NewUserProfile newUserProfile = NewUserServlet.getNewUserProfile(pwmRequest);
+        final NewUserProfile newUserProfile = NewUserServlet.getNewUserProfile( pwmRequest );
         final Configuration config = pwmApplication.getConfig();
-        final Map<String, String> tokenPayloadMap = NewUserFormUtils.toTokenPayload(pwmRequest, newUserBean);
-        final MacroMachine macroMachine = createMacroMachineForNewUser(pwmApplication, pwmRequest.getSessionLabel(), newUserBean.getNewUserForm());
+        final Map<String, String> tokenPayloadMap = NewUserFormUtils.toTokenPayload( pwmRequest, newUserBean );
+        final MacroMachine macroMachine = createMacroMachineForNewUser( pwmApplication, pwmRequest.getSessionLabel(), newUserBean.getNewUserForm() );
 
-        switch (tokenType) {
-            case SMS: {
+        switch ( tokenType )
+        {
+            case SMS:
+            {
                 String toNum = null;
                 final NewUserForm userForm = newUserBean.getNewUserForm();
-                if(userForm!=null && userForm.getFormData() != null && userForm.getFormData().get(pwmApplication.getConfig().getDefaultLdapProfile().readSettingAsString(PwmSetting.SMS_USER_PHONE_ATTRIBUTE))!=null)
+                if ( userForm != null
+                        && userForm.getFormData() != null
+                        && userForm.getFormData().get( pwmApplication.getConfig().getDefaultLdapProfile().readSettingAsString( PwmSetting.SMS_USER_PHONE_ATTRIBUTE ) ) != null
+                        )
                 {
-                    toNum = userForm.getFormData().get(pwmApplication.getConfig().getDefaultLdapProfile().readSettingAsString(PwmSetting.SMS_USER_PHONE_ATTRIBUTE));    
-                    if(toNum.isEmpty())
+                    toNum = userForm.getFormData().get( pwmApplication.getConfig().getDefaultLdapProfile().readSettingAsString( PwmSetting.SMS_USER_PHONE_ATTRIBUTE ) );
+                    if ( toNum.isEmpty() )
                     {
-                        toNum=null;
+                        toNum = null;
                     }
                 }
-                
+
                 final RestTokenDataClient.TokenDestinationData inputTokenDestData = new RestTokenDataClient.TokenDestinationData(
-                        null, toNum, null);
-                final RestTokenDataClient restTokenDataClient = new RestTokenDataClient(pwmApplication);
+                        null, toNum, null );
+                final RestTokenDataClient restTokenDataClient = new RestTokenDataClient( pwmApplication );
                 final RestTokenDataClient.TokenDestinationData outputDestTokenData = restTokenDataClient.figureDestTokenDisplayString(
                         pwmRequest.getSessionLabel(),
                         inputTokenDestData,
                         null,
-                        pwmRequest.getLocale());
-                if(outputDestTokenData == null || outputDestTokenData.getSms() == null || outputDestTokenData.getSms().isEmpty())
+                        pwmRequest.getLocale() );
+                if ( outputDestTokenData == null || outputDestTokenData.getSms() == null || outputDestTokenData.getSms().isEmpty() )
                 {
                     //avoid sending SMS code token
                     break;
                 }
                 final String tokenKey;
-                try {
+                try
+                {
                     final TokenPayload tokenPayload = pwmApplication.getTokenService().createTokenPayload(
                             password.pwm.svc.token.TokenType.NEWUSER_SMS,
-                            newUserProfile.getTokenDurationSMS(config),
+                            newUserProfile.getTokenDurationSMS( config ),
                             tokenPayloadMap,
                             null,
-                            Collections.singleton(outputDestTokenData.getSms())
+                            Collections.singleton( outputDestTokenData.getSms() )
                     );
-                    tokenKey = pwmApplication.getTokenService().generateNewToken(tokenPayload,
-                            pwmRequest.getSessionLabel());
-                } catch (PwmOperationalException e) {
-                    throw new PwmUnrecoverableException(e.getErrorInformation());
+                    tokenKey = pwmApplication.getTokenService().generateNewToken( tokenPayload,
+                            pwmRequest.getSessionLabel() );
+                }
+                catch ( PwmOperationalException e )
+                {
+                    throw new PwmUnrecoverableException( e.getErrorInformation() );
                 }
 
-                final String message = config.readSettingAsLocalizedString(PwmSetting.SMS_NEWUSER_TOKEN_TEXT,
-                        pwmSession.getSessionStateBean().getLocale());
+                final String message = config.readSettingAsLocalizedString( PwmSetting.SMS_NEWUSER_TOKEN_TEXT,
+                        pwmSession.getSessionStateBean().getLocale() );
 
-                try {
+                try
+                {
                     TokenService.TokenSender.sendSmsToken(
                             TokenService.TokenSendInfo.builder()
-                            .pwmApplication( pwmApplication )
-                            .userInfo( null )
-                            .macroMachine( macroMachine )
-                            .smsNumber( outputDestTokenData.getSms() )
-                            .smsMessage( message )
-                            .tokenKey( tokenKey )
-                            .sessionLabel( pwmRequest.getSessionLabel() )
-                            .build()
+                                    .pwmApplication( pwmApplication )
+                                    .userInfo( null )
+                                    .macroMachine( macroMachine )
+                                    .smsNumber( outputDestTokenData.getSms() )
+                                    .smsMessage( message )
+                                    .tokenKey( tokenKey )
+                                    .sessionLabel( pwmRequest.getSessionLabel() )
+                                    .build()
                     );
-                } catch (Exception e) {
-                    throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_UNKNOWN));
+                }
+                catch ( Exception e )
+                {
+                    throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_UNKNOWN ) );
                 }
 
-                newUserBean.getTokenVerificationProgress().getIssuedTokens().add(TokenVerificationProgress.TokenChannel.SMS);
-                final ValueObfuscator valueObfuscator = new ValueObfuscator(pwmApplication.getConfig());
-                newUserBean.getTokenVerificationProgress().setTokenDisplayText(valueObfuscator.maskPhone(toNum));
-                newUserBean.getTokenVerificationProgress().setPhase(TokenVerificationProgress.TokenChannel.SMS);
+                newUserBean.getTokenVerificationProgress().getIssuedTokens().add( TokenVerificationProgress.TokenChannel.SMS );
+                final ValueObfuscator valueObfuscator = new ValueObfuscator( pwmApplication.getConfig() );
+                newUserBean.getTokenVerificationProgress().setTokenDisplayText( valueObfuscator.maskPhone( toNum ) );
+                newUserBean.getTokenVerificationProgress().setPhase( TokenVerificationProgress.TokenChannel.SMS );
             }
             break;
 
-            case EMAIL: {
+            case EMAIL:
+            {
                 final EmailItemBean configuredEmailSetting = config.readSettingAsEmail(
-                        PwmSetting.EMAIL_NEWUSER_VERIFICATION, pwmSession.getSessionStateBean().getLocale());
-                final String toAddress = macroMachine.expandMacros(configuredEmailSetting.getTo());
+                        PwmSetting.EMAIL_NEWUSER_VERIFICATION, pwmSession.getSessionStateBean().getLocale() );
+                final String toAddress = macroMachine.expandMacros( configuredEmailSetting.getTo() );
 
                 final RestTokenDataClient.TokenDestinationData inputTokenDestData = new RestTokenDataClient.TokenDestinationData(
-                        toAddress, null, null);
-                final RestTokenDataClient restTokenDataClient = new RestTokenDataClient(pwmApplication);
+                        toAddress, null, null );
+                final RestTokenDataClient restTokenDataClient = new RestTokenDataClient( pwmApplication );
                 final RestTokenDataClient.TokenDestinationData outputDestTokenData = restTokenDataClient.figureDestTokenDisplayString(
                         pwmRequest.getSessionLabel(),
                         inputTokenDestData,
                         null,
-                        pwmRequest.getLocale());
-                if(outputDestTokenData == null || outputDestTokenData.getEmail() == null || outputDestTokenData.getEmail().isEmpty())
+                        pwmRequest.getLocale() );
+                if ( outputDestTokenData == null || outputDestTokenData.getEmail() == null || outputDestTokenData.getEmail().isEmpty() )
                 {
                     //avoid sending Email code token
                     break;
                 }
                 final String tokenKey;
-                try {
+                try
+                {
                     final TokenPayload tokenPayload = pwmApplication.getTokenService().createTokenPayload(
                             password.pwm.svc.token.TokenType.NEWUSER_EMAIL,
-                            newUserProfile.getTokenDurationEmail(config),
+                            newUserProfile.getTokenDurationEmail( config ),
                             tokenPayloadMap,
                             null,
-                            Collections.singleton(outputDestTokenData.getEmail())
+                            Collections.singleton( outputDestTokenData.getEmail() )
                     );
-                    tokenKey = pwmApplication.getTokenService().generateNewToken(tokenPayload,
-                            pwmRequest.getSessionLabel());
-                } catch (PwmOperationalException e) {
-                    throw new PwmUnrecoverableException(e.getErrorInformation());
+                    tokenKey = pwmApplication.getTokenService().generateNewToken( tokenPayload,
+                            pwmRequest.getSessionLabel() );
+                }
+                catch ( PwmOperationalException e )
+                {
+                    throw new PwmUnrecoverableException( e.getErrorInformation() );
                 }
 
-                newUserBean.getTokenVerificationProgress().getIssuedTokens().add(TokenVerificationProgress.TokenChannel.EMAIL);
-                newUserBean.getTokenVerificationProgress().setPhase(TokenVerificationProgress.TokenChannel.EMAIL);
-                final ValueObfuscator valueObfuscator = new ValueObfuscator(pwmApplication.getConfig());
-                newUserBean.getTokenVerificationProgress().setTokenDisplayText(valueObfuscator.maskEmail(toAddress));
+                newUserBean.getTokenVerificationProgress().getIssuedTokens().add( TokenVerificationProgress.TokenChannel.EMAIL );
+                newUserBean.getTokenVerificationProgress().setPhase( TokenVerificationProgress.TokenChannel.EMAIL );
+                final ValueObfuscator valueObfuscator = new ValueObfuscator( pwmApplication.getConfig() );
+                newUserBean.getTokenVerificationProgress().setTokenDisplayText( valueObfuscator.maskEmail( toAddress ) );
 
                 final EmailItemBean emailItemBean = new EmailItemBean(
                         outputDestTokenData.getEmail(),
                         configuredEmailSetting.getFrom(),
                         configuredEmailSetting.getSubject(),
-                        configuredEmailSetting.getBodyPlain().replace("%TOKEN%", tokenKey),
-                        configuredEmailSetting.getBodyHtml().replace("%TOKEN%", tokenKey));
+                        configuredEmailSetting.getBodyPlain().replace( "%TOKEN%", tokenKey ),
+                        configuredEmailSetting.getBodyHtml().replace( "%TOKEN%", tokenKey ) );
 
-                try {
+                try
+                {
                     TokenService.TokenSender.sendEmailToken(
                             TokenService.TokenSendInfo.builder()
                                     .pwmApplication( pwmApplication )
@@ -593,27 +666,32 @@ class NewUserUtils {
                                     .sessionLabel( pwmRequest.getSessionLabel() )
                                     .build()
                     );
-                } catch (Exception e) {
-                    throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_UNKNOWN));
+                }
+                catch ( Exception e )
+                {
+                    throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_UNKNOWN ) );
                 }
             }
             break;
 
             default:
-                newUserBean.getTokenVerificationProgress().setPhase(null);
-                JavaHelper.unhandledSwitchStatement(tokenType);
+                newUserBean.getTokenVerificationProgress().setPhase( null );
+                JavaHelper.unhandledSwitchStatement( tokenType );
         }
     }
 
-    static Map<String,String> figureDisplayableProfiles(final PwmRequest pwmRequest) {
-        final Map<String,String> returnMap = new LinkedHashMap<>();
-        for (final NewUserProfile newUserProfile : pwmRequest.getConfig().getNewUserProfiles().values()) {
-            final boolean visible = newUserProfile.readSettingAsBoolean(PwmSetting.NEWUSER_PROFILE_DISPLAY_VISIBLE);
-            if (visible) {
-                returnMap.put(newUserProfile.getIdentifier(), newUserProfile.getDisplayName(pwmRequest.getLocale()));
+    static Map<String, String> figureDisplayableProfiles( final PwmRequest pwmRequest )
+    {
+        final Map<String, String> returnMap = new LinkedHashMap<>();
+        for ( final NewUserProfile newUserProfile : pwmRequest.getConfig().getNewUserProfiles().values() )
+        {
+            final boolean visible = newUserProfile.readSettingAsBoolean( PwmSetting.NEWUSER_PROFILE_DISPLAY_VISIBLE );
+            if ( visible )
+            {
+                returnMap.put( newUserProfile.getIdentifier(), newUserProfile.getDisplayName( pwmRequest.getLocale() ) );
             }
         }
-        return Collections.unmodifiableMap(returnMap);
+        return Collections.unmodifiableMap( returnMap );
     }
 
     static void remoteVerifyFormData(
@@ -652,35 +730,40 @@ class NewUserUtils {
     )
             throws PwmUnrecoverableException, PwmDataValidationException
     {
-        final RestFormDataClient restFormDataClient = new RestFormDataClient(pwmRequest.getPwmApplication(), pwmRequest.getSessionLabel());
-        if (!restFormDataClient.isEnabled()) {
+        final RestFormDataClient restFormDataClient = new RestFormDataClient( pwmRequest.getPwmApplication(), pwmRequest.getSessionLabel() );
+        if ( !restFormDataClient.isEnabled() )
+        {
             return;
         }
 
-        final NewUserBean newUserBean = NewUserServlet.getNewUserBean(pwmRequest);
-        final NewUserProfile newUserProfile = NewUserServlet.getNewUserProfile(pwmRequest);
+        final NewUserBean newUserBean = NewUserServlet.getNewUserBean( pwmRequest );
+        final NewUserProfile newUserProfile = NewUserServlet.getNewUserProfile( pwmRequest );
 
         final FormDataRequestBean.FormInfo formInfo = FormDataRequestBean.FormInfo.builder()
-                .mode(mode)
-                .moduleProfileID(newUserBean.getProfileID())
-                .sessionID(pwmRequest.getPwmSession().getLoginInfoBean().getGuid())
-                .module(FormDataRequestBean.FormType.NewUser)
+                .mode( mode )
+                .moduleProfileID( newUserBean.getProfileID() )
+                .sessionID( pwmRequest.getPwmSession().getLoginInfoBean().getGuid() )
+                .module( FormDataRequestBean.FormType.NewUser )
                 .build();
 
         final FormDataRequestBean formDataRequestBean = FormDataRequestBean.builder()
-                .formInfo(formInfo)
-                .formConfigurations(newUserProfile.readSettingAsForm(PwmSetting.NEWUSER_FORM))
-                .formValues(newUserForm.getFormData())
+                .formInfo( formInfo )
+                .formConfigurations( newUserProfile.readSettingAsForm( PwmSetting.NEWUSER_FORM ) )
+                .formValues( newUserForm.getFormData() )
                 .build();
 
-        final FormDataResponseBean formDataResponseBean = restFormDataClient.invoke(formDataRequestBean, pwmRequest.getLocale());
-        if (formDataResponseBean.isError()) {
+        final FormDataResponseBean formDataResponseBean = restFormDataClient.invoke( formDataRequestBean, pwmRequest.getLocale() );
+        if ( formDataResponseBean.isError() )
+        {
             final ErrorInformation error = new ErrorInformation(
                     PwmError.ERROR_REMOTE_ERROR_VALUE,
                     formDataResponseBean.getErrorDetail(),
-                    new String[]{formDataResponseBean.getErrorMessage()}
+                    new String[]
+                            {
+                                    formDataResponseBean.getErrorMessage(),
+                            }
             );
-            throw new PwmDataValidationException(error);
+            throw new PwmDataValidationException( error );
         }
     }
 

+ 1 - 0
server/src/main/java/password/pwm/http/servlet/oauth/OAuthConsumerServlet.java

@@ -74,6 +74,7 @@ public class OAuthConsumerServlet extends AbstractPwmServlet
     }
 
     @Override
+    @SuppressWarnings( "checkstyle:MethodLength" )
     protected void processAction( final PwmRequest pwmRequest )
             throws ServletException, IOException, ChaiUnavailableException, PwmUnrecoverableException
     {

+ 1 - 0
server/src/main/java/password/pwm/http/servlet/oauth/OAuthRequestState.java

@@ -26,6 +26,7 @@ import java.io.Serializable;
 
 public class OAuthRequestState implements Serializable
 {
+    @SuppressWarnings( "checkstyle:MemberName" )
     private OAuthState oAuthState;
     private boolean sessionMatch;
 

+ 6 - 1
server/src/main/java/password/pwm/http/servlet/peoplesearch/PeopleSearchClientConfigBean.java

@@ -38,10 +38,15 @@ import java.util.Map;
 @Setter
 public class PeopleSearchClientConfigBean implements Serializable
 {
-
+    @SuppressWarnings( "checkstyle:MemberName" )
     private Map<String, String> peoplesearch_search_columns;
+
+    @SuppressWarnings( "checkstyle:MemberName" )
     private boolean peoplesearch_enablePhoto;
+
+    @SuppressWarnings( "checkstyle:MemberName" )
     private boolean peoplesearch_orgChartEnabled;
+
     private boolean orgChartShowChildCount;
     private int orgChartMaxParents;
 

+ 1 - 0
server/src/main/java/password/pwm/http/servlet/resource/ResourceFileServlet.java

@@ -149,6 +149,7 @@ public class ResourceFileServlet extends HttpServlet implements PwmServlet
         handleUncachedResponse( resp, file, false );
     }
 
+    @SuppressWarnings( "checkstyle:MethodLength" )
     protected void processAction( final PwmRequest pwmRequest )
             throws ServletException, IOException, PwmUnrecoverableException
     {

+ 3 - 2
server/src/main/java/password/pwm/http/tag/PasswordRequirementsTag.java

@@ -59,6 +59,7 @@ public class PasswordRequirementsTag extends TagSupport
     private String prepend;
     private String form;
 
+    @SuppressWarnings( "checkstyle:MethodLength" )
     public static List<String> getPasswordRequirementsStrings(
             final PwmPasswordPolicy pwordPolicy,
             final Configuration config,
@@ -280,10 +281,10 @@ public class PasswordRequirementsTag extends TagSupport
             final int value = ruleHelper.readIntValue( PwmPasswordRule.MinimumLifetime );
             if ( value > 0 )
             {
-                final int SECONDS_PER_DAY = 60 * 60 * 24;
+                final int secondsPerDay = 60 * 60 * 24;
 
                 final String durationStr;
-                if ( value % SECONDS_PER_DAY == 0 )
+                if ( value % secondsPerDay == 0 )
                 {
                     final int valueAsDays = value / ( 60 * 60 * 24 );
                     final Display key = valueAsDays <= 1 ? Display.Display_Day : Display.Display_Days;

+ 1 - 2
server/src/main/java/password/pwm/i18n/PwmSetting.java

@@ -24,8 +24,7 @@ package password.pwm.i18n;
 
 public enum PwmSetting implements PwmDisplayBundle
 {
-
-    ;
+    value,;
 
     public static final String SETTING_LABEL_PREFIX = "Setting_Label_";
     public static final String SETTING_DESCRIPTION_PREFIX = "Setting_Description_";

+ 30 - 20
server/src/main/java/password/pwm/ldap/PwmLdapVendor.java

@@ -2,37 +2,44 @@ package password.pwm.ldap;
 
 import com.novell.ldapchai.provider.DirectoryVendor;
 
-public enum PwmLdapVendor {
-    ACTIVE_DIRECTORY(DirectoryVendor.ACTIVE_DIRECTORY, "MICROSOFT_ACTIVE_DIRECTORY"),
-    EDIRECTORY(DirectoryVendor.EDIRECTORY, "NOVELL_EDIRECTORY"),
-    OPEN_LDAP(DirectoryVendor.OPEN_LDAP),
-    DIRECTORY_SERVER_389(DirectoryVendor.DIRECTORY_SERVER_389),
-    ORACLE_DS(DirectoryVendor.ORACLE_DS),
-    GENERIC(DirectoryVendor.GENERIC),
-
-    ;
+public enum PwmLdapVendor
+{
+    ACTIVE_DIRECTORY( DirectoryVendor.ACTIVE_DIRECTORY, "MICROSOFT_ACTIVE_DIRECTORY" ),
+    EDIRECTORY( DirectoryVendor.EDIRECTORY, "NOVELL_EDIRECTORY" ),
+    OPEN_LDAP( DirectoryVendor.OPEN_LDAP ),
+    DIRECTORY_SERVER_389( DirectoryVendor.DIRECTORY_SERVER_389 ),
+    ORACLE_DS( DirectoryVendor.ORACLE_DS ),
+    GENERIC( DirectoryVendor.GENERIC ),;
 
     private final DirectoryVendor chaiVendor;
     private final String[] otherNames;
 
-    PwmLdapVendor( final DirectoryVendor directoryVendor, final String... otherNames ) {
+    PwmLdapVendor( final DirectoryVendor directoryVendor, final String... otherNames )
+    {
         this.chaiVendor = directoryVendor;
         this.otherNames = otherNames;
     }
 
-    public static PwmLdapVendor fromString(final String input) {
-        if (input == null) {
+    public static PwmLdapVendor fromString( final String input )
+    {
+        if ( input == null )
+        {
             return null;
         }
 
-        for (PwmLdapVendor vendor : PwmLdapVendor.values()) {
-            if ( vendor.name().equals( input ) ) {
+        for ( PwmLdapVendor vendor : PwmLdapVendor.values() )
+        {
+            if ( vendor.name().equals( input ) )
+            {
                 return vendor;
             }
 
-            if (vendor.otherNames != null) {
-                for (final String otherName : vendor.otherNames) {
-                    if (otherName.equals( input )) {
+            if ( vendor.otherNames != null )
+            {
+                for ( final String otherName : vendor.otherNames )
+                {
+                    if ( otherName.equals( input ) )
+                    {
                         return vendor;
                     }
                 }
@@ -42,9 +49,12 @@ public enum PwmLdapVendor {
         return null;
     }
 
-    public static PwmLdapVendor fromChaiVendor(final DirectoryVendor directoryVendor) {
-        for (PwmLdapVendor vendor : PwmLdapVendor.values()) {
-            if (vendor.chaiVendor == directoryVendor) {
+    public static PwmLdapVendor fromChaiVendor( final DirectoryVendor directoryVendor )
+    {
+        for ( PwmLdapVendor vendor : PwmLdapVendor.values() )
+        {
+            if ( vendor.chaiVendor == directoryVendor )
+            {
                 return vendor;
             }
         }

+ 1 - 0
server/src/main/java/password/pwm/ldap/ViewableUserInfoDisplayReader.java

@@ -26,6 +26,7 @@ public final class ViewableUserInfoDisplayReader
     {
     }
 
+    @SuppressWarnings( "checkstyle:MethodLength" )
     public static List<DisplayElement> makeDisplayData(
             final Set<ViewStatusFields> viewStatusFields,
             final Configuration config,

+ 1 - 0
server/src/main/java/password/pwm/svc/event/HelpdeskAuditRecord.java

@@ -30,6 +30,7 @@ public class HelpdeskAuditRecord extends UserAuditRecord
     protected String targetDN;
     protected String targetLdapProfile;
 
+    @SuppressWarnings( "checkstyle:ParameterNumber" )
     HelpdeskAuditRecord(
             final Instant timestamp,
             final AuditEvent eventCode,

+ 218 - 153
server/src/main/java/password/pwm/svc/event/SyslogAuditService.java

@@ -73,8 +73,9 @@ import java.util.Collections;
 import java.util.List;
 
 
-public class SyslogAuditService {
-    private static final PwmLogger LOGGER = PwmLogger.forClass(SyslogAuditService.class);
+public class SyslogAuditService
+{
+    private static final PwmLogger LOGGER = PwmLogger.forClass( SyslogAuditService.class );
 
     private static final int WARNING_WINDOW_MS = 30 * 60 * 1000;
     private static final String SYSLOG_INSTANCE_NAME = "syslog-audit";
@@ -92,98 +93,111 @@ public class SyslogAuditService {
     private final PwmApplication pwmApplication;
     private final SyslogOutputFormat syslogOutputFormat;
 
-    public SyslogAuditService(final PwmApplication pwmApplication)
+    public SyslogAuditService( final PwmApplication pwmApplication )
             throws LocalDBException
     {
-        syslogOutputFormat = pwmApplication.getConfig().readSettingAsEnum(PwmSetting.AUDIT_SYSLOG_OUTPUT_FORMAT, SyslogOutputFormat.class);
+        syslogOutputFormat = pwmApplication.getConfig().readSettingAsEnum( PwmSetting.AUDIT_SYSLOG_OUTPUT_FORMAT, SyslogOutputFormat.class );
         this.pwmApplication = pwmApplication;
         this.configuration = pwmApplication.getConfig();
-        this.certificates = configuration.readSettingAsCertificate(PwmSetting.AUDIT_SYSLOG_CERTIFICATES);
-
-        final List<String> syslogConfigStringArray = configuration.readSettingAsStringArray(PwmSetting.AUDIT_SYSLOG_SERVERS);
-        try {
-            for(String entry : syslogConfigStringArray) {
-                final SyslogConfig syslogCfg = SyslogConfig.fromConfigString(entry);
-                final SyslogIF syslogInstance = makeSyslogInstance(syslogCfg);
-                syslogInstances.add(syslogInstance);
+        this.certificates = configuration.readSettingAsCertificate( PwmSetting.AUDIT_SYSLOG_CERTIFICATES );
+
+        final List<String> syslogConfigStringArray = configuration.readSettingAsStringArray( PwmSetting.AUDIT_SYSLOG_SERVERS );
+        try
+        {
+            for ( String entry : syslogConfigStringArray )
+            {
+                final SyslogConfig syslogCfg = SyslogConfig.fromConfigString( entry );
+                final SyslogIF syslogInstance = makeSyslogInstance( syslogCfg );
+                syslogInstances.add( syslogInstance );
             }
-            LOGGER.trace("queued service running for syslog entries");
-        } catch (IllegalArgumentException e) {
-            LOGGER.error("error parsing syslog configuration for  syslogConfigStrings ERROR: " + e.getMessage());
+            LOGGER.trace( "queued service running for syslog entries" );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            LOGGER.error( "error parsing syslog configuration for  syslogConfigStrings ERROR: " + e.getMessage() );
         }
 
         final WorkQueueProcessor.Settings settings = WorkQueueProcessor.Settings.builder()
-                .maxEvents(Integer.parseInt(configuration.readAppProperty(AppProperty.QUEUE_SYSLOG_MAX_COUNT)))
-                .retryDiscardAge(new TimeDuration(Long.parseLong(configuration.readAppProperty(AppProperty.QUEUE_SYSLOG_MAX_AGE_MS))))
-                .retryInterval(new TimeDuration(Long.parseLong(configuration.readAppProperty(AppProperty.QUEUE_SYSLOG_RETRY_TIMEOUT_MS))))
+                .maxEvents( Integer.parseInt( configuration.readAppProperty( AppProperty.QUEUE_SYSLOG_MAX_COUNT ) ) )
+                .retryDiscardAge( new TimeDuration( Long.parseLong( configuration.readAppProperty( AppProperty.QUEUE_SYSLOG_MAX_AGE_MS ) ) ) )
+                .retryInterval( new TimeDuration( Long.parseLong( configuration.readAppProperty( AppProperty.QUEUE_SYSLOG_RETRY_TIMEOUT_MS ) ) ) )
                 .build();
 
-        final LocalDBStoredQueue localDBStoredQueue = LocalDBStoredQueue.createLocalDBStoredQueue(pwmApplication, pwmApplication.getLocalDB(), LocalDB.DB.SYSLOG_QUEUE);
+        final LocalDBStoredQueue localDBStoredQueue = LocalDBStoredQueue.createLocalDBStoredQueue( pwmApplication, pwmApplication.getLocalDB(), LocalDB.DB.SYSLOG_QUEUE );
 
-        workQueueProcessor = new WorkQueueProcessor<>(pwmApplication, localDBStoredQueue, settings, new SyslogItemProcessor(), this.getClass());
+        workQueueProcessor = new WorkQueueProcessor<>( pwmApplication, localDBStoredQueue, settings, new SyslogItemProcessor(), this.getClass() );
     }
 
-    private class SyslogItemProcessor implements WorkQueueProcessor.ItemProcessor<String> {
+    private class SyslogItemProcessor implements WorkQueueProcessor.ItemProcessor<String>
+    {
         @Override
-        public WorkQueueProcessor.ProcessResult process(final String workItem) {
-            return processEvent(workItem);
+        public WorkQueueProcessor.ProcessResult process( final String workItem )
+        {
+            return processEvent( workItem );
         }
 
         @Override
-        public String convertToDebugString(final String workItem) {
-            return JsonUtil.serialize(workItem);
+        public String convertToDebugString( final String workItem )
+        {
+            return JsonUtil.serialize( workItem );
         }
     }
 
 
-    private SyslogIF makeSyslogInstance(final SyslogConfig syslogConfig)
+    private SyslogIF makeSyslogInstance( final SyslogConfig syslogConfig )
     {
         final AbstractSyslogConfigIF syslogConfigIF;
         final AbstractNetSyslog syslogInstance;
 
-        switch (syslogConfig.getProtocol()) {
+        switch ( syslogConfig.getProtocol() )
+        {
             case sslTcp:
-            case tls: {
+            case tls:
+            {
                 syslogConfigIF = new SSLTCPNetSyslogConfig();
-                ((SSLTCPNetSyslogConfig)syslogConfigIF).setBackLogHandlers(Collections.singletonList(new NullSyslogBackLogHandler()));
+                ( ( SSLTCPNetSyslogConfig ) syslogConfigIF ).setBackLogHandlers( Collections.singletonList( new NullSyslogBackLogHandler() ) );
                 syslogInstance = new LocalTrustSSLTCPNetSyslog();
             }
             break;
 
-            case tcp: {
+            case tcp:
+            {
                 syslogConfigIF = new TCPNetSyslogConfig();
-                ((TCPNetSyslogConfig) syslogConfigIF).setBackLogHandlers(Collections.singletonList(new NullSyslogBackLogHandler()));
+                ( ( TCPNetSyslogConfig ) syslogConfigIF ).setBackLogHandlers( Collections.singletonList( new NullSyslogBackLogHandler() ) );
                 syslogInstance = new TCPNetSyslog();
             }
             break;
 
-            case udp: {
+            case udp:
+            {
                 syslogConfigIF = new UDPNetSyslogConfig();
                 syslogInstance = new UDPNetSyslog();
             }
             break;
 
             default:
-                throw new IllegalArgumentException("unknown protocol type");
+                throw new IllegalArgumentException( "unknown protocol type" );
         }
 
-        final int maxLength = Integer.parseInt(configuration.readAppProperty(AppProperty.AUDIT_SYSLOG_MAX_MESSAGE_LENGTH));
+        final int maxLength = Integer.parseInt( configuration.readAppProperty( AppProperty.AUDIT_SYSLOG_MAX_MESSAGE_LENGTH ) );
 
-        syslogConfigIF.setThreaded(false);
-        syslogConfigIF.setMaxQueueSize(0);
-        syslogConfigIF.setMaxMessageLength(maxLength + LENGTH_OVERSIZE);
-        syslogConfigIF.setThrowExceptionOnWrite(true);
-        syslogConfigIF.setHost(syslogConfig.getHost());
-        syslogConfigIF.setPort(syslogConfig.getPort());
-        syslogInstance.initialize(SYSLOG_INSTANCE_NAME, syslogConfigIF);
+        syslogConfigIF.setThreaded( false );
+        syslogConfigIF.setMaxQueueSize( 0 );
+        syslogConfigIF.setMaxMessageLength( maxLength + LENGTH_OVERSIZE );
+        syslogConfigIF.setThrowExceptionOnWrite( true );
+        syslogConfigIF.setHost( syslogConfig.getHost() );
+        syslogConfigIF.setPort( syslogConfig.getPort() );
+        syslogInstance.initialize( SYSLOG_INSTANCE_NAME, syslogConfigIF );
         return syslogInstance;
     }
 
-    public void add(final AuditRecord event) throws PwmOperationalException {
+    public void add( final AuditRecord event ) throws PwmOperationalException
+    {
 
         final String syslogMsg;
 
-        switch ( syslogOutputFormat ) {
+        switch ( syslogOutputFormat )
+        {
             case JSON:
                 syslogMsg = convertAuditRecordToSyslogMessage( event, configuration );
                 break;
@@ -194,48 +208,64 @@ public class SyslogAuditService {
 
             default:
                 JavaHelper.unhandledSwitchStatement( syslogOutputFormat );
-                throw new IllegalStateException(  );
+                throw new IllegalStateException();
         }
 
-        try {
-            workQueueProcessor.submit(syslogMsg);
-        } catch (PwmOperationalException e) {
-            LOGGER.warn("unable to add syslog message to queue: " + e.getMessage());
+        try
+        {
+            workQueueProcessor.submit( syslogMsg );
+        }
+        catch ( PwmOperationalException e )
+        {
+            LOGGER.warn( "unable to add syslog message to queue: " + e.getMessage() );
         }
     }
 
-    public List<HealthRecord> healthCheck() {
+    public List<HealthRecord> healthCheck( )
+    {
         final List<HealthRecord> healthRecords = new ArrayList<>();
-        if (lastError != null) {
+        if ( lastError != null )
+        {
             final ErrorInformation errorInformation = lastError;
-            if (TimeDuration.fromCurrent(errorInformation.getDate()).isShorterThan(WARNING_WINDOW_MS)) {
-                healthRecords.add(new HealthRecord(HealthStatus.WARN, HealthTopic.Audit,
-                        errorInformation.toUserStr(PwmConstants.DEFAULT_LOCALE, configuration)));
+            if ( TimeDuration.fromCurrent( errorInformation.getDate() ).isShorterThan( WARNING_WINDOW_MS ) )
+            {
+                healthRecords.add( new HealthRecord( HealthStatus.WARN, HealthTopic.Audit,
+                        errorInformation.toUserStr( PwmConstants.DEFAULT_LOCALE, configuration ) ) );
             }
         }
         return healthRecords;
     }
 
-    private WorkQueueProcessor.ProcessResult processEvent(final String auditRecord) {
+    private WorkQueueProcessor.ProcessResult processEvent( final String auditRecord )
+    {
 
-        for(SyslogIF syslogInstance : syslogInstances) {
-            try {
-                syslogInstance.info(auditRecord);
-                LOGGER.trace("delivered syslog audit event: " + auditRecord);
+        for ( SyslogIF syslogInstance : syslogInstances )
+        {
+            try
+            {
+                syslogInstance.info( auditRecord );
+                LOGGER.trace( "delivered syslog audit event: " + auditRecord );
                 lastError = null;
-                StatisticsManager.incrementStat(this.pwmApplication, Statistic.SYSLOG_MESSAGES_SENT);
+                StatisticsManager.incrementStat( this.pwmApplication, Statistic.SYSLOG_MESSAGES_SENT );
                 return WorkQueueProcessor.ProcessResult.SUCCESS;
-            } catch (Exception e) {
+            }
+            catch ( Exception e )
+            {
                 final String errorMsg = "error while sending syslog message to remote service: " + e.getMessage();
-                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SYSLOG_WRITE_ERROR, errorMsg, new String[]{e.getMessage()});
+                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_SYSLOG_WRITE_ERROR, errorMsg, new String[]
+                        {
+                                e.getMessage(),
+                        }
+                );
                 lastError = errorInformation;
-                LOGGER.error(errorInformation.toDebugStr());
+                LOGGER.error( errorInformation.toDebugStr() );
             }
         }
         return WorkQueueProcessor.ProcessResult.RETRY;
     }
 
-    public void close() {
+    public void close( )
+    {
         final SyslogIF syslogIF = syslogInstance;
         syslogIF.shutdown();
         workQueueProcessor.close();
@@ -243,169 +273,203 @@ public class SyslogAuditService {
     }
 
 
-
     private static String convertAuditRecordToSyslogMessage(
             final AuditRecord auditRecord,
             final Configuration configuration
     )
     {
-        final int maxLength = Integer.parseInt(configuration.readAppProperty(AppProperty.AUDIT_SYSLOG_MAX_MESSAGE_LENGTH));
+        final int maxLength = Integer.parseInt( configuration.readAppProperty( AppProperty.AUDIT_SYSLOG_MAX_MESSAGE_LENGTH ) );
         String jsonValue = "";
         final StringBuilder message = new StringBuilder();
-        message.append(PwmConstants.PWM_APP_NAME);
-        message.append(" ");
+        message.append( PwmConstants.PWM_APP_NAME );
+        message.append( " " );
 
-        jsonValue = JsonUtil.serialize(auditRecord);
+        jsonValue = JsonUtil.serialize( auditRecord );
 
-        if (message.length() + jsonValue.length() <= maxLength) {
-            message.append(jsonValue);
-        } else {
-            final AuditRecord inputRecord = JsonUtil.cloneUsingJson(auditRecord, auditRecord.getClass());
+        if ( message.length() + jsonValue.length() <= maxLength )
+        {
+            message.append( jsonValue );
+        }
+        else
+        {
+            final AuditRecord inputRecord = JsonUtil.cloneUsingJson( auditRecord, auditRecord.getClass() );
             inputRecord.message = inputRecord.message == null ? "" : inputRecord.message;
-            inputRecord.narrative= inputRecord.narrative == null ? "" : inputRecord.narrative;
+            inputRecord.narrative = inputRecord.narrative == null ? "" : inputRecord.narrative;
 
-            final String truncateMessage = configuration.readAppProperty(AppProperty.AUDIT_SYSLOG_TRUNCATE_MESSAGE);
-            final AuditRecord copiedRecord = JsonUtil.cloneUsingJson(auditRecord, auditRecord.getClass());
+            final String truncateMessage = configuration.readAppProperty( AppProperty.AUDIT_SYSLOG_TRUNCATE_MESSAGE );
+            final AuditRecord copiedRecord = JsonUtil.cloneUsingJson( auditRecord, auditRecord.getClass() );
             copiedRecord.message = "";
             copiedRecord.narrative = "";
             final int shortenedMessageLength = message.length()
-                    + JsonUtil.serialize(copiedRecord).length()
+                    + JsonUtil.serialize( copiedRecord ).length()
                     + truncateMessage.length();
-            final int maxMessageAndNarrativeLength = maxLength - (shortenedMessageLength + (truncateMessage.length() * 2));
+            final int maxMessageAndNarrativeLength = maxLength - ( shortenedMessageLength + ( truncateMessage.length() * 2 ) );
             int maxMessageLength = inputRecord.getMessage().length();
             int maxNarrativeLength = inputRecord.getNarrative().length();
 
             {
                 int top = maxMessageAndNarrativeLength;
-                while (maxMessageLength + maxNarrativeLength > maxMessageAndNarrativeLength) {
+                while ( maxMessageLength + maxNarrativeLength > maxMessageAndNarrativeLength )
+                {
                     top--;
-                    maxMessageLength = Math.min(maxMessageLength, top);
-                    maxNarrativeLength = Math.min(maxNarrativeLength, top);
+                    maxMessageLength = Math.min( maxMessageLength, top );
+                    maxNarrativeLength = Math.min( maxNarrativeLength, top );
                 }
             }
 
             copiedRecord.message = inputRecord.getMessage().length() > maxMessageLength
-                    ? inputRecord.message.substring(0, maxMessageLength) + truncateMessage
+                    ? inputRecord.message.substring( 0, maxMessageLength ) + truncateMessage
                     : inputRecord.message;
 
             copiedRecord.narrative = inputRecord.getNarrative().length() > maxNarrativeLength
-                    ? inputRecord.narrative.substring(0, maxNarrativeLength) + truncateMessage
+                    ? inputRecord.narrative.substring( 0, maxNarrativeLength ) + truncateMessage
                     : inputRecord.narrative;
 
-            message.append(JsonUtil.serialize(copiedRecord));
+            message.append( JsonUtil.serialize( copiedRecord ) );
         }
 
         return message.toString();
     }
 
-    private static String convertAuditRecordToCEFMessage(final AuditRecord auditRecord, final Configuration configuration) {
+    private static String convertAuditRecordToCEFMessage( final AuditRecord auditRecord, final Configuration configuration )
+    {
 
         final String recordType = auditRecord.getType().name();
         String recordString = "";
         String translatedString = "";
-        if ("USER".equalsIgnoreCase(recordType)) {
-            final UserAuditRecord cefRecord = new UserAuditRecord(auditRecord.timestamp, auditRecord.eventCode, null, null, null,
-                    auditRecord.message, null, null);
-            recordString = JsonUtil.serialize(cefRecord);
-        } else if ("SYSTEM".equalsIgnoreCase(recordType)) {
-            final SystemAuditRecord cefRecord = new SystemAuditRecord(auditRecord.eventCode, auditRecord.message, null);
-            recordString = JsonUtil.serialize(cefRecord);
-        } else if ("HELPDESK".equalsIgnoreCase(recordType)) {
-            final HelpdeskAuditRecord cefRecord = new HelpdeskAuditRecord(auditRecord.timestamp, auditRecord.eventCode, null, null, null,
-                    auditRecord.message, null, null, null, null, null);
-            recordString = JsonUtil.serialize(cefRecord);
-        } else {
-            recordString = JsonUtil.serialize(auditRecord);
+        if ( "USER".equalsIgnoreCase( recordType ) )
+        {
+            final UserAuditRecord cefRecord = new UserAuditRecord( auditRecord.timestamp, auditRecord.eventCode, null, null, null,
+                    auditRecord.message, null, null );
+            recordString = JsonUtil.serialize( cefRecord );
+        }
+        else if ( "SYSTEM".equalsIgnoreCase( recordType ) )
+        {
+            final SystemAuditRecord cefRecord = new SystemAuditRecord( auditRecord.eventCode, auditRecord.message, null );
+            recordString = JsonUtil.serialize( cefRecord );
+        }
+        else if ( "HELPDESK".equalsIgnoreCase( recordType ) )
+        {
+            final HelpdeskAuditRecord cefRecord = new HelpdeskAuditRecord( auditRecord.timestamp, auditRecord.eventCode, null, null, null,
+                    auditRecord.message, null, null, null, null, null );
+            recordString = JsonUtil.serialize( cefRecord );
+        }
+        else
+        {
+            recordString = JsonUtil.serialize( auditRecord );
         }
-        recordString = recordString.replace("\"", "");
-        recordString = recordString.replace("\\", "");
-        recordString = recordString.replace("{", "");
-        recordString = recordString.replace("}", "");
-
-        recordString = recordString.replace("type:", " cat | ");
-        recordString = recordString.replace("eventCode:", " act | ");
-        recordString = recordString.replace("timestamp:", " rt | ");
-        recordString = recordString.replace("message:", " msg | ");
-        recordString = recordString.replace("narrative:", " reason | ");
-        recordString = recordString.replace("perpetratorID:", " suid | ");
-        recordString = recordString.replace("perpetratorDN:", " suser | ");
-        recordString = recordString.replace("sourceAddress:", " dvc | ");
-        recordString = recordString.replace("sourceHost:", " dvchost | ");
-        recordString = recordString.replace("targetID:", " duid | ");
-        recordString = recordString.replace("targetDN:", " duser | ");
-        recordString = recordString.replace("SSPR:", " sproc | ");
-        recordString = recordString.replace("PWM:", " sproc | ");
+        recordString = recordString.replace( "\"", "" );
+        recordString = recordString.replace( "\\", "" );
+        recordString = recordString.replace( "{", "" );
+        recordString = recordString.replace( "}", "" );
+
+        recordString = recordString.replace( "type:", " cat | " );
+        recordString = recordString.replace( "eventCode:", " act | " );
+        recordString = recordString.replace( "timestamp:", " rt | " );
+        recordString = recordString.replace( "message:", " msg | " );
+        recordString = recordString.replace( "narrative:", " reason | " );
+        recordString = recordString.replace( "perpetratorID:", " suid | " );
+        recordString = recordString.replace( "perpetratorDN:", " suser | " );
+        recordString = recordString.replace( "sourceAddress:", " dvc | " );
+        recordString = recordString.replace( "sourceHost:", " dvchost | " );
+        recordString = recordString.replace( "targetID:", " duid | " );
+        recordString = recordString.replace( "targetDN:", " duser | " );
+        recordString = recordString.replace( "SSPR:", " sproc | " );
+        recordString = recordString.replace( "PWM:", " sproc | " );
 
         translatedString = auditRecord.getTimestamp().toString();
-        translatedString = translatedString.concat(" host CEF:0 | security | threatmanager | 1.0 | 100 ");
-        recordString = recordString.replace(",", " ");
+        translatedString = translatedString.concat( " host CEF:0 | security | threatmanager | 1.0 | 100 " );
+        recordString = recordString.replace( ",", " " );
 
-        translatedString = translatedString.concat(recordString);
-        return (translatedString);
+        translatedString = translatedString.concat( recordString );
+        return ( translatedString );
     }
 
     @Getter
-    @AllArgsConstructor(access = AccessLevel.PRIVATE)
-    public static class SyslogConfig implements Serializable {
-        public enum Protocol { sslTcp, tcp, udp, tls }
+    @AllArgsConstructor( access = AccessLevel.PRIVATE )
+    public static class SyslogConfig implements Serializable
+    {
+        public enum Protocol
+        {
+            sslTcp, tcp, udp, tls
+        }
 
         private Protocol protocol;
         private String host;
         private int port;
 
-        public static SyslogConfig fromConfigString(final String input) throws IllegalArgumentException {
-            if (input == null) {
-                throw new IllegalArgumentException("input cannot be null");
+        public static SyslogConfig fromConfigString( final String input ) throws IllegalArgumentException
+        {
+            if ( input == null )
+            {
+                throw new IllegalArgumentException( "input cannot be null" );
             }
 
-            final String[] parts = input.split(",");
-            if (parts.length != 3) {
-                throw new IllegalArgumentException("input must have three comma separated parts.");
+            final String[] parts = input.split( "," );
+            if ( parts.length != 3 )
+            {
+                throw new IllegalArgumentException( "input must have three comma separated parts." );
             }
 
             final Protocol protocol;
-            try {
-                protocol = Protocol.valueOf(parts[0]);
-            } catch (IllegalArgumentException e) {
-                throw new IllegalArgumentException("unknown protocol '" + parts[0] + "'");
+            try
+            {
+                protocol = Protocol.valueOf( parts[ 0 ] );
+            }
+            catch ( IllegalArgumentException e )
+            {
+                throw new IllegalArgumentException( "unknown protocol '" + parts[ 0 ] + "'" );
             }
 
             final int port;
-            try {
-                port = Integer.parseInt(parts[2]);
-            } catch (NumberFormatException e) {
-                throw new IllegalArgumentException("invalid port number '" + parts[2] + "'");
+            try
+            {
+                port = Integer.parseInt( parts[ 2 ] );
+            }
+            catch ( NumberFormatException e )
+            {
+                throw new IllegalArgumentException( "invalid port number '" + parts[ 2 ] + "'" );
             }
 
-            return new SyslogConfig(protocol,parts[1],port);
+            return new SyslogConfig( protocol, parts[ 1 ], port );
         }
 
-        public String toString() {
-            return JsonUtil.serialize(this);
+        public String toString( )
+        {
+            return JsonUtil.serialize( this );
         }
     }
 
-    public int queueSize() {
+    public int queueSize( )
+    {
         return workQueueProcessor.queueSize();
     }
 
-    private class LocalTrustSyslogWriterClass extends SSLTCPNetSyslogWriter {
-        private LocalTrustSyslogWriterClass()
+    private class LocalTrustSyslogWriterClass extends SSLTCPNetSyslogWriter
+    {
+        private LocalTrustSyslogWriterClass( )
         {
             super();
         }
 
         @Override
-        protected SocketFactory obtainSocketFactory()
+        protected SocketFactory obtainSocketFactory( )
         {
-            if (certificates != null && certificates.size() >= 1) {
-                try {
-                    final SSLContext sc = SSLContext.getInstance("SSL");
-                    sc.init(null, new X509TrustManager[]{new X509Utils.CertMatchingTrustManager(configuration, certificates)},
-                            new java.security.SecureRandom());
+            if ( certificates != null && certificates.size() >= 1 )
+            {
+                try
+                {
+                    final SSLContext sc = SSLContext.getInstance( "SSL" );
+                    sc.init( null, new X509TrustManager[]
+                                    {
+                                            new X509Utils.CertMatchingTrustManager( configuration, certificates ),
+                                    },
+                            new java.security.SecureRandom() );
                     return sc.getSocketFactory();
-                } catch (NoSuchAlgorithmException | KeyManagementException e) {
-                    LOGGER.error("unexpected error loading syslog certificates: " + e.getMessage());
+                }
+                catch ( NoSuchAlgorithmException | KeyManagementException e )
+                {
+                    LOGGER.error( "unexpected error loading syslog certificates: " + e.getMessage() );
                 }
             }
 
@@ -413,14 +477,15 @@ public class SyslogAuditService {
         }
     }
 
-    private class LocalTrustSSLTCPNetSyslog extends SSLTCPNetSyslog {
+    private class LocalTrustSSLTCPNetSyslog extends SSLTCPNetSyslog
+    {
 
 
         @Override
-        public AbstractSyslogWriter createWriter()
+        public AbstractSyslogWriter createWriter( )
         {
             final LocalTrustSyslogWriterClass newClass = new LocalTrustSyslogWriterClass();
-            newClass.initialize(this);
+            newClass.initialize( this );
             return newClass;
         }
     }

+ 1 - 0
server/src/main/java/password/pwm/svc/event/UserAuditRecord.java

@@ -36,6 +36,7 @@ public class UserAuditRecord extends AuditRecord implements Serializable
     protected String sourceAddress;
     protected String sourceHost;
 
+    @SuppressWarnings( "checkstyle:ParameterNumber" )
     protected UserAuditRecord(
             final Instant timestamp,
             final AuditEvent eventCode,

+ 1 - 0
server/src/main/java/password/pwm/svc/intruder/IntruderManager.java

@@ -105,6 +105,7 @@ public class IntruderManager implements PwmService
     }
 
     @Override
+    @SuppressWarnings( "checkstyle:MethodLength" )
     public void init( final PwmApplication pwmApplication )
             throws PwmException
     {

+ 1 - 0
server/src/main/java/password/pwm/svc/report/ReportSummaryData.java

@@ -144,6 +144,7 @@ public class ReportSummaryData
         update( userCacheRecord, false );
     }
 
+    @SuppressWarnings( "checkstyle:MethodLength" )
     private void update( final UserCacheRecord userCacheRecord, final boolean adding )
     {
         final int modifier = adding ? 1 : -1;

+ 28 - 15
server/src/main/java/password/pwm/svc/sessiontrack/UserAgentUtils.java

@@ -14,17 +14,22 @@ import password.pwm.util.logging.PwmLogger;
 
 import java.io.IOException;
 
-public class UserAgentUtils  {
+public class UserAgentUtils
+{
     private static final PwmLogger LOGGER = PwmLogger.forClass( UserAgentUtils.class );
 
     private static UserAgentParser cachedParser;
 
-    private static UserAgentParser getUserAgentParser() throws PwmUnrecoverableException
+    private static UserAgentParser getUserAgentParser( ) throws PwmUnrecoverableException
     {
-        if (cachedParser == null) {
-            try {
+        if ( cachedParser == null )
+        {
+            try
+            {
                 cachedParser = new UserAgentService().loadParser();
-            }  catch ( IOException | ParseException e ) {
+            }
+            catch ( IOException | ParseException e )
+            {
                 final String msg = "error loading user-agent parser: " + e.getMessage();
                 LOGGER.error( msg, e );
                 throw new PwmUnrecoverableException( PwmError.ERROR_UNKNOWN, msg );
@@ -33,10 +38,12 @@ public class UserAgentUtils  {
         return cachedParser;
     }
 
-    public static void checkIfPreIE11( final PwmRequest pwmRequest) throws PwmUnrecoverableException  {
-        final String userAgentString = pwmRequest.readHeaderValueAsString( HttpHeader.UserAgent);
-        if ( StringUtil.isEmpty( userAgentString )) {
-            return ;
+    public static void checkIfPreIE11( final PwmRequest pwmRequest ) throws PwmUnrecoverableException
+    {
+        final String userAgentString = pwmRequest.readHeaderValueAsString( HttpHeader.UserAgent );
+        if ( StringUtil.isEmpty( userAgentString ) )
+        {
+            return;
         }
 
         boolean badBrowser = false;
@@ -46,20 +53,26 @@ public class UserAgentUtils  {
         final String browser = capabilities.getBrowser();
         final String browserMajorVersion = capabilities.getBrowserMajorVersion();
 
-        if ("IE".equalsIgnoreCase( browser )) {
-            try {
+        if ( "IE".equalsIgnoreCase( browser ) )
+        {
+            try
+            {
                 final int majorVersionInt = Integer.parseInt( browserMajorVersion );
-                if (majorVersionInt <= 10) {
+                if ( majorVersionInt <= 10 )
+                {
                     badBrowser = true;
                 }
-            }  catch ( NumberFormatException e ) {
+            }
+            catch ( NumberFormatException e )
+            {
                 LOGGER.error( "error parsing user-agent major version" + e.getMessage(), e );
             }
         }
 
-        if (badBrowser) {
+        if ( badBrowser )
+        {
             final String errorMsg = "Internet Explorer version is not supported for this function.  Please use Internet Explorer 11 or higher or another web browser.";
-            throw new PwmUnrecoverableException(new ErrorInformation( PwmError.ERROR_UNAUTHORIZED, errorMsg));
+            throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_UNAUTHORIZED, errorMsg ) );
         }
     }
 }

+ 157 - 117
server/src/main/java/password/pwm/svc/telemetry/TelemetryService.java

@@ -71,8 +71,9 @@ import java.util.TreeMap;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
-public class TelemetryService implements PwmService {
-    private static final PwmLogger LOGGER = PwmLogger.forClass(TelemetryService.class);
+public class TelemetryService implements PwmService
+{
+    private static final PwmLogger LOGGER = PwmLogger.forClass( TelemetryService.class );
 
     private ScheduledExecutorService executorService;
     private PwmApplication pwmApplication;
@@ -86,261 +87,300 @@ public class TelemetryService implements PwmService {
 
 
     @Override
-    public STATUS status()
+    public STATUS status( )
     {
         return status;
     }
 
     @Override
-    public void init(final PwmApplication pwmApplication) throws PwmException
+    public void init( final PwmApplication pwmApplication ) throws PwmException
     {
         status = STATUS.OPENING;
         this.pwmApplication = pwmApplication;
 
-        if (pwmApplication.getApplicationMode() != PwmApplicationMode.RUNNING) {
-            LOGGER.trace(SessionLabel.TELEMETRY_SESSION_LABEL, "will remain closed, app is not running");
+        if ( pwmApplication.getApplicationMode() != PwmApplicationMode.RUNNING )
+        {
+            LOGGER.trace( SessionLabel.TELEMETRY_SESSION_LABEL, "will remain closed, app is not running" );
             status = STATUS.CLOSED;
             return;
         }
 
-        if (!pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.PUBLISH_STATS_ENABLE)) {
-            LOGGER.trace(SessionLabel.TELEMETRY_SESSION_LABEL, "will remain closed, publish stats not enabled");
+        if ( !pwmApplication.getConfig().readSettingAsBoolean( PwmSetting.PUBLISH_STATS_ENABLE ) )
+        {
+            LOGGER.trace( SessionLabel.TELEMETRY_SESSION_LABEL, "will remain closed, publish stats not enabled" );
             status = STATUS.CLOSED;
             return;
         }
 
-        if (pwmApplication.getLocalDB().status() != LocalDB.Status.OPEN) {
-            LOGGER.trace(SessionLabel.TELEMETRY_SESSION_LABEL, "will remain closed, localdb not enabled");
+        if ( pwmApplication.getLocalDB().status() != LocalDB.Status.OPEN )
+        {
+            LOGGER.trace( SessionLabel.TELEMETRY_SESSION_LABEL, "will remain closed, localdb not enabled" );
             status = STATUS.CLOSED;
             return;
         }
 
-        if (pwmApplication.getStatisticsManager().status() != STATUS.OPEN) {
-            LOGGER.trace(SessionLabel.TELEMETRY_SESSION_LABEL, "will remain closed, statistics manager is not enabled");
+        if ( pwmApplication.getStatisticsManager().status() != STATUS.OPEN )
+        {
+            LOGGER.trace( SessionLabel.TELEMETRY_SESSION_LABEL, "will remain closed, statistics manager is not enabled" );
             status = STATUS.CLOSED;
             return;
         }
 
-        settings = Settings.fromConfig(pwmApplication.getConfig());
-        try {
+        settings = Settings.fromConfig( pwmApplication.getConfig() );
+        try
+        {
             initSender();
-        } catch (PwmUnrecoverableException e) {
-            LOGGER.trace(SessionLabel.TELEMETRY_SESSION_LABEL, "will remain closed, unable to init sender: " + e.getMessage());
+        }
+        catch ( PwmUnrecoverableException e )
+        {
+            LOGGER.trace( SessionLabel.TELEMETRY_SESSION_LABEL, "will remain closed, unable to init sender: " + e.getMessage() );
             status = STATUS.CLOSED;
             return;
         }
 
         {
-            final Instant storedLastPublishTimestamp = pwmApplication.readAppAttribute(PwmApplication.AppAttribute.TELEMETRY_LAST_PUBLISH_TIMESTAMP, Instant.class);
-            lastPublishTime = storedLastPublishTimestamp != null ?
-                    storedLastPublishTimestamp :
-                    pwmApplication.getInstallTime();
-            LOGGER.trace(SessionLabel.TELEMETRY_SESSION_LABEL, "last publish time was " + JavaHelper.toIsoDate(lastPublishTime));
+            final Instant storedLastPublishTimestamp = pwmApplication.readAppAttribute( PwmApplication.AppAttribute.TELEMETRY_LAST_PUBLISH_TIMESTAMP, Instant.class );
+            lastPublishTime = storedLastPublishTimestamp != null
+                    ? storedLastPublishTimestamp
+                    : pwmApplication.getInstallTime();
+            LOGGER.trace( SessionLabel.TELEMETRY_SESSION_LABEL, "last publish time was " + JavaHelper.toIsoDate( lastPublishTime ) );
         }
 
-        executorService = JavaHelper.makeSingleThreadExecutorService(pwmApplication, TelemetryService.class);
+        executorService = JavaHelper.makeSingleThreadExecutorService( pwmApplication, TelemetryService.class );
 
         scheduleNextJob();
 
         status = STATUS.OPEN;
     }
 
-    private void initSender() throws PwmUnrecoverableException
+    private void initSender( ) throws PwmUnrecoverableException
     {
-        if (StringUtil.isEmpty(settings.getSenderImplementation())) {
+        if ( StringUtil.isEmpty( settings.getSenderImplementation() ) )
+        {
             final String msg = "telemetry sender implementation not specified";
-            throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_TELEMETRY_SEND_ERROR, msg));
+            throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_TELEMETRY_SEND_ERROR, msg ) );
         }
 
         final TelemetrySender telemetrySender;
-        try {
+        try
+        {
             final String senderClass = settings.getSenderImplementation();
-            final Class theClass = Class.forName(senderClass);
-            telemetrySender = (TelemetrySender) theClass.newInstance();
-        } catch (Exception e) {
+            final Class theClass = Class.forName( senderClass );
+            telemetrySender = ( TelemetrySender ) theClass.newInstance();
+        }
+        catch ( Exception e )
+        {
             final String msg = "unable to load implementation class: " + e.getMessage();
-            throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_UNKNOWN, msg));
+            throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_UNKNOWN, msg ) );
         }
 
-        try {
-            final String macrodSettings = MacroMachine.forNonUserSpecific(pwmApplication, null).expandMacros(settings.getSenderSettings());
-            telemetrySender.init(pwmApplication, macrodSettings);
-        } catch (Exception e) {
+        try
+        {
+            final String macrodSettings = MacroMachine.forNonUserSpecific( pwmApplication, null ).expandMacros( settings.getSenderSettings() );
+            telemetrySender.init( pwmApplication, macrodSettings );
+        }
+        catch ( Exception e )
+        {
             final String msg = "unable to init implementation class: " + e.getMessage();
-            throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_UNKNOWN, msg));
+            throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_UNKNOWN, msg ) );
         }
         sender = telemetrySender;
     }
 
-    private void executePublishJob() throws PwmUnrecoverableException, IOException, URISyntaxException
+    private void executePublishJob( ) throws PwmUnrecoverableException, IOException, URISyntaxException
     {
-        final String authValue = pwmApplication.getStatisticsManager().getStatBundleForKey(StatisticsManager.KEY_CUMULATIVE).getStatistic(Statistic.AUTHENTICATIONS);
-        if (StringUtil.isEmpty(authValue) || Integer.parseInt(authValue) < settings.getMinimumAuthentications()) {
-            LOGGER.trace(SessionLabel.TELEMETRY_SESSION_LABEL, "skipping telemetry send, authentication count is too low");
-        } else {
-            try {
+        final String authValue = pwmApplication.getStatisticsManager().getStatBundleForKey( StatisticsManager.KEY_CUMULATIVE ).getStatistic( Statistic.AUTHENTICATIONS );
+        if ( StringUtil.isEmpty( authValue ) || Integer.parseInt( authValue ) < settings.getMinimumAuthentications() )
+        {
+            LOGGER.trace( SessionLabel.TELEMETRY_SESSION_LABEL, "skipping telemetry send, authentication count is too low" );
+        }
+        else
+        {
+            try
+            {
                 final TelemetryPublishBean telemetryPublishBean = generatePublishableBean();
-                sender.publish(telemetryPublishBean);
-                LOGGER.trace(SessionLabel.TELEMETRY_SESSION_LABEL, "sent telemetry data: " + JsonUtil.serialize(telemetryPublishBean));
-            } catch (PwmException e) {
+                sender.publish( telemetryPublishBean );
+                LOGGER.trace( SessionLabel.TELEMETRY_SESSION_LABEL, "sent telemetry data: " + JsonUtil.serialize( telemetryPublishBean ) );
+            }
+            catch ( PwmException e )
+            {
                 lastError = e.getErrorInformation();
-                LOGGER.error(SessionLabel.TELEMETRY_SESSION_LABEL, "error sending telemetry data: " + e.getMessage());
+                LOGGER.error( SessionLabel.TELEMETRY_SESSION_LABEL, "error sending telemetry data: " + e.getMessage() );
             }
         }
 
         lastPublishTime = Instant.now();
-        pwmApplication.writeAppAttribute(PwmApplication.AppAttribute.TELEMETRY_LAST_PUBLISH_TIMESTAMP, lastPublishTime);
+        pwmApplication.writeAppAttribute( PwmApplication.AppAttribute.TELEMETRY_LAST_PUBLISH_TIMESTAMP, lastPublishTime );
         scheduleNextJob();
     }
 
-    private void scheduleNextJob() {
+    private void scheduleNextJob( )
+    {
         final TimeDuration durationUntilNextPublish = durationUntilNextPublish();
         executorService.schedule(
                 new PublishJob(),
                 durationUntilNextPublish.getTotalMilliseconds(),
-                TimeUnit.MILLISECONDS);
-        LOGGER.trace(SessionLabel.TELEMETRY_SESSION_LABEL, "next publish time: " + durationUntilNextPublish().asCompactString());
+                TimeUnit.MILLISECONDS );
+        LOGGER.trace( SessionLabel.TELEMETRY_SESSION_LABEL, "next publish time: " + durationUntilNextPublish().asCompactString() );
     }
 
-    private class PublishJob implements Runnable {
+    private class PublishJob implements Runnable
+    {
         @Override
-        public void run()
+        public void run( )
         {
-            try {
+            try
+            {
                 executePublishJob();
-            } catch (PwmException e) {
-                LOGGER.error(e.getErrorInformation());
-            } catch (Exception e) {
-                LOGGER.error("unexpected error during telemetry publish job: " + e.getMessage());
+            }
+            catch ( PwmException e )
+            {
+                LOGGER.error( e.getErrorInformation() );
+            }
+            catch ( Exception e )
+            {
+                LOGGER.error( "unexpected error during telemetry publish job: " + e.getMessage() );
             }
         }
     }
 
     @Override
-    public void close()
+    public void close( )
     {
 
     }
 
     @Override
-    public List<HealthRecord> healthCheck()
+    public List<HealthRecord> healthCheck( )
     {
         return null;
     }
 
     @Override
-    public ServiceInfoBean serviceInfo()
+    public ServiceInfoBean serviceInfo( )
     {
-        final Map<String,String> debugMap = new LinkedHashMap<>();
-        debugMap.put("lastPublishTime", JavaHelper.toIsoDate(lastPublishTime));
-        if (lastError != null) {
-            debugMap.put("lastError", lastError.toDebugStr());
+        final Map<String, String> debugMap = new LinkedHashMap<>();
+        debugMap.put( "lastPublishTime", JavaHelper.toIsoDate( lastPublishTime ) );
+        if ( lastError != null )
+        {
+            debugMap.put( "lastError", lastError.toDebugStr() );
         }
-        return new ServiceInfoBean(null,Collections.unmodifiableMap(debugMap));
+        return new ServiceInfoBean( null, Collections.unmodifiableMap( debugMap ) );
     }
 
 
-    public TelemetryPublishBean generatePublishableBean()
+    public TelemetryPublishBean generatePublishableBean( )
             throws URISyntaxException, IOException, PwmUnrecoverableException
     {
-        final StatisticsBundle bundle = pwmApplication.getStatisticsManager().getStatBundleForKey(StatisticsManager.KEY_CUMULATIVE);
+        final StatisticsBundle bundle = pwmApplication.getStatisticsManager().getStatBundleForKey( StatisticsManager.KEY_CUMULATIVE );
         final Configuration config = pwmApplication.getConfig();
-        final Map<PwmAboutProperty,String> aboutPropertyStringMap = PwmAboutProperty.makeInfoBean(pwmApplication);
+        final Map<PwmAboutProperty, String> aboutPropertyStringMap = PwmAboutProperty.makeInfoBean( pwmApplication );
 
-        final Map<String,String> statData = new TreeMap<>();
-        for (final Statistic loopStat : Statistic.values()) {
-            statData.put(loopStat.getKey(),bundle.getStatistic(loopStat));
+        final Map<String, String> statData = new TreeMap<>();
+        for ( final Statistic loopStat : Statistic.values() )
+        {
+            statData.put( loopStat.getKey(), bundle.getStatistic( loopStat ) );
         }
 
         final List<String> configuredSettings = new ArrayList<>();
-        for (final PwmSetting pwmSetting : config.nonDefaultSettings()) {
-            if (!pwmSetting.getCategory().hasProfiles() && !config.isDefaultValue(pwmSetting)) {
-                configuredSettings.add(pwmSetting.getKey());
+        for ( final PwmSetting pwmSetting : config.nonDefaultSettings() )
+        {
+            if ( !pwmSetting.getCategory().hasProfiles() && !config.isDefaultValue( pwmSetting ) )
+            {
+                configuredSettings.add( pwmSetting.getKey() );
             }
         }
 
         final Set<PwmLdapVendor> ldapVendors = new LinkedHashSet<>();
-        for (final LdapProfile ldapProfile : config.getLdapProfiles().values()) {
-            try {
-                final DirectoryVendor directoryVendor = ldapProfile.getProxyChaiProvider(pwmApplication).getDirectoryVendor();
-                final PwmLdapVendor pwmLdapVendor = PwmLdapVendor.fromChaiVendor(directoryVendor);
-                ldapVendors.add(pwmLdapVendor);
-            } catch (Exception e) {
-                LOGGER.trace(SessionLabel.TELEMETRY_SESSION_LABEL, "unable to read ldap vendor type for stats publication: " + e.getMessage());
+        for ( final LdapProfile ldapProfile : config.getLdapProfiles().values() )
+        {
+            try
+            {
+                final DirectoryVendor directoryVendor = ldapProfile.getProxyChaiProvider( pwmApplication ).getDirectoryVendor();
+                final PwmLdapVendor pwmLdapVendor = PwmLdapVendor.fromChaiVendor( directoryVendor );
+                ldapVendors.add( pwmLdapVendor );
+            }
+            catch ( Exception e )
+            {
+                LOGGER.trace( SessionLabel.TELEMETRY_SESSION_LABEL, "unable to read ldap vendor type for stats publication: " + e.getMessage() );
             }
         }
 
         final Map<String, String> aboutStrings = new TreeMap<>();
         {
-            for (final Map.Entry<PwmAboutProperty, String> entry : aboutPropertyStringMap.entrySet()) {
+            for ( final Map.Entry<PwmAboutProperty, String> entry : aboutPropertyStringMap.entrySet() )
+            {
                 final PwmAboutProperty pwmAboutProperty = entry.getKey();
-                aboutStrings.put(pwmAboutProperty.name(), entry.getValue());
+                aboutStrings.put( pwmAboutProperty.name(), entry.getValue() );
             }
-            aboutStrings.remove(PwmAboutProperty.app_instanceID.name());
-            aboutStrings.remove(PwmAboutProperty.app_siteUrl.name());
+            aboutStrings.remove( PwmAboutProperty.app_instanceID.name() );
+            aboutStrings.remove( PwmAboutProperty.app_siteUrl.name() );
         }
 
         final TelemetryPublishBean.TelemetryPublishBeanBuilder builder = TelemetryPublishBean.builder();
-        builder.timestamp(Instant.now());
-        builder.id(makeId(pwmApplication));
-        builder.instanceHash(pwmApplication.getSecureService().hash(pwmApplication.getInstanceID()));
-        builder.installTime(pwmApplication.getInstallTime());
-        builder.siteDescription(config.readSettingAsString(PwmSetting.PUBLISH_STATS_SITE_DESCRIPTION));
-        builder.versionBuild(PwmConstants.BUILD_NUMBER);
-        builder.versionVersion(PwmConstants.BUILD_VERSION);
-        builder.ldapVendor(Collections.unmodifiableList(new ArrayList<>(ldapVendors)));
-        builder.statistics(Collections.unmodifiableMap(statData));
-        builder.configuredSettings(Collections.unmodifiableList(configuredSettings));
-        builder.about(aboutStrings);
+        builder.timestamp( Instant.now() );
+        builder.id( makeId( pwmApplication ) );
+        builder.instanceHash( pwmApplication.getSecureService().hash( pwmApplication.getInstanceID() ) );
+        builder.installTime( pwmApplication.getInstallTime() );
+        builder.siteDescription( config.readSettingAsString( PwmSetting.PUBLISH_STATS_SITE_DESCRIPTION ) );
+        builder.versionBuild( PwmConstants.BUILD_NUMBER );
+        builder.versionVersion( PwmConstants.BUILD_VERSION );
+        builder.ldapVendor( Collections.unmodifiableList( new ArrayList<>( ldapVendors ) ) );
+        builder.statistics( Collections.unmodifiableMap( statData ) );
+        builder.configuredSettings( Collections.unmodifiableList( configuredSettings ) );
+        builder.about( aboutStrings );
         return builder.build();
     }
 
-    private static String makeId(final PwmApplication pwmApplication) throws PwmUnrecoverableException
+    private static String makeId( final PwmApplication pwmApplication ) throws PwmUnrecoverableException
     {
-        final String SEPARATOR = "-";
-        final String DATETIME_PATTERN = "yyyyMMdd-HHmmss'Z'";
-        final String timestamp = DateTimeFormatter.ofPattern(DATETIME_PATTERN).format(ZonedDateTime.now(ZoneId.of("Zulu")));
+        final String separator = "-";
+        final String datetimePattern = "yyyyMMdd-HHmmss'Z'";
+        final String timestamp = DateTimeFormatter.ofPattern( datetimePattern ).format( ZonedDateTime.now( ZoneId.of( "Zulu" ) ) );
         return PwmConstants.PWM_APP_NAME.toLowerCase()
-                + SEPARATOR + instanceHash(pwmApplication)
-                + SEPARATOR + timestamp;
+                + separator + instanceHash( pwmApplication )
+                + separator + timestamp;
 
     }
 
-    private static String instanceHash(final PwmApplication pwmApplication) throws PwmUnrecoverableException
+    private static String instanceHash( final PwmApplication pwmApplication ) throws PwmUnrecoverableException
     {
-        final int MAX_HASH_LENGTH = 64;
+        final int maxHashLength = 64;
         final String instanceID = pwmApplication.getInstanceID();
-        final String hash = pwmApplication.getSecureService().hash(instanceID);
+        final String hash = pwmApplication.getSecureService().hash( instanceID );
         return hash.length() > 64
-                ? hash.substring(0, MAX_HASH_LENGTH)
+                ? hash.substring( 0, maxHashLength )
                 : hash;
     }
 
     @Getter
     @Builder
-    private static class Settings {
+    private static class Settings
+    {
         private TimeDuration publishFrequency;
         private int minimumAuthentications;
         private String senderImplementation;
         private String senderSettings;
 
-        static Settings fromConfig(final Configuration config) {
+        static Settings fromConfig( final Configuration config )
+        {
             return Settings.builder()
-                    .minimumAuthentications(Integer.parseInt(config.readAppProperty(AppProperty.TELEMETRY_MIN_AUTHENTICATIONS)))
-                    .publishFrequency(new TimeDuration(Integer.parseInt(config.readAppProperty(AppProperty.TELEMETRY_SEND_FREQUENCY_SECONDS)),TimeUnit.SECONDS))
-                    .senderImplementation(config.readAppProperty(AppProperty.TELEMETRY_SENDER_IMPLEMENTATION))
-                    .senderSettings(config.readAppProperty(AppProperty.TELEMETRY_SENDER_SETTINGS))
+                    .minimumAuthentications( Integer.parseInt( config.readAppProperty( AppProperty.TELEMETRY_MIN_AUTHENTICATIONS ) ) )
+                    .publishFrequency( new TimeDuration( Integer.parseInt( config.readAppProperty( AppProperty.TELEMETRY_SEND_FREQUENCY_SECONDS ) ), TimeUnit.SECONDS ) )
+                    .senderImplementation( config.readAppProperty( AppProperty.TELEMETRY_SENDER_IMPLEMENTATION ) )
+                    .senderSettings( config.readAppProperty( AppProperty.TELEMETRY_SENDER_SETTINGS ) )
                     .build();
         }
     }
 
-    private TimeDuration durationUntilNextPublish() {
+    private TimeDuration durationUntilNextPublish( )
+    {
 
-        final Instant nextPublishTime = settings.getPublishFrequency().incrementFromInstant(lastPublishTime);
-        final Instant minuteFromNow = TimeDuration.MINUTE.incrementFromInstant(Instant.now());
-        return nextPublishTime.isBefore(minuteFromNow)
-                ? TimeDuration.fromCurrent(minuteFromNow)
-                : TimeDuration.fromCurrent(nextPublishTime.toEpochMilli() + (PwmRandom.getInstance().nextInt(600) - 300));
+        final Instant nextPublishTime = settings.getPublishFrequency().incrementFromInstant( lastPublishTime );
+        final Instant minuteFromNow = TimeDuration.MINUTE.incrementFromInstant( Instant.now() );
+        return nextPublishTime.isBefore( minuteFromNow )
+                ? TimeDuration.fromCurrent( minuteFromNow )
+                : TimeDuration.fromCurrent( nextPublishTime.toEpochMilli() + ( PwmRandom.getInstance().nextInt( 600 ) - 300 ) );
     }
 
 }

+ 367 - 256
server/src/main/java/password/pwm/svc/token/TokenService.java

@@ -91,9 +91,10 @@ import java.util.concurrent.atomic.AtomicLong;
  *
  * @author jrivard@gmail.com
  */
-public class TokenService implements PwmService {
+public class TokenService implements PwmService
+{
 
-    private static final PwmLogger LOGGER = PwmLogger.forClass(TokenService.class);
+    private static final PwmLogger LOGGER = PwmLogger.forClass( TokenService.class );
 
     private ScheduledExecutorService executorService;
 
@@ -103,14 +104,14 @@ public class TokenService implements PwmService {
     private TokenMachine tokenMachine;
     private AtomicLong counter = new AtomicLong();
 
-    private ServiceInfoBean serviceInfo = new ServiceInfoBean(Collections.emptyList());
+    private ServiceInfoBean serviceInfo = new ServiceInfoBean( Collections.emptyList() );
     private STATUS status = STATUS.NEW;
 
     private ErrorInformation errorInformation = null;
 
     private boolean verifyPwModifyTime = true;
 
-    public TokenService()
+    public TokenService( )
             throws PwmOperationalException
     {
     }
@@ -121,141 +122,161 @@ public class TokenService implements PwmService {
             final Map<String, String> data,
             final UserIdentity userIdentity,
             final Set<String> dest
-    ) {
-        final long count = counter.getAndUpdate(operand -> {
+    )
+    {
+        final long count = counter.getAndUpdate( operand ->
+        {
             operand++;
-            if (operand <= 0) {
+            if ( operand <= 0 )
+            {
                 operand = 0;
             }
             return operand;
-        });
+        } );
         final StringBuilder guid = new StringBuilder();
-        try {
+        try
+        {
             final SecureService secureService = pwmApplication.getSecureService();
-            guid.append(secureService.hash(pwmApplication.getInstanceID() + pwmApplication.getStartupTime().toString()));
-            guid.append("-");
-            guid.append(count);
-        } catch (Exception e) {
-            LOGGER.error("error making payload guid: " + e.getMessage(),e);
-        }
-        final Instant expiration = lifetime.incrementFromInstant(Instant.now());
-        return new TokenPayload(name.name(), expiration, data, userIdentity, dest, guid.toString());
+            guid.append( secureService.hash( pwmApplication.getInstanceID() + pwmApplication.getStartupTime().toString() ) );
+            guid.append( "-" );
+            guid.append( count );
+        }
+        catch ( Exception e )
+        {
+            LOGGER.error( "error making payload guid: " + e.getMessage(), e );
+        }
+        final Instant expiration = lifetime.incrementFromInstant( Instant.now() );
+        return new TokenPayload( name.name(), expiration, data, userIdentity, dest, guid.toString() );
     }
 
-    public void init(final PwmApplication pwmApplication)
+    public void init( final PwmApplication pwmApplication )
             throws PwmException
     {
-        LOGGER.trace("opening");
+        LOGGER.trace( "opening" );
         status = STATUS.OPENING;
 
         this.pwmApplication = pwmApplication;
         this.configuration = pwmApplication.getConfig();
 
         storageMethod = configuration.getTokenStorageMethod();
-        if (storageMethod == null) {
+        if ( storageMethod == null )
+        {
             final String errorMsg = "no storage method specified";
-            errorInformation = new ErrorInformation(PwmError.ERROR_INVALID_CONFIG,errorMsg);
+            errorInformation = new ErrorInformation( PwmError.ERROR_INVALID_CONFIG, errorMsg );
             status = STATUS.CLOSED;
-            throw new PwmOperationalException(errorInformation);
+            throw new PwmOperationalException( errorInformation );
         }
 
-        try {
+        try
+        {
             DataStorageMethod usedStorageMethod = null;
-            switch (storageMethod) {
-                case STORE_LOCALDB: {
-                    final DataStore dataStore = new LocalDBDataStore(pwmApplication.getLocalDB(), LocalDB.DB.TOKENS);
-                    tokenMachine = new DataStoreTokenMachine(pwmApplication, this, dataStore);
+            switch ( storageMethod )
+            {
+                case STORE_LOCALDB:
+                {
+                    final DataStore dataStore = new LocalDBDataStore( pwmApplication.getLocalDB(), LocalDB.DB.TOKENS );
+                    tokenMachine = new DataStoreTokenMachine( pwmApplication, this, dataStore );
                     usedStorageMethod = DataStorageMethod.LOCALDB;
                     break;
                 }
 
-                case STORE_DB: {
-                    final DataStore dataStore = new DatabaseDataStore(pwmApplication.getDatabaseService(), DatabaseTable.TOKENS);
-                    tokenMachine = new DataStoreTokenMachine(pwmApplication, this, dataStore);
+                case STORE_DB:
+                {
+                    final DataStore dataStore = new DatabaseDataStore( pwmApplication.getDatabaseService(), DatabaseTable.TOKENS );
+                    tokenMachine = new DataStoreTokenMachine( pwmApplication, this, dataStore );
                     usedStorageMethod = DataStorageMethod.DB;
                     break;
                 }
 
                 case STORE_CRYPTO:
-                    tokenMachine = new CryptoTokenMachine(this);
+                    tokenMachine = new CryptoTokenMachine( this );
                     usedStorageMethod = DataStorageMethod.CRYPTO;
                     break;
 
                 case STORE_LDAP:
-                    tokenMachine = new LdapTokenMachine(this, pwmApplication);
+                    tokenMachine = new LdapTokenMachine( this, pwmApplication );
                     usedStorageMethod = DataStorageMethod.LDAP;
                     break;
 
                 default:
-                    JavaHelper.unhandledSwitchStatement(storageMethod);
+                    JavaHelper.unhandledSwitchStatement( storageMethod );
             }
-            serviceInfo = new ServiceInfoBean(Collections.singletonList(usedStorageMethod));
-        } catch (PwmException e) {
+            serviceInfo = new ServiceInfoBean( Collections.singletonList( usedStorageMethod ) );
+        }
+        catch ( PwmException e )
+        {
             final String errorMsg = "unable to start token manager: " + e.getErrorInformation().getDetailedErrorMsg();
-            final ErrorInformation newErrorInformation = new ErrorInformation(e.getError(), errorMsg);
+            final ErrorInformation newErrorInformation = new ErrorInformation( e.getError(), errorMsg );
             errorInformation = newErrorInformation;
-            LOGGER.error(newErrorInformation.toDebugStr());
+            LOGGER.error( newErrorInformation.toDebugStr() );
             status = STATUS.CLOSED;
             return;
         }
 
         executorService = Executors.newSingleThreadScheduledExecutor(
                 JavaHelper.makePwmThreadFactory(
-                        JavaHelper.makeThreadName(pwmApplication, this.getClass()) + "-",
+                        JavaHelper.makeThreadName( pwmApplication, this.getClass() ) + "-",
                         true
-                ));
+                ) );
 
         final TimerTask cleanerTask = new CleanerTask();
 
         {
-            final int cleanerFrequencySeconds = Integer.parseInt(configuration.readAppProperty(AppProperty.TOKEN_CLEANER_INTERVAL_SECONDS));
-            final TimeDuration cleanerFrequency = new TimeDuration(cleanerFrequencySeconds, TimeUnit.SECONDS);
-            executorService.scheduleAtFixedRate(cleanerTask, 10 , cleanerFrequencySeconds, TimeUnit.SECONDS);
-            LOGGER.trace("token cleanup will occur every " + cleanerFrequency.asCompactString());
+            final int cleanerFrequencySeconds = Integer.parseInt( configuration.readAppProperty( AppProperty.TOKEN_CLEANER_INTERVAL_SECONDS ) );
+            final TimeDuration cleanerFrequency = new TimeDuration( cleanerFrequencySeconds, TimeUnit.SECONDS );
+            executorService.scheduleAtFixedRate( cleanerTask, 10, cleanerFrequencySeconds, TimeUnit.SECONDS );
+            LOGGER.trace( "token cleanup will occur every " + cleanerFrequency.asCompactString() );
         }
 
-        final String counterString = pwmApplication.readAppAttribute(PwmApplication.AppAttribute.TOKEN_COUNTER, String.class);
-        try {
-            final long storedCounter = Long.parseLong(counterString);
-            counter = new AtomicLong(storedCounter);
-        } catch (Exception e) {
-            LOGGER.trace("can not parse stored last counter position, setting issue counter at 0");
+        final String counterString = pwmApplication.readAppAttribute( PwmApplication.AppAttribute.TOKEN_COUNTER, String.class );
+        try
+        {
+            final long storedCounter = Long.parseLong( counterString );
+            counter = new AtomicLong( storedCounter );
+        }
+        catch ( Exception e )
+        {
+            LOGGER.trace( "can not parse stored last counter position, setting issue counter at 0" );
         }
 
-        verifyPwModifyTime = Boolean.parseBoolean(configuration.readAppProperty(AppProperty.TOKEN_VERIFY_PW_MODIFY_TIME));
+        verifyPwModifyTime = Boolean.parseBoolean( configuration.readAppProperty( AppProperty.TOKEN_VERIFY_PW_MODIFY_TIME ) );
 
         status = STATUS.OPEN;
-        LOGGER.debug("open");
+        LOGGER.debug( "open" );
     }
 
-    public boolean supportsName() {
+    public boolean supportsName( )
+    {
         return tokenMachine.supportsName();
     }
 
-    public String generateNewToken(final TokenPayload tokenPayload, final SessionLabel sessionLabel)
+    public String generateNewToken( final TokenPayload tokenPayload, final SessionLabel sessionLabel )
             throws PwmUnrecoverableException, PwmOperationalException
     {
         checkStatus();
 
         final String tokenKey;
-        try {
-            tokenKey = tokenMachine.generateToken(sessionLabel, tokenPayload);
-            tokenMachine.storeToken(tokenMachine.keyFromKey(tokenKey), tokenPayload);
-        } catch (PwmException e) {
+        try
+        {
+            tokenKey = tokenMachine.generateToken( sessionLabel, tokenPayload );
+            tokenMachine.storeToken( tokenMachine.keyFromKey( tokenKey ), tokenPayload );
+        }
+        catch ( PwmException e )
+        {
             final String errorMsg = "unexpected error trying to store token in datastore: " + e.getMessage();
-            final ErrorInformation errorInformation = new ErrorInformation(e.getError(),errorMsg);
-            throw new PwmOperationalException(errorInformation);
+            final ErrorInformation errorInformation = new ErrorInformation( e.getError(), errorMsg );
+            throw new PwmOperationalException( errorInformation );
         }
 
-        LOGGER.trace(sessionLabel, "generated token with payload: "  + tokenPayload.toDebugString());
+        LOGGER.trace( sessionLabel, "generated token with payload: " + tokenPayload.toDebugString() );
 
-        final AuditRecord auditRecord = new AuditRecordFactory(pwmApplication).createUserAuditRecord(
+        final AuditRecord auditRecord = new AuditRecordFactory( pwmApplication ).createUserAuditRecord(
                 AuditEvent.TOKEN_ISSUED,
                 tokenPayload.getUserIdentity(),
                 sessionLabel,
-                JsonUtil.serialize(tokenPayload)
+                JsonUtil.serialize( tokenPayload )
         );
-        pwmApplication.getAuditManager().submit(auditRecord);
+        pwmApplication.getAuditManager().submit( auditRecord );
         return tokenKey;
     }
 
@@ -267,90 +288,112 @@ public class TokenService implements PwmService {
     )
             throws PwmUnrecoverableException
     {
-        if (tokenPayload == null || tokenPayload.getUserIdentity() == null) {
+        if ( tokenPayload == null || tokenPayload.getUserIdentity() == null )
+        {
             return;
         }
 
-        final boolean removeOnClaim = Boolean.parseBoolean(configuration.readAppProperty(AppProperty.TOKEN_REMOVE_ON_CLAIM));
+        final boolean removeOnClaim = Boolean.parseBoolean( configuration.readAppProperty( AppProperty.TOKEN_REMOVE_ON_CLAIM ) );
 
-        if (removeOnClaim) {
-            try {
-                LOGGER.trace(pwmSession, "removing claimed token: " + tokenPayload.toDebugString());
-                tokenMachine.removeToken(tokenKey);
-            } catch (PwmOperationalException e) {
-                LOGGER.error(pwmSession, "error clearing claimed token: " + e.getMessage());
+        if ( removeOnClaim )
+        {
+            try
+            {
+                LOGGER.trace( pwmSession, "removing claimed token: " + tokenPayload.toDebugString() );
+                tokenMachine.removeToken( tokenKey );
+            }
+            catch ( PwmOperationalException e )
+            {
+                LOGGER.error( pwmSession, "error clearing claimed token: " + e.getMessage() );
             }
         }
 
-        final AuditRecord auditRecord = new AuditRecordFactory(pwmApplication).createUserAuditRecord(
+        final AuditRecord auditRecord = new AuditRecordFactory( pwmApplication ).createUserAuditRecord(
                 AuditEvent.TOKEN_CLAIMED,
                 tokenPayload.getUserIdentity(),
                 pwmSession.getLabel(),
-                JsonUtil.serialize(tokenPayload)
+                JsonUtil.serialize( tokenPayload )
         );
-        pwmApplication.getAuditManager().submit(auditRecord);
+        pwmApplication.getAuditManager().submit( auditRecord );
 
-        StatisticsManager.incrementStat(pwmApplication, Statistic.TOKENS_PASSSED);
+        StatisticsManager.incrementStat( pwmApplication, Statistic.TOKENS_PASSSED );
     }
 
-    public TokenPayload retrieveTokenData(final SessionLabel sessionLabel, final String tokenKey)
+    public TokenPayload retrieveTokenData( final SessionLabel sessionLabel, final String tokenKey )
             throws PwmOperationalException
     {
         checkStatus();
 
-        try {
-            final TokenPayload storedToken = tokenMachine.retrieveToken(tokenMachine.keyFromKey(tokenKey));
-            if (storedToken != null) {
+        try
+        {
+            final TokenPayload storedToken = tokenMachine.retrieveToken( tokenMachine.keyFromKey( tokenKey ) );
+            if ( storedToken != null )
+            {
 
-                if (testIfTokenIsExpired(sessionLabel, storedToken)) {
-                    throw new PwmOperationalException(new ErrorInformation(PwmError.ERROR_TOKEN_EXPIRED));
+                if ( testIfTokenIsExpired( sessionLabel, storedToken ) )
+                {
+                    throw new PwmOperationalException( new ErrorInformation( PwmError.ERROR_TOKEN_EXPIRED ) );
                 }
 
                 return storedToken;
             }
-        } catch (PwmException e) {
-            if (e.getError() == PwmError.ERROR_TOKEN_EXPIRED || e.getError() == PwmError.ERROR_TOKEN_INCORRECT || e.getError() == PwmError.ERROR_TOKEN_MISSING_CONTACT) {
-                throw new PwmOperationalException(e.getErrorInformation());
+        }
+        catch ( PwmException e )
+        {
+            if ( e.getError() == PwmError.ERROR_TOKEN_EXPIRED || e.getError() == PwmError.ERROR_TOKEN_INCORRECT || e.getError() == PwmError.ERROR_TOKEN_MISSING_CONTACT )
+            {
+                throw new PwmOperationalException( e.getErrorInformation() );
             }
             final String errorMsg = "error trying to retrieve token from datastore: " + e.getMessage();
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_INCORRECT,errorMsg);
-            throw new PwmOperationalException(errorInformation);
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_TOKEN_INCORRECT, errorMsg );
+            throw new PwmOperationalException( errorInformation );
         }
         return null;
     }
 
-    public STATUS status() {
+    public STATUS status( )
+    {
         return status;
     }
 
-    public void close() {
-        if (executorService != null) {
+    public void close( )
+    {
+        if ( executorService != null )
+        {
             executorService.shutdown();
         }
         status = STATUS.CLOSED;
     }
 
-    public List<HealthRecord> healthCheck() {
+    public List<HealthRecord> healthCheck( )
+    {
         final List<HealthRecord> returnRecords = new ArrayList<>();
 
-        if (tokensAreUsedInConfig(configuration)) {
-            if (errorInformation != null) {
-                returnRecords.add(HealthRecord.forMessage(HealthMessage.CryptoTokenWithNewUserVerification,errorInformation.toDebugStr()));
+        if ( tokensAreUsedInConfig( configuration ) )
+        {
+            if ( errorInformation != null )
+            {
+                returnRecords.add( HealthRecord.forMessage( HealthMessage.CryptoTokenWithNewUserVerification, errorInformation.toDebugStr() ) );
             }
         }
 
-        if (storageMethod == TokenStorageMethod.STORE_LDAP) {
-            if (configuration.readSettingAsBoolean(PwmSetting.NEWUSER_ENABLE)) {
-                for (final NewUserProfile newUserProfile : configuration.getNewUserProfiles().values()) {
-                    if (newUserProfile.readSettingAsBoolean(PwmSetting.NEWUSER_EMAIL_VERIFICATION)) {
-                        final String label = PwmSetting.NEWUSER_EMAIL_VERIFICATION.toMenuLocationDebug(newUserProfile.getIdentifier(),PwmConstants.DEFAULT_LOCALE);
-                        final String label2 = PwmSetting.TOKEN_STORAGEMETHOD.toMenuLocationDebug(null,PwmConstants.DEFAULT_LOCALE);
-                        returnRecords.add(HealthRecord.forMessage(HealthMessage.CryptoTokenWithNewUserVerification, label, label2));
+        if ( storageMethod == TokenStorageMethod.STORE_LDAP )
+        {
+            if ( configuration.readSettingAsBoolean( PwmSetting.NEWUSER_ENABLE ) )
+            {
+                for ( final NewUserProfile newUserProfile : configuration.getNewUserProfiles().values() )
+                {
+                    if ( newUserProfile.readSettingAsBoolean( PwmSetting.NEWUSER_EMAIL_VERIFICATION ) )
+                    {
+                        final String label = PwmSetting.NEWUSER_EMAIL_VERIFICATION.toMenuLocationDebug( newUserProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE );
+                        final String label2 = PwmSetting.TOKEN_STORAGEMETHOD.toMenuLocationDebug( null, PwmConstants.DEFAULT_LOCALE );
+                        returnRecords.add( HealthRecord.forMessage( HealthMessage.CryptoTokenWithNewUserVerification, label, label2 ) );
                     }
-                    if (newUserProfile.readSettingAsBoolean(PwmSetting.NEWUSER_SMS_VERIFICATION)) {
-                        final String label = PwmSetting.NEWUSER_SMS_VERIFICATION.toMenuLocationDebug(newUserProfile.getIdentifier(),PwmConstants.DEFAULT_LOCALE);
-                        final String label2 = PwmSetting.TOKEN_STORAGEMETHOD.toMenuLocationDebug(null,PwmConstants.DEFAULT_LOCALE);
-                        returnRecords.add(HealthRecord.forMessage(HealthMessage.CryptoTokenWithNewUserVerification, label, label2));
+                    if ( newUserProfile.readSettingAsBoolean( PwmSetting.NEWUSER_SMS_VERIFICATION ) )
+                    {
+                        final String label = PwmSetting.NEWUSER_SMS_VERIFICATION.toMenuLocationDebug( newUserProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE );
+                        final String label2 = PwmSetting.TOKEN_STORAGEMETHOD.toMenuLocationDebug( null, PwmConstants.DEFAULT_LOCALE );
+                        returnRecords.add( HealthRecord.forMessage( HealthMessage.CryptoTokenWithNewUserVerification, label, label2 ) );
                     }
                 }
             }
@@ -359,88 +402,112 @@ public class TokenService implements PwmService {
         return returnRecords;
     }
 
-    private boolean testIfTokenIsExpired(final SessionLabel sessionLabel, final TokenPayload theToken) {
-        if (theToken == null) {
+    private boolean testIfTokenIsExpired( final SessionLabel sessionLabel, final TokenPayload theToken )
+    {
+        if ( theToken == null )
+        {
             return false;
         }
         final Instant issueDate = theToken.getIssueTime();
-        if (issueDate == null) {
-            LOGGER.error(sessionLabel, "retrieved token has no issueDate, marking as expired: " + theToken.toDebugString());
+        if ( issueDate == null )
+        {
+            LOGGER.error( sessionLabel, "retrieved token has no issueDate, marking as expired: " + theToken.toDebugString() );
             return true;
         }
-        if (theToken.getExpiration() == null) {
-            LOGGER.error(sessionLabel, "retrieved token has no expiration timestamp, marking as expired: " + theToken.toDebugString());
+        if ( theToken.getExpiration() == null )
+        {
+            LOGGER.error( sessionLabel, "retrieved token has no expiration timestamp, marking as expired: " + theToken.toDebugString() );
             return true;
         }
-        return theToken.getExpiration().isBefore(Instant.now());
+        return theToken.getExpiration().isBefore( Instant.now() );
     }
 
-    private static String makeRandomCode(final Configuration config) {
-        final String RANDOM_CHARS = config.readSettingAsString(PwmSetting.TOKEN_CHARACTERS);
-        final int CODE_LENGTH = (int) config.readSettingAsLong(PwmSetting.TOKEN_LENGTH);
-        final PwmRandom RANDOM = PwmRandom.getInstance();
+    private static String makeRandomCode( final Configuration config )
+    {
+        final String randomChars = config.readSettingAsString( PwmSetting.TOKEN_CHARACTERS );
+        final int codeLength = ( int ) config.readSettingAsLong( PwmSetting.TOKEN_LENGTH );
+        final PwmRandom random = PwmRandom.getInstance();
 
-        return RANDOM.alphaNumericString(RANDOM_CHARS, CODE_LENGTH);
+        return random.alphaNumericString( randomChars, codeLength );
     }
 
-    private class CleanerTask extends TimerTask {
-        public void run() {
-            try {
+    private class CleanerTask extends TimerTask
+    {
+        public void run( )
+        {
+            try
+            {
                 tokenMachine.cleanup();
-            } catch (Exception e) {
-                LOGGER.warn("unexpected error while cleaning expired stored tokens: " + e.getMessage(),e);
+            }
+            catch ( Exception e )
+            {
+                LOGGER.warn( "unexpected error while cleaning expired stored tokens: " + e.getMessage(), e );
             }
         }
     }
 
-    private void checkStatus() throws PwmOperationalException {
-        if (status != STATUS.OPEN) {
-            throw new PwmOperationalException(new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE,"token manager is not open"));
+    private void checkStatus( ) throws PwmOperationalException
+    {
+        if ( status != STATUS.OPEN )
+        {
+            throw new PwmOperationalException( new ErrorInformation( PwmError.ERROR_SERVICE_NOT_AVAILABLE, "token manager is not open" ) );
         }
     }
 
-    public int size() throws PwmUnrecoverableException {
-        if (status != STATUS.OPEN) {
+    public int size( ) throws PwmUnrecoverableException
+    {
+        if ( status != STATUS.OPEN )
+        {
             return -1;
         }
 
-        try {
+        try
+        {
             return tokenMachine.size();
-        } catch (Exception e) {
-            LOGGER.error("unexpected error reading size of token storage table: " + e.getMessage());
+        }
+        catch ( Exception e )
+        {
+            LOGGER.error( "unexpected error reading size of token storage table: " + e.getMessage() );
         }
 
         return -1;
     }
 
-    String makeUniqueTokenForMachine(final SessionLabel sessionLabel, final TokenMachine machine)
+    String makeUniqueTokenForMachine( final SessionLabel sessionLabel, final TokenMachine machine )
             throws PwmUnrecoverableException, PwmOperationalException
     {
         String tokenKey = null;
         int attempts = 0;
-        final int maxUniqueCreateAttempts = Integer.parseInt(pwmApplication.getConfig().readAppProperty(AppProperty.TOKEN_MAX_UNIQUE_CREATE_ATTEMPTS));
-        while (tokenKey == null && attempts < maxUniqueCreateAttempts) {
-            tokenKey = makeRandomCode(configuration);
-            LOGGER.trace(sessionLabel, "generated new token random code, checking for uniqueness");
-            final TokenPayload existingPayload = machine.retrieveToken(tokenMachine.keyFromKey(tokenKey));
-            if (existingPayload != null) {
+        final int maxUniqueCreateAttempts = Integer.parseInt( pwmApplication.getConfig().readAppProperty( AppProperty.TOKEN_MAX_UNIQUE_CREATE_ATTEMPTS ) );
+        while ( tokenKey == null && attempts < maxUniqueCreateAttempts )
+        {
+            tokenKey = makeRandomCode( configuration );
+            LOGGER.trace( sessionLabel, "generated new token random code, checking for uniqueness" );
+            final TokenPayload existingPayload = machine.retrieveToken( tokenMachine.keyFromKey( tokenKey ) );
+            if ( existingPayload != null )
+            {
                 tokenKey = null;
             }
             attempts++;
         }
 
-        if (tokenKey == null) {
-            throw new PwmOperationalException(new ErrorInformation(PwmError.ERROR_UNKNOWN,"unable to generate a unique token key after " + attempts + " attempts"));
+        if ( tokenKey == null )
+        {
+            throw new PwmOperationalException( new ErrorInformation( PwmError.ERROR_UNKNOWN, "unable to generate a unique token key after " + attempts + " attempts" ) );
         }
 
-        LOGGER.trace(sessionLabel, "created new unique random token value after " + attempts + " attempts");
+        LOGGER.trace( sessionLabel, "created new unique random token value after " + attempts + " attempts" );
         return tokenKey;
     }
 
-    private static boolean tokensAreUsedInConfig(final Configuration configuration) {
-        if (configuration.readSettingAsBoolean(PwmSetting.NEWUSER_ENABLE)) {
-            for (final NewUserProfile newUserProfile : configuration.getNewUserProfiles().values()) {
-                if (newUserProfile.readSettingAsBoolean(PwmSetting.NEWUSER_EMAIL_VERIFICATION)) {
+    private static boolean tokensAreUsedInConfig( final Configuration configuration )
+    {
+        if ( configuration.readSettingAsBoolean( PwmSetting.NEWUSER_ENABLE ) )
+        {
+            for ( final NewUserProfile newUserProfile : configuration.getNewUserProfiles().values() )
+            {
+                if ( newUserProfile.readSettingAsBoolean( PwmSetting.NEWUSER_EMAIL_VERIFICATION ) )
+                {
                     return true;
                 }
             }
@@ -448,17 +515,22 @@ public class TokenService implements PwmService {
         }
 
 
-        if (configuration.readSettingAsBoolean(PwmSetting.ACTIVATE_USER_ENABLE)) {
-            final MessageSendMethod activateMethod = configuration.readSettingAsEnum(PwmSetting.ACTIVATE_TOKEN_SEND_METHOD, MessageSendMethod.class);
-            if (MessageSendMethod.NONE != activateMethod) {
+        if ( configuration.readSettingAsBoolean( PwmSetting.ACTIVATE_USER_ENABLE ) )
+        {
+            final MessageSendMethod activateMethod = configuration.readSettingAsEnum( PwmSetting.ACTIVATE_TOKEN_SEND_METHOD, MessageSendMethod.class );
+            if ( MessageSendMethod.NONE != activateMethod )
+            {
                 return true;
             }
         }
 
-        if (configuration.readSettingAsBoolean(PwmSetting.CHALLENGE_ENABLE)) {
-            for (final ForgottenPasswordProfile forgottenPasswordProfile : configuration.getForgottenPasswordProfiles().values()) {
-                final MessageSendMethod messageSendMethod = forgottenPasswordProfile.readSettingAsEnum(PwmSetting.RECOVERY_TOKEN_SEND_METHOD, MessageSendMethod.class);
-                if (messageSendMethod != null && messageSendMethod != MessageSendMethod.NONE) {
+        if ( configuration.readSettingAsBoolean( PwmSetting.CHALLENGE_ENABLE ) )
+        {
+            for ( final ForgottenPasswordProfile forgottenPasswordProfile : configuration.getForgottenPasswordProfiles().values() )
+            {
+                final MessageSendMethod messageSendMethod = forgottenPasswordProfile.readSettingAsEnum( PwmSetting.RECOVERY_TOKEN_SEND_METHOD, MessageSendMethod.class );
+                if ( messageSendMethod != null && messageSendMethod != MessageSendMethod.NONE )
+                {
                     return true;
                 }
             }
@@ -466,28 +538,31 @@ public class TokenService implements PwmService {
         return false;
     }
 
-    String toEncryptedString(final TokenPayload tokenPayload)
+    String toEncryptedString( final TokenPayload tokenPayload )
             throws PwmUnrecoverableException, PwmOperationalException
     {
-        final String jsonPayload = JsonUtil.serialize(tokenPayload);
-        return pwmApplication.getSecureService().encryptToString(jsonPayload);
+        final String jsonPayload = JsonUtil.serialize( tokenPayload );
+        return pwmApplication.getSecureService().encryptToString( jsonPayload );
     }
 
-    TokenPayload fromEncryptedString(final String inputString)
+    TokenPayload fromEncryptedString( final String inputString )
             throws PwmOperationalException, PwmUnrecoverableException
     {
-        final String deWhiteSpacedToken = inputString.replaceAll("\\s", "");
-        try {
-            final String decryptedString = pwmApplication.getSecureService().decryptStringValue(deWhiteSpacedToken);
-            return JsonUtil.deserialize(decryptedString, TokenPayload.class);
-        } catch (PwmUnrecoverableException e) {
+        final String deWhiteSpacedToken = inputString.replaceAll( "\\s", "" );
+        try
+        {
+            final String decryptedString = pwmApplication.getSecureService().decryptStringValue( deWhiteSpacedToken );
+            return JsonUtil.deserialize( decryptedString, TokenPayload.class );
+        }
+        catch ( PwmUnrecoverableException e )
+        {
             final String errorMsg = "unable to decrypt token payload: " + e.getErrorInformation().toDebugStr();
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_INCORRECT,errorMsg);
-            throw new PwmOperationalException(errorInformation);
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_TOKEN_INCORRECT, errorMsg );
+            throw new PwmOperationalException( errorInformation );
         }
     }
 
-    public ServiceInfoBean serviceInfo()
+    public ServiceInfoBean serviceInfo( )
     {
         return serviceInfo;
     }
@@ -500,38 +575,47 @@ public class TokenService implements PwmService {
     )
             throws PwmOperationalException, PwmUnrecoverableException
     {
-        try {
+        try
+        {
             final TokenPayload tokenPayload = processUserEnteredCodeImpl(
                     pwmSession,
                     sessionUserIdentity,
                     tokenType,
                     userEnteredCode
             );
-            if (tokenPayload.getDest() != null) {
-                for (final String dest : tokenPayload.getDest()) {
-                    pwmApplication.getIntruderManager().clear(RecordType.TOKEN_DEST, dest);
+            if ( tokenPayload.getDest() != null )
+            {
+                for ( final String dest : tokenPayload.getDest() )
+                {
+                    pwmApplication.getIntruderManager().clear( RecordType.TOKEN_DEST, dest );
                 }
             }
-            markTokenAsClaimed(tokenMachine.keyFromKey(userEnteredCode), pwmSession, tokenPayload);
+            markTokenAsClaimed( tokenMachine.keyFromKey( userEnteredCode ), pwmSession, tokenPayload );
             return tokenPayload;
-        } catch (Exception e) {
+        }
+        catch ( Exception e )
+        {
             final ErrorInformation errorInformation;
-            if (e instanceof PwmException) {
-                errorInformation = ((PwmException) e).getErrorInformation();
-            } else {
-                errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_INCORRECT, e.getMessage());
+            if ( e instanceof PwmException )
+            {
+                errorInformation = ( ( PwmException ) e ).getErrorInformation();
+            }
+            else
+            {
+                errorInformation = new ErrorInformation( PwmError.ERROR_TOKEN_INCORRECT, e.getMessage() );
             }
 
-            LOGGER.debug(pwmSession, errorInformation.toDebugStr());
+            LOGGER.debug( pwmSession, errorInformation.toDebugStr() );
 
-            if (sessionUserIdentity != null) {
-                final SessionAuthenticator sessionAuthenticator = new SessionAuthenticator(pwmApplication, pwmSession, null);
-                sessionAuthenticator.simulateBadPassword(sessionUserIdentity);
-                pwmApplication.getIntruderManager().convenience().markUserIdentity(sessionUserIdentity, pwmSession);
+            if ( sessionUserIdentity != null )
+            {
+                final SessionAuthenticator sessionAuthenticator = new SessionAuthenticator( pwmApplication, pwmSession, null );
+                sessionAuthenticator.simulateBadPassword( sessionUserIdentity );
+                pwmApplication.getIntruderManager().convenience().markUserIdentity( sessionUserIdentity, pwmSession );
             }
-            pwmApplication.getIntruderManager().convenience().markAddressAndSession(pwmSession);
-            pwmApplication.getStatisticsManager().incrementValue(Statistic.RECOVERY_FAILURES);
-            throw new PwmOperationalException(errorInformation);
+            pwmApplication.getIntruderManager().convenience().markAddressAndSession( pwmSession );
+            pwmApplication.getStatisticsManager().incrementValue( Statistic.RECOVERY_FAILURES );
+            throw new PwmOperationalException( errorInformation );
         }
     }
 
@@ -544,80 +628,96 @@ public class TokenService implements PwmService {
             throws PwmOperationalException, PwmUnrecoverableException
     {
         final TokenPayload tokenPayload;
-        try {
-            tokenPayload = pwmApplication.getTokenService().retrieveTokenData(pwmSession.getLabel(), userEnteredCode);
-        } catch (PwmOperationalException e) {
+        try
+        {
+            tokenPayload = pwmApplication.getTokenService().retrieveTokenData( pwmSession.getLabel(), userEnteredCode );
+        }
+        catch ( PwmOperationalException e )
+        {
             final String errorMsg = "unexpected error attempting to read token from storage: " + e.getErrorInformation().toDebugStr();
-            throw new PwmOperationalException(PwmError.ERROR_TOKEN_INCORRECT,errorMsg);
+            throw new PwmOperationalException( PwmError.ERROR_TOKEN_INCORRECT, errorMsg );
         }
 
-        if (tokenPayload == null) {
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_INCORRECT,"token not found");
-            throw new PwmOperationalException(errorInformation);
+        if ( tokenPayload == null )
+        {
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_TOKEN_INCORRECT, "token not found" );
+            throw new PwmOperationalException( errorInformation );
         }
 
-        LOGGER.trace(pwmSession, "retrieved tokenPayload: " + tokenPayload.toDebugString());
+        LOGGER.trace( pwmSession, "retrieved tokenPayload: " + tokenPayload.toDebugString() );
 
-        if (tokenType != null && pwmApplication.getTokenService().supportsName()) {
-            if (!tokenType.matchesName(tokenPayload.getName()) ) {
-                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_INCORRECT,"incorrect token/name format");
-                throw new PwmOperationalException(errorInformation);
+        if ( tokenType != null && pwmApplication.getTokenService().supportsName() )
+        {
+            if ( !tokenType.matchesName( tokenPayload.getName() ) )
+            {
+                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_TOKEN_INCORRECT, "incorrect token/name format" );
+                throw new PwmOperationalException( errorInformation );
             }
         }
 
         // check current session identity
-        if (tokenPayload.getUserIdentity() != null && sessionUserIdentity != null) {
-            if (!tokenPayload.getUserIdentity().canonicalEquals(sessionUserIdentity, pwmApplication)) {
-                final String errorMsg = "user in session '" + sessionUserIdentity + "' entered code for user '" + tokenPayload.getUserIdentity()+ "', counting as invalid attempt";
-                throw new PwmOperationalException(PwmError.ERROR_TOKEN_INCORRECT,errorMsg);
+        if ( tokenPayload.getUserIdentity() != null && sessionUserIdentity != null )
+        {
+            if ( !tokenPayload.getUserIdentity().canonicalEquals( sessionUserIdentity, pwmApplication ) )
+            {
+                final String errorMsg = "user in session '" + sessionUserIdentity + "' entered code for user '" + tokenPayload.getUserIdentity() + "', counting as invalid attempt";
+                throw new PwmOperationalException( PwmError.ERROR_TOKEN_INCORRECT, errorMsg );
             }
         }
 
         // check if password-last-modified is same as when tried to read it before.
-        if (verifyPwModifyTime
+        if ( verifyPwModifyTime
                 && tokenPayload.getUserIdentity() != null
                 && tokenPayload.getData() != null
-                && tokenPayload.getData().containsKey(PwmConstants.TOKEN_KEY_PWD_CHG_DATE)
-                ) {
-            try {
+                && tokenPayload.getData().containsKey( PwmConstants.TOKEN_KEY_PWD_CHG_DATE )
+                )
+        {
+            try
+            {
                 final Instant userLastPasswordChange = PasswordUtility.determinePwdLastModified(
                         pwmApplication,
                         pwmSession.getLabel(),
-                        tokenPayload.getUserIdentity());
+                        tokenPayload.getUserIdentity() );
 
-                final String dateStringInToken = tokenPayload.getData().get(PwmConstants.TOKEN_KEY_PWD_CHG_DATE);
+                final String dateStringInToken = tokenPayload.getData().get( PwmConstants.TOKEN_KEY_PWD_CHG_DATE );
 
-                LOGGER.trace(pwmSession, "tokenPayload=" + tokenPayload.toDebugString()
-                        + ", sessionUser=" + (sessionUserIdentity == null ? "null" : sessionUserIdentity.toDisplayString())
+                LOGGER.trace( pwmSession, "tokenPayload=" + tokenPayload.toDebugString()
+                        + ", sessionUser=" + ( sessionUserIdentity == null ? "null" : sessionUserIdentity.toDisplayString() )
                         + ", payloadUserIdentity=" + tokenPayload.getUserIdentity().toDisplayString()
-                        + ", userLastPasswordChange=" + JavaHelper.toIsoDate(userLastPasswordChange)
-                        + ", dateStringInToken=" + dateStringInToken);
+                        + ", userLastPasswordChange=" + JavaHelper.toIsoDate( userLastPasswordChange )
+                        + ", dateStringInToken=" + dateStringInToken );
 
-                if (userLastPasswordChange != null && dateStringInToken != null) {
+                if ( userLastPasswordChange != null && dateStringInToken != null )
+                {
 
-                    final String userChangeString = JavaHelper.toIsoDate(userLastPasswordChange);
+                    final String userChangeString = JavaHelper.toIsoDate( userLastPasswordChange );
 
-                    if (!dateStringInToken.equalsIgnoreCase(userChangeString)) {
-                        final String errorString = "user password has changed since token issued, token rejected; currentValue=" + userChangeString + ", tokenValue=" + dateStringInToken;
-                        LOGGER.trace(pwmSession, errorString + "; token=" + tokenPayload.toDebugString());
-                        final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_EXPIRED, errorString);
-                        throw new PwmOperationalException(errorInformation);
+                    if ( !dateStringInToken.equalsIgnoreCase( userChangeString ) )
+                    {
+                        final String errorString = "user password has changed since token issued, token rejected;"
+                                + " currentValue=" + userChangeString + ", tokenValue=" + dateStringInToken;
+                        LOGGER.trace( pwmSession, errorString + "; token=" + tokenPayload.toDebugString() );
+                        final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_TOKEN_EXPIRED, errorString );
+                        throw new PwmOperationalException( errorInformation );
                     }
                 }
-            } catch (ChaiUnavailableException | PwmUnrecoverableException e) {
+            }
+            catch ( ChaiUnavailableException | PwmUnrecoverableException e )
+            {
                 final String errorMsg = "unexpected error reading user's last password change time while validating token: " + e.getMessage();
-                final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_TOKEN_INCORRECT, errorMsg);
-                throw new PwmOperationalException(errorInformation);
+                final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_TOKEN_INCORRECT, errorMsg );
+                throw new PwmOperationalException( errorInformation );
             }
         }
 
-        LOGGER.debug(pwmSession, "token validation has been passed");
+        LOGGER.debug( pwmSession, "token validation has been passed" );
         return tokenPayload;
     }
 
     @Value
     @Builder
-    public static class TokenSendInfo {
+    public static class TokenSendInfo
+    {
         private PwmApplication pwmApplication;
         private UserInfo userInfo;
         private MacroMachine macroMachine;
@@ -630,7 +730,8 @@ public class TokenService implements PwmService {
         private SessionLabel sessionLabel;
     }
 
-    public static class TokenSender {
+    public static class TokenSender
+    {
         public static List<TokenDestinationItem.Type> sendToken(
                 final TokenSendInfo tokenSendInfo
         )
@@ -640,30 +741,32 @@ public class TokenService implements PwmService {
 
             final List<TokenDestinationItem.Type> sentTypes = new ArrayList<>();
 
-            switch (tokenSendInfo.getTokenSendMethod()) {
+            switch ( tokenSendInfo.getTokenSendMethod() )
+            {
                 case NONE:
                     // should never read here
-                    LOGGER.error("attempt to send token to destination type 'NONE'");
-                    throw new PwmUnrecoverableException(PwmError.ERROR_UNKNOWN);
+                    LOGGER.error( "attempt to send token to destination type 'NONE'" );
+                    throw new PwmUnrecoverableException( PwmError.ERROR_UNKNOWN );
                 case SMSONLY:
                     // Only try SMS
-                    success = sendSmsToken(tokenSendInfo);
-                    sentTypes.add(TokenDestinationItem.Type.sms);
+                    success = sendSmsToken( tokenSendInfo );
+                    sentTypes.add( TokenDestinationItem.Type.sms );
                     break;
                 case EMAILONLY:
                 default:
                     // Only try email
-                    success = sendEmailToken(tokenSendInfo);
-                    sentTypes.add(TokenDestinationItem.Type.email);
+                    success = sendEmailToken( tokenSendInfo );
+                    sentTypes.add( TokenDestinationItem.Type.email );
                     break;
             }
 
-            if (!success) {
-                throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_TOKEN_MISSING_CONTACT));
+            if ( !success )
+            {
+                throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_TOKEN_MISSING_CONTACT ) );
             }
 
             final PwmApplication pwmApplication = tokenSendInfo.getPwmApplication();
-            pwmApplication.getStatisticsManager().incrementValue(Statistic.TOKENS_SENT);
+            pwmApplication.getStatisticsManager().incrementValue( Statistic.TOKENS_SENT );
 
             return sentTypes;
         }
@@ -674,22 +777,23 @@ public class TokenService implements PwmService {
                 throws PwmUnrecoverableException
         {
             final String toAddress = tokenSendInfo.getEmailAddress();
-            if ( StringUtil.isEmpty( toAddress ) ) {
+            if ( StringUtil.isEmpty( toAddress ) )
+            {
                 return false;
             }
 
             final PwmApplication pwmApplication = tokenSendInfo.getPwmApplication();
-            pwmApplication.getIntruderManager().mark(RecordType.TOKEN_DEST, toAddress, null);
+            pwmApplication.getIntruderManager().mark( RecordType.TOKEN_DEST, toAddress, null );
 
             final EmailItemBean configuredEmailSetting = tokenSendInfo.getConfiguredEmailSetting();
-            pwmApplication.getEmailQueue().submitEmailImmediate(new EmailItemBean(
+            pwmApplication.getEmailQueue().submitEmailImmediate( new EmailItemBean(
                     toAddress,
                     configuredEmailSetting.getFrom(),
                     configuredEmailSetting.getSubject(),
-                    configuredEmailSetting.getBodyPlain().replace("%TOKEN%", tokenSendInfo.getTokenKey()),
-                    configuredEmailSetting.getBodyHtml().replace("%TOKEN%", tokenSendInfo.getTokenKey())
-            ), tokenSendInfo.getUserInfo(), tokenSendInfo.getMacroMachine());
-            LOGGER.debug("token email added to send queue for " + toAddress);
+                    configuredEmailSetting.getBodyPlain().replace( "%TOKEN%", tokenSendInfo.getTokenKey() ),
+                    configuredEmailSetting.getBodyHtml().replace( "%TOKEN%", tokenSendInfo.getTokenKey() )
+            ), tokenSendInfo.getUserInfo(), tokenSendInfo.getMacroMachine() );
+            LOGGER.debug( "token email added to send queue for " + toAddress );
             return true;
         }
 
@@ -699,18 +803,19 @@ public class TokenService implements PwmService {
                 throws PwmUnrecoverableException
         {
             final String smsNumber = tokenSendInfo.getSmsNumber();
-            if ( StringUtil.isEmpty( smsNumber) ) {
+            if ( StringUtil.isEmpty( smsNumber ) )
+            {
                 return false;
             }
 
 
-            final String modifiedMessage = tokenSendInfo.getSmsMessage().replaceAll("%TOKEN%", tokenSendInfo.getTokenKey());
+            final String modifiedMessage = tokenSendInfo.getSmsMessage().replaceAll( "%TOKEN%", tokenSendInfo.getTokenKey() );
 
             final PwmApplication pwmApplication = tokenSendInfo.getPwmApplication();
-            pwmApplication.getIntruderManager().mark(RecordType.TOKEN_DEST, smsNumber, tokenSendInfo.getSessionLabel());
+            pwmApplication.getIntruderManager().mark( RecordType.TOKEN_DEST, smsNumber, tokenSendInfo.getSessionLabel() );
 
-            pwmApplication.sendSmsUsingQueue(smsNumber, modifiedMessage, tokenSendInfo.getSessionLabel(), tokenSendInfo.getMacroMachine());
-            LOGGER.debug("token SMS added to send queue for " + smsNumber);
+            pwmApplication.sendSmsUsingQueue( smsNumber, modifiedMessage, tokenSendInfo.getSessionLabel(), tokenSendInfo.getMacroMachine() );
+            LOGGER.debug( "token SMS added to send queue for " + smsNumber );
             return true;
         }
 
@@ -719,33 +824,39 @@ public class TokenService implements PwmService {
                 final List<TokenDestinationItem.Type> sentTypes,
                 final String email,
                 final String sms
-        ) {
-            final ValueObfuscator valueObfuscator = new ValueObfuscator(configuration);
+        )
+        {
+            final ValueObfuscator valueObfuscator = new ValueObfuscator( configuration );
             final StringBuilder displayDestAddress = new StringBuilder();
             {
-                if (sentTypes.contains(TokenDestinationItem.Type.email)) {
-                    displayDestAddress.append(valueObfuscator.maskEmail(email));
+                if ( sentTypes.contains( TokenDestinationItem.Type.email ) )
+                {
+                    displayDestAddress.append( valueObfuscator.maskEmail( email ) );
                 }
 
-                if (sentTypes.contains(TokenDestinationItem.Type.sms)) {
-                    if (displayDestAddress.length() > 0) {
-                        displayDestAddress.append(" & ");
+                if ( sentTypes.contains( TokenDestinationItem.Type.sms ) )
+                {
+                    if ( displayDestAddress.length() > 0 )
+                    {
+                        displayDestAddress.append( " & " );
                     }
-                    displayDestAddress.append(valueObfuscator.maskPhone(sms));
+                    displayDestAddress.append( valueObfuscator.maskPhone( sms ) );
                 }
             }
             return displayDestAddress.toString();
         }
     }
 
-    static TimeDuration maxTokenAge(final Configuration configuration) {
+    static TimeDuration maxTokenAge( final Configuration configuration )
+    {
         long maxValue = 0;
-        maxValue = Math.max(maxValue, configuration.readSettingAsLong(PwmSetting.TOKEN_LIFETIME));
-        maxValue = Math.max(maxValue, configuration.readSettingAsLong(PwmSetting.TOKEN_LIFETIME));
-        for (NewUserProfile newUserProfile : configuration.getNewUserProfiles().values()) {
-            maxValue = Math.max(maxValue, newUserProfile.readSettingAsLong(PwmSetting.NEWUSER_TOKEN_LIFETIME_EMAIL));
-            maxValue = Math.max(maxValue, newUserProfile.readSettingAsLong(PwmSetting.NEWUSER_TOKEN_LIFETIME_SMS));
+        maxValue = Math.max( maxValue, configuration.readSettingAsLong( PwmSetting.TOKEN_LIFETIME ) );
+        maxValue = Math.max( maxValue, configuration.readSettingAsLong( PwmSetting.TOKEN_LIFETIME ) );
+        for ( NewUserProfile newUserProfile : configuration.getNewUserProfiles().values() )
+        {
+            maxValue = Math.max( maxValue, newUserProfile.readSettingAsLong( PwmSetting.NEWUSER_TOKEN_LIFETIME_EMAIL ) );
+            maxValue = Math.max( maxValue, newUserProfile.readSettingAsLong( PwmSetting.NEWUSER_TOKEN_LIFETIME_SMS ) );
         }
-        return new TimeDuration(maxValue, TimeUnit.SECONDS);
+        return new TimeDuration( maxValue, TimeUnit.SECONDS );
     }
 }

+ 29 - 29
server/src/main/java/password/pwm/svc/wordlist/AbstractWordlist.java

@@ -75,8 +75,8 @@ abstract class AbstractWordlist implements Wordlist, PwmService
     protected volatile STATUS wlStatus = STATUS.NEW;
     protected LocalDB localDB;
 
-    protected static PwmLogger LOGGER = PwmLogger.forClass( AbstractWordlist.class );
-    protected static String DEBUG_LABEL = "Generic Word List";
+    protected PwmLogger logger = PwmLogger.forClass( AbstractWordlist.class );
+    protected String debugLabel = "Generic Word List";
 
     protected int storedSize = 0;
     protected boolean debugTrace;
@@ -133,7 +133,7 @@ abstract class AbstractWordlist implements Wordlist, PwmService
             }
             catch ( Exception e )
             {
-                LOGGER.warn( "error during startup: " + e.getMessage() );
+                logger.warn( "error during startup: " + e.getMessage() );
             }
         }, 0, TimeUnit.MILLISECONDS );
     }
@@ -145,8 +145,8 @@ abstract class AbstractWordlist implements Wordlist, PwmService
 
         if ( localDB == null )
         {
-            final String errorMsg = "LocalDB is not available, " + DEBUG_LABEL + " will remain closed";
-            LOGGER.warn( errorMsg );
+            final String errorMsg = "LocalDB is not available, " + debugLabel + " will remain closed";
+            logger.warn( errorMsg );
             lastError = new ErrorInformation( PwmError.ERROR_SERVICE_NOT_AVAILABLE, errorMsg );
             close();
             return;
@@ -161,11 +161,11 @@ abstract class AbstractWordlist implements Wordlist, PwmService
             final String errorMsg = "unexpected error while examining wordlist db: " + e.getMessage();
             if ( ( e instanceof PwmUnrecoverableException ) || ( e instanceof NullPointerException ) || ( e instanceof LocalDBException ) )
             {
-                LOGGER.warn( errorMsg );
+                logger.warn( errorMsg );
             }
             else
             {
-                LOGGER.warn( errorMsg, e );
+                logger.warn( errorMsg, e );
             }
             lastError = new ErrorInformation( PwmError.ERROR_SERVICE_NOT_AVAILABLE, errorMsg );
             populator = null;
@@ -240,13 +240,13 @@ abstract class AbstractWordlist implements Wordlist, PwmService
             final TimeDuration timeDuration = TimeDuration.fromCurrent( startTime );
             if ( timeDuration.isLongerThan( 100 ) )
             {
-                LOGGER.debug( "wordlist search time for " + testWords.size() + " wordlist permutations was greater then 100ms: " + timeDuration.asCompactString() );
+                logger.debug( "wordlist search time for " + testWords.size() + " wordlist permutations was greater then 100ms: " + timeDuration.asCompactString() );
             }
             return result;
         }
         catch ( Exception e )
         {
-            LOGGER.error( "database error checking for word: " + e.getMessage() );
+            logger.error( "database error checking for word: " + e.getMessage() );
         }
 
         return false;
@@ -273,7 +273,7 @@ abstract class AbstractWordlist implements Wordlist, PwmService
             }
             catch ( PwmUnrecoverableException e )
             {
-                LOGGER.error( "wordlist populator failed to exit" );
+                logger.error( "wordlist populator failed to exit" );
             }
         }
 
@@ -325,13 +325,13 @@ abstract class AbstractWordlist implements Wordlist, PwmService
 
         if ( wlStatus == STATUS.OPENING )
         {
-            final HealthRecord healthRecord = new HealthRecord( HealthStatus.CAUTION, HealthTopic.Application, this.DEBUG_LABEL + " is not yet open: " + this.getDebugStatus() );
+            final HealthRecord healthRecord = new HealthRecord( HealthStatus.CAUTION, HealthTopic.Application, this.debugLabel + " is not yet open: " + this.getDebugStatus() );
             returnList.add( healthRecord );
         }
 
         if ( lastError != null )
         {
-            final HealthRecord healthRecord = new HealthRecord( HealthStatus.WARN, HealthTopic.Application, this.DEBUG_LABEL + " error: " + lastError.toDebugStr() );
+            final HealthRecord healthRecord = new HealthRecord( HealthStatus.WARN, HealthTopic.Application, this.debugLabel + " error: " + lastError.toDebugStr() );
             returnList.add( healthRecord );
         }
         return Collections.unmodifiableList( returnList );
@@ -377,7 +377,7 @@ abstract class AbstractWordlist implements Wordlist, PwmService
 
         if ( !inputUrl.startsWith( "http:" ) && !inputUrl.startsWith( "https:" ) && !inputUrl.startsWith( "file:" ) )
         {
-            LOGGER.debug( "assuming configured auto-import url is a file url; derived url is " + inputUrl );
+            logger.debug( "assuming configured auto-import url is a file url; derived url is " + inputUrl );
             return "file:" + inputUrl;
         }
 
@@ -397,7 +397,7 @@ abstract class AbstractWordlist implements Wordlist, PwmService
     void writeMetadata( final StoredWordlistDataBean metadataBean )
     {
         pwmApplication.writeAppAttribute( getMetaDataAppAttribute(), metadataBean );
-        LOGGER.trace( "updated stored state: " + JsonUtil.serialize( metadataBean ) );
+        logger.trace( "updated stored state: " + JsonUtil.serialize( metadataBean ) );
     }
 
     @Override
@@ -412,7 +412,7 @@ abstract class AbstractWordlist implements Wordlist, PwmService
         {
             if ( !readMetadata().isCompleted() )
             {
-                LOGGER.debug( "beginning population using builtin source in background thread" );
+                logger.debug( "beginning population using builtin source in background thread" );
                 final Thread t = new Thread( ( ) ->
                 {
                     try
@@ -421,7 +421,7 @@ abstract class AbstractWordlist implements Wordlist, PwmService
                     }
                     catch ( Exception e )
                     {
-                        LOGGER.warn( "unexpected error during builtin source population process: " + e.getMessage(), e );
+                        logger.warn( "unexpected error during builtin source population process: " + e.getMessage(), e );
                     }
                     populator = null;
                 }, JavaHelper.makeThreadName( pwmApplication, WordlistManager.class ) );
@@ -445,7 +445,7 @@ abstract class AbstractWordlist implements Wordlist, PwmService
                 }
                 catch ( Exception e )
                 {
-                    LOGGER.error( "error during clear operation: " + e.getMessage() );
+                    logger.error( "error during clear operation: " + e.getMessage() );
                 }
             }, 0, TimeUnit.MILLISECONDS );
         }
@@ -465,7 +465,7 @@ abstract class AbstractWordlist implements Wordlist, PwmService
                 {
                     if ( !remoteHash.equals( readMetadata().getSha1hash() ) )
                     {
-                        LOGGER.debug( "auto-import url remote hash does not equal currently stored hash, will start auto-import" );
+                        logger.debug( "auto-import url remote hash does not equal currently stored hash, will start auto-import" );
                         populateAutoImport();
                     }
                 }
@@ -473,17 +473,17 @@ abstract class AbstractWordlist implements Wordlist, PwmService
                 if ( autoImportError != null )
                 {
                     final int retrySeconds = Integer.parseInt( pwmApplication.getConfig().readAppProperty( AppProperty.APPLICATION_WORDLIST_RETRY_SECONDS ) );
-                    LOGGER.error( "auto-import of remote wordlist failed, will retry in " + ( new TimeDuration( retrySeconds, TimeUnit.SECONDS ).asCompactString() ) );
+                    logger.error( "auto-import of remote wordlist failed, will retry in " + ( new TimeDuration( retrySeconds, TimeUnit.SECONDS ).asCompactString() ) );
                     executorService.schedule( ( ) ->
                     {
                         try
                         {
-                            LOGGER.debug( "attempting wordlist remote import" );
+                            logger.debug( "attempting wordlist remote import" );
                             checkPopulation();
                         }
                         catch ( Exception e )
                         {
-                            LOGGER.error( "error during auto-import retry: " + e.getMessage() );
+                            logger.error( "error during auto-import retry: " + e.getMessage() );
                         }
 
                     }, retrySeconds, TimeUnit.SECONDS );
@@ -493,7 +493,7 @@ abstract class AbstractWordlist implements Wordlist, PwmService
             {
                 if ( readMetadata().getSource() == StoredWordlistDataBean.Source.AutoImport )
                 {
-                    LOGGER.trace( "source list is from auto-import, but not currently configured for auto-import; clearing stored data" );
+                    logger.trace( "source list is from auto-import, but not currently configured for auto-import; clearing stored data" );
 
                     // clear previous auto-import wl
                     writeMetadata( StoredWordlistDataBean.builder().build() );
@@ -504,14 +504,14 @@ abstract class AbstractWordlist implements Wordlist, PwmService
             if ( !readMetadata().isCompleted() )
             {
                 needsBuiltinPopulating = true;
-                LOGGER.debug( "wordlist stored in database does not have a completed load status, will load built-in wordlist" );
+                logger.debug( "wordlist stored in database does not have a completed load status, will load built-in wordlist" );
             }
             else if ( StoredWordlistDataBean.Source.BuiltIn == readMetadata().getSource() )
             {
                 final String builtInWordlistHash = getBuiltInWordlistHash();
                 if ( !builtInWordlistHash.equals( readMetadata().getSha1hash() ) )
                 {
-                    LOGGER.debug( "wordlist stored in database does not have match checksum with built-in wordlist file, will load built-in wordlist" );
+                    logger.debug( "wordlist stored in database does not have match checksum with built-in wordlist file, will load built-in wordlist" );
                     needsBuiltinPopulating = true;
                 }
             }
@@ -580,7 +580,7 @@ abstract class AbstractWordlist implements Wordlist, PwmService
                 populationError = e instanceof PwmException
                         ? ( ( PwmException ) e ).getErrorInformation()
                         : new ErrorInformation( PwmError.ERROR_UNKNOWN, e.getMessage() );
-                LOGGER.error( "error during wordlist population: " + populationError.toDebugStr() );
+                logger.error( "error during wordlist population: " + populationError.toDebugStr() );
                 throw new PwmUnrecoverableException( populationError );
             }
             finally
@@ -626,7 +626,7 @@ abstract class AbstractWordlist implements Wordlist, PwmService
             catch ( Exception e )
             {
                 final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_UNKNOWN, "error during remote wordlist import: " + e.getMessage() );
-                LOGGER.error( errorInformation );
+                logger.error( errorInformation );
                 autoImportError = errorInformation;
             }
             finally
@@ -642,13 +642,13 @@ abstract class AbstractWordlist implements Wordlist, PwmService
             try
             {
                 final Instant startTime = Instant.now();
-                LOGGER.debug( "beginning read of auto-import wordlist url hash checksum from '" + wordlistConfiguration.getAutoImportUrl() + "'" );
+                logger.debug( "beginning read of auto-import wordlist url hash checksum from '" + wordlistConfiguration.getAutoImportUrl() + "'" );
                 inputStream = autoImportInputStream();
                 final ChecksumInputStream checksumInputStream = new ChecksumInputStream( CHECKSUM_HASH_ALG, inputStream );
                 JavaHelper.copyWhilePredicate( checksumInputStream, new NullOutputStream(), o -> wlStatus != STATUS.CLOSED );
                 IOUtils.copy( checksumInputStream, new NullOutputStream() );
                 final String hash = JavaHelper.binaryArrayToHex( checksumInputStream.closeAndFinalChecksum() );
-                LOGGER.debug( "completed read of auto-import wordlist url hash, value=" + hash + " (" + TimeDuration.fromCurrent( startTime ).asCompactString() + ")" );
+                logger.debug( "completed read of auto-import wordlist url hash, value=" + hash + " (" + TimeDuration.fromCurrent( startTime ).asCompactString() + ")" );
                 autoImportError = null;
                 return hash;
             }
@@ -658,7 +658,7 @@ abstract class AbstractWordlist implements Wordlist, PwmService
                         PwmError.ERROR_UNKNOWN,
                         "error reading from remote wordlist auto-import url: " + JavaHelper.readHostileExceptionMessage( e )
                 );
-                LOGGER.error( errorInformation );
+                logger.error( errorInformation );
                 autoImportError = errorInformation;
             }
             finally

+ 7 - 5
server/src/main/java/password/pwm/svc/wordlist/Populator.java

@@ -137,11 +137,12 @@ class Populator
         final int lps = perReportStats.getElapsedSeconds() <= 0 ? 0 : perReportStats.getLines() / perReportStats.getElapsedSeconds();
 
         perReportStats = new PopulationStats();
-        return rootWordlist.DEBUG_LABEL + ", lines/second="
+        return rootWordlist.debugLabel + ", lines/second="
                 + lps + ", line=" + overallStats.getLines() + ""
                 + " current zipEntry=" + zipFileReader.currentZipName();
     }
 
+    @SuppressWarnings( "checkstyle:InnerAssignment" )
     void populate( ) throws IOException, LocalDBException, PwmUnrecoverableException
     {
         try
@@ -153,6 +154,7 @@ class Populator
             long lastReportTime = System.currentTimeMillis() - ( long ) ( DEBUG_OUTPUT_FREQUENCY.getTotalMilliseconds() * 0.33 );
 
             String line;
+
             while ( !abortFlag && ( line = zipFileReader.nextLine() ) != null )
             {
 
@@ -176,7 +178,7 @@ class Populator
 
             if ( abortFlag )
             {
-                LOGGER.warn( "pausing " + rootWordlist.DEBUG_LABEL + " population" );
+                LOGGER.warn( "pausing " + rootWordlist.debugLabel + " population" );
             }
             else
             {
@@ -230,7 +232,7 @@ class Populator
         if ( bufferedWords.size() > 0 )
         {
             final StringBuilder sb = new StringBuilder();
-            sb.append( rootWordlist.DEBUG_LABEL ).append( " " );
+            sb.append( rootWordlist.debugLabel ).append( " " );
             sb.append( "read " ).append( loopLines ).append( ", " );
             sb.append( "saved " );
             sb.append( bufferedWords.size() ).append( " words" );
@@ -253,11 +255,11 @@ class Populator
         final int wordlistSize = localDB.size( rootWordlist.getWordlistDB() );
         if ( wordlistSize < 1 )
         {
-            throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_UNKNOWN, rootWordlist.DEBUG_LABEL + " population completed, but no words stored" ) );
+            throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_UNKNOWN, rootWordlist.debugLabel + " population completed, but no words stored" ) );
         }
 
         final StringBuilder sb = new StringBuilder();
-        sb.append( rootWordlist.DEBUG_LABEL );
+        sb.append( rootWordlist.debugLabel );
         sb.append( " population complete, added " ).append( wordlistSize );
         sb.append( " total words in " ).append( new TimeDuration( overallStats.getElapsedSeconds() * 1000 ).asCompactString() );
         {

+ 4 - 4
server/src/main/java/password/pwm/svc/wordlist/SeedlistManager.java

@@ -42,7 +42,7 @@ public class SeedlistManager extends AbstractWordlist implements Wordlist
 
     public SeedlistManager( )
     {
-        LOGGER = PwmLogger.forClass( SeedlistManager.class );
+        logger = PwmLogger.forClass( SeedlistManager.class );
     }
 
     public String randomSeed( )
@@ -68,12 +68,12 @@ public class SeedlistManager extends AbstractWordlist implements Wordlist
         }
         catch ( Exception e )
         {
-            LOGGER.warn( "error while generating random word: " + e.getMessage() );
+            logger.warn( "error while generating random word: " + e.getMessage() );
         }
 
         if ( debugTrace )
         {
-            LOGGER.trace( "getRandomSeed fetch time: " + TimeDuration.fromCurrent( startTime ).asCompactString() );
+            logger.trace( "getRandomSeed fetch time: " + TimeDuration.fromCurrent( startTime ).asCompactString() );
         }
         return returnValue;
     }
@@ -94,7 +94,7 @@ public class SeedlistManager extends AbstractWordlist implements Wordlist
         final int maxSize = Integer.parseInt( pwmApplication.getConfig().readAppProperty( AppProperty.WORDLIST_CHAR_LENGTH_MAX ) );
 
         this.wordlistConfiguration = new WordlistConfiguration( true, 0, seedlistUrl, minSize, maxSize );
-        this.DEBUG_LABEL = PwmConstants.PWM_APP_NAME + "-Seedist";
+        this.debugLabel = PwmConstants.PWM_APP_NAME + "-Seedist";
         backgroundStartup();
     }
 

+ 2 - 2
server/src/main/java/password/pwm/svc/wordlist/WordlistManager.java

@@ -43,7 +43,7 @@ public class WordlistManager extends AbstractWordlist implements Wordlist
 
     public WordlistManager( )
     {
-        LOGGER = PwmLogger.forClass( WordlistManager.class );
+        logger = PwmLogger.forClass( WordlistManager.class );
     }
 
 
@@ -69,7 +69,7 @@ public class WordlistManager extends AbstractWordlist implements Wordlist
         final int maxSize = Integer.parseInt( pwmApplication.getConfig().readAppProperty( AppProperty.WORDLIST_CHAR_LENGTH_MAX ) );
 
         this.wordlistConfiguration = new WordlistConfiguration( caseSensitive, checkSize, wordlistUrl, minSize, maxSize );
-        this.DEBUG_LABEL = PwmConstants.PWM_APP_NAME + "-Wordlist";
+        this.debugLabel = PwmConstants.PWM_APP_NAME + "-Wordlist";
         backgroundStartup();
     }
 

+ 1 - 0
server/src/main/java/password/pwm/util/LDAPPermissionCalculator.java

@@ -228,6 +228,7 @@ public class LDAPPermissionCalculator implements Serializable
         return permissionRecords;
     }
 
+    @SuppressWarnings( "checkstyle:MethodLength" )
     private Collection<LDAPPermissionInfo> figurePermissionInfos( final PwmSetting pwmSetting, final String profile )
     {
 

+ 2 - 0
server/src/main/java/password/pwm/util/PwmPasswordRuleValidator.java

@@ -193,6 +193,7 @@ public class PwmPasswordRuleValidator
         return internalPwmPolicyValidator( passwordString, oldPasswordString, userInfo, flags );
     }
 
+    @SuppressWarnings( "checkstyle:MethodLength" )
     public List<ErrorInformation> internalPwmPolicyValidator(
             final String passwordString,
             final String oldPasswordString,
@@ -786,6 +787,7 @@ public class PwmPasswordRuleValidator
         return returnedErrors;
     }
 
+    @SuppressWarnings( "checkstyle:MethodLength" )
     private static List<ErrorInformation> basicSyntaxRuleChecks(
             final String password,
             final PwmPasswordPolicy policy,

+ 293 - 204
server/src/main/java/password/pwm/util/RandomPasswordGenerator.java

@@ -58,30 +58,31 @@ import java.util.Map;
 import java.util.Set;
 
 /**
- * Random password generator
+ * Random password generator.
  *
  * @author Jason D. Rivard
  */
-public class RandomPasswordGenerator {
+public class RandomPasswordGenerator
+{
     /**
      * Default seed phrases.  Most basic ASCII chars, except those that are visually ambiguous are
      * represented here.  No multi-character phrases are included.
      */
-    public static final Set<String> DEFAULT_SEED_PHRASES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
+    public static final Set<String> DEFAULT_SEED_PHRASES = Collections.unmodifiableSet( new HashSet<>( Arrays.asList(
             "a", "b", "c", "d", "e", "f", "g", "h", "j", "k", "m", "n", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
             "a", "b", "c", "d", "e", "f", "g", "h", "j", "k", "m", "n", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
             "a", "b", "c", "d", "e", "f", "g", "h", "j", "k", "m", "n", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
             "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
             "2", "3", "4", "5", "6", "7", "8", "9",
             "@", "&", "!", "?", "%", "$", "#", "^", ")", "(", "+", "-", "=", ".", ",", "/", "\\"
-    )));
+    ) ) );
 
 
-    private static final SeedMachine DEFAULT_SEED_MACHINE = new SeedMachine(DEFAULT_SEED_PHRASES);
+    private static final SeedMachine DEFAULT_SEED_MACHINE = new SeedMachine( DEFAULT_SEED_PHRASES );
 
     private static final PwmRandom RANDOM = PwmRandom.getInstance();
 
-    private static final PwmLogger LOGGER = PwmLogger.forClass(RandomPasswordGenerator.class);
+    private static final PwmLogger LOGGER = PwmLogger.forClass( RandomPasswordGenerator.class );
 
     public static PasswordData createRandomPassword(
             final PwmSession pwmSession,
@@ -90,7 +91,7 @@ public class RandomPasswordGenerator {
             throws PwmUnrecoverableException
     {
         final PwmPasswordPolicy userPasswordPolicy = pwmSession.getUserInfo().getPasswordPolicy();
-        return createRandomPassword(pwmSession.getLabel(), userPasswordPolicy, pwmApplication);
+        return createRandomPassword( pwmSession.getLabel(), userPasswordPolicy, pwmApplication );
     }
 
     public static PasswordData createRandomPassword(
@@ -101,7 +102,7 @@ public class RandomPasswordGenerator {
             throws PwmUnrecoverableException
     {
         final RandomGeneratorConfig randomGeneratorConfig = RandomGeneratorConfig.builder()
-                .passwordPolicy(passwordPolicy)
+                .passwordPolicy( passwordPolicy )
                 .build();
 
         return createRandomPassword(
@@ -119,13 +120,12 @@ public class RandomPasswordGenerator {
      * If there is an identifiable reason the password can not be created (such as mis-configured rules) then
      * an {@link com.novell.ldapchai.exception.ImpossiblePasswordPolicyException} will be thrown.
      *
-     * @param sessionLabel A valid pwmSession
+     * @param sessionLabel          A valid pwmSession
      * @param randomGeneratorConfig Policy to be used during generation
-     * @param pwmApplication Used to read configuration, seedmanager and other services.
+     * @param pwmApplication        Used to read configuration, seedmanager and other services.
      * @return A randomly generated password value that meets the requirements of this {@code PasswordPolicy}
-     * @throws com.novell.ldapchai.exception.ImpossiblePasswordPolicyException
-     *          If there is no way to create a password using the configured rules and
-     *          default seed phrase
+     * @throws com.novell.ldapchai.exception.ImpossiblePasswordPolicyException If there is no way to create a password using the configured rules and
+     *                                                                         default seed phrase
      */
     public static PasswordData createRandomPassword(
             final SessionLabel sessionLabel,
@@ -136,34 +136,40 @@ public class RandomPasswordGenerator {
     {
         final Instant startTimeMS = Instant.now();
 
-        randomGeneratorConfig.validateSettings(pwmApplication);
+        randomGeneratorConfig.validateSettings( pwmApplication );
 
         final RandomGeneratorConfig effectiveConfig;
         {
-            if (randomGeneratorConfig.getSeedlistPhrases() == null || randomGeneratorConfig.getSeedlistPhrases().isEmpty()) {
+            if ( randomGeneratorConfig.getSeedlistPhrases() == null || randomGeneratorConfig.getSeedlistPhrases().isEmpty() )
+            {
                 Set<String> seeds = DEFAULT_SEED_PHRASES;
 
                 final SeedlistManager seedlistManager = pwmApplication.getSeedlistManager();
-                if (seedlistManager != null && seedlistManager.status() == PwmService.STATUS.OPEN && seedlistManager.size() > 0) {
+                if ( seedlistManager != null && seedlistManager.status() == PwmService.STATUS.OPEN && seedlistManager.size() > 0 )
+                {
                     seeds = new HashSet<>();
                     int safetyCounter = 0;
-                    while (seeds.size() < 10 && safetyCounter < 100) {
+                    while ( seeds.size() < 10 && safetyCounter < 100 )
+                    {
                         safetyCounter++;
                         final String randomWord = seedlistManager.randomSeed();
-                        if (randomWord != null) {
-                            seeds.add(randomWord);
+                        if ( randomWord != null )
+                        {
+                            seeds.add( randomWord );
                         }
                     }
                 }
                 effectiveConfig = randomGeneratorConfig.toBuilder()
-                        .seedlistPhrases(seeds)
+                        .seedlistPhrases( seeds )
                         .build();
-            } else {
+            }
+            else
+            {
                 effectiveConfig = randomGeneratorConfig;
             }
         }
 
-        final SeedMachine seedMachine = new SeedMachine(normalizeSeeds(effectiveConfig.getSeedlistPhrases()));
+        final SeedMachine seedMachine = new SeedMachine( normalizeSeeds( effectiveConfig.getSeedlistPhrases() ) );
 
         int tryCount = 0;
         final StringBuilder password = new StringBuilder();
@@ -172,242 +178,288 @@ public class RandomPasswordGenerator {
         final PwmPasswordPolicy randomGenPolicy;
         {
             final Map<String, String> newPolicyMap = new HashMap<>();
-            newPolicyMap.putAll(effectiveConfig.getPasswordPolicy().getPolicyMap());
+            newPolicyMap.putAll( effectiveConfig.getPasswordPolicy().getPolicyMap() );
 
-            final String max = newPolicyMap.put(PwmPasswordRule.MaximumLength.getKey(), String.valueOf(effectiveConfig.getMaximumLength()));
+            final String max = newPolicyMap.put( PwmPasswordRule.MaximumLength.getKey(), String.valueOf( effectiveConfig.getMaximumLength() ) );
 
-            if (effectiveConfig.getMinimumLength() > effectiveConfig.getPasswordPolicy().getRuleHelper().readIntValue(PwmPasswordRule.MinimumLength)) {
-                newPolicyMap.put(PwmPasswordRule.MinimumLength.getKey(), String.valueOf(effectiveConfig.getMinimumLength()));
+            if ( effectiveConfig.getMinimumLength() > effectiveConfig.getPasswordPolicy().getRuleHelper().readIntValue( PwmPasswordRule.MinimumLength ) )
+            {
+                newPolicyMap.put( PwmPasswordRule.MinimumLength.getKey(), String.valueOf( effectiveConfig.getMinimumLength() ) );
             }
-            if (effectiveConfig.getMaximumLength() < effectiveConfig.getPasswordPolicy().getRuleHelper().readIntValue(PwmPasswordRule.MaximumLength)) {
-                newPolicyMap.put(PwmPasswordRule.MaximumLength.getKey(), String.valueOf(effectiveConfig.getMaximumLength()));
+            if ( effectiveConfig.getMaximumLength() < effectiveConfig.getPasswordPolicy().getRuleHelper().readIntValue( PwmPasswordRule.MaximumLength ) )
+            {
+                newPolicyMap.put( PwmPasswordRule.MaximumLength.getKey(), String.valueOf( effectiveConfig.getMaximumLength() ) );
             }
-            if (effectiveConfig.getMinimumStrength() > effectiveConfig.getPasswordPolicy().getRuleHelper().readIntValue(PwmPasswordRule.MinimumStrength)) {
-                newPolicyMap.put(PwmPasswordRule.MinimumStrength.getKey(), String.valueOf(effectiveConfig.getMinimumStrength()));
+            if ( effectiveConfig.getMinimumStrength() > effectiveConfig.getPasswordPolicy().getRuleHelper().readIntValue( PwmPasswordRule.MinimumStrength ) )
+            {
+                newPolicyMap.put( PwmPasswordRule.MinimumStrength.getKey(), String.valueOf( effectiveConfig.getMinimumStrength() ) );
             }
-            randomGenPolicy = PwmPasswordPolicy.createPwmPasswordPolicy(newPolicyMap);
+            randomGenPolicy = PwmPasswordPolicy.createPwmPasswordPolicy( newPolicyMap );
         }
 
         // initial creation
-        password.append(generateNewPassword(seedMachine, effectiveConfig.getMinimumLength()));
+        password.append( generateNewPassword( seedMachine, effectiveConfig.getMinimumLength() ) );
 
         // read a rule validator
-        final PwmPasswordRuleValidator pwmPasswordRuleValidator = new PwmPasswordRuleValidator(pwmApplication, randomGenPolicy);
+        final PwmPasswordRuleValidator pwmPasswordRuleValidator = new PwmPasswordRuleValidator( pwmApplication, randomGenPolicy );
 
         // modify until it passes all the rules
-        final int MAX_TRY_COUNT = Integer.parseInt(pwmApplication.getConfig().readAppProperty(AppProperty.PASSWORD_RANDOMGEN_MAX_ATTEMPTS));
-        final int JITTER_COUNT = Integer.parseInt(pwmApplication.getConfig().readAppProperty(AppProperty.PASSWORD_RANDOMGEN_JITTER_COUNT));
+        final int maxTryCount = Integer.parseInt( pwmApplication.getConfig().readAppProperty( AppProperty.PASSWORD_RANDOMGEN_MAX_ATTEMPTS ) );
+        final int jitterCount = Integer.parseInt( pwmApplication.getConfig().readAppProperty( AppProperty.PASSWORD_RANDOMGEN_JITTER_COUNT ) );
         boolean validPassword = false;
-        while (!validPassword && tryCount < MAX_TRY_COUNT) {
+        while ( !validPassword && tryCount < maxTryCount )
+        {
             tryCount++;
             validPassword = true;
 
-            if (tryCount % JITTER_COUNT == 0) {
-                password.delete(0,password.length());
-                password.append(generateNewPassword(seedMachine, effectiveConfig.getMinimumLength()));
+            if ( tryCount % jitterCount == 0 )
+            {
+                password.delete( 0, password.length() );
+                password.append( generateNewPassword( seedMachine, effectiveConfig.getMinimumLength() ) );
             }
 
             final List<ErrorInformation> errors = pwmPasswordRuleValidator.internalPwmPolicyValidator(
-                    password.toString(), null, null, PwmPasswordRuleValidator.Flag.FailFast);
-            if (errors != null && !errors.isEmpty()) {
+                    password.toString(), null, null, PwmPasswordRuleValidator.Flag.FailFast );
+            if ( errors != null && !errors.isEmpty() )
+            {
                 validPassword = false;
-                modifyPasswordBasedOnErrors(password, errors, seedMachine);
-            } else if (checkPasswordAgainstDisallowedHttpValues(pwmApplication.getConfig(), password.toString())) {
+                modifyPasswordBasedOnErrors( password, errors, seedMachine );
+            }
+            else if ( checkPasswordAgainstDisallowedHttpValues( pwmApplication.getConfig(), password.toString() ) )
+            {
                 validPassword = false;
-                password.delete(0, password.length());
-                password.append(generateNewPassword(seedMachine, effectiveConfig.getMinimumLength()));
+                password.delete( 0, password.length() );
+                password.append( generateNewPassword( seedMachine, effectiveConfig.getMinimumLength() ) );
             }
         }
 
         // report outcome
         {
-            final TimeDuration td = TimeDuration.fromCurrent(startTimeMS);
-            if (validPassword) {
-                LOGGER.trace(sessionLabel, "finished random password generation in " + td.asCompactString() + " after " + tryCount + " tries.");
-            } else {
-                final List<ErrorInformation> errors = pwmPasswordRuleValidator.internalPwmPolicyValidator(password.toString(), null, null);
-                final int judgeLevel = PasswordUtility.judgePasswordStrength(pwmApplication.getConfig(), password.toString());
+            final TimeDuration td = TimeDuration.fromCurrent( startTimeMS );
+            if ( validPassword )
+            {
+                LOGGER.trace( sessionLabel, "finished random password generation in " + td.asCompactString() + " after " + tryCount + " tries." );
+            }
+            else
+            {
+                final List<ErrorInformation> errors = pwmPasswordRuleValidator.internalPwmPolicyValidator( password.toString(), null, null );
+                final int judgeLevel = PasswordUtility.judgePasswordStrength( pwmApplication.getConfig(), password.toString() );
                 final StringBuilder sb = new StringBuilder();
-                sb.append("failed random password generation after ").append(td.asCompactString()).append(" after ").append(tryCount).append(" tries. ");
-                sb.append("(errors=").append(errors.size()).append(", judgeLevel=").append(judgeLevel);
-                LOGGER.error(sessionLabel, sb.toString());
+                sb.append( "failed random password generation after " ).append( td.asCompactString() ).append( " after " ).append( tryCount ).append( " tries. " );
+                sb.append( "(errors=" ).append( errors.size() ).append( ", judgeLevel=" ).append( judgeLevel );
+                LOGGER.error( sessionLabel, sb.toString() );
             }
         }
 
-        StatisticsManager.incrementStat(pwmApplication, Statistic.GENERATED_PASSWORDS);
+        StatisticsManager.incrementStat( pwmApplication, Statistic.GENERATED_PASSWORDS );
 
-        final String logText = "real-time random password generator called" +
-                " (" + TimeDuration.compactFromCurrent(startTimeMS) +
-                ")";
-        LOGGER.trace(sessionLabel, logText);
+        final String logText = "real-time random password generator called"
+                + " (" + TimeDuration.compactFromCurrent( startTimeMS ) + ")";
+        LOGGER.trace( sessionLabel, logText );
 
-        return new PasswordData(password.toString());
+        return new PasswordData( password.toString() );
     }
 
     private static void modifyPasswordBasedOnErrors(
             final StringBuilder password,
             final List<ErrorInformation> errors,
             final SeedMachine seedMachine
-    ) {
-        if (password == null || errors == null || errors.isEmpty()) {
+    )
+    {
+        if ( password == null || errors == null || errors.isEmpty() )
+        {
             return;
         }
 
         final Set<PwmError> errorMessages = new HashSet<>();
-        for (final ErrorInformation errorInfo : errors) {
-            errorMessages.add(errorInfo.getError());
+        for ( final ErrorInformation errorInfo : errors )
+        {
+            errorMessages.add( errorInfo.getError() );
         }
 
         boolean touched = false;
 
-        if (errorMessages.contains(PwmError.PASSWORD_TOO_SHORT)) {
-            addRandChar(password, seedMachine.getAllChars());
+        if ( errorMessages.contains( PwmError.PASSWORD_TOO_SHORT ) )
+        {
+            addRandChar( password, seedMachine.getAllChars() );
             touched = true;
         }
 
-        if (errorMessages.contains(PwmError.PASSWORD_TOO_LONG)) {
-            password.deleteCharAt(RANDOM.nextInt(password.length()));
+        if ( errorMessages.contains( PwmError.PASSWORD_TOO_LONG ) )
+        {
+            password.deleteCharAt( RANDOM.nextInt( password.length() ) );
             touched = true;
         }
 
-        if (errorMessages.contains(PwmError.PASSWORD_FIRST_IS_NUMERIC) || errorMessages.contains(PwmError.PASSWORD_FIRST_IS_SPECIAL)) {
-            password.deleteCharAt(0);
+        if ( errorMessages.contains( PwmError.PASSWORD_FIRST_IS_NUMERIC ) || errorMessages.contains( PwmError.PASSWORD_FIRST_IS_SPECIAL ) )
+        {
+            password.deleteCharAt( 0 );
             touched = true;
         }
 
-        if (errorMessages.contains(PwmError.PASSWORD_LAST_IS_NUMERIC) || errorMessages.contains(PwmError.PASSWORD_LAST_IS_SPECIAL)) {
-            password.deleteCharAt(password.length() - 1);
+        if ( errorMessages.contains( PwmError.PASSWORD_LAST_IS_NUMERIC ) || errorMessages.contains( PwmError.PASSWORD_LAST_IS_SPECIAL ) )
+        {
+            password.deleteCharAt( password.length() - 1 );
             touched = true;
         }
 
-        if (errorMessages.contains(PwmError.PASSWORD_NOT_ENOUGH_NUM)) {
-            addRandChar(password, seedMachine.getNumChars());
+        if ( errorMessages.contains( PwmError.PASSWORD_NOT_ENOUGH_NUM ) )
+        {
+            addRandChar( password, seedMachine.getNumChars() );
             touched = true;
         }
 
-        if (errorMessages.contains(PwmError.PASSWORD_NOT_ENOUGH_SPECIAL)) {
-            addRandChar(password, seedMachine.getSpecialChars());
+        if ( errorMessages.contains( PwmError.PASSWORD_NOT_ENOUGH_SPECIAL ) )
+        {
+            addRandChar( password, seedMachine.getSpecialChars() );
             touched = true;
         }
 
-        if (errorMessages.contains(PwmError.PASSWORD_NOT_ENOUGH_UPPER)) {
-            addRandChar(password, seedMachine.getUpperChars());
+        if ( errorMessages.contains( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) )
+        {
+            addRandChar( password, seedMachine.getUpperChars() );
             touched = true;
         }
 
-        if (errorMessages.contains(PwmError.PASSWORD_NOT_ENOUGH_LOWER)) {
-            addRandChar(password, seedMachine.getLowerChars());
+        if ( errorMessages.contains( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) )
+        {
+            addRandChar( password, seedMachine.getLowerChars() );
             touched = true;
         }
 
-        PasswordCharCounter passwordCharCounter = new PasswordCharCounter(password.toString());
-        if (errorMessages.contains(PwmError.PASSWORD_TOO_MANY_NUMERIC) && passwordCharCounter.getNumericCharCount() > 0) {
-            deleteRandChar(password, passwordCharCounter.getNumericChars());
+        PasswordCharCounter passwordCharCounter = new PasswordCharCounter( password.toString() );
+        if ( errorMessages.contains( PwmError.PASSWORD_TOO_MANY_NUMERIC ) && passwordCharCounter.getNumericCharCount() > 0 )
+        {
+            deleteRandChar( password, passwordCharCounter.getNumericChars() );
             touched = true;
-            passwordCharCounter = new PasswordCharCounter(password.toString());
+            passwordCharCounter = new PasswordCharCounter( password.toString() );
         }
 
-        if (errorMessages.contains(PwmError.PASSWORD_TOO_MANY_SPECIAL) && passwordCharCounter.getSpecialCharsCount() > 0) {
-            deleteRandChar(password, passwordCharCounter.getSpecialChars());
+        if ( errorMessages.contains( PwmError.PASSWORD_TOO_MANY_SPECIAL ) && passwordCharCounter.getSpecialCharsCount() > 0 )
+        {
+            deleteRandChar( password, passwordCharCounter.getSpecialChars() );
             touched = true;
-            passwordCharCounter = new PasswordCharCounter(password.toString());
+            passwordCharCounter = new PasswordCharCounter( password.toString() );
         }
 
-        if (errorMessages.contains(PwmError.PASSWORD_TOO_MANY_UPPER) && passwordCharCounter.getUpperCharCount() > 0) {
-            deleteRandChar(password, passwordCharCounter.getUpperChars());
+        if ( errorMessages.contains( PwmError.PASSWORD_TOO_MANY_UPPER ) && passwordCharCounter.getUpperCharCount() > 0 )
+        {
+            deleteRandChar( password, passwordCharCounter.getUpperChars() );
             touched = true;
-            passwordCharCounter = new PasswordCharCounter(password.toString());
+            passwordCharCounter = new PasswordCharCounter( password.toString() );
         }
 
-        if (errorMessages.contains(PwmError.PASSWORD_TOO_MANY_LOWER) && passwordCharCounter.getLowerCharCount() > 0) {
-            deleteRandChar(password, passwordCharCounter.getLowerChars());
+        if ( errorMessages.contains( PwmError.PASSWORD_TOO_MANY_LOWER ) && passwordCharCounter.getLowerCharCount() > 0 )
+        {
+            deleteRandChar( password, passwordCharCounter.getLowerChars() );
             touched = true;
         }
 
-        if (errorMessages.contains(PwmError.PASSWORD_TOO_WEAK)) {
-            randomPasswordModifier(password, seedMachine);
+        if ( errorMessages.contains( PwmError.PASSWORD_TOO_WEAK ) )
+        {
+            randomPasswordModifier( password, seedMachine );
             touched = true;
         }
 
-        if (!touched) { // dunno whats wrong, try just deleting a RANDOM char, and hope a re-insert will add another.
-            randomPasswordModifier(password, seedMachine);
+        if ( !touched )
+        {
+            // dunno whats wrong, try just deleting a RANDOM char, and hope a re-insert will add another.
+            randomPasswordModifier( password, seedMachine );
         }
     }
 
-    private static void deleteRandChar(final StringBuilder password, final String charsToRemove)
-            throws ImpossiblePasswordPolicyException {
+    private static void deleteRandChar( final StringBuilder password, final String charsToRemove )
+            throws ImpossiblePasswordPolicyException
+    {
         final List<Integer> removePossibilities = new ArrayList<>();
-        for (int i = 0; i < password.length(); i++) {
-            final char loopChar = password.charAt(i);
-            final int index = charsToRemove.indexOf(loopChar);
-            if (index != -1) {
-                removePossibilities.add(i);
+        for ( int i = 0; i < password.length(); i++ )
+        {
+            final char loopChar = password.charAt( i );
+            final int index = charsToRemove.indexOf( loopChar );
+            if ( index != -1 )
+            {
+                removePossibilities.add( i );
             }
         }
-        if (removePossibilities.isEmpty()) {
-            throw new ImpossiblePasswordPolicyException(ImpossiblePasswordPolicyException.ErrorEnum.UNEXPECTED_ERROR);
+        if ( removePossibilities.isEmpty() )
+        {
+            throw new ImpossiblePasswordPolicyException( ImpossiblePasswordPolicyException.ErrorEnum.UNEXPECTED_ERROR );
         }
-        final Integer charToDelete = removePossibilities.get(RANDOM.nextInt(removePossibilities.size()));
-        password.deleteCharAt(charToDelete);
+        final Integer charToDelete = removePossibilities.get( RANDOM.nextInt( removePossibilities.size() ) );
+        password.deleteCharAt( charToDelete );
     }
 
-    private static void randomPasswordModifier(final StringBuilder password, final SeedMachine seedMachine) {
-        switch (RANDOM.nextInt(6)) {
+    private static void randomPasswordModifier( final StringBuilder password, final SeedMachine seedMachine )
+    {
+        switch ( RANDOM.nextInt( 6 ) )
+        {
             case 0:
             case 1:
-                addRandChar(password, seedMachine.getSpecialChars());
+                addRandChar( password, seedMachine.getSpecialChars() );
                 break;
             case 2:
             case 3:
-                addRandChar(password, seedMachine.getNumChars());
+                addRandChar( password, seedMachine.getNumChars() );
                 break;
             case 4:
-                addRandChar(password, seedMachine.getUpperChars());
+                addRandChar( password, seedMachine.getUpperChars() );
                 break;
             case 5:
-                addRandChar(password, seedMachine.getLowerChars());
+                addRandChar( password, seedMachine.getLowerChars() );
                 break;
             default:
-                switchRandomCase(password);
+                switchRandomCase( password );
                 break;
         }
     }
 
-    private static void switchRandomCase(final StringBuilder password) {
-        for (int i = 0; i < password.length(); i++) {
-            final int randspot = RANDOM.nextInt(password.length());
-            final char oldChar = password.charAt(randspot);
-            if (Character.isLetter(oldChar)) {
-                final char newChar = Character.isUpperCase(oldChar) ? Character.toLowerCase(oldChar) : Character.toUpperCase(oldChar);
-                password.deleteCharAt(randspot);
-                password.insert(randspot, newChar);
+    private static void switchRandomCase( final StringBuilder password )
+    {
+        for ( int i = 0; i < password.length(); i++ )
+        {
+            final int randspot = RANDOM.nextInt( password.length() );
+            final char oldChar = password.charAt( randspot );
+            if ( Character.isLetter( oldChar ) )
+            {
+                final char newChar = Character.isUpperCase( oldChar ) ? Character.toLowerCase( oldChar ) : Character.toUpperCase( oldChar );
+                password.deleteCharAt( randspot );
+                password.insert( randspot, newChar );
                 return;
             }
         }
     }
 
-    private static void addRandChar(final StringBuilder password, final String allowedChars)
-            throws ImpossiblePasswordPolicyException {
-        final int insertPosition = RANDOM.nextInt(password.length());
-        addRandChar(password, allowedChars, insertPosition);
+    private static void addRandChar( final StringBuilder password, final String allowedChars )
+            throws ImpossiblePasswordPolicyException
+    {
+        final int insertPosition = RANDOM.nextInt( password.length() );
+        addRandChar( password, allowedChars, insertPosition );
     }
 
-    private static void addRandChar(final StringBuilder password, final String allowedChars, final int insertPosition)
-            throws ImpossiblePasswordPolicyException {
-        if (allowedChars.length() < 1) {
-            throw new ImpossiblePasswordPolicyException(ImpossiblePasswordPolicyException.ErrorEnum.REQUIRED_CHAR_NOT_ALLOWED);
-        } else {
-            final int newCharPosition = RANDOM.nextInt(allowedChars.length());
-            final char charToAdd = allowedChars.charAt(newCharPosition);
-            password.insert(insertPosition, charToAdd);
+    private static void addRandChar( final StringBuilder password, final String allowedChars, final int insertPosition )
+            throws ImpossiblePasswordPolicyException
+    {
+        if ( allowedChars.length() < 1 )
+        {
+            throw new ImpossiblePasswordPolicyException( ImpossiblePasswordPolicyException.ErrorEnum.REQUIRED_CHAR_NOT_ALLOWED );
+        }
+        else
+        {
+            final int newCharPosition = RANDOM.nextInt( allowedChars.length() );
+            final char charToAdd = allowedChars.charAt( newCharPosition );
+            password.insert( insertPosition, charToAdd );
         }
     }
 
-    private static boolean checkPasswordAgainstDisallowedHttpValues(final Configuration config, final String password) {
-        if (config != null && password != null) {
-            final List<String> disallowedInputs = config.readSettingAsStringArray(PwmSetting.DISALLOWED_HTTP_INPUTS);
-            for (final String loopRegex : disallowedInputs) {
-                if (password.matches(loopRegex)) {
+    private static boolean checkPasswordAgainstDisallowedHttpValues( final Configuration config, final String password )
+    {
+        if ( config != null && password != null )
+        {
+            final List<String> disallowedInputs = config.readSettingAsStringArray( PwmSetting.DISALLOWED_HTTP_INPUTS );
+            for ( final String loopRegex : disallowedInputs )
+            {
+                if ( password.matches( loopRegex ) )
+                {
                     return true;
                 }
             }
@@ -415,10 +467,12 @@ public class RandomPasswordGenerator {
         return false;
     }
 
-    private RandomPasswordGenerator() {
+    private RandomPasswordGenerator( )
+    {
     }
 
-    protected static class SeedMachine {
+    protected static class SeedMachine
+    {
         private final Collection<String> seeds;
         private final String allChars;
         private final String numChars;
@@ -426,117 +480,144 @@ public class RandomPasswordGenerator {
         private final String upperChars;
         private final String lowerChars;
 
-        public SeedMachine(final Collection<String> seeds) {
+        public SeedMachine( final Collection<String> seeds )
+        {
             this.seeds = seeds;
 
             {
                 final StringBuilder sb = new StringBuilder();
-                for (final String s : seeds) {
-                    for (final Character c : s.toCharArray()) {
-                        if (sb.indexOf(c.toString()) == -1) {
-                            sb.append(c);
+                for ( final String s : seeds )
+                {
+                    for ( final Character c : s.toCharArray() )
+                    {
+                        if ( sb.indexOf( c.toString() ) == -1 )
+                        {
+                            sb.append( c );
                         }
                     }
                 }
-                allChars = sb.length() > 2 ? sb.toString() : (new SeedMachine(DEFAULT_SEED_PHRASES)).getAllChars();
+                allChars = sb.length() > 2 ? sb.toString() : ( new SeedMachine( DEFAULT_SEED_PHRASES ) ).getAllChars();
             }
 
             {
                 final StringBuilder sb = new StringBuilder();
-                for (final Character c : allChars.toCharArray()) {
-                    if (Character.isDigit(c)) {
-                        sb.append(c);
+                for ( final Character c : allChars.toCharArray() )
+                {
+                    if ( Character.isDigit( c ) )
+                    {
+                        sb.append( c );
                     }
                 }
-                numChars = sb.length() > 2 ? sb.toString() : (new SeedMachine(DEFAULT_SEED_PHRASES)).getNumChars();
+                numChars = sb.length() > 2 ? sb.toString() : ( new SeedMachine( DEFAULT_SEED_PHRASES ) ).getNumChars();
             }
 
             {
                 final StringBuilder sb = new StringBuilder();
-                for (final Character c : allChars.toCharArray()) {
-                    if (!Character.isLetterOrDigit(c)) {
-                        sb.append(c);
+                for ( final Character c : allChars.toCharArray() )
+                {
+                    if ( !Character.isLetterOrDigit( c ) )
+                    {
+                        sb.append( c );
                     }
                 }
-                specialChars = sb.length() > 2 ? sb.toString() : (new SeedMachine(DEFAULT_SEED_PHRASES)).getSpecialChars();
+                specialChars = sb.length() > 2 ? sb.toString() : ( new SeedMachine( DEFAULT_SEED_PHRASES ) ).getSpecialChars();
             }
 
             {
                 final StringBuilder sb = new StringBuilder();
-                for (final Character c : allChars.toCharArray()) {
-                    if (Character.isLowerCase(c)) {
-                        sb.append(c);
+                for ( final Character c : allChars.toCharArray() )
+                {
+                    if ( Character.isLowerCase( c ) )
+                    {
+                        sb.append( c );
                     }
                 }
-                lowerChars = sb.length() > 0 ? sb.toString() : (new SeedMachine(DEFAULT_SEED_PHRASES)).getLowerChars();
+                lowerChars = sb.length() > 0 ? sb.toString() : ( new SeedMachine( DEFAULT_SEED_PHRASES ) ).getLowerChars();
             }
 
             {
                 final StringBuilder sb = new StringBuilder();
-                for (final Character c : allChars.toCharArray()) {
-                    if (Character.isUpperCase(c)) {
-                        sb.append(c);
+                for ( final Character c : allChars.toCharArray() )
+                {
+                    if ( Character.isUpperCase( c ) )
+                    {
+                        sb.append( c );
                     }
                 }
-                upperChars = sb.length() > 0 ? sb.toString() : (new SeedMachine(DEFAULT_SEED_PHRASES)).getUpperChars();
+                upperChars = sb.length() > 0 ? sb.toString() : ( new SeedMachine( DEFAULT_SEED_PHRASES ) ).getUpperChars();
             }
         }
 
-        public String getRandomSeed() {
-            return new ArrayList<>(seeds).get(RANDOM.nextInt(seeds.size()));
+        public String getRandomSeed( )
+        {
+            return new ArrayList<>( seeds ).get( RANDOM.nextInt( seeds.size() ) );
         }
 
-        public String getAllChars() {
+        public String getAllChars( )
+        {
             return allChars;
         }
 
-        public String getNumChars() {
+        public String getNumChars( )
+        {
             return numChars;
         }
 
-        public String getSpecialChars() {
+        public String getSpecialChars( )
+        {
             return specialChars;
         }
 
-        public String getUpperChars() {
+        public String getUpperChars( )
+        {
             return upperChars;
         }
 
-        public String getLowerChars() {
+        public String getLowerChars( )
+        {
             return lowerChars;
         }
     }
 
-    private static String generateNewPassword(final SeedMachine seedMachine, final int desiredLength) {
+    private static String generateNewPassword( final SeedMachine seedMachine, final int desiredLength )
+    {
         final StringBuilder password = new StringBuilder();
 
-        while (password.length() < (desiredLength - 1)) {//loop around until we're long enough
-            password.append(seedMachine.getRandomSeed());
+        while ( password.length() < ( desiredLength - 1 ) )
+        {
+            //loop around until we're long enough
+            password.append( seedMachine.getRandomSeed() );
         }
 
-        if (RANDOM.nextInt(3) == 0) {
-            addRandChar(password, DEFAULT_SEED_MACHINE.getNumChars(), RANDOM.nextInt(password.length()));
+        if ( RANDOM.nextInt( 3 ) == 0 )
+        {
+            addRandChar( password, DEFAULT_SEED_MACHINE.getNumChars(), RANDOM.nextInt( password.length() ) );
         }
 
-        if (RANDOM.nextBoolean()) {
-            switchRandomCase(password);
+        if ( RANDOM.nextBoolean() )
+        {
+            switchRandomCase( password );
         }
 
         return password.toString();
     }
 
-    private static Collection<String> normalizeSeeds(final Collection<String> inputSeeds) {
+    private static Collection<String> normalizeSeeds( final Collection<String> inputSeeds )
+    {
 
-        if (inputSeeds == null) {
+        if ( inputSeeds == null )
+        {
             return DEFAULT_SEED_PHRASES;
         }
 
         final Collection<String> newSeeds = new HashSet<>();
-        newSeeds.addAll(inputSeeds);
+        newSeeds.addAll( inputSeeds );
 
-        for (final Iterator<String> iter = newSeeds.iterator(); iter.hasNext(); ) {
+        for ( final Iterator<String> iter = newSeeds.iterator(); iter.hasNext(); )
+        {
             final String s = iter.next();
-            if (s == null || s.length() < 1) {
+            if ( s == null || s.length() < 1 )
+            {
                 iter.remove();
             }
         }
@@ -545,8 +626,9 @@ public class RandomPasswordGenerator {
     }
 
     @Getter
-    @Builder(toBuilder = true)
-    public static class RandomGeneratorConfig {
+    @Builder( toBuilder = true )
+    public static class RandomGeneratorConfig
+    {
         private static final int DEFAULT_MINIMUM_LENGTH = 6;
         private static final int DEFAULT_MAXIMUM_LENGTH = 16;
         private static final int DEFAULT_DESIRED_STRENGTH = 45;
@@ -573,7 +655,7 @@ public class RandomPasswordGenerator {
 
         /**
          * @param minimumStrength The minimum length desired strength.  The algorithm will attempt to make
-         *                        the returned value at least this strong, but it is not guaranteed.
+         *         the returned value at least this strong, but it is not guaranteed.
          */
         @Builder.Default
         private int minimumStrength = DEFAULT_DESIRED_STRENGTH;
@@ -582,46 +664,53 @@ public class RandomPasswordGenerator {
         private PwmPasswordPolicy passwordPolicy = PwmPasswordPolicy.defaultPolicy();
 
 
-        public int getMaximumLength() {
+        public int getMaximumLength( )
+        {
             int policyMax = this.maximumLength;
-            if (this.getPasswordPolicy() != null) {
-                policyMax = this.getPasswordPolicy().getRuleHelper().readIntValue(PwmPasswordRule.MaximumLength);
+            if ( this.getPasswordPolicy() != null )
+            {
+                policyMax = this.getPasswordPolicy().getRuleHelper().readIntValue( PwmPasswordRule.MaximumLength );
             }
-            return Math.min(this.maximumLength, policyMax);
+            return Math.min( this.maximumLength, policyMax );
         }
 
-        public int getMinimumStrength() {
+        public int getMinimumStrength( )
+        {
             int policyMin = this.minimumStrength;
-            if (this.getPasswordPolicy() != null) {
-                policyMin = this.getPasswordPolicy().getRuleHelper().readIntValue(PwmPasswordRule.MinimumStrength);
+            if ( this.getPasswordPolicy() != null )
+            {
+                policyMin = this.getPasswordPolicy().getRuleHelper().readIntValue( PwmPasswordRule.MinimumStrength );
             }
-            return Math.max(this.minimumStrength, policyMin);
+            return Math.max( this.minimumStrength, policyMin );
         }
 
-        void validateSettings(final PwmApplication pwmApplication)
+        void validateSettings( final PwmApplication pwmApplication )
                 throws PwmUnrecoverableException
         {
             final int maxLength = Integer.parseInt(
-                    pwmApplication.getConfig().readAppProperty(AppProperty.PASSWORD_RANDOMGEN_MAX_LENGTH));
-            if (this.getMinimumLength() > maxLength) {
-                throw new PwmUnrecoverableException(new ErrorInformation(
+                    pwmApplication.getConfig().readAppProperty( AppProperty.PASSWORD_RANDOMGEN_MAX_LENGTH ) );
+            if ( this.getMinimumLength() > maxLength )
+            {
+                throw new PwmUnrecoverableException( new ErrorInformation(
                         PwmError.ERROR_UNKNOWN,
                         "minimum random generated password length exceeds preset random generator threshold"
-                ));
+                ) );
             }
 
-            if (this.getMaximumLength() > maxLength) {
-                throw new PwmUnrecoverableException(new ErrorInformation(
+            if ( this.getMaximumLength() > maxLength )
+            {
+                throw new PwmUnrecoverableException( new ErrorInformation(
                         PwmError.ERROR_UNKNOWN,
                         "maximum random generated password length exceeds preset random generator threshold"
-                ));
+                ) );
             }
 
-            if (this.getMinimumStrength() > RandomGeneratorConfig.MAXIMUM_STRENGTH) {
-                throw new PwmUnrecoverableException(new ErrorInformation(
+            if ( this.getMinimumStrength() > RandomGeneratorConfig.MAXIMUM_STRENGTH )
+            {
+                throw new PwmUnrecoverableException( new ErrorInformation(
                         PwmError.ERROR_UNKNOWN,
                         "minimum random generated password strength exceeds maximum possible"
-                ));
+                ) );
             }
         }
     }

+ 1 - 0
server/src/main/java/password/pwm/util/cli/CliEnvironment.java

@@ -43,6 +43,7 @@ public class CliEnvironment
     final Map<String, Object> options;
     final MainOptions mainOptions;
 
+    @SuppressWarnings( "checkstyle:ParameterNumber" )
     public CliEnvironment(
             final ConfigurationReader configurationReader,
             final File configurationFile,

+ 255 - 183
server/src/main/java/password/pwm/util/cli/MainClass.java

@@ -88,83 +88,94 @@ import java.util.Map;
 import java.util.Queue;
 import java.util.TreeMap;
 
-public class MainClass {
-    private static final PwmLogger LOGGER = PwmLogger.forClass(MainClass.class);
+public class MainClass
+{
+    private static final PwmLogger LOGGER = PwmLogger.forClass( MainClass.class );
 
     private static final String LOGGING_PATTERN = "%d{yyyy-MM-dd'T'HH:mm:ssX}{GMT}, %-5p, %c{2}, %m%n";
 
-    private static MainOptions MAIN_OPTIONS;
+    private static MainOptions mainOptions;
 
-    public static final Map<String,CliCommand> COMMANDS;
+    public static final Map<String, CliCommand> COMMANDS;
 
-    static {
+    static
+    {
         final List<CliCommand> commandList = new ArrayList<>();
-        commandList.add(new LocalDBInfoCommand());
-        commandList.add(new ExportLogsCommand());
-        commandList.add(new UserReportCommand());
-        commandList.add(new ExportLocalDBCommand());
-        commandList.add(new ImportLocalDBCommand());
-        commandList.add(new ExportAuditCommand());
-        commandList.add(new ConfigUnlockCommand());
-        commandList.add(new ConfigLockCommand());
-        commandList.add(new ConfigSetPasswordCommand());
-        commandList.add(new ExportStatsCommand());
-        commandList.add(new ExportResponsesCommand());
-        commandList.add(new ClearResponsesCommand());
-        commandList.add(new ImportResponsesCommand());
-        commandList.add(new TokenInfoCommand());
-        commandList.add(new ConfigNewCommand());
-        commandList.add(new VersionCommand());
-        commandList.add(new LdapSchemaExtendCommand());
-        commandList.add(new ConfigDeleteCommand());
-        commandList.add(new ResponseStatsCommand());
-        commandList.add(new ImportHttpsKeyStoreCommand());
-        commandList.add(new ExportHttpsKeyStoreCommand());
-        commandList.add(new ExportHttpsTomcatConfigCommand());
-        commandList.add(new ShellCommand());
-        commandList.add(new ConfigResetHttpsCommand());
-        commandList.add(new HelpCommand());
+        commandList.add( new LocalDBInfoCommand() );
+        commandList.add( new ExportLogsCommand() );
+        commandList.add( new UserReportCommand() );
+        commandList.add( new ExportLocalDBCommand() );
+        commandList.add( new ImportLocalDBCommand() );
+        commandList.add( new ExportAuditCommand() );
+        commandList.add( new ConfigUnlockCommand() );
+        commandList.add( new ConfigLockCommand() );
+        commandList.add( new ConfigSetPasswordCommand() );
+        commandList.add( new ExportStatsCommand() );
+        commandList.add( new ExportResponsesCommand() );
+        commandList.add( new ClearResponsesCommand() );
+        commandList.add( new ImportResponsesCommand() );
+        commandList.add( new TokenInfoCommand() );
+        commandList.add( new ConfigNewCommand() );
+        commandList.add( new VersionCommand() );
+        commandList.add( new LdapSchemaExtendCommand() );
+        commandList.add( new ConfigDeleteCommand() );
+        commandList.add( new ResponseStatsCommand() );
+        commandList.add( new ImportHttpsKeyStoreCommand() );
+        commandList.add( new ExportHttpsKeyStoreCommand() );
+        commandList.add( new ExportHttpsTomcatConfigCommand() );
+        commandList.add( new ShellCommand() );
+        commandList.add( new ConfigResetHttpsCommand() );
+        commandList.add( new HelpCommand() );
         //commandList.add(new PasswordExpireNotificationCommand());
 
-        final Map<String,CliCommand> sortedMap = new TreeMap<>();
-        for (final CliCommand command : commandList) {
-            sortedMap.put(command.getCliParameters().commandName,command);
+        final Map<String, CliCommand> sortedMap = new TreeMap<>();
+        for ( final CliCommand command : commandList )
+        {
+            sortedMap.put( command.getCliParameters().commandName, command );
         }
-        COMMANDS = Collections.unmodifiableMap(sortedMap);
+        COMMANDS = Collections.unmodifiableMap( sortedMap );
     }
 
-    public static String helpTextFromCommands(final Collection<CliCommand> commands) {
+    public static String helpTextFromCommands( final Collection<CliCommand> commands )
+    {
         final StringBuilder output = new StringBuilder();
-        for (final CliCommand command : commands) {
-            output.append(command.getCliParameters().commandName);
-            if (command.getCliParameters().options != null) {
-                for (final CliParameters.Option option : command.getCliParameters().options) {
-                    output.append(" ");
-                    if (option.isOptional()) {
-                        output.append("<").append(option.getName()).append(">");
-                    } else {
-                        output.append("[").append(option.getName()).append("]");
+        for ( final CliCommand command : commands )
+        {
+            output.append( command.getCliParameters().commandName );
+            if ( command.getCliParameters().options != null )
+            {
+                for ( final CliParameters.Option option : command.getCliParameters().options )
+                {
+                    output.append( " " );
+                    if ( option.isOptional() )
+                    {
+                        output.append( "<" ).append( option.getName() ).append( ">" );
+                    }
+                    else
+                    {
+                        output.append( "[" ).append( option.getName() ).append( "]" );
                     }
                 }
             }
-            output.append("\n");
-            output.append("       ").append(command.getCliParameters().description);
-            output.append("\n");
+            output.append( "\n" );
+            output.append( "       " ).append( command.getCliParameters().description );
+            output.append( "\n" );
         }
         return output.toString();
     }
 
-    private static String makeHelpTextOutput() {
+    private static String makeHelpTextOutput( )
+    {
         final StringBuilder output = new StringBuilder();
-        output.append(helpTextFromCommands(COMMANDS.values()));
-        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, ERROR, 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>");
+        output.append( helpTextFromCommands( COMMANDS.values() ) );
+        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, ERROR, 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();
     }
@@ -176,34 +187,39 @@ public class MainClass {
             throws Exception
     {
 
-        final Map<String,Object> options = parseCommandOptions(parameters, args);
-        final File applicationPath = figureApplicationPath(MAIN_OPTIONS);
-        out("applicationPath=" + applicationPath.getAbsolutePath());
-        PwmEnvironment.verifyApplicationPath(applicationPath);
+        final Map<String, Object> options = parseCommandOptions( parameters, args );
+        final File applicationPath = figureApplicationPath( mainOptions );
+        out( "applicationPath=" + applicationPath.getAbsolutePath() );
+        PwmEnvironment.verifyApplicationPath( applicationPath );
 
-        final File configurationFile = locateConfigurationFile(applicationPath);
+        final File configurationFile = locateConfigurationFile( applicationPath );
 
-        final ConfigurationReader configReader = loadConfiguration(configurationFile);
+        final ConfigurationReader configReader = loadConfiguration( configurationFile );
         final Configuration config = configReader.getConfiguration();
 
         final PwmApplication pwmApplication;
         final LocalDB localDB;
 
-        if (parameters.needsPwmApplication) {
-            pwmApplication = loadPwmApplication(applicationPath, MAIN_OPTIONS.getApplicationFlags(), config, configurationFile, parameters.readOnly);
+        if ( parameters.needsPwmApplication )
+        {
+            pwmApplication = loadPwmApplication( applicationPath, mainOptions.getApplicationFlags(), config, configurationFile, parameters.readOnly );
             localDB = pwmApplication.getLocalDB();
-        } else if (parameters.needsLocalDB) {
+        }
+        else if ( parameters.needsLocalDB )
+        {
             pwmApplication = null;
-            localDB = loadPwmDB(config, parameters.readOnly, applicationPath);
-        } else {
+            localDB = loadPwmDB( config, parameters.readOnly, applicationPath );
+        }
+        else
+        {
             pwmApplication = null;
             localDB = null;
         }
 
-        out("environment initialized");
-        out("");
+        out( "environment initialized" );
+        out( "" );
 
-        final Writer outputStream = new OutputStreamWriter(System.out, PwmConstants.DEFAULT_CHARSET);
+        final Writer outputStream = new OutputStreamWriter( System.out, PwmConstants.DEFAULT_CHARSET );
         return new CliEnvironment(
                 configReader,
                 configurationFile,
@@ -213,101 +229,123 @@ public class MainClass {
                 localDB,
                 outputStream,
                 options,
-                MAIN_OPTIONS
+                mainOptions
         );
     }
 
-    public static Map<String,Object> parseCommandOptions(
+    public static Map<String, Object> parseCommandOptions(
             final CliParameters cliParameters,
             final List<String> args
     )
             throws CliException
     {
-        final Queue<String> argQueue = new LinkedList<>(args);
-        final Map<String,Object> returnObj = new LinkedHashMap<>();
-
-        if (cliParameters.options != null) {
-            for (final CliParameters.Option option : cliParameters.options) {
-                if (!option.isOptional() && argQueue.isEmpty()) {
-                    throw new CliException("missing required option '" + option.getName() + "'");
+        final Queue<String> argQueue = new LinkedList<>( args );
+        final Map<String, Object> returnObj = new LinkedHashMap<>();
+
+        if ( cliParameters.options != null )
+        {
+            for ( final CliParameters.Option option : cliParameters.options )
+            {
+                if ( !option.isOptional() && argQueue.isEmpty() )
+                {
+                    throw new CliException( "missing required option '" + option.getName() + "'" );
                 }
 
-                if (!argQueue.isEmpty()) {
+                if ( !argQueue.isEmpty() )
+                {
                     final String argument = argQueue.poll();
-                    switch (option.getType()) {
+                    switch ( option.getType() )
+                    {
                         case NEW_FILE:
-                            try {
-                                final File theFile = new File(argument);
-                                if (theFile.exists()) {
-                                    throw new CliException("file for option '" + option.getName() + "' at '" + theFile.getAbsolutePath() + "' already exists");
+                            try
+                            {
+                                final File theFile = new File( argument );
+                                if ( theFile.exists() )
+                                {
+                                    throw new CliException( "file for option '" + option.getName() + "' at '" + theFile.getAbsolutePath() + "' already exists" );
                                 }
-                                returnObj.put(option.getName(),theFile);
-                            } catch (Exception e) {
-                                if (e instanceof CliException) {
-                                    throw (CliException)e;
+                                returnObj.put( option.getName(), theFile );
+                            }
+                            catch ( Exception e )
+                            {
+                                if ( e instanceof CliException )
+                                {
+                                    throw ( CliException ) e;
                                 }
-                                throw new CliException("cannot access file for option '" + option.getName() + "', " + e.getMessage());
+                                throw new CliException( "cannot access file for option '" + option.getName() + "', " + e.getMessage() );
 
                             }
                             break;
 
                         case EXISTING_FILE:
-                            try {
-                                final File theFile = new File(argument);
-                                if (!theFile.exists()) {
-                                    throw new CliException("file for option '" + option.getName() + "' at '" + theFile.getAbsolutePath() + "' does not exist");
+                            try
+                            {
+                                final File theFile = new File( argument );
+                                if ( !theFile.exists() )
+                                {
+                                    throw new CliException( "file for option '" + option.getName() + "' at '" + theFile.getAbsolutePath() + "' does not exist" );
                                 }
-                                returnObj.put(option.getName(),theFile);
-                            } catch (Exception e) {
-                                if (e instanceof CliException) {
-                                    throw (CliException)e;
+                                returnObj.put( option.getName(), theFile );
+                            }
+                            catch ( Exception e )
+                            {
+                                if ( e instanceof CliException )
+                                {
+                                    throw ( CliException ) e;
                                 }
-                                throw new CliException("cannot access file for option '" + option.getName() + "', " + e.getMessage());
+                                throw new CliException( "cannot access file for option '" + option.getName() + "', " + e.getMessage() );
                             }
                             break;
 
                         case STRING:
-                            returnObj.put(option.getName(), argument);
+                            returnObj.put( option.getName(), argument );
                             break;
 
                         default:
-                            JavaHelper.unhandledSwitchStatement(option.getType());
+                            JavaHelper.unhandledSwitchStatement( option.getType() );
                     }
                 }
             }
         }
 
-        if (!argQueue.isEmpty()) {
-            throw new CliException("unknown option '" + argQueue.poll() + "'");
+        if ( !argQueue.isEmpty() )
+        {
+            throw new CliException( "unknown option '" + argQueue.poll() + "'" );
         }
 
         return returnObj;
     }
 
-    public static void main(final String[] args)
+    public static void main( final String[] args )
             throws Exception
     {
-        out(PwmConstants.PWM_APP_NAME + " " + PwmConstants.SERVLET_VERSION + " Command Line Utility");
-        MAIN_OPTIONS = MainOptions.parseMainCommandLineOptions(args, new OutputStreamWriter(System.out, PwmConstants.DEFAULT_CHARSET));
-        final List<String> workingArgs = MAIN_OPTIONS.getRemainingArguments();
+        out( PwmConstants.PWM_APP_NAME + " " + PwmConstants.SERVLET_VERSION + " Command Line Utility" );
+        mainOptions = MainOptions.parseMainCommandLineOptions( args, new OutputStreamWriter( System.out, PwmConstants.DEFAULT_CHARSET ) );
+        final List<String> workingArgs = mainOptions.getRemainingArguments();
 
-        initLog4j(MAIN_OPTIONS.getPwmLogLevel());
+        initLog4j( mainOptions.getPwmLogLevel() );
 
         final String commandStr = workingArgs == null || workingArgs.size() < 1 ? null : workingArgs.iterator().next();
 
         boolean commandExceuted = false;
-        if (commandStr == null) {
-            out("\n");
-            out(makeHelpTextOutput());
-        } else {
-            for (final CliCommand command : COMMANDS.values()) {
-                if (commandStr.equalsIgnoreCase(command.getCliParameters().commandName)) {
+        if ( commandStr == null )
+        {
+            out( "\n" );
+            out( makeHelpTextOutput() );
+        }
+        else
+        {
+            for ( final CliCommand command : COMMANDS.values() )
+            {
+                if ( commandStr.equalsIgnoreCase( command.getCliParameters().commandName ) )
+                {
                     commandExceuted = true;
-                    executeCommand(command, commandStr, workingArgs.toArray(new String[workingArgs.size()]));
+                    executeCommand( command, commandStr, workingArgs.toArray( new String[ workingArgs.size() ] ) );
                     break;
                 }
             }
-            if (!commandExceuted) {
+            if ( !commandExceuted )
+            {
                 out( "unknown command '" + workingArgs.iterator().next() + "'" );
             }
         }
@@ -317,43 +355,58 @@ public class MainClass {
             final CliCommand command,
             final String commandStr,
             final String[] args
-    ) {
-        final List<String> argList = new LinkedList<>(Arrays.asList(args));
-        argList.remove(0);
+    )
+    {
+        final List<String> argList = new LinkedList<>( Arrays.asList( args ) );
+        argList.remove( 0 );
 
         final CliEnvironment cliEnvironment;
-        try {
-            cliEnvironment = createEnv(command.getCliParameters(), argList);
-        } catch (Exception e) {
+        try
+        {
+            cliEnvironment = createEnv( command.getCliParameters(), argList );
+        }
+        catch ( Exception e )
+        {
             final String errorMsg = "unable to establish operating environment: " + e.getMessage();
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_ENVIRONMENT_ERROR, errorMsg);
-            LOGGER.error(errorInformation.toDebugStr(),e);
-            out("unable to establish operating environment: " + e.getMessage());
-            System.exit(-1);
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_ENVIRONMENT_ERROR, errorMsg );
+            LOGGER.error( errorInformation.toDebugStr(), e );
+            out( "unable to establish operating environment: " + e.getMessage() );
+            System.exit( -1 );
             return;
         }
 
-        try {
-            command.execute(commandStr, cliEnvironment);
-        } catch (Exception e) {
-            System.out.println(e.getMessage());
+        try
+        {
+            command.execute( commandStr, cliEnvironment );
+        }
+        catch ( Exception e )
+        {
+            System.out.println( e.getMessage() );
             //System.exit(-1);
             return;
         }
 
-        if (cliEnvironment.getPwmApplication() != null) {
-            try {
+        if ( cliEnvironment.getPwmApplication() != null )
+        {
+            try
+            {
                 cliEnvironment.getPwmApplication().shutdown();
-            } catch (Exception e) {
-                out("error closing operating environment: " + e.getMessage());
+            }
+            catch ( Exception e )
+            {
+                out( "error closing operating environment: " + e.getMessage() );
                 e.printStackTrace();
             }
         }
-        if (cliEnvironment.getLocalDB() != null) {
-            try {
+        if ( cliEnvironment.getLocalDB() != null )
+        {
+            try
+            {
                 cliEnvironment.getLocalDB().close();
-            } catch (Exception e) {
-                out("error closing LocalDB environment: " + e.getMessage());
+            }
+            catch ( Exception e )
+            {
+                out( "error closing LocalDB environment: " + e.getMessage() );
             }
         }
 
@@ -362,21 +415,25 @@ public class MainClass {
 
     }
 
-    private static void initLog4j(final PwmLogLevel logLevel) {
-        if (logLevel == null) {
+    private static void initLog4j( final PwmLogLevel logLevel )
+    {
+        if ( logLevel == null )
+        {
             Logger.getRootLogger().removeAllAppenders();
-            Logger.getRootLogger().addAppender(new NullAppender());
+            Logger.getRootLogger().addAppender( new NullAppender() );
             PwmLogger.markInitialized();
             return;
         }
 
-        final Layout patternLayout = new EnhancedPatternLayout(LOGGING_PATTERN);
-        final ConsoleAppender consoleAppender = new ConsoleAppender(patternLayout);
-        for (final Package logPackage : PwmLogManager.LOGGING_PACKAGES) {
-            if (logPackage != null) {
-                final Logger logger = Logger.getLogger(logPackage.getName());
-                logger.addAppender(consoleAppender);
-                logger.setLevel(logLevel.getLog4jLevel());
+        final Layout patternLayout = new EnhancedPatternLayout( LOGGING_PATTERN );
+        final ConsoleAppender consoleAppender = new ConsoleAppender( patternLayout );
+        for ( final Package logPackage : PwmLogManager.LOGGING_PACKAGES )
+        {
+            if ( logPackage != null )
+            {
+                final Logger logger = Logger.getLogger( logPackage.getName() );
+                logger.addAppender( consoleAppender );
+                logger.setLevel( logLevel.getLog4jLevel() );
             }
         }
         PwmLogger.markInitialized();
@@ -390,18 +447,20 @@ public class MainClass {
             throws Exception
     {
         final File databaseDirectory;
-        final String pwmDBLocationSetting = config.readAppProperty(AppProperty.LOCALDB_LOCATION);
-        databaseDirectory = FileSystemUtility.figureFilepath(pwmDBLocationSetting, applicationPath);
-        return LocalDBFactory.getInstance(databaseDirectory, readonly, null, config);
+        final String pwmDBLocationSetting = config.readAppProperty( AppProperty.LOCALDB_LOCATION );
+        databaseDirectory = FileSystemUtility.figureFilepath( pwmDBLocationSetting, applicationPath );
+        return LocalDBFactory.getInstance( databaseDirectory, readonly, null, config );
     }
 
-    private static ConfigurationReader loadConfiguration(final File configurationFile) throws Exception {
-        final ConfigurationReader reader = new ConfigurationReader(configurationFile);
+    private static ConfigurationReader loadConfiguration( final File configurationFile ) throws Exception
+    {
+        final ConfigurationReader reader = new ConfigurationReader( configurationFile );
 
-        if (reader.getConfigMode() == PwmApplicationMode.ERROR) {
+        if ( reader.getConfigMode() == PwmApplicationMode.ERROR )
+        {
             final String errorMsg = reader.getConfigFileError() == null ? "error" : reader.getConfigFileError().toDebugStr();
-            out("unable to load configuration: " + errorMsg);
-            System.exit(-1);
+            out( "unable to load configuration: " + errorMsg );
+            System.exit( -1 );
         }
 
         return reader;
@@ -418,54 +477,67 @@ public class MainClass {
     {
         final PwmApplicationMode mode = readonly ? PwmApplicationMode.READ_ONLY : PwmApplicationMode.RUNNING;
         final Collection<PwmEnvironment.ApplicationFlag> applicationFlags = new HashSet<>();
-        if (flags == null) {
-            applicationFlags.addAll(PwmEnvironment.ParseHelper.readApplicationFlagsFromSystem(null));
-        } else {
-            applicationFlags.addAll(flags);
+        if ( flags == null )
+        {
+            applicationFlags.addAll( PwmEnvironment.ParseHelper.readApplicationFlagsFromSystem( null ) );
         }
-        applicationFlags.add(PwmEnvironment.ApplicationFlag.CommandLineInstance);
-        final PwmEnvironment pwmEnvironment = new PwmEnvironment.Builder(config, applicationPath)
-                .setApplicationMode(mode)
-                .setConfigurationFile(configurationFile)
-                .setFlags(applicationFlags)
+        else
+        {
+            applicationFlags.addAll( flags );
+        }
+        applicationFlags.add( PwmEnvironment.ApplicationFlag.CommandLineInstance );
+        final PwmEnvironment pwmEnvironment = new PwmEnvironment.Builder( config, applicationPath )
+                .setApplicationMode( mode )
+                .setConfigurationFile( configurationFile )
+                .setFlags( applicationFlags )
                 .createPwmEnvironment();
-        final PwmApplication pwmApplication = new PwmApplication(pwmEnvironment);
+        final PwmApplication pwmApplication = new PwmApplication( pwmEnvironment );
         final PwmApplicationMode runningMode = pwmApplication.getApplicationMode();
 
-        if (runningMode != mode) {
-            out("unable to start application in required state '" + mode + "', current state: " + runningMode);
-            System.exit(-1);
+        if ( runningMode != mode )
+        {
+            out( "unable to start application in required state '" + mode + "', current state: " + runningMode );
+            System.exit( -1 );
         }
 
         return pwmApplication;
     }
 
-    private static File locateConfigurationFile(final File applicationPath) {
-        return new File(applicationPath + File.separator + PwmConstants.DEFAULT_CONFIG_FILE_FILENAME);
+    private static File locateConfigurationFile( final File applicationPath )
+    {
+        return new File( applicationPath + File.separator + PwmConstants.DEFAULT_CONFIG_FILE_FILENAME );
     }
 
-    private static void out(final CharSequence txt) {
-        System.out.println(txt);
+    private static void out( final CharSequence txt )
+    {
+        System.out.println( txt );
     }
 
-    private static File figureApplicationPath(final MainOptions mainOptions) throws IOException, PwmUnrecoverableException {
+    private static File figureApplicationPath( final MainOptions mainOptions ) throws IOException, PwmUnrecoverableException
+    {
         final File applicationPath;
-        if (mainOptions != null && mainOptions.getApplicationPath() != null) {
+        if ( mainOptions != null && mainOptions.getApplicationPath() != null )
+        {
             applicationPath = mainOptions.getApplicationPath();
-        } else {
-            final String appPathStr = PwmEnvironment.ParseHelper.readValueFromSystem(PwmEnvironment.EnvironmentParameter.applicationPath,null);
-            if (appPathStr != null && !appPathStr.isEmpty()) {
-                applicationPath = new File(appPathStr);
-            } else {
+        }
+        else
+        {
+            final String appPathStr = PwmEnvironment.ParseHelper.readValueFromSystem( PwmEnvironment.EnvironmentParameter.applicationPath, null );
+            if ( appPathStr != null && !appPathStr.isEmpty() )
+            {
+                applicationPath = new File( appPathStr );
+            }
+            else
+            {
                 final String errorMsg = "unable to locate applicationPath.  Specify using -applicationPath option, java option "
                         + "\"" + PwmEnvironment.EnvironmentParameter.applicationPath.conicalJavaOptionSystemName() + "\""
                         + ", or system environment setting "
                         + "\"" + PwmEnvironment.EnvironmentParameter.applicationPath.conicalEnvironmentSystemName() + "\"";
-                throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_STARTUP_ERROR,errorMsg));
+                throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_STARTUP_ERROR, errorMsg ) );
             }
         }
 
-        LOGGER.debug("using applicationPath " + applicationPath.getAbsolutePath());
+        LOGGER.debug( "using applicationPath " + applicationPath.getAbsolutePath() );
         return applicationPath;
     }
 }

+ 278 - 176
server/src/main/java/password/pwm/util/db/DatabaseAccessorImpl.java

@@ -43,9 +43,10 @@ import java.util.concurrent.locks.ReentrantLock;
 /**
  * @author Jason D. Rivard
  */
-class DatabaseAccessorImpl implements DatabaseAccessor {
+class DatabaseAccessorImpl implements DatabaseAccessor
+{
 
-    private static final PwmLogger LOGGER = PwmLogger.forClass(DatabaseAccessorImpl.class, true);
+    private static final PwmLogger LOGGER = PwmLogger.forClass( DatabaseAccessorImpl.class, true );
 
     private final Connection connection;
     private final DatabaseService databaseService;
@@ -53,15 +54,15 @@ class DatabaseAccessorImpl implements DatabaseAccessor {
 
     private final boolean traceLogEnabled;
 
-    private static final AtomicInteger ACCESSOR_COUNTER = new AtomicInteger(0);
+    private static final AtomicInteger ACCESSOR_COUNTER = new AtomicInteger( 0 );
     private final int accessorNumber = ACCESSOR_COUNTER.getAndIncrement();
 
-    private static final AtomicInteger ITERATOR_COUNTER = new AtomicInteger(0);
+    private static final AtomicInteger ITERATOR_COUNTER = new AtomicInteger( 0 );
     private final Set<DBIterator> outstandingIterators = ConcurrentHashMap.newKeySet();
 
-    private final AtomicBoolean closed = new AtomicBoolean(false);
+    private final AtomicBoolean closed = new AtomicBoolean( false );
 
-    private final ReentrantLock LOCK = new ReentrantLock();
+    private final ReentrantLock lock = new ReentrantLock();
 
     DatabaseAccessorImpl(
             final DatabaseService databaseService,
@@ -83,9 +84,9 @@ class DatabaseAccessorImpl implements DatabaseAccessor {
     )
             throws DatabaseException
     {
-        DatabaseUtil.rollbackTransaction(connection);
-        final DatabaseException databaseException = DatabaseUtil.convertSqlException(debugInfo, e);
-        databaseService.setLastError(databaseException.getErrorInformation());
+        DatabaseUtil.rollbackTransaction( connection );
+        final DatabaseException databaseException = DatabaseUtil.convertSqlException( debugInfo, e );
+        databaseService.setLastError( databaseException.getErrorInformation() );
         throw databaseException;
     }
 
@@ -99,30 +100,39 @@ class DatabaseAccessorImpl implements DatabaseAccessor {
     {
         preCheck();
 
-        final DatabaseUtil.DebugInfo debugInfo = DatabaseUtil.DebugInfo.create("put", table, key, value);
+        final DatabaseUtil.DebugInfo debugInfo = DatabaseUtil.DebugInfo.create( "put", table, key, value );
 
-        return execute(debugInfo, () -> {
+        return execute( debugInfo, ( ) ->
+        {
             boolean exists = false;
-            try {
-                exists = containsImpl(table, key);
-            } catch (SQLException e) {
-                processSqlException(debugInfo, e);
+            try
+            {
+                exists = containsImpl( table, key );
+            }
+            catch ( SQLException e )
+            {
+                processSqlException( debugInfo, e );
             }
 
-            if (exists) {
+            if ( exists )
+            {
                 final String sqlText = "UPDATE " + table.toString()
                         + " SET " + DatabaseService.VALUE_COLUMN + "=? WHERE "
                         + DatabaseService.KEY_COLUMN + "=?";
-                executeUpdate(sqlText, debugInfo, value, key); // note the value/key are reversed for this statement
-            } else {
+
+                // note the value/key are reversed for this statement
+                executeUpdate( sqlText, debugInfo, value, key );
+            }
+            else
+            {
                 final String sqlText = "INSERT INTO " + table.toString()
                         + "(" + DatabaseService.KEY_COLUMN + ", "
                         + DatabaseService.VALUE_COLUMN + ") VALUES(?,?)";
-                executeUpdate(sqlText, debugInfo, key, value);
+                executeUpdate( sqlText, debugInfo, key, value );
             }
 
             return !exists;
-        });
+        } );
     }
 
     @Override
@@ -135,23 +145,28 @@ class DatabaseAccessorImpl implements DatabaseAccessor {
     {
         preCheck();
 
-        final DatabaseUtil.DebugInfo debugInfo = DatabaseUtil.DebugInfo.create("putIfAbsent", table, key, value);
+        final DatabaseUtil.DebugInfo debugInfo = DatabaseUtil.DebugInfo.create( "putIfAbsent", table, key, value );
 
-        return execute(debugInfo, () -> {
+        return execute( debugInfo, ( ) ->
+        {
             boolean valueExists = false;
-            try {
-                valueExists = DatabaseAccessorImpl.this.containsImpl(table, key);
-            } catch (final SQLException e) {
-                DatabaseAccessorImpl.this.processSqlException(debugInfo, e);
+            try
+            {
+                valueExists = DatabaseAccessorImpl.this.containsImpl( table, key );
+            }
+            catch ( final SQLException e )
+            {
+                DatabaseAccessorImpl.this.processSqlException( debugInfo, e );
             }
 
-            if (!valueExists) {
+            if ( !valueExists )
+            {
                 final String insertSql = "INSERT INTO " + table.name() + "(" + DatabaseService.KEY_COLUMN + ", " + DatabaseService.VALUE_COLUMN + ") VALUES(?,?)";
-                DatabaseAccessorImpl.this.executeUpdate(insertSql, debugInfo, key, value);
+                DatabaseAccessorImpl.this.executeUpdate( insertSql, debugInfo, key, value );
             }
 
             return !valueExists;
-        });
+        } );
     }
 
 
@@ -164,17 +179,21 @@ class DatabaseAccessorImpl implements DatabaseAccessor {
     {
         preCheck();
 
-        final DatabaseUtil.DebugInfo debugInfo = DatabaseUtil.DebugInfo.create("contains", table, key, null);
+        final DatabaseUtil.DebugInfo debugInfo = DatabaseUtil.DebugInfo.create( "contains", table, key, null );
 
-        return execute(debugInfo, () -> {
+        return execute( debugInfo, ( ) ->
+        {
             boolean valueExists = false;
-            try {
-                valueExists = containsImpl(table, key);
-            } catch (final SQLException e) {
-                processSqlException(debugInfo, e);
+            try
+            {
+                valueExists = containsImpl( table, key );
+            }
+            catch ( final SQLException e )
+            {
+                processSqlException( debugInfo, e );
             }
             return valueExists;
-        });
+        } );
     }
 
     @Override
@@ -186,36 +205,45 @@ class DatabaseAccessorImpl implements DatabaseAccessor {
     {
         preCheck();
 
-        final DatabaseUtil.DebugInfo debugInfo = DatabaseUtil.DebugInfo.create("get", table, key, null);
+        final DatabaseUtil.DebugInfo debugInfo = DatabaseUtil.DebugInfo.create( "get", table, key, null );
 
-        return execute(debugInfo, () -> {
+        return execute( debugInfo, ( ) ->
+        {
             final String sqlStatement = "SELECT * FROM " + table.name() + " WHERE " + DatabaseService.KEY_COLUMN + " = ?";
 
-            try (PreparedStatement statement = connection.prepareStatement(sqlStatement)) {
-                statement.setString(1, key);
-                statement.setMaxRows(1);
+            try ( PreparedStatement statement = connection.prepareStatement( sqlStatement ) )
+            {
+                statement.setString( 1, key );
+                statement.setMaxRows( 1 );
 
-                try (ResultSet resultSet= statement.executeQuery()) {
-                    if (resultSet.next()) {
-                        return resultSet.getString(DatabaseService.VALUE_COLUMN);
+                try ( ResultSet resultSet = statement.executeQuery() )
+                {
+                    if ( resultSet.next() )
+                    {
+                        return resultSet.getString( DatabaseService.VALUE_COLUMN );
                     }
                 }
-            } catch (SQLException e) {
-                processSqlException(debugInfo, e);
+            }
+            catch ( SQLException e )
+            {
+                processSqlException( debugInfo, e );
             }
             return null;
-        });
+        } );
     }
 
     @Override
-    public ClosableIterator<String> iterator(final DatabaseTable table)
+    public ClosableIterator<String> iterator( final DatabaseTable table )
             throws DatabaseException
     {
-        try {
-            LOCK.lock();
-            return new DBIterator(table);
-        } finally {
-            LOCK.unlock();
+        try
+        {
+            lock.lock();
+            return new DBIterator( table );
+        }
+        finally
+        {
+            lock.unlock();
         }
     }
 
@@ -228,71 +256,85 @@ class DatabaseAccessorImpl implements DatabaseAccessor {
     {
         preCheck();
 
-        final DatabaseUtil.DebugInfo debugInfo = DatabaseUtil.DebugInfo.create("remove", table, key, null);
+        final DatabaseUtil.DebugInfo debugInfo = DatabaseUtil.DebugInfo.create( "remove", table, key, null );
 
-        execute(debugInfo, () -> {
+        execute( debugInfo, ( ) ->
+        {
 
 
             final String sqlText = "DELETE FROM " + table.name() + " WHERE " + DatabaseService.KEY_COLUMN + "=?";
-            executeUpdate(sqlText, debugInfo, key);
+            executeUpdate( sqlText, debugInfo, key );
 
             return null;
-        });
+        } );
     }
 
     @Override
-    public int size(final DatabaseTable table)
+    public int size( final DatabaseTable table )
             throws DatabaseException
     {
         preCheck();
 
-        final DatabaseUtil.DebugInfo debugInfo = DatabaseUtil.DebugInfo.create("size", table, null, null);
+        final DatabaseUtil.DebugInfo debugInfo = DatabaseUtil.DebugInfo.create( "size", table, null, null );
 
-        return execute(debugInfo, () -> {
+        return execute( debugInfo, ( ) ->
+        {
             final String sqlStatement = "SELECT COUNT(" + DatabaseService.KEY_COLUMN + ") FROM " + table.name();
 
-            try (PreparedStatement statement = connection.prepareStatement(sqlStatement)) {
-                try (ResultSet resultSet = statement.executeQuery()) {
-                    if (resultSet.next()) {
-                        return resultSet.getInt(1);
+            try ( PreparedStatement statement = connection.prepareStatement( sqlStatement ) )
+            {
+                try ( ResultSet resultSet = statement.executeQuery() )
+                {
+                    if ( resultSet.next() )
+                    {
+                        return resultSet.getInt( 1 );
                     }
                 }
-            } catch (SQLException e) {
-                processSqlException(debugInfo, e);
+            }
+            catch ( SQLException e )
+            {
+                processSqlException( debugInfo, e );
             }
 
             return 0;
-        });
+        } );
     }
 
-    boolean isValid() {
+    boolean isValid( )
+    {
         preCheck();
 
-        if (connection == null) {
+        if ( connection == null )
+        {
             return false;
         }
 
-        try {
-            if (connection.isClosed()) {
+        try
+        {
+            if ( connection.isClosed() )
+            {
                 return false;
             }
 
             final int connectionTimeout = dbConfiguration.getConnectionTimeout();
 
-            if (!connection.isValid(connectionTimeout)) {
+            if ( !connection.isValid( connectionTimeout ) )
+            {
                 return false;
             }
 
-        } catch (SQLException e) {
-            LOGGER.debug("error while checking connection validity: " + e.getMessage());
+        }
+        catch ( SQLException e )
+        {
+            LOGGER.debug( "error while checking connection validity: " + e.getMessage() );
         }
 
         return true;
     }
 
 
-
-    public class DBIterator implements ClosableIterator<String> {
+    public class DBIterator implements ClosableIterator<String>
+    {
         private final DatabaseTable table;
         private ResultSet resultSet;
         private PreparedStatement statement;
@@ -300,7 +342,7 @@ class DatabaseAccessorImpl implements DatabaseAccessor {
         private boolean finished;
         private int counter = ITERATOR_COUNTER.getAndIncrement();
 
-        DBIterator(final DatabaseTable table)
+        DBIterator( final DatabaseTable table )
                 throws DatabaseException
         {
             this.table = table;
@@ -308,188 +350,242 @@ class DatabaseAccessorImpl implements DatabaseAccessor {
             getNextItem();
         }
 
-        private void init() throws DatabaseException {
+        private void init( ) throws DatabaseException
+        {
             final DatabaseUtil.DebugInfo debugInfo = DatabaseUtil.DebugInfo.create(
-                    "iterator #" + counter + " open", table, null, null);
-            traceBegin(debugInfo);
+                    "iterator #" + counter + " open", table, null, null );
+            traceBegin( debugInfo );
 
             final String sqlText = "SELECT " + DatabaseService.KEY_COLUMN + " FROM " + table.name();
-            try {
-                outstandingIterators.add(this);
-                statement = connection.prepareStatement(sqlText);
+            try
+            {
+                outstandingIterators.add( this );
+                statement = connection.prepareStatement( sqlText );
                 resultSet = statement.executeQuery();
                 connection.commit();
-            } catch (SQLException e) {
-                processSqlException(null, e);
+            }
+            catch ( SQLException e )
+            {
+                processSqlException( null, e );
             }
 
-            traceResult(debugInfo, null);
+            traceResult( debugInfo, null );
         }
 
-        public boolean hasNext() {
+        public boolean hasNext( )
+        {
             return !finished;
         }
 
-        public String next() {
-            if (finished) {
-                throw new IllegalStateException("iterator completed");
+        public String next( )
+        {
+            if ( finished )
+            {
+                throw new IllegalStateException( "iterator completed" );
             }
             final String returnValue = nextValue;
             getNextItem();
             return returnValue;
         }
 
-        public void remove() {
-            throw new UnsupportedOperationException("remove not supported");
+        public void remove( )
+        {
+            throw new UnsupportedOperationException( "remove not supported" );
         }
 
-        private void getNextItem() {
-            try {
-                if (resultSet.next()) {
-                    nextValue = resultSet.getString(DatabaseService.KEY_COLUMN);
-                } else {
+        private void getNextItem( )
+        {
+            try
+            {
+                if ( resultSet.next() )
+                {
+                    nextValue = resultSet.getString( DatabaseService.KEY_COLUMN );
+                }
+                else
+                {
                     close();
                 }
-            } catch (SQLException e) {
+            }
+            catch ( SQLException e )
+            {
                 finished = true;
-                LOGGER.warn("unexpected error during result set iteration: " + e.getMessage());
+                LOGGER.warn( "unexpected error during result set iteration: " + e.getMessage() );
             }
-            databaseService.updateStats(DatabaseService.OperationType.READ);
+            databaseService.updateStats( DatabaseService.OperationType.READ );
         }
 
-        public void close() {
+        public void close( )
+        {
             final DatabaseUtil.DebugInfo debugInfo = DatabaseUtil.DebugInfo.create(
-                    "iterator #" + counter + " close", table, null, null);
-            traceBegin(debugInfo);
-
-            try {
-                LOCK.lock();
-                outstandingIterators.remove(this);
-
-                if (resultSet != null) {
-                    try {
+                    "iterator #" + counter + " close", table, null, null );
+            traceBegin( debugInfo );
+
+            try
+            {
+                lock.lock();
+                outstandingIterators.remove( this );
+
+                if ( resultSet != null )
+                {
+                    try
+                    {
                         resultSet.close();
                         resultSet = null;
-                    } catch (SQLException e) {
-                        LOGGER.error("error closing inner resultSet in iterator: " + e.getMessage());
+                    }
+                    catch ( SQLException e )
+                    {
+                        LOGGER.error( "error closing inner resultSet in iterator: " + e.getMessage() );
                     }
                 }
 
-                if (statement != null) {
-                    try {
+                if ( statement != null )
+                {
+                    try
+                    {
                         statement.close();
                         statement = null;
-                    } catch (SQLException e) {
-                        LOGGER.error("error closing inner statement in iterator: " + e.getMessage());
+                    }
+                    catch ( SQLException e )
+                    {
+                        LOGGER.error( "error closing inner statement in iterator: " + e.getMessage() );
                     }
                 }
 
                 finished = true;
-            } finally {
-                LOCK.unlock();
+            }
+            finally
+            {
+                lock.unlock();
             }
 
-            traceResult(debugInfo, "outstandingIterators=" + outstandingIterators.size());
+            traceResult( debugInfo, "outstandingIterators=" + outstandingIterators.size() );
         }
     }
 
-    private void traceBegin(final DatabaseUtil.DebugInfo debugInfo) {
-        if (!traceLogEnabled) {
+    private void traceBegin( final DatabaseUtil.DebugInfo debugInfo )
+    {
+        if ( !traceLogEnabled )
+        {
             return;
         }
 
-        LOGGER.trace("accessor #" + accessorNumber + " begin operation: " + JsonUtil.serialize(debugInfo));
+        LOGGER.trace( "accessor #" + accessorNumber + " begin operation: " + JsonUtil.serialize( debugInfo ) );
     }
 
     private void traceResult(
             final DatabaseUtil.DebugInfo debugInfo,
             final Object result
-    ) {
-        if (!traceLogEnabled) {
+    )
+    {
+        if ( !traceLogEnabled )
+        {
             return;
         }
 
-        final Map<String,String> map = JsonUtil.deserializeStringMap(JsonUtil.serialize(debugInfo));
-        map.put("duration", TimeDuration.fromCurrent(debugInfo.getStartTime()).asCompactString());
-        if (result != null) {
-            map.put("result", String.valueOf(result));
+        final Map<String, String> map = JsonUtil.deserializeStringMap( JsonUtil.serialize( debugInfo ) );
+        map.put( "duration", TimeDuration.fromCurrent( debugInfo.getStartTime() ).asCompactString() );
+        if ( result != null )
+        {
+            map.put( "result", String.valueOf( result ) );
         }
-        LOGGER.trace("accessor #" + accessorNumber + " operation result: " + StringUtil.mapToString(map));
+        LOGGER.trace( "accessor #" + accessorNumber + " operation result: " + StringUtil.mapToString( map ) );
     }
 
-    private interface SqlFunction<T>  {
-        T execute() throws DatabaseException;
+    private interface SqlFunction<T>
+    {
+        T execute( ) throws DatabaseException;
     }
 
-    private <T> T execute(final DatabaseUtil.DebugInfo debugInfo, final SqlFunction<T> sqlFunction)
+    private <T> T execute( final DatabaseUtil.DebugInfo debugInfo, final SqlFunction<T> sqlFunction )
             throws DatabaseException
     {
-        traceBegin(debugInfo);
+        traceBegin( debugInfo );
 
-        try {
-            LOCK.lock();
+        try
+        {
+            lock.lock();
 
-            try {
+            try
+            {
                 final T result = sqlFunction.execute();
-                traceResult(debugInfo, result);
-                databaseService.updateStats(DatabaseService.OperationType.WRITE);
+                traceResult( debugInfo, result );
+                databaseService.updateStats( DatabaseService.OperationType.WRITE );
                 return result;
-            } finally {
-                DatabaseUtil.commit(connection);
+            }
+            finally
+            {
+                DatabaseUtil.commit( connection );
             }
 
-        } finally {
-            LOCK.unlock();
+        }
+        finally
+        {
+            lock.unlock();
         }
 
     }
 
-    Connection getConnection()
+    Connection getConnection( )
     {
         return connection;
     }
 
-    void close() {
-        closed.set(true);
+    void close( )
+    {
+        closed.set( true );
 
-        try {
-            LOCK.lock();
-            try {
-                if (!outstandingIterators.isEmpty()) {
-                    LOGGER.warn("closing outstanding " + outstandingIterators.size() + " iterators");
+        try
+        {
+            lock.lock();
+            try
+            {
+                if ( !outstandingIterators.isEmpty() )
+                {
+                    LOGGER.warn( "closing outstanding " + outstandingIterators.size() + " iterators" );
                 }
-                for (final DBIterator iterator : new HashSet<>(outstandingIterators)) {
+                for ( final DBIterator iterator : new HashSet<>( outstandingIterators ) )
+                {
                     iterator.close();
                 }
-            } catch (Exception e) {
-                LOGGER.warn("error while closing connection: " + e.getMessage());
+            }
+            catch ( Exception e )
+            {
+                LOGGER.warn( "error while closing connection: " + e.getMessage() );
             }
 
-            try {
+            try
+            {
                 connection.close();
-            } catch (SQLException e) {
-                LOGGER.warn("error while closing connection: " + e.getMessage());
             }
-        } finally {
-            LOCK.unlock();
+            catch ( SQLException e )
+            {
+                LOGGER.warn( "error while closing connection: " + e.getMessage() );
+            }
+        }
+        finally
+        {
+            lock.unlock();
         }
 
-        LOGGER.trace("closed accessor #" + accessorNumber);
+        LOGGER.trace( "closed accessor #" + accessorNumber );
     }
 
-    private boolean containsImpl(final DatabaseTable table, final String key)
+    private boolean containsImpl( final DatabaseTable table, final String key )
             throws SQLException
     {
         final String sqlStatement = "SELECT COUNT(" + DatabaseService.KEY_COLUMN + ") FROM " + table.name()
                 + " WHERE " + DatabaseService.KEY_COLUMN + " = ?";
 
-        try (PreparedStatement selectStatement = connection.prepareStatement(sqlStatement);) {
-            selectStatement.setString(1, key);
-            selectStatement.setMaxRows(1);
-
-            try (ResultSet resultSet = selectStatement.executeQuery()) {
-                if (resultSet.next()) {
-                    return resultSet.getInt(1) > 0;
+        try ( PreparedStatement selectStatement = connection.prepareStatement( sqlStatement ); )
+        {
+            selectStatement.setString( 1, key );
+            selectStatement.setMaxRows( 1 );
+
+            try ( ResultSet resultSet = selectStatement.executeQuery() )
+            {
+                if ( resultSet.next() )
+                {
+                    return resultSet.getInt( 1 ) > 0;
                 }
             }
         }
@@ -497,22 +593,28 @@ class DatabaseAccessorImpl implements DatabaseAccessor {
         return false;
     }
 
-    private void executeUpdate(final String sqlStatement, final DatabaseUtil.DebugInfo debugInfo, final String... params)
+    private void executeUpdate( final String sqlStatement, final DatabaseUtil.DebugInfo debugInfo, final String... params )
             throws DatabaseException
     {
-        try (PreparedStatement statement = connection.prepareStatement(sqlStatement) ){
-            for (int i = 0; i < params.length; i++) {
-                statement.setString(i + 1, params[i]);
+        try ( PreparedStatement statement = connection.prepareStatement( sqlStatement ) )
+        {
+            for ( int i = 0; i < params.length; i++ )
+            {
+                statement.setString( i + 1, params[ i ] );
             }
             statement.executeUpdate();
-        } catch (SQLException e) {
-            processSqlException(debugInfo, e);
+        }
+        catch ( SQLException e )
+        {
+            processSqlException( debugInfo, e );
         }
     }
 
-    private void preCheck() {
-        if (closed.get()) {
-            throw new IllegalStateException("call to perform database operation but accessor has been closed");
+    private void preCheck( )
+    {
+        if ( closed.get() )
+        {
+            throw new IllegalStateException( "call to perform database operation but accessor has been closed" );
         }
     }
 }

+ 1 - 0
server/src/main/java/password/pwm/util/form/FormUtility.java

@@ -221,6 +221,7 @@ public class FormUtility
         checkReadOnlyAndHidden,
     }
 
+    @SuppressWarnings( "checkstyle:MethodLength" )
     public static void validateFormValueUniqueness(
             final PwmApplication pwmApplication,
             final Map<FormConfiguration, String> formValues,

+ 187 - 116
server/src/main/java/password/pwm/util/java/JsonUtil.java

@@ -54,78 +54,98 @@ import java.util.List;
 import java.util.Map;
 import java.util.TimeZone;
 
-public class JsonUtil {
-    private static final PwmLogger LOGGER = PwmLogger.forClass(JsonUtil.class);
+public class JsonUtil
+{
+    private static final PwmLogger LOGGER = PwmLogger.forClass( JsonUtil.class );
 
-    public enum Flag {
+    public enum Flag
+    {
         PrettyPrint,
         HtmlEscape,
     }
 
-    private static final Gson GENERIC_GSON = registerTypeAdapters(new GsonBuilder())
+    private static final Gson GENERIC_GSON = registerTypeAdapters( new GsonBuilder() )
             .disableHtmlEscaping()
             .create();
 
-    private static Gson getGson(final Flag... flags) {
-        if (flags == null || flags.length == 0) {
+    private static Gson getGson( final Flag... flags )
+    {
+        if ( flags == null || flags.length == 0 )
+        {
             return GENERIC_GSON;
         }
 
-        final GsonBuilder gsonBuilder = registerTypeAdapters(new GsonBuilder());
+        final GsonBuilder gsonBuilder = registerTypeAdapters( new GsonBuilder() );
 
-        if (!JavaHelper.enumArrayContainsValue(flags, Flag.HtmlEscape)) {
+        if ( !JavaHelper.enumArrayContainsValue( flags, Flag.HtmlEscape ) )
+        {
             gsonBuilder.disableHtmlEscaping();
         }
 
-        if (JavaHelper.enumArrayContainsValue(flags, Flag.PrettyPrint)) {
+        if ( JavaHelper.enumArrayContainsValue( flags, Flag.PrettyPrint ) )
+        {
             gsonBuilder.setPrettyPrinting();
         }
 
         return gsonBuilder.create();
     }
 
-    public static <T> T deserialize(final String jsonString, final TypeToken typeToken) {
-        return JsonUtil.getGson().fromJson(jsonString, typeToken.getType());
+    public static <T> T deserialize( final String jsonString, final TypeToken typeToken )
+    {
+        return JsonUtil.getGson().fromJson( jsonString, typeToken.getType() );
     }
 
-    public static <T> T deserialize(final String jsonString, final Type type) {
-        return JsonUtil.getGson().fromJson(jsonString, type);
+    public static <T> T deserialize( final String jsonString, final Type type )
+    {
+        return JsonUtil.getGson().fromJson( jsonString, type );
     }
 
-    public static List<String> deserializeStringList(final String jsonString) {
-        return JsonUtil.getGson().fromJson(jsonString, new TypeToken<List<Object>>() {
-        }.getType());
+    public static List<String> deserializeStringList( final String jsonString )
+    {
+        return JsonUtil.getGson().fromJson( jsonString, new TypeToken<List<Object>>()
+        {
+        }.getType() );
     }
 
-    public static Map<String, String> deserializeStringMap(final String jsonString) {
-        return JsonUtil.getGson().fromJson(jsonString, new TypeToken<Map<String, String>>() {
-        }.getType());
+    public static Map<String, String> deserializeStringMap( final String jsonString )
+    {
+        return JsonUtil.getGson().fromJson( jsonString, new TypeToken<Map<String, String>>()
+        {
+        }.getType() );
     }
 
-    public static Map<String, Object> deserializeStringObjectMap(final String jsonString) {
-        return JsonUtil.getGson().fromJson(jsonString, new TypeToken<Map<String, Object>>() {
-        }.getType());
+    public static Map<String, Object> deserializeStringObjectMap( final String jsonString )
+    {
+        return JsonUtil.getGson().fromJson( jsonString, new TypeToken<Map<String, Object>>()
+        {
+        }.getType() );
     }
 
-    public static Map<String, Object> deserializeMap(final String jsonString) {
-        return JsonUtil.getGson().fromJson(jsonString, new TypeToken<Map<String, Object>>() {
-        }.getType());
+    public static Map<String, Object> deserializeMap( final String jsonString )
+    {
+        return JsonUtil.getGson().fromJson( jsonString, new TypeToken<Map<String, Object>>()
+        {
+        }.getType() );
     }
 
-    public static <T> T deserialize(final String json, final Class<T> classOfT) {
-        return JsonUtil.getGson().fromJson(json, classOfT);
+    public static <T> T deserialize( final String json, final Class<T> classOfT )
+    {
+        return JsonUtil.getGson().fromJson( json, classOfT );
     }
 
-    public static String serialize(final Serializable object, final Flag... flags) {
-        return JsonUtil.getGson(flags).toJson(object);
+    public static String serialize( final Serializable object, final Flag... flags )
+    {
+        return JsonUtil.getGson( flags ).toJson( object );
     }
 
-    public static String serializeMap(final Map object, final Flag... flags) {
-        return JsonUtil.getGson(flags).toJson(object);
+    public static String serializeMap( final Map object, final Flag... flags )
+    {
+        return JsonUtil.getGson( flags ).toJson( object );
     }
 
-    public static String serializeCollection(final Collection object, final Flag... flags) {
-        return JsonUtil.getGson(flags).toJson(object);
+    public static String serializeCollection( final Collection object, final Flag... flags )
+    {
+        return JsonUtil.getGson( flags ).toJson( object );
     }
 
     /**
@@ -133,26 +153,36 @@ public class JsonUtil {
      * and the default gson serializer will cause a {@code java.lang.StackOverflowError}.  Standard Base64 encoding of
      * the cert is used as the json format.
      */
-    private static class X509CertificateAdapter implements JsonSerializer<X509Certificate>, JsonDeserializer<X509Certificate> {
-        private X509CertificateAdapter() {
+    private static class X509CertificateAdapter implements JsonSerializer<X509Certificate>, JsonDeserializer<X509Certificate>
+    {
+        private X509CertificateAdapter( )
+        {
         }
 
-        public synchronized JsonElement serialize(final X509Certificate cert, final Type type, final JsonSerializationContext jsonSerializationContext) {
-            try {
-                return new JsonPrimitive(StringUtil.base64Encode(cert.getEncoded()));
-            } catch (CertificateEncodingException e) {
-                throw new IllegalStateException("unable to json-encode certificate: " + e.getMessage());
+        public synchronized JsonElement serialize( final X509Certificate cert, final Type type, final JsonSerializationContext jsonSerializationContext )
+        {
+            try
+            {
+                return new JsonPrimitive( StringUtil.base64Encode( cert.getEncoded() ) );
+            }
+            catch ( CertificateEncodingException e )
+            {
+                throw new IllegalStateException( "unable to json-encode certificate: " + e.getMessage() );
             }
         }
 
-        public X509Certificate deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext jsonDeserializationContext)
-                throws JsonParseException {
-            try {
-                final CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
-                return (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(StringUtil.base64Decode(
-                        jsonElement.getAsString())));
-            } catch (Exception e) {
-                throw new JsonParseException("unable to parse x509certificate: " + e.getMessage());
+        public X509Certificate deserialize( final JsonElement jsonElement, final Type type, final JsonDeserializationContext jsonDeserializationContext )
+                throws JsonParseException
+        {
+            try
+            {
+                final CertificateFactory certificateFactory = CertificateFactory.getInstance( "X.509" );
+                return ( X509Certificate ) certificateFactory.generateCertificate( new ByteArrayInputStream( StringUtil.base64Decode(
+                        jsonElement.getAsString() ) ) );
+            }
+            catch ( Exception e )
+            {
+                throw new JsonParseException( "unable to parse x509certificate: " + e.getMessage() );
             }
         }
     }
@@ -160,36 +190,47 @@ public class JsonUtil {
     /**
      * GsonSerializer that stores dates in ISO 8601 format, with a deserialier that also reads local-platform format reading.
      */
-    private static class DateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
+    private static class DateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date>
+    {
         private static final DateFormat ISO_DATE_FORMAT;
         private static final DateFormat GSON_DATE_FORMAT;
 
-        static {
-            ISO_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
-            ISO_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("Zulu"));
+        static
+        {
+            ISO_DATE_FORMAT = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss'Z'" );
+            ISO_DATE_FORMAT.setTimeZone( TimeZone.getTimeZone( "Zulu" ) );
 
-            GSON_DATE_FORMAT = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT);
-            GSON_DATE_FORMAT.setTimeZone(TimeZone.getDefault());
+            GSON_DATE_FORMAT = DateFormat.getDateTimeInstance( DateFormat.DEFAULT, DateFormat.DEFAULT );
+            GSON_DATE_FORMAT.setTimeZone( TimeZone.getDefault() );
         }
 
-        private DateTypeAdapter() {
+        private DateTypeAdapter( )
+        {
         }
 
-        public synchronized JsonElement serialize(final Date date, final Type type, final JsonSerializationContext jsonSerializationContext) {
-            return new JsonPrimitive(ISO_DATE_FORMAT.format(date));
+        public synchronized JsonElement serialize( final Date date, final Type type, final JsonSerializationContext jsonSerializationContext )
+        {
+            return new JsonPrimitive( ISO_DATE_FORMAT.format( date ) );
         }
 
-        public synchronized Date deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext jsonDeserializationContext) {
-            try {
-                return ISO_DATE_FORMAT.parse(jsonElement.getAsString());
-            } catch (ParseException e) { /* noop */ }
+        public synchronized Date deserialize( final JsonElement jsonElement, final Type type, final JsonDeserializationContext jsonDeserializationContext )
+        {
+            try
+            {
+                return ISO_DATE_FORMAT.parse( jsonElement.getAsString() );
+            }
+            catch ( ParseException e )
+            { /* noop */ }
 
             // for backwards compatibility
-            try {
-                return GSON_DATE_FORMAT.parse(jsonElement.getAsString());
-            } catch (ParseException e) {
-                LOGGER.debug("unable to parse stored json Date.class timestamp '" + jsonElement.getAsString() + "' error: " + e.getMessage());
-                throw new JsonParseException(e);
+            try
+            {
+                return GSON_DATE_FORMAT.parse( jsonElement.getAsString() );
+            }
+            catch ( ParseException e )
+            {
+                LOGGER.debug( "unable to parse stored json Date.class timestamp '" + jsonElement.getAsString() + "' error: " + e.getMessage() );
+                throw new JsonParseException( e );
             }
         }
     }
@@ -197,90 +238,120 @@ public class JsonUtil {
     /**
      * GsonSerializer that stores instants in ISO 8601 format, with a deserialier that also reads local-platform format reading.
      */
-    private static class InstantTypeAdapter implements JsonSerializer<Instant>, JsonDeserializer<Instant> {
-        private InstantTypeAdapter() {
+    private static class InstantTypeAdapter implements JsonSerializer<Instant>, JsonDeserializer<Instant>
+    {
+        private InstantTypeAdapter( )
+        {
         }
 
-        public synchronized JsonElement serialize(final Instant instant, final Type type, final JsonSerializationContext jsonSerializationContext) {
-            return new JsonPrimitive(JavaHelper.toIsoDate(instant));
+        public synchronized JsonElement serialize( final Instant instant, final Type type, final JsonSerializationContext jsonSerializationContext )
+        {
+            return new JsonPrimitive( JavaHelper.toIsoDate( instant ) );
         }
 
-        public synchronized Instant deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext jsonDeserializationContext) {
-            try {
-                return JavaHelper.parseIsoToInstant(jsonElement.getAsString());
-            } catch (Exception e) {
-                LOGGER.debug("unable to parse stored json Instant.class timestamp '" + jsonElement.getAsString() + "' error: " + e.getMessage());
-                throw new JsonParseException(e);
+        public synchronized Instant deserialize( final JsonElement jsonElement, final Type type, final JsonDeserializationContext jsonDeserializationContext )
+        {
+            try
+            {
+                return JavaHelper.parseIsoToInstant( jsonElement.getAsString() );
+            }
+            catch ( Exception e )
+            {
+                LOGGER.debug( "unable to parse stored json Instant.class timestamp '" + jsonElement.getAsString() + "' error: " + e.getMessage() );
+                throw new JsonParseException( e );
             }
         }
     }
 
-    private static class ByteArrayToBase64TypeAdapter implements JsonSerializer<byte[]>, JsonDeserializer<byte[]> {
-        public byte[] deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
-            try {
-                return StringUtil.base64Decode(json.getAsString());
-            } catch (IOException e) {
+    private static class ByteArrayToBase64TypeAdapter implements JsonSerializer<byte[]>, JsonDeserializer<byte[]>
+    {
+        public byte[] deserialize( final JsonElement json, final Type typeOfT, final JsonDeserializationContext context ) throws JsonParseException
+        {
+            try
+            {
+                return StringUtil.base64Decode( json.getAsString() );
+            }
+            catch ( IOException e )
+            {
                 final String errorMsg = "io stream error while de-serializing byte array: " + e.getMessage();
-                LOGGER.error(errorMsg);
-                throw new JsonParseException(errorMsg, e);
+                LOGGER.error( errorMsg );
+                throw new JsonParseException( errorMsg, e );
             }
         }
 
-        public JsonElement serialize(final byte[] src, final Type typeOfSrc, final JsonSerializationContext context) {
-            try {
-                return new JsonPrimitive(StringUtil.base64Encode(src, StringUtil.Base64Options.GZIP));
-            } catch (IOException e) {
+        public JsonElement serialize( final byte[] src, final Type typeOfSrc, final JsonSerializationContext context )
+        {
+            try
+            {
+                return new JsonPrimitive( StringUtil.base64Encode( src, StringUtil.Base64Options.GZIP ) );
+            }
+            catch ( IOException e )
+            {
                 final String errorMsg = "io stream error while serializing byte array: " + e.getMessage();
-                LOGGER.error(errorMsg);
-                throw new JsonParseException(errorMsg, e);
+                LOGGER.error( errorMsg );
+                throw new JsonParseException( errorMsg, e );
             }
         }
     }
 
-    private static class PasswordDataTypeAdapter implements JsonSerializer<PasswordData>, JsonDeserializer<PasswordData> {
-        public PasswordData deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
-            try {
-                return new PasswordData(json.getAsString());
-            } catch (PwmUnrecoverableException e) {
+    private static class PasswordDataTypeAdapter implements JsonSerializer<PasswordData>, JsonDeserializer<PasswordData>
+    {
+        public PasswordData deserialize( final JsonElement json, final Type typeOfT, final JsonDeserializationContext context ) throws JsonParseException
+        {
+            try
+            {
+                return new PasswordData( json.getAsString() );
+            }
+            catch ( PwmUnrecoverableException e )
+            {
                 final String errorMsg = "error while deserializing password data: " + e.getMessage();
-                LOGGER.error(errorMsg);
-                throw new JsonParseException(errorMsg, e);
+                LOGGER.error( errorMsg );
+                throw new JsonParseException( errorMsg, e );
             }
         }
 
-        public JsonElement serialize(final PasswordData src, final Type typeOfSrc, final JsonSerializationContext context) {
-            try {
-                return new JsonPrimitive(src.getStringValue());
-            } catch (PwmUnrecoverableException e) {
+        public JsonElement serialize( final PasswordData src, final Type typeOfSrc, final JsonSerializationContext context )
+        {
+            try
+            {
+                return new JsonPrimitive( src.getStringValue() );
+            }
+            catch ( PwmUnrecoverableException e )
+            {
                 final String errorMsg = "error while serializing password data: " + e.getMessage();
-                LOGGER.error(errorMsg);
-                throw new JsonParseException(errorMsg, e);
+                LOGGER.error( errorMsg );
+                throw new JsonParseException( errorMsg, e );
             }
         }
 
     }
 
-    private static class PwmLdapVendorTypeAdaptor implements JsonSerializer<PwmLdapVendor>, JsonDeserializer<PwmLdapVendor> {
-        public PwmLdapVendor deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
-                return PwmLdapVendor.fromString( json.getAsString() );
+    private static class PwmLdapVendorTypeAdaptor implements JsonSerializer<PwmLdapVendor>, JsonDeserializer<PwmLdapVendor>
+    {
+        public PwmLdapVendor deserialize( final JsonElement json, final Type typeOfT, final JsonDeserializationContext context ) throws JsonParseException
+        {
+            return PwmLdapVendor.fromString( json.getAsString() );
         }
 
-        public JsonElement serialize(final PwmLdapVendor src, final Type typeOfSrc, final JsonSerializationContext context) {
-                return new JsonPrimitive(src.name());
+        public JsonElement serialize( final PwmLdapVendor src, final Type typeOfSrc, final JsonSerializationContext context )
+        {
+            return new JsonPrimitive( src.name() );
         }
     }
 
-    private static GsonBuilder registerTypeAdapters(final GsonBuilder gsonBuilder) {
-        gsonBuilder.registerTypeAdapter(Date.class, new DateTypeAdapter());
-        gsonBuilder.registerTypeAdapter(Instant.class, new InstantTypeAdapter());
-        gsonBuilder.registerTypeAdapter(X509Certificate.class, new X509CertificateAdapter());
-        gsonBuilder.registerTypeAdapter(byte[].class, new ByteArrayToBase64TypeAdapter());
-        gsonBuilder.registerTypeAdapter(PasswordData.class, new PasswordDataTypeAdapter());
+    private static GsonBuilder registerTypeAdapters( final GsonBuilder gsonBuilder )
+    {
+        gsonBuilder.registerTypeAdapter( Date.class, new DateTypeAdapter() );
+        gsonBuilder.registerTypeAdapter( Instant.class, new InstantTypeAdapter() );
+        gsonBuilder.registerTypeAdapter( X509Certificate.class, new X509CertificateAdapter() );
+        gsonBuilder.registerTypeAdapter( byte[].class, new ByteArrayToBase64TypeAdapter() );
+        gsonBuilder.registerTypeAdapter( PasswordData.class, new PasswordDataTypeAdapter() );
         return gsonBuilder;
     }
 
-    public static <T> T cloneUsingJson(final Serializable srcObject, final Class<T> classOfT) {
-        final String asJson = JsonUtil.serialize(srcObject);
-        return JsonUtil.deserialize(asJson, classOfT);
+    public static <T> T cloneUsingJson( final Serializable srcObject, final Class<T> classOfT )
+    {
+        final String asJson = JsonUtil.serialize( srcObject );
+        return JsonUtil.deserialize( asJson, classOfT );
     }
 }

+ 3 - 0
server/src/main/java/password/pwm/util/logging/PwmLogEvent.java

@@ -74,6 +74,8 @@ public class PwmLogEvent implements Serializable, Comparable
         return JsonUtil.deserialize( encodedString, PwmLogEvent.class );
     }
 
+
+    @SuppressWarnings( "checkstyle:ParameterNumber" )
     private PwmLogEvent(
             final Instant date,
             final String topic,
@@ -153,6 +155,7 @@ public class PwmLogEvent implements Serializable, Comparable
         return sb.toString();
     }
 
+    @SuppressWarnings( "checkstyle:ParameterNumber" )
     public static PwmLogEvent createPwmLogEvent(
             final Instant date,
             final String topic,

File diff suppressed because it is too large
+ 379 - 270
server/src/main/java/password/pwm/util/operations/PasswordUtility.java


+ 240 - 171
server/src/main/java/password/pwm/util/queue/SmsQueueManager.java

@@ -69,16 +69,19 @@ import java.util.regex.Pattern;
 /**
  * @author Menno Pieters, Jason D. Rivard
  */
-public class SmsQueueManager implements PwmService {
-    private static final PwmLogger LOGGER = PwmLogger.forClass(SmsQueueManager.class);
+public class SmsQueueManager implements PwmService
+{
+    private static final PwmLogger LOGGER = PwmLogger.forClass( SmsQueueManager.class );
 
-    public enum SmsNumberFormat {
+    public enum SmsNumberFormat
+    {
         PLAIN,
         PLUS,
         ZEROS
     }
 
-    public enum SmsDataEncoding {
+    public enum SmsDataEncoding
+    {
         NONE,
         URL,
         XML,
@@ -89,12 +92,12 @@ public class SmsQueueManager implements PwmService {
         SQL
     }
 
-    public static final String TOKEN_USER       = "%USER%";
-    public static final String TOKEN_SENDERID   = "%SENDERID%";
-    public static final String TOKEN_MESSAGE    = "%MESSAGE%";
-    public static final String TOKEN_TO         = "%TO%";
-    public static final String TOKEN_PASS       = "%PASS%";
-    public static final String TOKEN_REQUESTID  = "%REQUESTID%";
+    public static final String TOKEN_USER = "%USER%";
+    public static final String TOKEN_SENDERID = "%SENDERID%";
+    public static final String TOKEN_MESSAGE = "%MESSAGE%";
+    public static final String TOKEN_TO = "%TO%";
+    public static final String TOKEN_PASS = "%PASS%";
+    public static final String TOKEN_REQUESTID = "%REQUESTID%";
 
     private SmsSendEngine smsSendEngine;
 
@@ -103,7 +106,8 @@ public class SmsQueueManager implements PwmService {
     private STATUS status = STATUS.NEW;
     private ErrorInformation lastError;
 
-    public SmsQueueManager() {
+    public SmsQueueManager( )
+    {
     }
 
     public void init(
@@ -113,44 +117,53 @@ public class SmsQueueManager implements PwmService {
     {
         status = STATUS.OPENING;
         this.pwmApplication = pwmApplication;
-        if (pwmApplication.getLocalDB() == null || pwmApplication.getLocalDB().status() != LocalDB.Status.OPEN) {
-            LOGGER.warn("localdb is not open,  will remain closed");
+        if ( pwmApplication.getLocalDB() == null || pwmApplication.getLocalDB().status() != LocalDB.Status.OPEN )
+        {
+            LOGGER.warn( "localdb is not open,  will remain closed" );
             status = STATUS.CLOSED;
             return;
         }
 
         final WorkQueueProcessor.Settings settings = WorkQueueProcessor.Settings.builder()
-                .maxEvents(Integer.parseInt(pwmApplication.getConfig().readAppProperty(AppProperty.QUEUE_SMS_MAX_COUNT)))
-                .retryDiscardAge(new TimeDuration(pwmApplication.getConfig().readSettingAsLong(PwmSetting.SMS_MAX_QUEUE_AGE), TimeUnit.SECONDS))
-                .retryInterval(new TimeDuration(Long.parseLong(pwmApplication.getConfig().readAppProperty(AppProperty.QUEUE_SMS_RETRY_TIMEOUT_MS))))
+                .maxEvents( Integer.parseInt( pwmApplication.getConfig().readAppProperty( AppProperty.QUEUE_SMS_MAX_COUNT ) ) )
+                .retryDiscardAge( new TimeDuration( pwmApplication.getConfig().readSettingAsLong( PwmSetting.SMS_MAX_QUEUE_AGE ), TimeUnit.SECONDS ) )
+                .retryInterval( new TimeDuration( Long.parseLong( pwmApplication.getConfig().readAppProperty( AppProperty.QUEUE_SMS_RETRY_TIMEOUT_MS ) ) ) )
                 .build();
 
-        final LocalDBStoredQueue localDBStoredQueue = LocalDBStoredQueue.createLocalDBStoredQueue(pwmApplication, pwmApplication.getLocalDB(), LocalDB.DB.SMS_QUEUE);
+        final LocalDBStoredQueue localDBStoredQueue = LocalDBStoredQueue.createLocalDBStoredQueue( pwmApplication, pwmApplication.getLocalDB(), LocalDB.DB.SMS_QUEUE );
 
-        workQueueProcessor = new WorkQueueProcessor<>(pwmApplication, localDBStoredQueue, settings, new SmsItemProcessor(), this.getClass());
+        workQueueProcessor = new WorkQueueProcessor<>( pwmApplication, localDBStoredQueue, settings, new SmsItemProcessor(), this.getClass() );
 
-        smsSendEngine = new SmsSendEngine(pwmApplication, pwmApplication.getConfig());
+        smsSendEngine = new SmsSendEngine( pwmApplication, pwmApplication.getConfig() );
 
         status = STATUS.OPEN;
     }
 
-    private class SmsItemProcessor implements WorkQueueProcessor.ItemProcessor<SmsItemBean> {
+    private class SmsItemProcessor implements WorkQueueProcessor.ItemProcessor<SmsItemBean>
+    {
         @Override
-        public WorkQueueProcessor.ProcessResult process(final SmsItemBean workItem) {
-            try {
-                for (final String msgPart : splitMessage(workItem.getMessage())) {
-                    smsSendEngine.sendSms(workItem.getTo(), msgPart, workItem.getSessionLabel());
+        public WorkQueueProcessor.ProcessResult process( final SmsItemBean workItem )
+        {
+            try
+            {
+                for ( final String msgPart : splitMessage( workItem.getMessage() ) )
+                {
+                    smsSendEngine.sendSms( workItem.getTo(), msgPart, workItem.getSessionLabel() );
                 }
-                StatisticsManager.incrementStat(pwmApplication, Statistic.SMS_SEND_SUCCESSES);
+                StatisticsManager.incrementStat( pwmApplication, Statistic.SMS_SEND_SUCCESSES );
                 lastError = null;
-            } catch (PwmUnrecoverableException e) {
-                StatisticsManager.incrementStat(pwmApplication, Statistic.SMS_SEND_DISCARDS);
-                StatisticsManager.incrementStat(pwmApplication, Statistic.SMS_SEND_FAILURES);
-                LOGGER.error("discarding sms message due to permanent failure: " + e.getErrorInformation().toDebugStr());
+            }
+            catch ( PwmUnrecoverableException e )
+            {
+                StatisticsManager.incrementStat( pwmApplication, Statistic.SMS_SEND_DISCARDS );
+                StatisticsManager.incrementStat( pwmApplication, Statistic.SMS_SEND_FAILURES );
+                LOGGER.error( "discarding sms message due to permanent failure: " + e.getErrorInformation().toDebugStr() );
                 lastError = e.getErrorInformation();
                 return WorkQueueProcessor.ProcessResult.FAILED;
-            } catch (PwmOperationalException e) {
-                StatisticsManager.incrementStat(pwmApplication, Statistic.SMS_SEND_FAILURES);
+            }
+            catch ( PwmOperationalException e )
+            {
+                StatisticsManager.incrementStat( pwmApplication, Statistic.SMS_SEND_FAILURES );
                 lastError = e.getErrorInformation();
                 return WorkQueueProcessor.ProcessResult.RETRY;
             }
@@ -159,27 +172,32 @@ public class SmsQueueManager implements PwmService {
         }
 
         @Override
-        public String convertToDebugString(final SmsItemBean workItem) {
-            final Map<String,Object> debugOutputMap = new LinkedHashMap<>();
+        public String convertToDebugString( final SmsItemBean workItem )
+        {
+            final Map<String, Object> debugOutputMap = new LinkedHashMap<>();
 
-            debugOutputMap.put("to", workItem.getTo());
+            debugOutputMap.put( "to", workItem.getTo() );
 
-            return JsonUtil.serializeMap(debugOutputMap);
+            return JsonUtil.serializeMap( debugOutputMap );
         }
     }
 
-    public void addSmsToQueue(final SmsItemBean smsItem)
+    public void addSmsToQueue( final SmsItemBean smsItem )
             throws PwmUnrecoverableException
     {
-        final SmsItemBean shortenedBean = shortenMessageIfNeeded(smsItem);
-        if (!determineIfItemCanBeDelivered(shortenedBean)) {
+        final SmsItemBean shortenedBean = shortenMessageIfNeeded( smsItem );
+        if ( !determineIfItemCanBeDelivered( shortenedBean ) )
+        {
             return;
         }
 
-        try {
-            workQueueProcessor.submit(shortenedBean);
-        } catch (Exception e) {
-            LOGGER.error("error writing to LocalDB queue, discarding sms send request: " + e.getMessage());
+        try
+        {
+            workQueueProcessor.submit( shortenedBean );
+        }
+        catch ( Exception e )
+        {
+            LOGGER.error( "error writing to LocalDB queue, discarding sms send request: " + e.getMessage() );
         }
     }
 
@@ -188,45 +206,53 @@ public class SmsQueueManager implements PwmService {
     )
             throws PwmUnrecoverableException
     {
-        final Boolean shorten = pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.SMS_USE_URL_SHORTENER);
-        if (shorten) {
+        final Boolean shorten = pwmApplication.getConfig().readSettingAsBoolean( PwmSetting.SMS_USE_URL_SHORTENER );
+        if ( shorten )
+        {
             final String message = smsItem.getMessage();
-            final String shortenedMessage = pwmApplication.getUrlShortener().shortenUrlInText(message);
-            return new SmsItemBean(smsItem.getTo(), shortenedMessage, smsItem.getSessionLabel());
+            final String shortenedMessage = pwmApplication.getUrlShortener().shortenUrlInText( message );
+            return new SmsItemBean( smsItem.getTo(), shortenedMessage, smsItem.getSessionLabel() );
         }
         return smsItem;
     }
 
-    public static boolean smsIsConfigured(final Configuration config) {
-        final String gatewayUrl = config.readSettingAsString(PwmSetting.SMS_GATEWAY_URL);
-        final String gatewayUser = config.readSettingAsString(PwmSetting.SMS_GATEWAY_USER);
-        final PasswordData gatewayPass = config.readSettingAsPassword(PwmSetting.SMS_GATEWAY_PASSWORD);
-        if (gatewayUrl == null || gatewayUrl.length() < 1) {
-            LOGGER.debug("SMS gateway url is not configured");
+    public static boolean smsIsConfigured( final Configuration config )
+    {
+        final String gatewayUrl = config.readSettingAsString( PwmSetting.SMS_GATEWAY_URL );
+        final String gatewayUser = config.readSettingAsString( PwmSetting.SMS_GATEWAY_USER );
+        final PasswordData gatewayPass = config.readSettingAsPassword( PwmSetting.SMS_GATEWAY_PASSWORD );
+        if ( gatewayUrl == null || gatewayUrl.length() < 1 )
+        {
+            LOGGER.debug( "SMS gateway url is not configured" );
             return false;
         }
 
-        if (gatewayUser != null && gatewayUser.length() > 0 && (gatewayPass == null)) {
-            LOGGER.debug("SMS gateway user configured, but no password provided");
+        if ( gatewayUser != null && gatewayUser.length() > 0 && ( gatewayPass == null ) )
+        {
+            LOGGER.debug( "SMS gateway user configured, but no password provided" );
             return false;
         }
 
         return true;
     }
 
-    boolean determineIfItemCanBeDelivered(final SmsItemBean smsItem) {
+    boolean determineIfItemCanBeDelivered( final SmsItemBean smsItem )
+    {
         final Configuration config = pwmApplication.getConfig();
-        if (!smsIsConfigured(config)) {
+        if ( !smsIsConfigured( config ) )
+        {
             return false;
         }
 
-        if (smsItem.getTo() == null || smsItem.getTo().length() < 1) {
-            LOGGER.debug("discarding sms send event (no to address) " + smsItem.toString());
+        if ( smsItem.getTo() == null || smsItem.getTo().length() < 1 )
+        {
+            LOGGER.debug( "discarding sms send event (no to address) " + smsItem.toString() );
             return false;
         }
 
-        if (smsItem.getMessage() == null || smsItem.getMessage().length() < 1) {
-            LOGGER.debug("discarding sms send event (no message) " + smsItem.toString());
+        if ( smsItem.getMessage() == null || smsItem.getMessage().length() < 1 )
+        {
+            LOGGER.debug( "discarding sms send event (no message) " + smsItem.toString() );
             return false;
         }
 
@@ -234,13 +260,16 @@ public class SmsQueueManager implements PwmService {
     }
 
     @Override
-    public STATUS status() {
+    public STATUS status( )
+    {
         return status;
     }
 
     @Override
-    public void close() {
-        if (workQueueProcessor != null) {
+    public void close( )
+    {
+        if ( workQueueProcessor != null )
+        {
             workQueueProcessor.close();
         }
         workQueueProcessor = null;
@@ -249,62 +278,73 @@ public class SmsQueueManager implements PwmService {
     }
 
     @Override
-    public List<HealthRecord> healthCheck() {
-        if (lastError != null) {
-            return Collections.singletonList(HealthRecord.forMessage(HealthMessage.SMS_SendFailure, lastError.toDebugStr()));
+    public List<HealthRecord> healthCheck( )
+    {
+        if ( lastError != null )
+        {
+            return Collections.singletonList( HealthRecord.forMessage( HealthMessage.SMS_SendFailure, lastError.toDebugStr() ) );
         }
         return null;
     }
 
     @Override
-    public ServiceInfoBean serviceInfo() {
-        final Map<String,String> debugItems = new LinkedHashMap<>();
-        if (workQueueProcessor != null) {
-            debugItems.putAll(workQueueProcessor.debugInfo());
+    public ServiceInfoBean serviceInfo( )
+    {
+        final Map<String, String> debugItems = new LinkedHashMap<>();
+        if ( workQueueProcessor != null )
+        {
+            debugItems.putAll( workQueueProcessor.debugInfo() );
+        }
+        if ( status() == STATUS.OPEN )
+        {
+            return new ServiceInfoBean( Collections.singletonList( DataStorageMethod.LOCALDB ), debugItems );
         }
-        if (status() == STATUS.OPEN) {
-            return new ServiceInfoBean(Collections.singletonList(DataStorageMethod.LOCALDB), debugItems);
-        } else {
-            return new ServiceInfoBean(Collections.emptyList(), debugItems);
+        else
+        {
+            return new ServiceInfoBean( Collections.emptyList(), debugItems );
         }
     }
 
-    private List<String> splitMessage(final String input) {
-        final int size = (int)pwmApplication.getConfig().readSettingAsLong(PwmSetting.SMS_MAX_TEXT_LENGTH);
+    private List<String> splitMessage( final String input )
+    {
+        final int size = ( int ) pwmApplication.getConfig().readSettingAsLong( PwmSetting.SMS_MAX_TEXT_LENGTH );
 
-        final List<String> returnObj = new ArrayList<>((input.length() + size - 1) / size);
+        final List<String> returnObj = new ArrayList<>( ( input.length() + size - 1 ) / size );
 
-        for (int start = 0; start < input.length(); start += size) {
-            returnObj.add(input.substring(start, Math.min(input.length(), start + size)));
+        for ( int start = 0; start < input.length(); start += size )
+        {
+            returnObj.add( input.substring( start, Math.min( input.length(), start + size ) ) );
         }
         return returnObj;
     }
 
 
-    protected static String smsDataEncode(final String data, final SmsDataEncoding encoding) {
+    protected static String smsDataEncode( final String data, final SmsDataEncoding encoding )
+    {
         final String normalizedString = data == null ? "" : data;
 
-        switch (encoding) {
+        switch ( encoding )
+        {
             case NONE:
                 return normalizedString;
 
             case URL:
-                return StringUtil.urlEncode(normalizedString);
+                return StringUtil.urlEncode( normalizedString );
 
             case CSV:
-                return StringUtil.escapeCsv(normalizedString);
+                return StringUtil.escapeCsv( normalizedString );
 
             case HTML:
-                return StringUtil.escapeHtml(normalizedString);
+                return StringUtil.escapeHtml( normalizedString );
 
             case JAVA:
-                return StringUtil.escapeJava(normalizedString);
+                return StringUtil.escapeJava( normalizedString );
 
             case JAVASCRIPT:
-                return StringUtil.escapeJS(normalizedString);
+                return StringUtil.escapeJS( normalizedString );
 
             case XML:
-                return StringUtil.escapeXml(normalizedString);
+                return StringUtil.escapeXml( normalizedString );
 
             default:
                 return normalizedString;
@@ -319,82 +359,94 @@ public class SmsQueueManager implements PwmService {
     )
             throws PwmOperationalException
     {
-        final List<String> resultCodeTests = config.readSettingAsStringArray(PwmSetting.SMS_SUCCESS_RESULT_CODE);
-        if (resultCodeTests != null && !resultCodeTests.isEmpty()) {
-            final String resultCodeStr = String.valueOf(resultCode);
-            if (!resultCodeTests.contains(resultCodeStr)) {
-                throw new PwmOperationalException(new ErrorInformation(
+        final List<String> resultCodeTests = config.readSettingAsStringArray( PwmSetting.SMS_SUCCESS_RESULT_CODE );
+        if ( resultCodeTests != null && !resultCodeTests.isEmpty() )
+        {
+            final String resultCodeStr = String.valueOf( resultCode );
+            if ( !resultCodeTests.contains( resultCodeStr ) )
+            {
+                throw new PwmOperationalException( new ErrorInformation(
                         PwmError.ERROR_SMS_SEND_ERROR,
                         "response result code " + resultCode + " is not a configured successful result code"
-                ));
+                ) );
             }
         }
 
-        final List<String> regexBodyTests = config.readSettingAsStringArray(PwmSetting.SMS_RESPONSE_OK_REGEX);
-        if (regexBodyTests == null || regexBodyTests.isEmpty()) {
+        final List<String> regexBodyTests = config.readSettingAsStringArray( PwmSetting.SMS_RESPONSE_OK_REGEX );
+        if ( regexBodyTests == null || regexBodyTests.isEmpty() )
+        {
             return;
 
         }
 
-        if (resultBody == null || resultBody.isEmpty()) {
-            throw new PwmOperationalException(new ErrorInformation(
+        if ( resultBody == null || resultBody.isEmpty() )
+        {
+            throw new PwmOperationalException( new ErrorInformation(
                     PwmError.ERROR_SMS_SEND_ERROR,
                     "result has no body but there are configured regex response matches, so send not considered successful"
-            ));
+            ) );
         }
 
-        for (final String regex : regexBodyTests) {
-            final Pattern p = Pattern.compile(regex, Pattern.DOTALL);
-            final Matcher m = p.matcher(resultBody);
-            if (m.matches()) {
-                LOGGER.trace("result body matched configured regex match setting: " + regex);
+        for ( final String regex : regexBodyTests )
+        {
+            final Pattern p = Pattern.compile( regex, Pattern.DOTALL );
+            final Matcher m = p.matcher( resultBody );
+            if ( m.matches() )
+            {
+                LOGGER.trace( "result body matched configured regex match setting: " + regex );
                 return;
             }
         }
 
-        throw new PwmOperationalException(new ErrorInformation(
+        throw new PwmOperationalException( new ErrorInformation(
                 PwmError.ERROR_SMS_SEND_ERROR,
                 "result body did not matching any configured regex match settings"
-        ));
+        ) );
     }
 
-    static String formatSmsNumber(final Configuration config, final String smsNumber) {
-        final long ccLong = config.readSettingAsLong(PwmSetting.SMS_DEFAULT_COUNTRY_CODE);
+    static String formatSmsNumber( final Configuration config, final String smsNumber )
+    {
+        final long ccLong = config.readSettingAsLong( PwmSetting.SMS_DEFAULT_COUNTRY_CODE );
         String countryCodeNumber = "";
-        if (ccLong > 0) {
-            countryCodeNumber = String.valueOf(ccLong);
+        if ( ccLong > 0 )
+        {
+            countryCodeNumber = String.valueOf( ccLong );
         }
 
-        final SmsNumberFormat format = config.readSettingAsEnum(PwmSetting.SMS_PHONE_NUMBER_FORMAT,SmsNumberFormat.class);
+        final SmsNumberFormat format = config.readSettingAsEnum( PwmSetting.SMS_PHONE_NUMBER_FORMAT, SmsNumberFormat.class );
         String returnValue = smsNumber;
 
         // Remove (0)
-        returnValue = returnValue.replaceAll("\\(0\\)","");
+        returnValue = returnValue.replaceAll( "\\(0\\)", "" );
 
         // Remove leading double zero, replace by plus
-        if (returnValue.startsWith("00")) {
-            returnValue = "+" + returnValue.substring(2, returnValue.length());
+        if ( returnValue.startsWith( "00" ) )
+        {
+            returnValue = "+" + returnValue.substring( 2, returnValue.length() );
         }
 
         // Replace leading zero by country code
-        if (returnValue.startsWith("0")) {
-            returnValue = countryCodeNumber + returnValue.substring(1, returnValue.length());
+        if ( returnValue.startsWith( "0" ) )
+        {
+            returnValue = countryCodeNumber + returnValue.substring( 1, returnValue.length() );
         }
 
         // Add a leading plus if necessary
-        if (!returnValue.startsWith("+")) {
+        if ( !returnValue.startsWith( "+" ) )
+        {
             returnValue = "+" + returnValue;
         }
 
         // Remove any non-numeric, non-plus characters
-        returnValue = returnValue.replaceAll("[^0-9\\+]","");
+        returnValue = returnValue.replaceAll( "[^0-9\\+]", "" );
 
         // Now the number should be in full international format
         // Let's see if we need to change anything:
-        switch(format) {
+        switch ( format )
+        {
             case PLAIN:
                 // remove plus
-                returnValue = returnValue.replaceAll("^\\+","");
+                returnValue = returnValue.replaceAll( "^\\+", "" );
 
                 // add country code
                 returnValue = countryCodeNumber + returnValue;
@@ -404,7 +456,7 @@ public class SmsQueueManager implements PwmService {
                 break;
             case ZEROS:
                 // replace + with 00
-                returnValue = "00" + returnValue.substring(1);
+                returnValue = "00" + returnValue.substring( 1 );
                 break;
             default:
                 // keep full international format
@@ -413,26 +465,27 @@ public class SmsQueueManager implements PwmService {
         return returnValue;
     }
 
-    private static class SmsSendEngine {
-        private static final PwmLogger LOGGER = PwmLogger.forClass(SmsSendEngine.class);
+    private static class SmsSendEngine
+    {
+        private static final PwmLogger LOGGER = PwmLogger.forClass( SmsSendEngine.class );
         private final PwmApplication pwmApplication;
         private final Configuration config;
         private String lastResponseBody;
 
-        private SmsSendEngine( final PwmApplication pwmApplication, final Configuration configuration)
+        private SmsSendEngine( final PwmApplication pwmApplication, final Configuration configuration )
         {
             this.pwmApplication = pwmApplication;
             this.config = configuration;
         }
 
-        protected void sendSms(final String to, final String message, final SessionLabel sessionLabel)
+        protected void sendSms( final String to, final String message, final SessionLabel sessionLabel )
                 throws PwmUnrecoverableException, PwmOperationalException
         {
             lastResponseBody = null;
 
             final String requestData = makeRequestData( to, message );
 
-            LOGGER.trace("preparing to send SMS data: " + requestData);
+            LOGGER.trace( "preparing to send SMS data: " + requestData );
 
             final PwmHttpClientRequest pwmHttpClientRequest = makeRequest( requestData );
 
@@ -442,54 +495,62 @@ public class SmsQueueManager implements PwmService {
 
             final PwmHttpClient pwmHttpClient = new PwmHttpClient( pwmApplication, sessionLabel, pwmHttpClientConfiguration );
 
-            try {
+            try
+            {
                 final PwmHttpClientResponse pwmHttpClientResponse = pwmHttpClient.makeRequest( pwmHttpClientRequest );
                 final int resultCode = pwmHttpClientResponse.getStatusCode();
 
                 final String responseBody = pwmHttpClientResponse.getBody();
                 lastResponseBody = responseBody;
 
-                determineIfResultSuccessful(config, resultCode, responseBody);
-                LOGGER.debug("SMS send successful, HTTP status: " + resultCode);
-            } catch (PwmUnrecoverableException e) {
+                determineIfResultSuccessful( config, resultCode, responseBody );
+                LOGGER.debug( "SMS send successful, HTTP status: " + resultCode );
+            }
+            catch ( PwmUnrecoverableException e )
+            {
                 final ErrorInformation errorInformation = new ErrorInformation(
                         PwmError.ERROR_SMS_SEND_ERROR,
-                        "error while sending SMS, discarding message: " + e.getMessage());
-                throw new PwmUnrecoverableException(errorInformation);
+                        "error while sending SMS, discarding message: " + e.getMessage() );
+                throw new PwmUnrecoverableException( errorInformation );
             }
         }
 
         private String makeRequestData(
                 final String to,
                 final String message
-        ) {
-            final String gatewayUser = config.readSettingAsString(PwmSetting.SMS_GATEWAY_USER);
-            final PasswordData gatewayPass = config.readSettingAsPassword(PwmSetting.SMS_GATEWAY_PASSWORD);
-            final SmsDataEncoding encoding = config.readSettingAsEnum(PwmSetting.SMS_REQUEST_CONTENT_ENCODING, SmsDataEncoding.class);
+        )
+        {
+            final String gatewayUser = config.readSettingAsString( PwmSetting.SMS_GATEWAY_USER );
+            final PasswordData gatewayPass = config.readSettingAsPassword( PwmSetting.SMS_GATEWAY_PASSWORD );
+            final SmsDataEncoding encoding = config.readSettingAsEnum( PwmSetting.SMS_REQUEST_CONTENT_ENCODING, SmsDataEncoding.class );
 
-            String requestData = config.readSettingAsString(PwmSetting.SMS_REQUEST_DATA);
+            String requestData = config.readSettingAsString( PwmSetting.SMS_REQUEST_DATA );
 
             // Replace strings in requestData
             {
-                final String senderId = config.readSettingAsString(PwmSetting.SMS_SENDER_ID);
-                requestData = requestData.replace(TOKEN_USER, smsDataEncode(gatewayUser, encoding));
-                requestData = requestData.replace(TOKEN_SENDERID, smsDataEncode(senderId, encoding));
-                requestData = requestData.replace(TOKEN_MESSAGE, smsDataEncode(message, encoding));
-                requestData = requestData.replace(TOKEN_TO, smsDataEncode(formatSmsNumber(config, to), encoding));
+                final String senderId = config.readSettingAsString( PwmSetting.SMS_SENDER_ID );
+                requestData = requestData.replace( TOKEN_USER, smsDataEncode( gatewayUser, encoding ) );
+                requestData = requestData.replace( TOKEN_SENDERID, smsDataEncode( senderId, encoding ) );
+                requestData = requestData.replace( TOKEN_MESSAGE, smsDataEncode( message, encoding ) );
+                requestData = requestData.replace( TOKEN_TO, smsDataEncode( formatSmsNumber( config, to ), encoding ) );
             }
 
-            try {
+            try
+            {
                 final String gatewayStrPass = gatewayPass == null ? null : gatewayPass.getStringValue();
-                requestData = requestData.replace(TOKEN_PASS, smsDataEncode(gatewayStrPass, encoding));
-            } catch (PwmUnrecoverableException e) {
-                LOGGER.error("unable to read sms password while reading configuration");
+                requestData = requestData.replace( TOKEN_PASS, smsDataEncode( gatewayStrPass, encoding ) );
+            }
+            catch ( PwmUnrecoverableException e )
+            {
+                LOGGER.error( "unable to read sms password while reading configuration" );
             }
 
-            if (requestData.contains(TOKEN_REQUESTID)) {
-                final String chars = config.readSettingAsString(PwmSetting.SMS_REQUESTID_CHARS);
-                final int idLength = Long.valueOf(config.readSettingAsLong(PwmSetting.SMS_REQUESTID_LENGTH)).intValue();
-                final String requestId = PwmRandom.getInstance().alphaNumericString(chars, idLength);
-                requestData = requestData.replaceAll(TOKEN_REQUESTID, smsDataEncode(requestId, encoding));
+            if ( requestData.contains( TOKEN_REQUESTID ) )
+            {
+                final String chars = config.readSettingAsString( PwmSetting.SMS_REQUESTID_CHARS );
+                final int idLength = Long.valueOf( config.readSettingAsLong( PwmSetting.SMS_REQUESTID_LENGTH ) ).intValue();
+                final String requestId = PwmRandom.getInstance().alphaNumericString( chars, idLength );
+                requestData = requestData.replaceAll( TOKEN_REQUESTID, smsDataEncode( requestId, encoding ) );
             }
 
             return requestData;
@@ -500,40 +561,46 @@ public class SmsQueueManager implements PwmService {
         )
                 throws PwmUnrecoverableException
         {
-            final String gatewayUser = config.readSettingAsString(PwmSetting.SMS_GATEWAY_USER);
-            final PasswordData gatewayPass = config.readSettingAsPassword(PwmSetting.SMS_GATEWAY_PASSWORD);
-            final String contentType = config.readSettingAsString(PwmSetting.SMS_REQUEST_CONTENT_TYPE);
-            final List<String> extraHeaders = config.readSettingAsStringArray(PwmSetting.SMS_GATEWAY_REQUEST_HEADERS);
-            final String gatewayUrl = config.readSettingAsString(PwmSetting.SMS_GATEWAY_URL);
-            final String gatewayMethod = config.readSettingAsString(PwmSetting.SMS_GATEWAY_METHOD);
-            final String gatewayAuthMethod = config.readSettingAsString(PwmSetting.SMS_GATEWAY_AUTHMETHOD);
-
-            final HttpMethod httpMethod = "POST".equalsIgnoreCase(gatewayMethod)
+            final String gatewayUser = config.readSettingAsString( PwmSetting.SMS_GATEWAY_USER );
+            final PasswordData gatewayPass = config.readSettingAsPassword( PwmSetting.SMS_GATEWAY_PASSWORD );
+            final String contentType = config.readSettingAsString( PwmSetting.SMS_REQUEST_CONTENT_TYPE );
+            final List<String> extraHeaders = config.readSettingAsStringArray( PwmSetting.SMS_GATEWAY_REQUEST_HEADERS );
+            final String gatewayUrl = config.readSettingAsString( PwmSetting.SMS_GATEWAY_URL );
+            final String gatewayMethod = config.readSettingAsString( PwmSetting.SMS_GATEWAY_METHOD );
+            final String gatewayAuthMethod = config.readSettingAsString( PwmSetting.SMS_GATEWAY_AUTHMETHOD );
+
+            final HttpMethod httpMethod = "POST".equalsIgnoreCase( gatewayMethod )
                     ? HttpMethod.POST
                     : HttpMethod.GET;
 
-            final Map<String,String> headers = new LinkedHashMap<>(  );
+            final Map<String, String> headers = new LinkedHashMap<>();
             {
-                if ( "HTTP".equalsIgnoreCase( gatewayAuthMethod ) && gatewayUser != null && gatewayPass != null ) {
+                if ( "HTTP".equalsIgnoreCase( gatewayAuthMethod ) && gatewayUser != null && gatewayPass != null )
+                {
                     final BasicAuthInfo basicAuthInfo = new BasicAuthInfo( gatewayUser, gatewayPass );
                     headers.put( HttpHeader.Authorization.getHttpName(), basicAuthInfo.toAuthHeader() );
                 }
 
 
-                if ( !StringUtil.isEmpty( contentType ) && httpMethod == HttpMethod.POST ) {
+                if ( !StringUtil.isEmpty( contentType ) && httpMethod == HttpMethod.POST )
+                {
                     headers.put( HttpHeader.Content_Type.getHttpName(), contentType );
                 }
 
-                if ( extraHeaders != null ) {
+                if ( extraHeaders != null )
+                {
                     final Pattern pattern = Pattern.compile( "^([A-Za-z0-9_\\.-]+):[ \t]*([^ \t].*)" );
                     for ( final String header : extraHeaders )
                     {
                         final Matcher matcher = pattern.matcher( header );
-                        if ( matcher.matches() ) {
+                        if ( matcher.matches() )
+                        {
                             final String headerName = matcher.group( 1 );
                             final String headerValue = matcher.group( 2 );
                             headers.put( headerName, headerValue );
-                        } else {
+                        }
+                        else
+                        {
                             LOGGER.warn( "Cannot parse HTTP header: " + header );
                         }
                     }
@@ -543,7 +610,7 @@ public class SmsQueueManager implements PwmService {
 
             final String fullUrl = httpMethod == HttpMethod.POST
                     ? gatewayUrl
-                    : gatewayUrl.endsWith("?") ? gatewayUrl + requestData : gatewayUrl + "?" + requestData;
+                    : gatewayUrl.endsWith( "?" ) ? gatewayUrl + requestData : gatewayUrl + "?" + requestData;
 
             final String body = httpMethod == HttpMethod.POST
                     ? requestData
@@ -552,7 +619,7 @@ public class SmsQueueManager implements PwmService {
             return new PwmHttpClientRequest( httpMethod, fullUrl, body, headers );
         }
 
-        public String getLastResponseBody()
+        public String getLastResponseBody( )
         {
             return lastResponseBody;
         }
@@ -567,18 +634,20 @@ public class SmsQueueManager implements PwmService {
     )
             throws PwmUnrecoverableException, PwmOperationalException
     {
-        final SmsSendEngine smsSendEngine = new SmsSendEngine(pwmApplication, configuration);
-        smsSendEngine.sendSms(smsItemBean.getTo(), smsItemBean.getMessage(), sessionLabel);
+        final SmsSendEngine smsSendEngine = new SmsSendEngine( pwmApplication, configuration );
+        smsSendEngine.sendSms( smsItemBean.getTo(), smsItemBean.getMessage(), sessionLabel );
         return smsSendEngine.getLastResponseBody();
     }
 
-    public int queueSize() {
+    public int queueSize( )
+    {
         return workQueueProcessor == null
                 ? 0
                 : workQueueProcessor.queueSize();
     }
 
-    public Instant eldestItem() {
+    public Instant eldestItem( )
+    {
         return workQueueProcessor == null
                 ? null
                 : workQueueProcessor.eldestItem();

+ 2 - 2
server/src/main/java/password/pwm/util/secure/SecureEngine.java

@@ -342,8 +342,8 @@ public class SecureEngine
         {
 
             final Mac mac = Mac.getInstance( hmacAlgorithm.getAlgorithmName() );
-            final SecretKey secret_key = pwmSecurityKey.getKey( hmacAlgorithm.getKeyType() );
-            mac.init( secret_key );
+            final SecretKey secretKey = pwmSecurityKey.getKey( hmacAlgorithm.getKeyType() );
+            mac.init( secretKey );
             return mac.doFinal( input );
         }
         catch ( GeneralSecurityException e )

+ 255 - 152
server/src/main/java/password/pwm/ws/server/RestServlet.java

@@ -44,114 +44,149 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Locale;
 
-public abstract class RestServlet extends HttpServlet{
-    private static final AtomicLoopIntIncrementer REQUEST_COUNTER = new AtomicLoopIntIncrementer(Integer.MAX_VALUE);
+public abstract class RestServlet extends HttpServlet
+{
+    private static final AtomicLoopIntIncrementer REQUEST_COUNTER = new AtomicLoopIntIncrementer( Integer.MAX_VALUE );
 
-    private static final PwmLogger LOGGER = PwmLogger.forClass(RestServlet.class);
+    private static final PwmLogger LOGGER = PwmLogger.forClass( RestServlet.class );
 
-    protected void service(final HttpServletRequest req, final HttpServletResponse resp)
+    protected void service( final HttpServletRequest req, final HttpServletResponse resp )
             throws ServletException, IOException
     {
         final Instant startTime = Instant.now();
 
-        RestResultBean restResultBean = RestResultBean.fromError(new ErrorInformation(PwmError.ERROR_APP_UNAVAILABLE), false);
+        RestResultBean restResultBean = RestResultBean.fromError( new ErrorInformation( PwmError.ERROR_APP_UNAVAILABLE ), false );
 
         final PwmApplication pwmApplication;
-        try {
-            pwmApplication = ContextManager.getContextManager(req.getServletContext()).getPwmApplication();
-        } catch (PwmUnrecoverableException e) {
-            outputRestResultBean(restResultBean, req, resp);
+        try
+        {
+            pwmApplication = ContextManager.getContextManager( req.getServletContext() ).getPwmApplication();
+        }
+        catch ( PwmUnrecoverableException e )
+        {
+            outputRestResultBean( restResultBean, req, resp );
             return;
         }
 
         final Locale locale;
         {
             final List<Locale> knownLocales = pwmApplication.getConfig().getKnownLocales();
-            locale = LocaleHelper.localeResolver(req.getLocale(), knownLocales);
+            locale = LocaleHelper.localeResolver( req.getLocale(), knownLocales );
         }
 
         final SessionLabel sessionLabel;
-        try {
+        try
+        {
             sessionLabel = new SessionLabel(
                     "rest-" + REQUEST_COUNTER.next(),
                     null,
                     null,
-                    RequestInitializationFilter.readUserIPAddress(req, pwmApplication.getConfig()),
-                    RequestInitializationFilter.readUserHostname(req, pwmApplication.getConfig())
+                    RequestInitializationFilter.readUserIPAddress( req, pwmApplication.getConfig() ),
+                    RequestInitializationFilter.readUserHostname( req, pwmApplication.getConfig() )
             );
-        } catch (PwmUnrecoverableException e) {
-            restResultBean = RestResultBean.fromError(e.getErrorInformation(), pwmApplication, locale, pwmApplication.getConfig(), pwmApplication.determineIfDetailErrorMsgShown());
-            outputRestResultBean(restResultBean, req, resp);
+        }
+        catch ( PwmUnrecoverableException e )
+        {
+            restResultBean = RestResultBean.fromError(
+                    e.getErrorInformation(),
+                    pwmApplication,
+                    locale,
+                    pwmApplication.getConfig(),
+                    pwmApplication.determineIfDetailErrorMsgShown()
+            );
+            outputRestResultBean( restResultBean, req, resp );
             return;
         }
-        LOGGER.trace(sessionLabel, "beginning rest service invocation");
+        LOGGER.trace( sessionLabel, "beginning rest service invocation" );
 
-        if (pwmApplication.getApplicationMode() != PwmApplicationMode.RUNNING) {
-            outputRestResultBean(restResultBean, req, resp);
+        if ( pwmApplication.getApplicationMode() != PwmApplicationMode.RUNNING )
+        {
+            outputRestResultBean( restResultBean, req, resp );
             return;
         }
 
-        if (!pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.ENABLE_EXTERNAL_WEBSERVICES)) {
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE, "webservices are not enabled");
-            restResultBean = RestResultBean.fromError(errorInformation, pwmApplication, locale, pwmApplication.getConfig(), pwmApplication.determineIfDetailErrorMsgShown());
-            outputRestResultBean(restResultBean, req, resp);
+        if ( !pwmApplication.getConfig().readSettingAsBoolean( PwmSetting.ENABLE_EXTERNAL_WEBSERVICES ) )
+        {
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_SERVICE_NOT_AVAILABLE, "webservices are not enabled" );
+            restResultBean = RestResultBean.fromError( errorInformation, pwmApplication, locale, pwmApplication.getConfig(), pwmApplication.determineIfDetailErrorMsgShown() );
+            outputRestResultBean( restResultBean, req, resp );
             return;
         }
 
-        try {
-            final RestAuthentication restAuthentication = new RestAuthenticationProcessor(pwmApplication, sessionLabel, req).readRestAuthentication();
-            LOGGER.debug(sessionLabel, "rest request authentication status: " + JsonUtil.serialize(restAuthentication));
+        try
+        {
+            final RestAuthentication restAuthentication = new RestAuthenticationProcessor( pwmApplication, sessionLabel, req ).readRestAuthentication();
+            LOGGER.debug( sessionLabel, "rest request authentication status: " + JsonUtil.serialize( restAuthentication ) );
 
-            final RestRequest restRequest = RestRequest.forRequest(pwmApplication, restAuthentication, sessionLabel, req);
+            final RestRequest restRequest = RestRequest.forRequest( pwmApplication, restAuthentication, sessionLabel, req );
 
             RequestInitializationFilter.addStaticResponseHeaders( pwmApplication, resp );
 
-            preCheck(restRequest);
+            preCheck( restRequest );
 
-            preCheckRequest(restRequest);
+            preCheckRequest( restRequest );
 
-            restResultBean = invokeWebService(restRequest);
-        } catch (PwmUnrecoverableException e) {
-            restResultBean = RestResultBean.fromError(e.getErrorInformation(), pwmApplication, locale, pwmApplication.getConfig(), pwmApplication.determineIfDetailErrorMsgShown());
-        } catch (Throwable e) {
+            restResultBean = invokeWebService( restRequest );
+        }
+        catch ( PwmUnrecoverableException e )
+        {
+            restResultBean = RestResultBean.fromError(
+                    e.getErrorInformation(),
+                    pwmApplication,
+                    locale,
+                    pwmApplication.getConfig(),
+                    pwmApplication.determineIfDetailErrorMsgShown()
+            );
+        }
+        catch ( Throwable e )
+        {
             final String errorMsg = "internal error during rest service invocation: " + e.getMessage();
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg);
-            restResultBean = RestResultBean.fromError(errorInformation, pwmApplication, locale, pwmApplication.getConfig(), pwmApplication.determineIfDetailErrorMsgShown());
-            LOGGER.error(sessionLabel, errorInformation);
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_UNKNOWN, errorMsg );
+            restResultBean = RestResultBean.fromError( errorInformation, pwmApplication, locale, pwmApplication.getConfig(), pwmApplication.determineIfDetailErrorMsgShown() );
+            LOGGER.error( sessionLabel, errorInformation );
         }
 
-        outputRestResultBean(restResultBean, req, resp);
-        LOGGER.trace(sessionLabel, "completed rest invocation in " + TimeDuration.compactFromCurrent(startTime) + " success=" + !restResultBean.isError());
+        outputRestResultBean( restResultBean, req, resp );
+        LOGGER.trace( sessionLabel, "completed rest invocation in " + TimeDuration.compactFromCurrent( startTime ) + " success=" + !restResultBean.isError() );
     }
 
-    private RestResultBean invokeWebService(final RestRequest restRequest) throws IOException, PwmUnrecoverableException {
-        final Method interestedMethod = discoverMethodForAction(this.getClass(), restRequest);
+    private RestResultBean invokeWebService( final RestRequest restRequest ) throws IOException, PwmUnrecoverableException
+    {
+        final Method interestedMethod = discoverMethodForAction( this.getClass(), restRequest );
 
-        if (interestedMethod != null) {
-            interestedMethod.setAccessible(true);
-            try {
-                return (RestResultBean) interestedMethod.invoke(this, restRequest);
-            } catch (InvocationTargetException e) {
+        if ( interestedMethod != null )
+        {
+            interestedMethod.setAccessible( true );
+            try
+            {
+                return ( RestResultBean ) interestedMethod.invoke( this, restRequest );
+            }
+            catch ( InvocationTargetException e )
+            {
                 final Throwable rootException = e.getTargetException();
-                if (rootException instanceof PwmUnrecoverableException) {
-                    throw (PwmUnrecoverableException)rootException;
+                if ( rootException instanceof PwmUnrecoverableException )
+                {
+                    throw ( PwmUnrecoverableException ) rootException;
                 }
-                throw PwmUnrecoverableException.newException(PwmError.ERROR_UNKNOWN, e.getMessage());
-            } catch (IllegalAccessException e) {
-                throw PwmUnrecoverableException.newException(PwmError.ERROR_UNKNOWN, e.getMessage());
+                throw PwmUnrecoverableException.newException( PwmError.ERROR_UNKNOWN, e.getMessage() );
+            }
+            catch ( IllegalAccessException e )
+            {
+                throw PwmUnrecoverableException.newException( PwmError.ERROR_UNKNOWN, e.getMessage() );
             }
         }
         return null;
     }
 
     @Data
-    private static class MethodMatcher {
+    private static class MethodMatcher
+    {
         boolean methodMatch;
         boolean contentMatch;
         boolean acceptMatch;
     }
 
-    private Method discoverMethodForAction(final Class clazz, final RestRequest restRequest)
+    private Method discoverMethodForAction( final Class clazz, final RestRequest restRequest )
             throws PwmUnrecoverableException
     {
         final HttpMethod reqMethod = restRequest.getMethod();
@@ -162,78 +197,101 @@ public abstract class RestServlet extends HttpServlet{
 
         final MethodMatcher anyMatch = new MethodMatcher();
 
-        final Collection<Method> methods = JavaHelper.getAllMethodsForClass(clazz);
-        for (Method method : methods) {
-            final RestMethodHandler annotation = method.getAnnotation(RestMethodHandler.class);
+        final Collection<Method> methods = JavaHelper.getAllMethodsForClass( clazz );
+        for ( Method method : methods )
+        {
+            final RestMethodHandler annotation = method.getAnnotation( RestMethodHandler.class );
             final MethodMatcher loopMatch = new MethodMatcher();
 
-            if (annotation != null) {
-                if (annotation.method().length == 0 || Arrays.asList(annotation.method()).contains(reqMethod)) {
-                    loopMatch.setMethodMatch(true);
-                    anyMatch.setMethodMatch(true);
+            if ( annotation != null )
+            {
+                if ( annotation.method().length == 0 || Arrays.asList( annotation.method() ).contains( reqMethod ) )
+                {
+                    loopMatch.setMethodMatch( true );
+                    anyMatch.setMethodMatch( true );
                 }
 
-                if (!careAboutContentType || annotation.consumes().length == 0 || Arrays.asList(annotation.consumes()).contains(reqContent)) {
-                    loopMatch.setContentMatch(true);
-                    anyMatch.setContentMatch(true);
+                if ( !careAboutContentType || annotation.consumes().length == 0 || Arrays.asList( annotation.consumes() ).contains( reqContent ) )
+                {
+                    loopMatch.setContentMatch( true );
+                    anyMatch.setContentMatch( true );
                 }
 
-                if (annotation.produces().length == 0 || Arrays.asList(annotation.produces()).contains(reqAccept)) {
-                    loopMatch.setAcceptMatch(true);
-                    anyMatch.setAcceptMatch(true);
+                if ( annotation.produces().length == 0 || Arrays.asList( annotation.produces() ).contains( reqAccept ) )
+                {
+                    loopMatch.setAcceptMatch( true );
+                    anyMatch.setAcceptMatch( true );
                 }
 
-                if (loopMatch.isMethodMatch() && loopMatch.isContentMatch() && loopMatch.isAcceptMatch()) {
+                if ( loopMatch.isMethodMatch() && loopMatch.isContentMatch() && loopMatch.isAcceptMatch() )
+                {
                     return method;
                 }
             }
         }
 
         final String errorMsg;
-        if (!anyMatch.isMethodMatch()) {
+        if ( !anyMatch.isMethodMatch() )
+        {
             errorMsg = "HTTP method invalid";
-        } else if (reqAccept == null && !anyMatch.isAcceptMatch()) {
+        }
+        else if ( reqAccept == null && !anyMatch.isAcceptMatch() )
+        {
             errorMsg = HttpHeader.Accept.getHttpName() + " header is required";
-        } else if (!anyMatch.isAcceptMatch()) {
+        }
+        else if ( !anyMatch.isAcceptMatch() )
+        {
             errorMsg = HttpHeader.Accept.getHttpName() + " header value does not match an available processor";
-        } else if (reqContent == null && !anyMatch.isContentMatch()) {
+        }
+        else if ( reqContent == null && !anyMatch.isContentMatch() )
+        {
             errorMsg = HttpHeader.Content_Type.getHttpName() + " header is required";
-        } else if (!anyMatch.isContentMatch()) {
+        }
+        else if ( !anyMatch.isContentMatch() )
+        {
             errorMsg = HttpHeader.Content_Type.getHttpName() + " header value does not match an available processor";
-        } else {
+        }
+        else
+        {
             errorMsg = "incorrect method, Content-Type header, or Accept header.";
         }
 
-        throw PwmUnrecoverableException.newException(PwmError.ERROR_REST_INVOCATION_ERROR, errorMsg);
+        throw PwmUnrecoverableException.newException( PwmError.ERROR_REST_INVOCATION_ERROR, errorMsg );
     }
 
-    private void preCheck(final RestRequest restRequest)
+    private void preCheck( final RestRequest restRequest )
             throws PwmUnrecoverableException
     {
-        final RestWebServer classAnnotation = this.getClass().getDeclaredAnnotation(RestWebServer.class);
-        if (classAnnotation == null) {
-            throw PwmUnrecoverableException.newException(PwmError.ERROR_UNKNOWN, "class is missing " + RestWebServer.class.getSimpleName() + " annotation");
+        final RestWebServer classAnnotation = this.getClass().getDeclaredAnnotation( RestWebServer.class );
+        if ( classAnnotation == null )
+        {
+            throw PwmUnrecoverableException.newException( PwmError.ERROR_UNKNOWN, "class is missing " + RestWebServer.class.getSimpleName() + " annotation" );
         }
 
-        if (!restRequest.getRestAuthentication().getUsages().contains(classAnnotation.webService())) {
-            throw PwmUnrecoverableException.newException(PwmError.ERROR_UNAUTHORIZED, "access to " + classAnnotation.webService() + " service is not permitted for this login");
+        if ( !restRequest.getRestAuthentication().getUsages().contains( classAnnotation.webService() ) )
+        {
+            throw PwmUnrecoverableException.newException( PwmError.ERROR_UNAUTHORIZED, "access to " + classAnnotation.webService() + " service is not permitted for this login" );
         }
 
-        if (classAnnotation.requireAuthentication()) {
-            if (restRequest.getRestAuthentication().getType() == RestAuthenticationType.PUBLIC) {
-                throw PwmUnrecoverableException.newException(PwmError.ERROR_UNAUTHORIZED, "this service requires authentication");
+        if ( classAnnotation.requireAuthentication() )
+        {
+            if ( restRequest.getRestAuthentication().getType() == RestAuthenticationType.PUBLIC )
+            {
+                throw PwmUnrecoverableException.newException( PwmError.ERROR_UNAUTHORIZED, "this service requires authentication" );
             }
         }
 
-        if (restRequest.getMethod().isHasBody()) {
-            if (restRequest.readContentType() == null) {
+        if ( restRequest.getMethod().isHasBody() )
+        {
+            if ( restRequest.readContentType() == null )
+            {
                 final String message = restRequest.getMethod() + " method requires " + HttpHeader.Content_Type.getHttpName() + " header";
-                throw PwmUnrecoverableException.newException(PwmError.ERROR_UNAUTHORIZED, message);
+                throw PwmUnrecoverableException.newException( PwmError.ERROR_UNAUTHORIZED, message );
             }
         }
     }
 
-    public abstract void preCheckRequest(RestRequest request) throws PwmUnrecoverableException;
+    public abstract void preCheckRequest( RestRequest request ) throws PwmUnrecoverableException;
 
     private void outputRestResultBean(
             final RestResultBean restResultBean,
@@ -242,92 +300,121 @@ public abstract class RestServlet extends HttpServlet{
     )
             throws IOException
     {
-        final HttpContentType acceptType = RestRequest.readAcceptType(request);
-        resp.setHeader(HttpHeader.Server.getHttpName(), PwmConstants.PWM_APP_NAME);
-
-        if (acceptType != null) {
-            switch (acceptType) {
-                case json: {
-                    resp.setHeader(HttpHeader.Content_Type.getHttpName(), HttpContentType.json.getHeaderValue());
-                    try (PrintWriter pw = resp.getWriter()) {
-                        pw.write(restResultBean.toJson());
+        final HttpContentType acceptType = RestRequest.readAcceptType( request );
+        resp.setHeader( HttpHeader.Server.getHttpName(), PwmConstants.PWM_APP_NAME );
+
+        if ( acceptType != null )
+        {
+            switch ( acceptType )
+            {
+                case json:
+                {
+                    resp.setHeader( HttpHeader.Content_Type.getHttpName(), HttpContentType.json.getHeaderValue() );
+                    try ( PrintWriter pw = resp.getWriter() )
+                    {
+                        pw.write( restResultBean.toJson() );
                     }
                 }
                 break;
 
-                case plain: {
-                    resp.setHeader(HttpHeader.Content_Type.getHttpName(), HttpContentType.plain.getHeaderValue());
-                    if (restResultBean.isError()) {
-                        resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, restResultBean.getErrorMessage());
-                    } else {
-                        if (restResultBean.getData() != null) {
-                            try (PrintWriter pw = resp.getWriter()) {
-                                pw.write(restResultBean.getData().toString());
+                case plain:
+                {
+                    resp.setHeader( HttpHeader.Content_Type.getHttpName(), HttpContentType.plain.getHeaderValue() );
+                    if ( restResultBean.isError() )
+                    {
+                        resp.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, restResultBean.getErrorMessage() );
+                    }
+                    else
+                    {
+                        if ( restResultBean.getData() != null )
+                        {
+                            try ( PrintWriter pw = resp.getWriter() )
+                            {
+                                pw.write( restResultBean.getData().toString() );
                             }
                         }
                     }
                 }
                 break;
 
-                default: {
+                default:
+                {
                     final String msg = "unhandled " + HttpHeader.Accept.getHttpName() + " header value in request";
-                    outputLastHopeError(msg, resp);
+                    outputLastHopeError( msg, resp );
                 }
             }
-        } else {
+        }
+        else
+        {
             final String msg;
-            if (StringUtil.isEmpty(request.getHeader(HttpHeader.Accept.getHttpName()))) {
+            if ( StringUtil.isEmpty( request.getHeader( HttpHeader.Accept.getHttpName() ) ) )
+            {
                 msg = "missing " + HttpHeader.Accept.getHttpName() + " header value in request";
-            } else {
+            }
+            else
+            {
                 msg = "unknown value for " + HttpHeader.Accept.getHttpName() + " header value in request";
             }
-            outputLastHopeError(msg, resp);
+            outputLastHopeError( msg, resp );
         }
     }
 
-    private static void outputLastHopeError(final String msg, final HttpServletResponse response) throws IOException {
-        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-        response.setHeader(HttpHeader.Content_Type.getHttpName(), HttpContentType.json.getHeaderValue());
-        try (PrintWriter pw = response.getWriter()) {
-            pw.write("Error: ");
-            pw.write(msg);
-            pw.write("\n");
+    private static void outputLastHopeError( final String msg, final HttpServletResponse response ) throws IOException
+    {
+        response.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
+        response.setHeader( HttpHeader.Content_Type.getHttpName(), HttpContentType.json.getHeaderValue() );
+        try ( PrintWriter pw = response.getWriter() )
+        {
+            pw.write( "Error: " );
+            pw.write( msg );
+            pw.write( "\n" );
         }
     }
 
     @Value
-    public static class TargetUserIdentity {
+    public static class TargetUserIdentity
+    {
         private RestRequest restRequest;
         private UserIdentity userIdentity;
         private boolean self;
 
-        public ChaiProvider getChaiProvider() throws PwmUnrecoverableException {
-            return restRequest.getChaiProvider(userIdentity.getLdapProfileID());
+        public ChaiProvider getChaiProvider( ) throws PwmUnrecoverableException
+        {
+            return restRequest.getChaiProvider( userIdentity.getLdapProfileID() );
         }
 
-        public ChaiUser getChaiUser() throws PwmUnrecoverableException {
-            try {
-                return getChaiProvider().getEntryFactory().newChaiUser(userIdentity.getUserDN());
-            } catch (ChaiUnavailableException e) {
-                throw PwmUnrecoverableException.fromChaiException(e);
+        public ChaiUser getChaiUser( ) throws PwmUnrecoverableException
+        {
+            try
+            {
+                return getChaiProvider().getEntryFactory().newChaiUser( userIdentity.getUserDN() );
+            }
+            catch ( ChaiUnavailableException e )
+            {
+                throw PwmUnrecoverableException.fromChaiException( e );
             }
         }
     }
 
-    public static <T> T deserializeJsonBody(final RestRequest restRequest, final Class<T> classOfT)
+    public static <T> T deserializeJsonBody( final RestRequest restRequest, final Class<T> classOfT )
             throws IOException, PwmUnrecoverableException
     {
-        try {
-            final T jsonData = JsonUtil.deserialize(restRequest.readRequestBodyAsString(), classOfT);
-            if (jsonData == null) {
-                throw PwmUnrecoverableException.newException(PwmError.ERROR_REST_INVOCATION_ERROR, "missing json body");
+        try
+        {
+            final T jsonData = JsonUtil.deserialize( restRequest.readRequestBodyAsString(), classOfT );
+            if ( jsonData == null )
+            {
+                throw PwmUnrecoverableException.newException( PwmError.ERROR_REST_INVOCATION_ERROR, "missing json body" );
             }
             return jsonData;
-        } catch (Exception e) {
-            if (e.getCause() instanceof MalformedJsonException) {
-                throw PwmUnrecoverableException.newException(PwmError.ERROR_REST_INVOCATION_ERROR, "json parse error: " + e.getCause().getMessage());
+        }
+        catch ( Exception e )
+        {
+            if ( e.getCause() instanceof MalformedJsonException )
+            {
+                throw PwmUnrecoverableException.newException( PwmError.ERROR_REST_INVOCATION_ERROR, "json parse error: " + e.getCause().getMessage() );
             }
-            throw PwmUnrecoverableException.newException(PwmError.ERROR_REST_INVOCATION_ERROR, "json parse error: " + e.getMessage());
+            throw PwmUnrecoverableException.newException( PwmError.ERROR_REST_INVOCATION_ERROR, "json parse error: " + e.getMessage() );
         }
     }
 
@@ -339,39 +426,55 @@ public abstract class RestServlet extends HttpServlet{
     {
         final PwmApplication pwmApplication = restRequest.getPwmApplication();
 
-        if (StringUtil.isEmpty(username)) {
-            if (restRequest.getRestAuthentication().getType() == RestAuthenticationType.NAMED_SECRET) {
-                throw PwmUnrecoverableException.newException(PwmError.ERROR_REST_INVOCATION_ERROR, "username field required");
+        if ( StringUtil.isEmpty( username ) )
+        {
+            if ( restRequest.getRestAuthentication().getType() == RestAuthenticationType.NAMED_SECRET )
+            {
+                throw PwmUnrecoverableException.newException( PwmError.ERROR_REST_INVOCATION_ERROR, "username field required" );
             }
-        } else {
-            if (!restRequest.getRestAuthentication().isThirdPartyEnabled()) {
-                throw PwmUnrecoverableException.newException(PwmError.ERROR_UNAUTHORIZED, "username specified in request, however third party permission is not granted to the authenticated login.");
+        }
+        else
+        {
+            if ( !restRequest.getRestAuthentication().isThirdPartyEnabled() )
+            {
+                throw PwmUnrecoverableException.newException(
+                        PwmError.ERROR_UNAUTHORIZED,
+                        "username specified in request, however third party permission is not granted to the authenticated login."
+                );
             }
         }
 
-        if (StringUtil.isEmpty(username)) {
-            if (restRequest.getRestAuthentication().getType() == RestAuthenticationType.LDAP) {
-                return new TargetUserIdentity(restRequest, restRequest.getRestAuthentication().getLdapIdentity(), true);
+        if ( StringUtil.isEmpty( username ) )
+        {
+            if ( restRequest.getRestAuthentication().getType() == RestAuthenticationType.LDAP )
+            {
+                return new TargetUserIdentity( restRequest, restRequest.getRestAuthentication().getLdapIdentity(), true );
             }
         }
 
         final String ldapProfileID;
         final String effectiveUsername;
-        if (username.contains("|")) {
-            final int pipeIndex = username.indexOf("|");
-            ldapProfileID = username.substring(0, pipeIndex);
-            effectiveUsername = username.substring(pipeIndex + 1, username.length());
-        } else {
+        if ( username.contains( "|" ) )
+        {
+            final int pipeIndex = username.indexOf( "|" );
+            ldapProfileID = username.substring( 0, pipeIndex );
+            effectiveUsername = username.substring( pipeIndex + 1, username.length() );
+        }
+        else
+        {
             ldapProfileID = null;
             effectiveUsername = username;
         }
 
-        try {
+        try
+        {
             final UserSearchEngine userSearchEngine = pwmApplication.getUserSearchEngine();
-            final UserIdentity userIdentity = userSearchEngine.resolveUsername(effectiveUsername, null, ldapProfileID, restRequest.getSessionLabel());
-            return new TargetUserIdentity(restRequest, userIdentity, false);
-        } catch (PwmOperationalException e) {
-            throw new PwmUnrecoverableException(e.getErrorInformation());
+            final UserIdentity userIdentity = userSearchEngine.resolveUsername( effectiveUsername, null, ldapProfileID, restRequest.getSessionLabel() );
+            return new TargetUserIdentity( restRequest, userIdentity, false );
+        }
+        catch ( PwmOperationalException e )
+        {
+            throw new PwmUnrecoverableException( e.getErrorInformation() );
         }
     }
 }

+ 90 - 67
server/src/main/java/password/pwm/ws/server/rest/RestRandomPasswordServer.java

@@ -52,13 +52,14 @@ import java.util.ArrayList;
 import java.util.List;
 
 @WebServlet(
-        urlPatterns={
+        urlPatterns = {
                 PwmConstants.URL_PREFIX_PUBLIC + PwmConstants.URL_PREFIX_REST + "/randompassword",
         }
 )
-@RestWebServer(webService = WebServiceUsage.RandomPassword, requireAuthentication = false)
-public class RestRandomPasswordServer extends RestServlet {
-    private static final PwmLogger LOGGER = PwmLogger.forClass(RestRandomPasswordServer.class);
+@RestWebServer( webService = WebServiceUsage.RandomPassword, requireAuthentication = false )
+public class RestRandomPasswordServer extends RestServlet
+{
+    private static final PwmLogger LOGGER = PwmLogger.forClass( RestRandomPasswordServer.class );
 
     @Data
     public static class JsonOutput implements Serializable
@@ -79,76 +80,90 @@ public class RestRandomPasswordServer extends RestServlet {
     }
 
     @Override
-    public void preCheckRequest(final RestRequest request) throws PwmUnrecoverableException {
+    public void preCheckRequest( final RestRequest request ) throws PwmUnrecoverableException
+    {
     }
 
-    @RestMethodHandler(method = HttpMethod.POST, consumes = HttpContentType.form, produces = HttpContentType.json)
-    public RestResultBean doPostRandomPasswordForm(final RestRequest restRequest)
+    @RestMethodHandler( method = HttpMethod.POST, consumes = HttpContentType.form, produces = HttpContentType.json )
+    public RestResultBean doPostRandomPasswordForm( final RestRequest restRequest )
             throws PwmUnrecoverableException
     {
         final JsonInput jsonInput = new JsonInput();
-        jsonInput.username = restRequest.readParameterAsString("username", PwmHttpRequestWrapper.Flag.BypassValidation);
-        jsonInput.strength = restRequest.readParameterAsInt("strength", 0);
-        jsonInput.maxLength = restRequest.readParameterAsInt("maxLength", 0);
-        jsonInput.minLength = restRequest.readParameterAsInt("minLength", 0);
-        jsonInput.chars = restRequest.readParameterAsString("chars", PwmHttpRequestWrapper.Flag.BypassValidation);
-        jsonInput.noUser = restRequest.readParameterAsBoolean("noUser");
-
-        try {
-            final JsonOutput jsonOutput = doOperation(restRequest, jsonInput);
-            final RestResultBean restResultBean = RestResultBean.withData(jsonOutput);
+        jsonInput.username = restRequest.readParameterAsString( "username", PwmHttpRequestWrapper.Flag.BypassValidation );
+        jsonInput.strength = restRequest.readParameterAsInt( "strength", 0 );
+        jsonInput.maxLength = restRequest.readParameterAsInt( "maxLength", 0 );
+        jsonInput.minLength = restRequest.readParameterAsInt( "minLength", 0 );
+        jsonInput.chars = restRequest.readParameterAsString( "chars", PwmHttpRequestWrapper.Flag.BypassValidation );
+        jsonInput.noUser = restRequest.readParameterAsBoolean( "noUser" );
+
+        try
+        {
+            final JsonOutput jsonOutput = doOperation( restRequest, jsonInput );
+            final RestResultBean restResultBean = RestResultBean.withData( jsonOutput );
             return restResultBean;
-        } catch (PwmException e) {
-            LOGGER.error(restRequest.getSessionLabel(),"error executing rest-json random password request: " + e.getMessage(),e);
-            return RestResultBean.fromError(restRequest, e.getErrorInformation());
-        } catch (Exception e) {
+        }
+        catch ( PwmException e )
+        {
+            LOGGER.error( restRequest.getSessionLabel(), "error executing rest-json random password request: " + e.getMessage(), e );
+            return RestResultBean.fromError( restRequest, e.getErrorInformation() );
+        }
+        catch ( Exception e )
+        {
             final String errorMessage = "unexpected error executing web service: " + e.getMessage();
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMessage);
-            return RestResultBean.fromError(restRequest, errorInformation);
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_UNKNOWN, errorMessage );
+            return RestResultBean.fromError( restRequest, errorInformation );
         }
     }
 
     // This method is called if TEXT_PLAIN is request
-    @RestMethodHandler(method = HttpMethod.GET, produces = HttpContentType.plain)
-    public RestResultBean doPlainRandomPassword(final RestRequest restRequest)
+    @RestMethodHandler( method = HttpMethod.GET, produces = HttpContentType.plain )
+    public RestResultBean doPlainRandomPassword( final RestRequest restRequest )
             throws PwmUnrecoverableException
     {
         final JsonInput jsonInput = new JsonInput();
-        jsonInput.username = restRequest.readParameterAsString("username", PwmHttpRequestWrapper.Flag.BypassValidation);
-        jsonInput.strength = restRequest.readParameterAsInt("strength", 0);
-        jsonInput.maxLength = restRequest.readParameterAsInt("maxLength", 0);
-        jsonInput.minLength = restRequest.readParameterAsInt("minLength", 0);
-        jsonInput.chars = restRequest.readParameterAsString("chars", PwmHttpRequestWrapper.Flag.BypassValidation);
-        jsonInput.noUser = restRequest.readParameterAsBoolean("noUser");
-
-        try {
-            return RestResultBean.withData(doOperation(restRequest, jsonInput));
-        } catch (Exception e) {
-            LOGGER.error(restRequest.getSessionLabel(),"error executing rest-json random password request: " + e.getMessage(),e);
+        jsonInput.username = restRequest.readParameterAsString( "username", PwmHttpRequestWrapper.Flag.BypassValidation );
+        jsonInput.strength = restRequest.readParameterAsInt( "strength", 0 );
+        jsonInput.maxLength = restRequest.readParameterAsInt( "maxLength", 0 );
+        jsonInput.minLength = restRequest.readParameterAsInt( "minLength", 0 );
+        jsonInput.chars = restRequest.readParameterAsString( "chars", PwmHttpRequestWrapper.Flag.BypassValidation );
+        jsonInput.noUser = restRequest.readParameterAsBoolean( "noUser" );
+
+        try
+        {
+            return RestResultBean.withData( doOperation( restRequest, jsonInput ) );
+        }
+        catch ( Exception e )
+        {
+            LOGGER.error( restRequest.getSessionLabel(), "error executing rest-json random password request: " + e.getMessage(), e );
             final String errorMessage = "unexpected error executing web service: " + e.getMessage();
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMessage);
-            return RestResultBean.fromError(restRequest, errorInformation);
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_UNKNOWN, errorMessage );
+            return RestResultBean.fromError( restRequest, errorInformation );
         }
     }
 
 
-    @RestMethodHandler(method = HttpMethod.POST, consumes = HttpContentType.json, produces = HttpContentType.json)
-    public RestResultBean doPostRandomPasswordJson(final RestRequest restRequest)
+    @RestMethodHandler( method = HttpMethod.POST, consumes = HttpContentType.json, produces = HttpContentType.json )
+    public RestResultBean doPostRandomPasswordJson( final RestRequest restRequest )
             throws PwmUnrecoverableException, IOException
     {
-        final JsonInput jsonInput = deserializeJsonBody(restRequest, JsonInput.class);
-
-        try {
-            final JsonOutput jsonOutput = doOperation(restRequest, jsonInput);
-            return RestResultBean.withData(jsonOutput);
-        } catch (PwmException e) {
-            LOGGER.error(restRequest.getSessionLabel(),"error executing rest-form random password request: " + e.getMessage(),e);
-            return RestResultBean.fromError(restRequest, e.getErrorInformation());
-        } catch (Exception e) {
-            LOGGER.error(restRequest.getSessionLabel(),"error executing rest-form random password request: " + e.getMessage(),e);
+        final JsonInput jsonInput = deserializeJsonBody( restRequest, JsonInput.class );
+
+        try
+        {
+            final JsonOutput jsonOutput = doOperation( restRequest, jsonInput );
+            return RestResultBean.withData( jsonOutput );
+        }
+        catch ( PwmException e )
+        {
+            LOGGER.error( restRequest.getSessionLabel(), "error executing rest-form random password request: " + e.getMessage(), e );
+            return RestResultBean.fromError( restRequest, e.getErrorInformation() );
+        }
+        catch ( Exception e )
+        {
+            LOGGER.error( restRequest.getSessionLabel(), "error executing rest-form random password request: " + e.getMessage(), e );
             final String errorMessage = "unexpected error executing web service: " + e.getMessage();
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMessage);
-            return RestResultBean.fromError(restRequest, errorInformation);
+            final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_UNKNOWN, errorMessage );
+            return RestResultBean.fromError( restRequest, errorInformation );
         }
     }
 
@@ -160,10 +175,13 @@ public class RestRandomPasswordServer extends RestServlet {
     {
         final PwmPasswordPolicy pwmPasswordPolicy;
 
-        if (jsonInput.isNoUser()) {
+        if ( jsonInput.isNoUser() )
+        {
             pwmPasswordPolicy = PwmPasswordPolicy.defaultPolicy();
-        } else {
-            final TargetUserIdentity targetUserIdentity = resolveRequestedUsername(restRequest, jsonInput.getUsername());
+        }
+        else
+        {
+            final TargetUserIdentity targetUserIdentity = resolveRequestedUsername( restRequest, jsonInput.getUsername() );
             pwmPasswordPolicy = PasswordUtility.readPasswordPolicyForUser(
                     restRequest.getPwmApplication(),
                     restRequest.getSessionLabel(),
@@ -174,11 +192,11 @@ public class RestRandomPasswordServer extends RestServlet {
         }
 
         final RandomPasswordGenerator.RandomGeneratorConfig randomConfig = jsonInputToRandomConfig( jsonInput, pwmPasswordPolicy );
-        final PasswordData randomPassword = RandomPasswordGenerator.createRandomPassword(restRequest.getSessionLabel(), randomConfig, restRequest.getPwmApplication());
+        final PasswordData randomPassword = RandomPasswordGenerator.createRandomPassword( restRequest.getSessionLabel(), randomConfig, restRequest.getPwmApplication() );
         final JsonOutput outputMap = new JsonOutput();
         outputMap.password = randomPassword.getStringValue();
 
-        StatisticsManager.incrementStat(restRequest.getPwmApplication(), Statistic.REST_SETPASSWORD);
+        StatisticsManager.incrementStat( restRequest.getPwmApplication(), Statistic.REST_SETPASSWORD );
 
         return outputMap;
     }
@@ -191,21 +209,26 @@ public class RestRandomPasswordServer extends RestServlet {
         final RandomPasswordGenerator.RandomGeneratorConfig.RandomGeneratorConfigBuilder randomConfigBuilder
                 = RandomPasswordGenerator.RandomGeneratorConfig.builder();
 
-        if (jsonInput.getStrength() > 0 && jsonInput.getStrength() <= 100) {
-            randomConfigBuilder.minimumStrength(jsonInput.getStrength());
+        if ( jsonInput.getStrength() > 0 && jsonInput.getStrength() <= 100 )
+        {
+            randomConfigBuilder.minimumStrength( jsonInput.getStrength() );
         }
-        if (jsonInput.getMinLength() > 0 && jsonInput.getMinLength() <= 100 * 1024) {
-            randomConfigBuilder.minimumLength(jsonInput.getMinLength());
+        if ( jsonInput.getMinLength() > 0 && jsonInput.getMinLength() <= 100 * 1024 )
+        {
+            randomConfigBuilder.minimumLength( jsonInput.getMinLength() );
         }
-        if (jsonInput.getMaxLength() > 0 && jsonInput.getMaxLength() <= 100 * 1024) {
-            randomConfigBuilder.maximumLength(jsonInput.getMaxLength());
+        if ( jsonInput.getMaxLength() > 0 && jsonInput.getMaxLength() <= 100 * 1024 )
+        {
+            randomConfigBuilder.maximumLength( jsonInput.getMaxLength() );
         }
-        if (jsonInput.getChars() != null) {
+        if ( jsonInput.getChars() != null )
+        {
             final List<String> charValues = new ArrayList<>();
-            for (int i = 0; i < jsonInput.getChars().length(); i++) {
-                charValues.add(String.valueOf(jsonInput.getChars().charAt(i)));
+            for ( int i = 0; i < jsonInput.getChars().length(); i++ )
+            {
+                charValues.add( String.valueOf( jsonInput.getChars().charAt( i ) ) );
             }
-            randomConfigBuilder.seedlistPhrases(charValues);
+            randomConfigBuilder.seedlistPhrases( charValues );
         }
 
         randomConfigBuilder.passwordPolicy( pwmPasswordPolicy );

+ 1 - 0
server/src/main/java/password/pwm/ws/server/rest/RestStatisticsServer.java

@@ -64,6 +64,7 @@ public class RestStatisticsServer extends RestServlet
     @Data
     public static class JsonOutput implements Serializable
     {
+        @SuppressWarnings( "checkstyle:MemberName" )
         public Map<String, String> EPS;
         public Map<String, Object> nameData;
         public Map<String, Object> keyData;

Some files were not shown because too many files changed in this diff