فهرست منبع

ioutils refactoring

Jason Rivard 3 سال پیش
والد
کامیت
df830bbc12

+ 21 - 6
lib-util/src/main/java/password/pwm/util/java/JavaHelper.java

@@ -24,8 +24,10 @@ import org.apache.commons.io.IOUtils;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -205,12 +207,25 @@ public class JavaHelper
     }
 
 
-    public static String copyToString( final InputStream input, final Charset charset )
+    public static Optional<String> copyToString( final InputStream input, final Charset charset, final int maximumLength )
             throws IOException
     {
-        final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-        JavaHelper.copy( input, byteArrayOutputStream );
-        return byteArrayOutputStream.toString( charset );
+        if ( input == null )
+        {
+            return Optional.empty();
+        }
+        final StringWriter stringWriter = new StringWriter();
+        final InputStreamReader reader = new InputStreamReader( input, charset );
+        IOUtils.copyLarge( reader, stringWriter, 0, maximumLength );
+        final String value = stringWriter.toString();
+        return ( value.length() > 0 )
+                ? Optional.of( value )
+                : Optional.empty();
+    }
+
+    public static void closeQuietly( final Closeable closable )
+    {
+        IOUtils.closeQuietly( closable );
     }
 
     public static ImmutableByteArray copyToBytes( final InputStream inputStream, final int maxLength )
@@ -510,7 +525,7 @@ public class JavaHelper
             throws IOException
     {
         try ( ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-             GZIPOutputStream gzipOutputStream = new GZIPOutputStream( byteArrayOutputStream ) )
+              GZIPOutputStream gzipOutputStream = new GZIPOutputStream( byteArrayOutputStream ) )
         {
             gzipOutputStream.write( bytes );
             gzipOutputStream.close();
@@ -574,7 +589,7 @@ public class JavaHelper
         }
         catch ( final InterruptedException e )
         {
-           /* ignore */
+            /* ignore */
         }
     }
 

+ 6 - 0
rest-test-service/pom.xml

@@ -86,6 +86,12 @@
             <artifactId>commons-io</artifactId>
             <version>1.3.2</version>
         </dependency>
+        <dependency>
+            <groupId>org.pwm-project</groupId>
+            <artifactId>pwm-lib-util</artifactId>
+            <version>2.1.0-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
         <!-- / library dependencies -->
     </dependencies>
 

+ 3 - 2
rest-test-service/src/main/java/password/pwm/resttest/RestTestExternalTokenDestinationServlet.java

@@ -22,7 +22,7 @@ package password.pwm.resttest;
 
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
-import org.apache.commons.io.IOUtils;
+import password.pwm.util.java.JavaHelper;
 
 import javax.servlet.annotation.WebServlet;
 import javax.servlet.http.HttpServlet;
