Skip to content

Commit cbb7c9f

Browse files
authored
Merge branch 'master' into patch-12
2 parents 58d96d9 + e354e5d commit cbb7c9f

File tree

98 files changed

+1562
-1081
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+1562
-1081
lines changed

build/checkstyle-import.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
<allow pkg="java.security"/>
3939

4040
<allow pkg="org.apache.catalina"/>
41+
<allow pkg="org.apache.coyote"/>
4142

4243
<!-- chai -->
4344
<allow pkg="com.novell.ldapchai"/>

client/pom.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@
1818
<project.root.basedir>${project.basedir}/..</project.root.basedir>
1919
</properties>
2020

21+
<profiles>
22+
<profile>
23+
<id>skip-frontend</id>
24+
<properties>
25+
<skip.npm>true</skip.npm>
26+
</properties>
27+
</profile>
28+
</profiles>
29+
2130
<build>
2231
<plugins>
2332
<plugin>

data-service/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@
140140
<dependency>
141141
<groupId>org.apache.commons</groupId>
142142
<artifactId>commons-lang3</artifactId>
143-
<version>3.8.1</version>
143+
<version>3.9</version>
144144
</dependency>
145145
<dependency>
146146
<groupId>com.sun.mail</groupId>

data-service/src/main/java/password/pwm/receiver/SummaryBean.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,8 @@ static SummaryBean fromStorage( final Storage storage, final TimeDuration maxAge
125125
final Statistic statistic = Statistic.forKey( statKey );
126126
if ( statistic != null )
127127
{
128-
if ( statistic.getType() == Statistic.Type.INCREMENTER )
129-
{
130-
final int count = Integer.parseInt( bean.getStatistics().get( statKey ) );
131-
incrementCounterMap( statCount, statistic.getLabel( null ), count );
132-
}
128+
final int count = Integer.parseInt( bean.getStatistics().get( statKey ) );
129+
incrementCounterMap( statCount, statistic.getLabel( null ), count );
133130
}
134131
}
135132
}

docker/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
<plugin>
3535
<groupId>com.google.cloud.tools</groupId>
3636
<artifactId>jib-maven-plugin</artifactId>
37-
<version>1.0.2</version>
37+
<version>1.1.0</version>
3838
<executions>
3939
<execution>
4040
<id>make-docker-image</id>

onejar/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
<properties>
1919
<project.root.basedir>${project.basedir}/..</project.root.basedir>
20-
<tomcat.version>9.0.16</tomcat.version>
20+
<tomcat.version>9.0.19</tomcat.version>
2121
</properties>
2222

2323
<build>

onejar/src/main/java/password/pwm/onejar/TomcatOnejarRunner.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.apache.catalina.connector.Connector;
2626
import org.apache.catalina.startup.Tomcat;
2727
import org.apache.catalina.util.ServerInfo;
28+
import org.apache.coyote.http2.Http2Protocol;
2829

2930
import javax.servlet.ServletException;
3031
import java.io.BufferedReader;
@@ -159,6 +160,7 @@ private Connector makeConnector( final OnejarConfig onejarConfig, final Properti
159160
}
160161
connector.setSecure( true );
161162
connector.setScheme( "https" );
163+
connector.addUpgradeProtocol( new Http2Protocol() );
162164
connector.setAttribute( "SSLEnabled", "true" );
163165
connector.setAttribute( "keystoreFile", onejarConfig.getKeystoreFile().getAbsolutePath() );
164166
connector.setAttribute( "keystorePass", onejarConfig.getKeystorePass() );

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@
247247
<dependency>
248248
<groupId>com.github.spotbugs</groupId>
249249
<artifactId>spotbugs</artifactId>
250-
<version>3.1.12</version>
250+
<version>4.0.0-beta1</version>
251251
</dependency>
252252
</dependencies>
253253
<configuration>
@@ -291,7 +291,7 @@
291291
<dependency>
292292
<groupId>com.github.spotbugs</groupId>
293293
<artifactId>spotbugs-annotations</artifactId>
294-
<version>3.1.12</version>
294+
<version>4.0.0-beta1</version>
295295
<scope>provided</scope>
296296
</dependency>
297297
</dependencies>

