diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/config/InitialConfig.java b/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/config/InitialConfig.java index 4e6915413f3..307c1280fc8 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/config/InitialConfig.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/config/InitialConfig.java @@ -64,7 +64,6 @@ private static String getEnvOrProperty(String key) { } } - @SuppressWarnings("SameParameterValue") // packageFriendly for Testing static String[] getLocalConfigDirs( List dirProxies, UnaryOperator unProxyFunction ) { return dirProxies.stream() @@ -83,10 +82,10 @@ static SourcedFile clean( SourcedFile sourcedFile ) { return str.isEmpty() ? null : new SourcedFile( str, sourcedFile.getSource() ); } - @SuppressWarnings("SameParameterValue") // packageFriendly for Testing static InitialConfig create( SourcedFile localConfigFile, NanoTimeSupplier currentTimeSupplier ) { - if (localConfigFile == null) { // Leave everything disabled! + // Leave everything disabled! + if (localConfigFile == null) { return new InitialConfig( null, null, RateLimitingFactoriesSupplierWithStatus.NO_RATE_LIMITING ); } String errorMsg = null; @@ -99,8 +98,7 @@ static InitialConfig create( SourcedFile localConfigFile, NanoTimeSupplier curre try { dto = parseFile( bindYaml, localConfigFile.getBody() ); currentStatus = CurrentStatus.PENDING; - } - catch ( YamlRateLimitingConfigException e ) { + } catch ( YamlRateLimitingConfigException e ) { error = e; errorMsg = e.getMessage(); } diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/util/SourcedFile.java b/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/util/SourcedFile.java index c9ab6badaa7..ae60df05f9a 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/util/SourcedFile.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/ratelimiting/util/SourcedFile.java @@ -11,15 +11,18 @@ import org.apache.commons.lang3.StringUtils; -import lombok.AllArgsConstructor; import lombok.Getter; -@AllArgsConstructor @Getter public class SourcedFile { private final String body; private final String source; + public SourcedFile(String body, String source) { + this.body = body; + this.source = source; + } + public static SourcedFile locateAndLoadLocalFile( String name, String... dirs ) { if ( (name == null) || name.isBlank() ) { return null; @@ -48,8 +51,7 @@ static SourcedFile loadFile( InputStream is, String source ) { for ( String line; (line = reader.readLine()) != null; ) { sb.append( line ).append( '\n' ); } - } - catch ( IOException e ) { + } catch ( IOException e ) { throw new IllegalStateException( "Unable to read " + source, e ); } String str = sb.toString(); @@ -66,8 +68,7 @@ private static InputStream getFileInputStream( String dir, String name ) { if ( file.isFile() ) { return new FileInputStream( file ); } - } - catch ( IOException ignore ) { + } catch ( IOException ignore ) { // ignore! } return null; diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/ratelimiting/util/SourcedFileTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/ratelimiting/util/SourcedFileTest.java index 99ab15cd05d..51b5a2162b5 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/ratelimiting/util/SourcedFileTest.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/ratelimiting/util/SourcedFileTest.java @@ -7,6 +7,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; class SourcedFileTest { public static final String EFFECTIVELY_EMPTY_FILE_CONTENTS = "\n \n"; @@ -31,6 +32,26 @@ void loadFile() { check( ODD_FILE_CONTENTS, "test-2" ); } + @Test + void loadStream() { + ByteArrayInputStream is = new ByteArrayInputStream(ODD_FILE_CONTENTS.getBytes()); + assertNotNull( SourcedFile.loadFile( is, "test-0" ) ); + } + + @Test + void loadEnv() { + assertNotNull( SourcedFile.locateAndLoadLocalFile("uaa-ratelimit.yml", SourcedFileTest.class.getClassLoader().getResource("uaa-ratelimit.yml").getPath().replace("uaa-ratelimit.yml", ""))); + assertNull( SourcedFile.locateAndLoadLocalFile("", SourcedFileTest.class.getClassLoader().getResource("uaa-ratelimit.yml").getPath().replace("uaa-ratelimit.yml", ""))); + assertNull( SourcedFile.locateAndLoadLocalFile("random", "/dev")); + assertNull( SourcedFile.locateAndLoadLocalFile("?", "/proc/1/fdinfo")); + } + + @Test + void loadStreamException() { + InputStream in = mock(InputStream.class); + assertThrows(IllegalStateException.class, () -> SourcedFile.loadFile( in, "" ) ); + } + private void check( String fileContents, String source ) { SourcedFile sourcedFile = SourcedFile.loadFile( inputStringFrom( fileContents ), source ); assertNotNull( sourcedFile, source ); diff --git a/server/src/test/resources/uaa-ratelimit.yml b/server/src/test/resources/uaa-ratelimit.yml new file mode 100644 index 00000000000..1d7ec4aef6c --- /dev/null +++ b/server/src/test/resources/uaa-ratelimit.yml @@ -0,0 +1,33 @@ +ratelimit: + loggingOption: AllCalls + credentialID: 'JWT:Claims+"sub"\s*:\s*"(.*?)"' + limiterMappings: + - name: AuthToken + withCallerRemoteAddressID: 50r/s + pathSelectors: + - "equals:/oauth/token" + - name: AuthAuthorize + withCallerRemoteAddressID: 50r/s + pathSelectors: + - "equals:/oauth/authorize" + - name: LoginPage + withCallerRemoteAddressID: 50r/1s + pathSelectors: + - "equals:/login" + - name: LoginDo + withCallerRemoteAddressID: 50r/s + pathSelectors: + - "equals:/login.do" + - name: InfoLimit + withCallerRemoteAddressID: 20r/s + pathSelectors: + - "equals:/info" + - name: SCIM + withCallerCredentialsID: 500r/s + pathSelectors: + - "startsWith:/Users" + - "startsWith:/Groups" + - name: EverythingElse + global: 200r/s + pathSelectors: + - "other" \ No newline at end of file