@@ -31,6 +31,7 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
 
 @WebServlet(
         name = "RestTestExternalTokenDestinationServlet",
@@ -45,7 +46,7 @@ public class RestTestExternalTokenDestinationServlet extends HttpServlet
     {
         System.out.println( "--External Token Destination--" );
         final InputStream inputStream = req.getInputStream();
-        final String body = IOUtils.toString( inputStream );
+        final String body = JavaHelper.copyToString( inputStream, StandardCharsets.UTF_8, Integer.MAX_VALUE ).orElseThrow();
         final JsonObject jsonObject = JsonParser.parseString( body ).getAsJsonObject();
         final String email = jsonObject.getAsJsonObject( "tokenDestination" ).get( "email" ).getAsString();
         final String sms = jsonObject.getAsJsonObject( "tokenDestination" ).get( "sms" ).getAsString();

+ 2 - 1
rest-test-service/src/main/java/password/pwm/resttest/RestTestUtilities.java

@@ -21,6 +21,7 @@
 package password.pwm.resttest;
 
 import org.apache.commons.io.IOUtils;
+import password.pwm.util.java.JavaHelper;
 
 import javax.servlet.http.HttpServletRequest;
 import java.io.IOException;
@@ -51,7 +52,7 @@ public class RestTestUtilities
         }
         finally
         {
-            IOUtils.closeQuietly( readerStream );
+            JavaHelper.closeQuietly( readerStream );
         }
 
         return stringWriter.toString();

+ 6 - 3
server/src/main/java/password/pwm/config/stored/StoredConfigZipJsonSerializer.java

@@ -145,19 +145,22 @@ public class StoredConfigZipJsonSerializer implements StoredConfigSerializer
         {
             if ( SETTINGS_FILENAME.equals( zipEntry.getName() ) )
             {
-                final String stringData = JavaHelper.copyToString( zipInputStream, PwmConstants.DEFAULT_CHARSET );
+                final String stringData = JavaHelper.copyToString( zipInputStream, PwmConstants.DEFAULT_CHARSET, Integer.MAX_VALUE )
+                        .orElse( "" );
                 final List<SerializedValue> readComponents = JsonFactory.get().deserializeList( stringData, SerializedValue.class );
                 serializedValues.addAll( readComponents );
             }
             else if ( META_VALUES_FILENAME.equals( zipEntry.getName() ) )
             {
-                final String stringData = JavaHelper.copyToString( zipInputStream, PwmConstants.DEFAULT_CHARSET );
+                final String stringData = JavaHelper.copyToString( zipInputStream, PwmConstants.DEFAULT_CHARSET, Integer.MAX_VALUE )
+                        .orElse( "" );
                 final List<SerializedMetaValue> readMetaValues = JsonFactory.get().deserializeList( stringData, SerializedMetaValue.class );
                 serializedMetaValues.addAll( readMetaValues );
             }
             else if ( META_FILENAME.equals( zipEntry.getName() ) )
             {
-                final String stringData = JavaHelper.copyToString( zipInputStream, PwmConstants.DEFAULT_CHARSET );
+                final String stringData = JavaHelper.copyToString( zipInputStream, PwmConstants.DEFAULT_CHARSET, Integer.MAX_VALUE )
+                        .orElse( "" );
                 metaData = JsonFactory.get().deserialize( stringData, MetaData.class );
             }
             else if ( zipEntry.getName().endsWith( XREF_SUFFIX ) )

+ 0 - 192
server/src/main/java/password/pwm/health/ApplianceStatusChecker.java

@@ -1,192 +0,0 @@
-/*
- * Password Management Servlets (PWM)
- * http://www.pwm-project.org
- *
- * Copyright (c) 2006-2009 Novell, Inc.
- * Copyright (c) 2009-2021 The PWM Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package password.pwm.health;
-
-import org.apache.commons.io.FileUtils;
-import password.pwm.PwmApplication;
-import password.pwm.PwmEnvironment;
-import password.pwm.bean.DomainID;
-import password.pwm.error.ErrorInformation;
-import password.pwm.error.PwmError;
-import password.pwm.error.PwmOperationalException;
-import password.pwm.error.PwmUnrecoverableException;
-import password.pwm.http.HttpMethod;
-import password.pwm.svc.httpclient.PwmHttpClient;
-import password.pwm.svc.httpclient.PwmHttpClientConfiguration;
-import password.pwm.svc.httpclient.PwmHttpClientRequest;
-import password.pwm.svc.httpclient.PwmHttpClientResponse;
-import password.pwm.util.json.JsonFactory;
-import password.pwm.util.java.StringUtil;
-import password.pwm.util.logging.PwmLogger;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Supplier;
-
-public class ApplianceStatusChecker implements HealthSupplier
-{
-    private static final PwmLogger LOGGER = PwmLogger.forClass( ApplianceStatusChecker.class );
-
-    private static class UpdateStatus implements Serializable
-    {
-        boolean pendingInstallation;
-        boolean autoUpdatesEnabled;
-        boolean updateServiceConfigured;
-    }
-
-    @Override
-    public List<Supplier<List<HealthRecord>>> jobs( final HealthSupplier.HealthSupplierRequest request )
-    {
-        final Supplier<List<HealthRecord>> supplier = () -> doHealthCheck( request );
-        return Collections.singletonList( supplier );
-    }
-
-    private List<HealthRecord> doHealthCheck( final HealthSupplier.HealthSupplierRequest request )
-    {
-        final PwmApplication pwmApplication = request.getPwmApplication();
-        final boolean isApplianceAvailable = pwmApplication.getPwmEnvironment().getFlags().contains( PwmEnvironment.ApplicationFlag.Appliance );
-
-        if ( !isApplianceAvailable )
-        {
-            return Collections.emptyList();
-        }
-
-        try
-        {
-            return List.copyOf( readApplianceHealthStatus( request ) );
-        }
-        catch ( final Exception e )
-        {
-            LOGGER.error( request.getSessionLabel(), () -> "error communicating with client " + e.getMessage() );
-        }
-
-        return Collections.emptyList();
-    }
-
-    private List<HealthRecord> readApplianceHealthStatus( final HealthSupplier.HealthSupplierRequest request  )
-            throws PwmUnrecoverableException, PwmOperationalException
-    {
-        final PwmApplication pwmApplication = request.getPwmApplication();
-        final List<HealthRecord> healthRecords = new ArrayList<>();
-
-        final String url = figureUrl( request );
-        final Map<String, String> requestHeaders = Collections.singletonMap( "sspr-authorization-token", getApplianceAccessToken( pwmApplication ) );
-
-        final PwmHttpClientConfiguration pwmHttpClientConfiguration = PwmHttpClientConfiguration.builder()
-                .trustManagerType( PwmHttpClientConfiguration.TrustManagerType.promiscuous )
-                .build();
-
-        final PwmHttpClient pwmHttpClient = pwmApplication.getHttpClientService().getPwmHttpClient( pwmHttpClientConfiguration );
-        final PwmHttpClientRequest pwmHttpClientRequest = PwmHttpClientRequest.builder()
-                .method( HttpMethod.GET )
-                .url( url )
-                .headers( requestHeaders )
-                .build();
-
-        final PwmHttpClientResponse response = pwmHttpClient.makeRequest( pwmHttpClientRequest, request.getSessionLabel() );
-
-        LOGGER.trace( request.getSessionLabel(), () -> "https response from appliance server request: " + response.getBody() );
-
-        final String jsonString = response.getBody();
-
-        LOGGER.debug( () -> "response from /sspr/appliance-update-status: " + jsonString );
-
-        final UpdateStatus updateStatus = JsonFactory.get().deserialize( jsonString, UpdateStatus.class );
-
-        if ( updateStatus.pendingInstallation )
-        {
-            healthRecords.add( HealthRecord.forMessage( DomainID.systemId(), HealthMessage.Appliance_PendingUpdates ) );
-        }
-
-        if ( !updateStatus.autoUpdatesEnabled )
-        {
-            healthRecords.add( HealthRecord.forMessage( DomainID.systemId(), HealthMessage.Appliance_UpdatesNotEnabled ) );
-        }
-
-        if ( !updateStatus.updateServiceConfigured )
-        {
-            healthRecords.add( HealthRecord.forMessage( DomainID.systemId(), HealthMessage.Appliance_UpdateServiceNotConfigured ) );
-        }
-
-        return Collections.unmodifiableList( healthRecords );
-
-    }
-
-    private String getApplianceAccessToken( final PwmApplication pwmApplication ) throws PwmOperationalException
-    {
-        final String tokenFile = pwmApplication.getPwmEnvironment().getParameters().get( PwmEnvironment.ApplicationParameter.ApplianceTokenFile );
-        if ( StringUtil.isEmpty( tokenFile ) )
-        {
-            final String msg = "unable to determine appliance token, token file environment param "
-                    + PwmEnvironment.ApplicationParameter.ApplianceTokenFile + " is not set";
-            throw new PwmOperationalException( new ErrorInformation( PwmError.ERROR_INTERNAL, msg ) );
-        }
-        final String fileInput = readFileContents( tokenFile );
-        if ( fileInput != null )
-        {
-            return fileInput.trim();
-        }
-        return "";
-    }
-
-    private String figureUrl( final HealthSupplier.HealthSupplierRequest request ) throws PwmOperationalException
-    {
-        final PwmApplication pwmApplication = request.getPwmApplication();
-        final String hostnameFile = pwmApplication.getPwmEnvironment().getParameters().get( PwmEnvironment.ApplicationParameter.ApplianceHostnameFile );
-        if ( StringUtil.isEmpty( hostnameFile ) )
-        {
-            final String msg = "unable to determine appliance hostname, hostname file environment param "
-                    + PwmEnvironment.ApplicationParameter.ApplianceHostnameFile + " is not set";
-            throw new PwmOperationalException( new ErrorInformation( PwmError.ERROR_INTERNAL, msg ) );
-        }
-
-        final String hostname = readFileContents( hostnameFile );
-        final String port = pwmApplication.getPwmEnvironment().getParameters().get( PwmEnvironment.ApplicationParameter.AppliancePort );
-
-        final String url = "https://" + hostname + ":" + port + "/sspr/appliance-update-status";
-        LOGGER.trace( request.getSessionLabel(), () -> "calculated appliance host url as: " + url );
-        return url;
-    }
-
-    private String readFileContents( final String filename ) throws PwmOperationalException
-    {
-        try
-        {
-            final String fileInput = FileUtils.readFileToString( new File( filename ) );
-            if ( fileInput != null )
-            {
-                final String trimmedStr = fileInput.trim();
-                return trimmedStr.replace( "\n", "" );
-            }
-            return "";
-        }
-        catch ( final IOException e )
-        {
-            final String msg = "unable to read contents of file '" + filename + "', error: " + e.getMessage();
-            throw new PwmOperationalException( new ErrorInformation( PwmError.ERROR_INTERNAL, msg ), e );
-        }
-    }
-}

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

@@ -73,7 +73,6 @@ public class HealthService extends AbstractPwmService implements PwmService
             new JavaChecker(),
             new ConfigurationChecker(),
             new LocalDBHealthChecker(),
-            new ApplianceStatusChecker(),
             new CertificateChecker() );
 
 

+ 5 - 8
server/src/main/java/password/pwm/http/PwmRequest.java

@@ -24,7 +24,6 @@ import lombok.Value;
 import org.apache.commons.fileupload.FileItemIterator;
 import org.apache.commons.fileupload.FileItemStream;
 import org.apache.commons.fileupload.servlet.ServletFileUpload;
-import org.apache.commons.io.IOUtils;
 import password.pwm.AppProperty;
 import password.pwm.PwmApplication;
 import password.pwm.PwmApplicationMode;
@@ -52,12 +51,13 @@ import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmUnrecoverableException;
-import password.pwm.util.java.ImmutableByteArray;
 import password.pwm.http.servlet.AbstractPwmServlet;
 import password.pwm.http.servlet.PwmRequestID;
 import password.pwm.http.servlet.PwmServletDefinition;
 import password.pwm.ldap.UserInfo;
 import password.pwm.util.Validator;
+import password.pwm.util.java.ImmutableByteArray;
+import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.LazySupplier;
 import password.pwm.util.java.StringUtil;
 import password.pwm.util.java.TimeDuration;
@@ -69,7 +69,6 @@ import password.pwm.ws.server.RestResultBean;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Serializable;
@@ -282,20 +281,18 @@ public class PwmRequest extends PwmHttpRequestWrapper
                 {
                     final FileItemStream item = iter.next();
                     final InputStream inputStream = item.openStream();
-                    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                    final long length = IOUtils.copyLarge( inputStream, baos, 0, maxFileSize + 1 );
-                    if ( length > maxFileSize )
+                    final ImmutableByteArray fileContents = JavaHelper.copyToBytes( inputStream, maxFileSize + 1 );
+                    if ( fileContents.size() > maxFileSize )
                     {
                         final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_INTERNAL, "upload file size limit exceeded" );
                         LOGGER.error( this, errorInformation );
                         respondWithError( errorInformation );
                         return Collections.emptyMap();
                     }
-                    final byte[] outputFile = baos.toByteArray();
                     final FileUploadItem fileUploadItem = new FileUploadItem(
                             item.getName(),
                             item.getContentType(),
-                            ImmutableByteArray.of( outputFile )
+                            fileContents
                     );
                     returnObj.put( item.getFieldName(), fileUploadItem );
                 }

+ 1 - 8
server/src/main/java/password/pwm/http/servlet/configmanager/ConfigManagerServlet.java

@@ -22,7 +22,6 @@ package password.pwm.http.servlet.configmanager;
 
 import com.novell.ldapchai.exception.ChaiUnavailableException;
 import org.apache.commons.csv.CSVPrinter;
-import org.apache.commons.io.IOUtils;
 import password.pwm.AppProperty;
 import password.pwm.Permission;
 import password.pwm.PwmConstants;
@@ -419,11 +418,9 @@ public class ConfigManagerServlet extends AbstractPwmServlet
                 pwmRequest.getDomainConfig().readAppProperty( AppProperty.DOWNLOAD_FILENAME_LDAP_PERMISSION_CSV )
         );
 
-        final CSVPrinter csvPrinter = MiscUtil.makeCsvPrinter( pwmRequest.getPwmResponse().getOutputStream() );
-        try
+        try ( CSVPrinter csvPrinter = MiscUtil.makeCsvPrinter( pwmRequest.getPwmResponse().getOutputStream() ) )
         {
 
-            final StoredConfiguration storedConfiguration = readCurrentConfiguration( pwmRequest );
             final LDAPPermissionCalculator ldapPermissionCalculator = new LDAPPermissionCalculator( pwmRequest.getDomainConfig() );
 
             for ( final LDAPPermissionCalculator.PermissionRecord permissionRecord : ldapPermissionCalculator.getPermissionRecords() )
@@ -446,10 +443,6 @@ public class ConfigManagerServlet extends AbstractPwmServlet
             LOGGER.error( pwmRequest, errorInformation );
             pwmRequest.respondWithError( errorInformation );
         }
-        finally
-        {
-            IOUtils.closeQuietly( csvPrinter );
-        }
     }
 }
 

+ 25 - 9
server/src/main/java/password/pwm/http/servlet/resource/ResourceServletConfiguration.java

@@ -22,20 +22,19 @@ package password.pwm.http.servlet.resource;
 
 import lombok.Value;
 import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
 import password.pwm.AppProperty;
 import password.pwm.PwmDomain;
 import password.pwm.bean.SessionLabel;
 import password.pwm.config.DomainConfig;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.value.FileValue;
-import password.pwm.util.java.ImmutableByteArray;
 import password.pwm.util.java.CollectionUtil;
-import password.pwm.util.json.JsonFactory;
+import password.pwm.util.java.ImmutableByteArray;
+import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.StringUtil;
+import password.pwm.util.json.JsonFactory;
 import password.pwm.util.logging.PwmLogger;
 
-import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.Serializable;
@@ -55,6 +54,9 @@ class ResourceServletConfiguration
 {
     private static final PwmLogger LOGGER = PwmLogger.forClass( ResourceServletConfiguration.class );
 
+    private static final int MAX_RESOURCE_SIZE = 10_000_000;
+    private static final int MAX_RESOURCE_COUNT = 1000;
+
     // settings with default values, values are set by app properties.
     private int maxCacheItems;
     private long cacheExpireSeconds;
@@ -180,7 +182,10 @@ class ResourceServletConfiguration
         return new ResourceServletConfiguration();
     }
 
-    private static Map<String, FileResource> makeMemoryFileMapFromZipInput( final SessionLabel sessionLabel, final ImmutableByteArray content )
+    private static Map<String, FileResource> makeMemoryFileMapFromZipInput(
+            final SessionLabel sessionLabel,
+            final ImmutableByteArray content
+    )
             throws IOException
     {
         final ZipInputStream stream = new ZipInputStream( content.newByteArrayInputStream() );
@@ -193,11 +198,22 @@ class ResourceServletConfiguration
             {
                 final String name = entry.getName();
                 final Instant lastModified = Instant.ofEpochMilli( entry.getTime() );
-                final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-                IOUtils.copy( stream, byteArrayOutputStream );
-                final ImmutableByteArray contents = ImmutableByteArray.of( byteArrayOutputStream.toByteArray() );
-                memoryMap.put( name, new MemoryFileResource( name, contents, lastModified ) );
+                final ImmutableByteArray contents = JavaHelper.copyToBytes( stream, MAX_RESOURCE_SIZE + 1 );
+                if ( contents.size() > MAX_RESOURCE_COUNT )
+                {
+                    final String entryName = entry.getName();
+                    LOGGER.error( () -> "ignoring resource bundle zip file entry '" + entryName
+                            + "' due to size being greater than max of " + MAX_RESOURCE_SIZE + " bytes " );
+                }
+                else if ( memoryMap.size() > MAX_RESOURCE_COUNT )
+                {
+                    final String entryName = entry.getName();
+                    LOGGER.error( () -> "ignoring resource bundle zip file entry '" + entryName
+                            + "' due to total resource count being greater than max of " + MAX_RESOURCE_COUNT );
+                }
+                else
                 {
+                    memoryMap.put( name, new MemoryFileResource( name, contents, lastModified ) );
                     final String finalEntry = entry.getName();
                     LOGGER.trace( sessionLabel, () -> "discovered file in configured resource bundle: " + finalEntry );
                 }

+ 3 - 3
server/src/main/java/password/pwm/svc/wordlist/WordlistImporter.java

@@ -20,18 +20,18 @@
 
 package password.pwm.svc.wordlist;
 
-import org.apache.commons.io.IOUtils;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.util.TransactionSizeCalculator;
 import password.pwm.util.java.ConditionalTaskExecutor;
+import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.MiscUtil;
-import password.pwm.util.json.JsonFactory;
 import password.pwm.util.java.Percent;
 import password.pwm.util.java.StatisticAverageBundle;
 import password.pwm.util.java.StringUtil;
 import password.pwm.util.java.TimeDuration;
+import password.pwm.util.json.JsonFactory;
 import password.pwm.util.logging.PwmLogger;
 
 import java.time.Instant;
@@ -277,7 +277,7 @@ class WordlistImporter implements Runnable
         }
         finally
         {
-            IOUtils.closeQuietly( zipFileReader );
+            JavaHelper.closeQuietly( zipFileReader );
         }
     }
 

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

@@ -20,7 +20,6 @@
 
 package password.pwm.svc.wordlist;
 
-import org.apache.commons.io.IOUtils;
 import password.pwm.AppProperty;
 import password.pwm.PwmApplication;
 import password.pwm.bean.SessionLabel;
@@ -36,9 +35,9 @@ import password.pwm.svc.httpclient.PwmHttpClientRequest;
 import password.pwm.svc.httpclient.PwmHttpClientResponse;
 import password.pwm.util.java.ConditionalTaskExecutor;
 import password.pwm.util.java.JavaHelper;
-import password.pwm.util.json.JsonFactory;
 import password.pwm.util.java.StringUtil;
 import password.pwm.util.java.TimeDuration;
+import password.pwm.util.json.JsonFactory;
 import password.pwm.util.logging.PwmLogger;
 
 import java.io.IOException;
@@ -247,7 +246,7 @@ class WordlistSource
         finally
         {
             closeStreams( pwmLogger, processId, sessionLabel, inputStream );
-            IOUtils.closeQuietly( zipInputStream );
+            JavaHelper.closeQuietly( zipInputStream );
         }
 
         bytes = zipInputStream.getByteCount();
@@ -315,7 +314,7 @@ class WordlistSource
         pwmLogger.trace( sessionLabel, () -> processIdLabel( processId ) + "beginning close of remote wordlist read process" );
         for ( final InputStream inputStream : inputStreams )
         {
-            IOUtils.closeQuietly( inputStream );
+            JavaHelper.closeQuietly( inputStream );
         }
         pwmLogger.trace( sessionLabel, () -> processIdLabel( processId ) + "completed close of remote wordlist read process",
                 () -> TimeDuration.fromCurrent( startClose ) );

+ 6 - 27
server/src/main/java/password/pwm/util/ServletUtility.java

@@ -20,17 +20,14 @@
 
 package password.pwm.util;
 
-import org.apache.commons.io.IOUtils;
 import password.pwm.PwmConstants;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmUnrecoverableException;
+import password.pwm.util.java.JavaHelper;
 
 import javax.servlet.http.HttpServletRequest;
 import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringWriter;
 
 public final class ServletUtility
 {
@@ -41,32 +38,14 @@ public final class ServletUtility
     public static String readRequestBodyAsString( final HttpServletRequest req, final int maxChars )
             throws IOException, PwmUnrecoverableException
     {
-        final StringWriter stringWriter = new StringWriter();
-        final Reader readerStream = new InputStreamReader(
-                req.getInputStream(),
-                PwmConstants.DEFAULT_CHARSET
-        );
+        final String value = JavaHelper.copyToString( req.getInputStream(), PwmConstants.DEFAULT_CHARSET, maxChars + 1 )
+                .orElse( "" );
 
-        try
+        if ( value.length() > maxChars )
         {
-            IOUtils.copy( readerStream, stringWriter );
-        }
-        catch ( final Exception e )
-        {
-            final String errorMsg = "error reading request body stream: " + e.getMessage();
-            throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_INTERNAL, errorMsg ) );
-        }
-        finally
-        {
-            IOUtils.closeQuietly( readerStream );
-        }
-
-        final String stringValue = stringWriter.toString();
-        if ( stringValue.length() > maxChars )
-        {
-            final String msg = "input request body is to big, size=" + stringValue.length() + ", max=" + maxChars;
+            final String msg = "input request body is to big, size=" + value.length() + ", max=" + maxChars;
             throw new PwmUnrecoverableException( new ErrorInformation( PwmError.ERROR_INTERNAL, msg ) );
         }
-        return stringValue;
+        return value;
     }
 }

+ 2 - 2
server/src/main/java/password/pwm/util/cli/commands/ExportHttpsTomcatConfigCommand.java

@@ -20,12 +20,12 @@
 
 package password.pwm.util.cli.commands;
 
-import org.apache.commons.io.IOUtils;
 import password.pwm.PwmConstants;
 import password.pwm.config.AppConfig;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.option.TLSVersion;
 import password.pwm.util.cli.CliParameters;
+import password.pwm.util.java.JavaHelper;
 
 import java.io.File;
 import java.io.IOException;
@@ -118,7 +118,7 @@ public class ExportHttpsTomcatConfigCommand extends AbstractCliCommand
         )
                 throws IOException
         {
-            String fileContents = IOUtils.toString( sourceFile, PwmConstants.DEFAULT_CHARSET.toString() );
+            String fileContents = JavaHelper.copyToString( sourceFile, PwmConstants.DEFAULT_CHARSET, Integer.MAX_VALUE ).orElse( "" );
             fileContents = fileContents.replace( TOKEN_TLS_PROTOCOLS, getTlsProtocolsValue( appConfig ) );
             final String tlsCiphers = appConfig.readSettingAsString( PwmSetting.HTTPS_CIPHERS );
             fileContents = fileContents.replace( TOKEN_TLS_CIPHERS, tlsCiphers );

+ 22 - 15
server/src/test/java/password/pwm/svc/sms/EmailQueueManagerTest.java

@@ -23,16 +23,17 @@ package password.pwm.svc.sms;
 import jakarta.mail.Message;
 import jakarta.mail.MessagingException;
 import jakarta.mail.internet.InternetAddress;
-import org.apache.commons.io.IOUtils;
 import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
 import password.pwm.AppProperty;
+import password.pwm.PwmConstants;
 import password.pwm.bean.EmailItemBean;
 import password.pwm.config.AppConfig;
 import password.pwm.svc.email.EmailServer;
 import password.pwm.svc.email.EmailServerUtil;
 import password.pwm.svc.email.EmailService;
+import password.pwm.util.java.JavaHelper;
 
 import java.io.IOException;
 import java.util.List;
@@ -62,20 +63,26 @@ public class EmailQueueManagerTest
         final List<Message> messages = EmailServerUtil.convertEmailItemToMessages( emailItemBean, config, emailServer );
         Assert.assertEquals( 2, messages.size() );
 
-        Message message = messages.get( 0 );
-        Assert.assertEquals( new InternetAddress( "fred@flintstones.tv" ), message.getRecipients( Message.RecipientType.TO )[0] );
-        Assert.assertEquals( new InternetAddress( "bedrock-admin@flintstones.tv" ), message.getFrom()[0] );
-        Assert.assertEquals( "Test Subject", message.getSubject() );
-        String content = IOUtils.toString( message.getInputStream() );
-        Assert.assertTrue( content.contains( "bodyPlain" ) );
-        Assert.assertTrue( content.contains( "bodyHtml" ) );
+        {
+            final Message message = messages.get( 0 );
+            Assert.assertEquals( new InternetAddress( "fred@flintstones.tv" ), message.getRecipients( Message.RecipientType.TO )[0] );
+            Assert.assertEquals( new InternetAddress( "bedrock-admin@flintstones.tv" ), message.getFrom()[0] );
+            Assert.assertEquals( "Test Subject", message.getSubject() );
+            final String content = JavaHelper.copyToString( message.getInputStream(), PwmConstants.DEFAULT_CHARSET, Integer.MAX_VALUE )
+                    .orElse( "" );
+            Assert.assertTrue( content.contains( "bodyPlain" ) );
+            Assert.assertTrue( content.contains( "bodyHtml" ) );
+        }
 
-        message = messages.get( 1 );
-        Assert.assertEquals( new InternetAddress( "barney@flintstones.tv" ), message.getRecipients( Message.RecipientType.TO )[0] );
-        Assert.assertEquals( new InternetAddress( "bedrock-admin@flintstones.tv" ), message.getFrom()[0] );
-        Assert.assertEquals( "Test Subject", message.getSubject() );
-        content = IOUtils.toString( message.getInputStream() );
-        Assert.assertTrue( content.contains( "bodyPlain" ) );
-        Assert.assertTrue( content.contains( "bodyHtml" ) );
+        {
+            final Message message = messages.get( 1 );
+            Assert.assertEquals( new InternetAddress( "barney@flintstones.tv" ), message.getRecipients( Message.RecipientType.TO )[0] );
+            Assert.assertEquals( new InternetAddress( "bedrock-admin@flintstones.tv" ), message.getFrom()[0] );
+            Assert.assertEquals( "Test Subject", message.getSubject() );
+            final String content = JavaHelper.copyToString( message.getInputStream(), PwmConstants.DEFAULT_CHARSET, Integer.MAX_VALUE )
+                    .orElse( "" );
+            Assert.assertTrue( content.contains( "bodyPlain" ) );
+            Assert.assertTrue( content.contains( "bodyHtml" ) );
+        }
     }
 }

+ 2 - 2
server/src/test/java/password/pwm/util/java/XmlFactoryBenchmarkExtendedTest.java

@@ -20,7 +20,6 @@
 
 package password.pwm.util.java;
 
-import org.apache.commons.io.output.NullOutputStream;
 import org.jrivard.xmlchai.AccessMode;
 import org.jrivard.xmlchai.XmlChai;
 import org.jrivard.xmlchai.XmlDocument;
@@ -34,6 +33,7 @@ import org.openjdk.jmh.runner.options.OptionsBuilder;
 import org.openjdk.jmh.runner.options.TimeValue;
 
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.concurrent.TimeUnit;
 
 public class XmlFactoryBenchmarkExtendedTest
@@ -72,6 +72,6 @@ public class XmlFactoryBenchmarkExtendedTest
         final XmlFactory xmlFactory = XmlChai.getFactory();
         final InputStream xmlFactoryTestXmlFile = XmlFactoryTest.class.getResourceAsStream( "XmlFactoryTest.xml" );
         final XmlDocument xmlDocument = xmlFactory.parse( xmlFactoryTestXmlFile, AccessMode.IMMUTABLE );
-        xmlFactory.output( xmlDocument, new NullOutputStream() );
+        xmlFactory.output( xmlDocument, OutputStream.nullOutputStream() );
     }
 }