server/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@
249249
<dependency>
250250
<groupId>org.apache.commons</groupId>
251251
<artifactId>commons-lang3</artifactId>
252-
<version>3.8.1</version>
252+
<version>3.9</version>
253253
</dependency>
254254
<dependency>
255255
<groupId>commons-validator</groupId>

server/src/main/java/password/pwm/AppProperty.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public enum AppProperty
7878
CONFIG_EDITOR_QUERY_FILTER_TEST_LIMIT ( "configEditor.queryFilter.testLimit" ),
7979
CONFIG_EDITOR_IDLE_TIMEOUT ( "configEditor.idleTimeoutSeconds" ),
8080
CONFIG_GUIDE_IDLE_TIMEOUT ( "configGuide.idleTimeoutSeconds" ),
81-
CONFIG_MANAGER_ZIPDEBUG_MAXLOGLINES ( "configManager.zipDebug.maxLogLines" ),
81+
CONFIG_MANAGER_ZIPDEBUG_MAXLOGBYTES ( "configManager.zipDebug.maxLogBytes" ),
8282
CONFIG_MANAGER_ZIPDEBUG_MAXLOGSECONDS ( "configManager.zipDebug.maxLogSeconds" ),
8383
CLUSTER_DB_ENABLE ( "cluster.db.enable" ),
8484
CLUSTER_DB_HEARTBEAT_SECONDS ( "cluster.db.heartbeatSeconds" ),
@@ -194,6 +194,8 @@ public enum AppProperty
194194
HEALTHCHECK_MIN_CHECK_INTERVAL ( "healthCheck.minimumCheckIntervalSeconds" ),
195195
HEALTHCHECK_MAX_RECORD_AGE ( "healthCheck.maximumRecordAgeSeconds" ),
196196
HEALTHCHECK_MAX_FORCE_WAIT ( "healthCheck.maximumForceCheckWaitSeconds" ),
197+
HEALTH_SUPPORT_BUNDLE_WRITE_INTERVAL_SECONDS ( "health.supportBundle.file.writeIntervalSeconds" ),
198+
HEALTH_SUPPORT_BUNDLE_FILE_WRITE_COUNT ( "health.supportBundle.file.writeRetentionCount" ),
197199
HEALTH_CERTIFICATE_WARN_SECONDS ( "health.certificate.warnSeconds" ),
198200
HEALTH_LDAP_CAUTION_DURATION_MS ( "health.ldap.cautionDurationMS" ),
199201
HEALTH_LDAP_PROXY_WARN_PW_EXPIRE_SECONDS ( "health.ldap.proxy.pwExpireWarnSeconds" ),

server/src/main/java/password/pwm/bean/LocalSessionStateBean.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
import lombok.Data;
2626
import password.pwm.ldap.UserInfoBean;
27+
import password.pwm.util.EventRateMeter;
28+
import password.pwm.util.java.TimeDuration;
2729

2830
import java.io.Serializable;
2931
import java.time.Instant;
@@ -64,8 +66,11 @@ public class LocalSessionStateBean implements Serializable
6466

6567
private boolean passwordModified;
6668
private boolean privateUrlAccessed;
69+
private boolean captchaBypassedViaParameter;
6770

6871
private final AtomicInteger intruderAttempts = new AtomicInteger( 0 );
72+
private final AtomicInteger requestCount = new AtomicInteger( 0 );
73+
private final EventRateMeter.MovingAverage avgRequestDuration = new EventRateMeter.MovingAverage( TimeDuration.DAY );
6974
private boolean oauthInProgress;
7075

7176
private boolean sessionIdRecycleNeeded;

server/src/main/java/password/pwm/config/stored/StoredConfigurationImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@
4444
import password.pwm.error.PwmUnrecoverableException;
4545
import password.pwm.i18n.Config;
4646
import password.pwm.i18n.PwmLocaleBundle;
47-
import password.pwm.util.i18n.LocaleHelper;
4847
import password.pwm.util.PasswordData;
48+
import password.pwm.util.i18n.LocaleHelper;
4949
import password.pwm.util.java.JavaHelper;
5050
import password.pwm.util.java.JsonUtil;
5151
import password.pwm.util.java.StringUtil;

server/src/main/java/password/pwm/config/value/FileValue.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,30 +89,30 @@ public static FileContent fromEncodedString( final String input )
8989
throws IOException
9090
{
9191
final byte[] convertedBytes = StringUtil.base64Decode( input );
92-
return new FileContent( new ImmutableByteArray( convertedBytes ) );
92+
return new FileContent( ImmutableByteArray.of( convertedBytes ) );
9393
}
9494

9595
public String toEncodedString( )
9696
throws IOException
9797
{
98-
return StringUtil.base64Encode( contents.getBytes(), StringUtil.Base64Options.GZIP );
98+
return StringUtil.base64Encode( contents.copyOf(), StringUtil.Base64Options.GZIP );
9999
}
100100

101101
public String md5sum( )
102102
throws PwmUnrecoverableException
103103
{
104-
return SecureEngine.hash( new ByteArrayInputStream( contents.getBytes() ), PwmHashAlgorithm.MD5 );
104+
return SecureEngine.hash( new ByteArrayInputStream( contents.copyOf() ), PwmHashAlgorithm.MD5 );
105105
}
106106

107107
public String sha1sum( )
108108
throws PwmUnrecoverableException
109109
{
110-
return SecureEngine.hash( new ByteArrayInputStream( contents.getBytes() ), PwmHashAlgorithm.SHA1 );
110+
return SecureEngine.hash( new ByteArrayInputStream( contents.copyOf() ), PwmHashAlgorithm.SHA1 );
111111
}
112112

113113
public int size( )
114114
{
115-
return contents.getBytes().length;
115+
return contents.copyOf().length;
116116
}
117117
}
118118

server/src/main/java/password/pwm/health/HealthMessage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public enum HealthMessage
4444
LDAP_TestUserReadPwError( HealthStatus.WARN, HealthTopic.LDAP ),
4545
LDAP_TestUserOK( HealthStatus.GOOD, HealthTopic.LDAP ),
4646
Email_SendFailure( HealthStatus.WARN, HealthTopic.Email ),
47-
PwNotify_Failure( HealthStatus.WARN, HealthTopic.Email ),
47+
PwNotify_Failure( HealthStatus.WARN, HealthTopic.Application ),
4848
MissingResource( HealthStatus.DEBUG, HealthTopic.Integrity ),
4949
BrokenMethod( HealthStatus.DEBUG, HealthTopic.Integrity ),
5050
Appliance_PendingUpdates( HealthStatus.CAUTION, HealthTopic.Appliance ),

server/src/main/java/password/pwm/health/HealthMonitor.java

Lines changed: 104 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,22 @@
2525
import lombok.Value;
2626
import password.pwm.AppProperty;
2727
import password.pwm.PwmApplication;
28+
import password.pwm.bean.SessionLabel;
2829
import password.pwm.error.PwmException;
30+
import password.pwm.error.PwmUnrecoverableException;
31+
import password.pwm.http.servlet.configmanager.DebugItemGenerator;
2932
import password.pwm.svc.PwmService;
3033
import password.pwm.util.PwmScheduler;
34+
import password.pwm.util.java.FileSystemUtility;
35+
import password.pwm.util.java.JavaHelper;
3136
import password.pwm.util.java.TimeDuration;
3237
import password.pwm.util.logging.PwmLogger;
3338

39+
import java.io.File;
40+
import java.io.FileOutputStream;
41+
import java.io.IOException;
3442
import java.io.Serializable;
43+
import java.nio.file.Files;
3544
import java.time.Instant;
3645
import java.util.ArrayList;
3746
import java.util.Collection;
@@ -44,6 +53,7 @@
4453
import java.util.concurrent.ExecutorService;
4554
import java.util.concurrent.Future;
4655
import java.util.concurrent.atomic.AtomicInteger;
56+
import java.util.zip.ZipOutputStream;
4757

4858
public class HealthMonitor implements PwmService
4959
{
@@ -64,6 +74,7 @@ public class HealthMonitor implements PwmService
6474
}
6575

6676
private ExecutorService executorService;
77+
private ExecutorService supportZipWriterService;
6778
private HealthMonitorSettings settings;
6879

6980
private Map<HealthMonitorFlag, Serializable> healthProperties = new ConcurrentHashMap<>();
@@ -82,6 +93,26 @@ public HealthMonitor( )
8293
{
8394
}
8495

96+
public void init( final PwmApplication pwmApplication ) throws PwmException
97+
{
98+
status = STATUS.OPENING;
99+
this.pwmApplication = pwmApplication;
100+
settings = HealthMonitorSettings.fromConfiguration( pwmApplication.getConfig() );
101+
102+
if ( !Boolean.parseBoolean( pwmApplication.getConfig().readAppProperty( AppProperty.HEALTHCHECK_ENABLED ) ) )
103+
{
104+
LOGGER.debug( () -> "health monitor will remain inactive due to AppProperty " + AppProperty.HEALTHCHECK_ENABLED.getKey() );
105+
status = STATUS.CLOSED;
106+
return;
107+
}
108+
109+
executorService = PwmScheduler.makeBackgroundExecutor( pwmApplication, this.getClass() );
110+
supportZipWriterService = PwmScheduler.makeBackgroundExecutor( pwmApplication, this.getClass() );
111+
scheduleNextZipOutput();
112+
113+
status = STATUS.OPEN;
114+
}
115+
85116
public Instant getLastHealthCheckTime( )
86117
{
87118
if ( status != STATUS.OPEN )
@@ -122,24 +153,6 @@ public STATUS status( )
122153
return status;
123154
}
124155

125-
public void init( final PwmApplication pwmApplication ) throws PwmException
126-
{
127-
status = STATUS.OPENING;
128-
this.pwmApplication = pwmApplication;
129-
settings = HealthMonitorSettings.fromConfiguration( pwmApplication.getConfig() );
130-
131-
if ( !Boolean.parseBoolean( pwmApplication.getConfig().readAppProperty( AppProperty.HEALTHCHECK_ENABLED ) ) )
132-
{
133-
LOGGER.debug( () -> "health monitor will remain inactive due to AppProperty " + AppProperty.HEALTHCHECK_ENABLED.getKey() );
134-
status = STATUS.CLOSED;
135-
return;
136-
}
137-
138-
executorService = PwmScheduler.makeBackgroundExecutor( pwmApplication, this.getClass() );
139-
140-
status = STATUS.OPEN;
141-
}
142-
143156
public Set<HealthRecord> getHealthRecords( )
144157
{
145158
if ( status != STATUS.OPEN )
@@ -151,12 +164,12 @@ public Set<HealthRecord> getHealthRecords( )
151164
{
152165
final Instant startTime = Instant.now();
153166
LOGGER.trace( () -> "begin force immediate check" );
154-
final Future future = pwmApplication.getPwmScheduler().scheduleFutureJob( new ImmediateJob(), executorService, TimeDuration.ZERO );
167+
final Future future = pwmApplication.getPwmScheduler().scheduleJob( new ImmediateJob(), executorService, TimeDuration.ZERO );
155168
settings.getMaximumForceCheckWait().pause( future::isDone );
156169
LOGGER.trace( () -> "exit force immediate check, done=" + future.isDone() + ", " + TimeDuration.compactFromCurrent( startTime ) );
157170
}
158171

159-
pwmApplication.getPwmScheduler().scheduleFutureJob( new UpdateJob(), executorService, settings.getNominalCheckInterval() );
172+
pwmApplication.getPwmScheduler().scheduleJob( new UpdateJob(), executorService, settings.getNominalCheckInterval() );
160173

161174
{
162175
final HealthData localHealthData = this.healthData;
@@ -175,6 +188,10 @@ public void close( )
175188
{
176189
executorService.shutdown();
177190
}
191+
if ( supportZipWriterService != null )
192+
{
193+
supportZipWriterService.shutdown();
194+
}
178195
healthData = emptyHealthData();
179196
status = STATUS.CLOSED;
180197
}
@@ -299,4 +316,71 @@ private boolean recordsAreOutdated()
299316
return TimeDuration.fromCurrent( this.getTimeStamp() ).isLongerThan( settings.getMaximumRecordAge() );
300317
}
301318
}
319+
320+
private void scheduleNextZipOutput()
321+
{
322+
final int intervalSeconds = JavaHelper.silentParseInt( pwmApplication.getConfig().readAppProperty( AppProperty.HEALTH_SUPPORT_BUNDLE_WRITE_INTERVAL_SECONDS ), 0 );
323+
if ( intervalSeconds > 0 )
324+
{
325+
final TimeDuration intervalDuration = TimeDuration.of( intervalSeconds, TimeDuration.Unit.SECONDS );
326+
pwmApplication.getPwmScheduler().scheduleJob( new SupportZipFileWriter( pwmApplication ), supportZipWriterService, intervalDuration );
327+
}
328+
}
329+
330+
private class SupportZipFileWriter implements Runnable
331+
{
332+
private final PwmApplication pwmApplication;
333+
334+
SupportZipFileWriter( final PwmApplication pwmApplication )
335+
{
336+
this.pwmApplication = pwmApplication;
337+
}
338+
339+
@Override
340+
public void run()
341+
{
342+
try
343+
{
344+
writeSupportZipToAppPath();
345+
}
346+
catch ( Exception e )
347+
{
348+
LOGGER.debug( SessionLabel.HEALTH_SESSION_LABEL, () -> "error writing support zip to file system: " + e.getMessage() );
349+
}
350+
351+
scheduleNextZipOutput();
352+
}
353+
354+
private void writeSupportZipToAppPath()
355+
throws IOException, PwmUnrecoverableException
356+
{
357+
final File appPath = pwmApplication.getPwmEnvironment().getApplicationPath();
358+
if ( !appPath.exists() )
359+
{
360+
return;
361+
}
362+
363+
final int rotationCount = JavaHelper.silentParseInt( pwmApplication.getConfig().readAppProperty( AppProperty.HEALTH_SUPPORT_BUNDLE_FILE_WRITE_COUNT ), 10 );
364+
final DebugItemGenerator debugItemGenerator = new DebugItemGenerator( pwmApplication, SessionLabel.HEALTH_SESSION_LABEL );
365+
366+
final File supportPath = new File( appPath.getPath() + File.separator + "support" );
367+
368+
FileSystemUtility.mkdirs( supportPath );
369+
370+
final File supportFile = new File ( supportPath.getPath() + File.separator + debugItemGenerator.getFilename() );
371+
372+
FileSystemUtility.rotateBackups( supportFile, rotationCount );
373+
374+
final File newSupportFile = new File ( supportFile.getPath() + ".new" );
375+
Files.deleteIfExists( newSupportFile.toPath() );
376+
377+
try ( ZipOutputStream zipOutputStream = new ZipOutputStream( new FileOutputStream( newSupportFile ) ) )
378+
{
379+
LOGGER.trace( SessionLabel.HEALTH_SESSION_LABEL, () -> "beginning periodic support bundle filesystem output" );
380+
debugItemGenerator.outputZipDebugFile( zipOutputStream );
381+
}
382+
383+
Files.move( newSupportFile.toPath(), supportFile.toPath() );
384+
}
385+
}
302386
}

0 commit comments

Comments
 (0)