Skip to content

Commit

Permalink
Add some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikos410 committed Oct 14, 2024
1 parent 32273dc commit 90b7a44
Show file tree
Hide file tree
Showing 8 changed files with 624 additions and 7 deletions.
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@
<version>${keycloak.version}</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.11.2</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ public boolean matchCondition(AuthenticationFlowContext context) {

final ConditionalClientIpAddressAuthenticatorConfig config =
new ConditionalClientIpAddressAuthenticatorConfig(context.getAuthenticatorConfig());
return matchCondition(context, config);
}

// package-private for testing
boolean matchCondition(AuthenticationFlowContext context, ConditionalClientIpAddressAuthenticatorConfig config) {

final Optional<IPAddress> clientIpAddress = getClientIpAddress(context, config);

if (clientIpAddress.isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,20 @@ class ConditionalClientIpAddressAuthenticatorConfig {

private static final Logger LOG = Logger.getLogger(ConditionalClientIpAddressAuthenticatorConfig.class);

final Set<IPAddressRange> ipRanges;
final boolean exclude;
final boolean useForwardedHeader;
final String forwardedHeaderName;
final int trustedProxiesCount;
private Set<IPAddressRange> ipRanges;
private boolean exclude;
private boolean useForwardedHeader;
private String forwardedHeaderName;
private int trustedProxiesCount;

public ConditionalClientIpAddressAuthenticatorConfig(AuthenticatorConfigModel configModel) {
ConditionalClientIpAddressAuthenticatorConfig() {
}

ConditionalClientIpAddressAuthenticatorConfig(AuthenticatorConfigModel configModel) {
this(configModel.getConfig());
}

public ConditionalClientIpAddressAuthenticatorConfig(Map<String, String> configMap) {
ConditionalClientIpAddressAuthenticatorConfig(Map<String, String> configMap) {
this.ipRanges = getConfiguredIpRanges(configMap);
this.exclude = Boolean.parseBoolean(configMap.get(CONF_EXCLUDE));
this.useForwardedHeader = Boolean.parseBoolean(configMap.get(CONF_USE_FORWARDED_HEADER));
Expand Down Expand Up @@ -86,19 +89,47 @@ public Set<IPAddressRange> getIpRanges() {
return ipRanges;
}

public void setIpRanges(Set<IPAddressRange> ipRanges) {
this.ipRanges = ipRanges;
}

public void setIpRanges(String... ipRanges) {
this.ipRanges = Arrays.stream(ipRanges)
.map(this::parseIpAddress)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toSet());
}

public boolean isExclude() {
return exclude;
}

public void setExclude(boolean exclude) {
this.exclude = exclude;
}

public boolean isUseForwardedHeader() {
return useForwardedHeader;
}

public void setUseForwardedHeader(boolean useForwardedHeader) {
this.useForwardedHeader = useForwardedHeader;
}

public String getForwardedHeaderName() {
return forwardedHeaderName;
}

public void setForwardedHeaderName(String forwardedHeaderName) {
this.forwardedHeaderName = forwardedHeaderName;
}

public int getTrustedProxiesCount() {
return trustedProxiesCount;
}

public void setTrustedProxiesCount(int trustedProxiesCount) {
this.trustedProxiesCount = trustedProxiesCount;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package org.keycloak.authentication.authenticators.conditional;

import org.junit.jupiter.api.Test;
import org.keycloak.authentication.AuthenticationFlowContext;
import org.keycloak.authentication.authenticators.conditional.util.TestAuthenticationFlowContext;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static java.util.Arrays.asList;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

class ConditionalClientIpAddressAuthenticatorTest {

final ConditionalClientIpAddressAuthenticator conditionalClientIpAddressAuthenticator = ConditionalClientIpAddressAuthenticator.SINGLETON;

@Test
void testAccessGrantedWithoutForwardedHeader() {

final ConditionalClientIpAddressAuthenticatorConfig config = new ConditionalClientIpAddressAuthenticatorConfig();
config.setIpRanges("1.2.3.0/24", "4.5.0.0/16");
config.setExclude(false);

config.setUseForwardedHeader(false);
config.setForwardedHeaderName("X-Forwarded-For");
config.setTrustedProxiesCount(1);

testAccessGranted(config, "1.2.3.4", "X-Forwarded-For", "7.8.9.0");
}

@Test
void testAccessDeniedWithoutForwardedHeader() {

final ConditionalClientIpAddressAuthenticatorConfig config = new ConditionalClientIpAddressAuthenticatorConfig();
config.setIpRanges("1.2.3.0/24", "4.5.0.0/16");
config.setExclude(false);

config.setUseForwardedHeader(false);
config.setForwardedHeaderName("X-Forwarded-For");
config.setTrustedProxiesCount(1);

testAccessDenied(config, "7.8.9.0", "X-Forwarded-For", "1.2.3.4");
}

@Test
void testAccessGrantedWithForwardedHeader() {

final ConditionalClientIpAddressAuthenticatorConfig config = new ConditionalClientIpAddressAuthenticatorConfig();
config.setIpRanges("1.2.3.0/24", "4.5.0.0/16");
config.setExclude(false);

config.setUseForwardedHeader(true);
config.setForwardedHeaderName("X-Forwarded-For");
config.setTrustedProxiesCount(1);

testAccessGranted(config, "7.8.9.0", "X-Forwarded-For", "1.2.3.4");
}

@Test
void testAccessDeniedWithForwardedHeader() {

final ConditionalClientIpAddressAuthenticatorConfig config = new ConditionalClientIpAddressAuthenticatorConfig();
config.setIpRanges("1.2.3.0/24", "4.5.0.0/16");
config.setExclude(false);

config.setUseForwardedHeader(true);
config.setForwardedHeaderName("X-Forwarded-For");
config.setTrustedProxiesCount(1);

testAccessDenied(config, "1.2.3.4", "X-Forwarded-For", "7.8.9.0");
}

@Test
void testUntrustedIpsInForwardedHeaderIgnored() {

final ConditionalClientIpAddressAuthenticatorConfig config = new ConditionalClientIpAddressAuthenticatorConfig();
config.setIpRanges("1.2.3.0/24", "4.5.0.0/16");
config.setExclude(false);

config.setUseForwardedHeader(true);
config.setForwardedHeaderName("X-Forwarded-For");
config.setTrustedProxiesCount(1);

testAccessDenied(config, "1.2.3.4", "X-Forwarded-For", "1.2.3.4, 7.8.9.0");
}

@Test
void testUntrustedIpsInForwardedHeaderIgnoredMultipleHeaders() {

final ConditionalClientIpAddressAuthenticatorConfig config = new ConditionalClientIpAddressAuthenticatorConfig();
config.setIpRanges("1.2.3.0/24", "4.5.0.0/16");
config.setExclude(false);

config.setUseForwardedHeader(true);
config.setForwardedHeaderName("X-Forwarded-For");
config.setTrustedProxiesCount(2);

testAccessGranted(config, "1.2.3.4", "X-Forwarded-For", "5.6.7.0", "1.2.3.4, 7.8.9.0");
}

@Test
void testAccessDeniedCustomHeaderMissing() {

final ConditionalClientIpAddressAuthenticatorConfig config = new ConditionalClientIpAddressAuthenticatorConfig();
config.setIpRanges("1.2.3.0/24", "4.5.0.0/16");
config.setExclude(false);

config.setUseForwardedHeader(true);
config.setForwardedHeaderName("X-Forwarded-Custom");
config.setTrustedProxiesCount(1);

testAccessDenied(config, "4.5.6.7", "X-Forwarded-For", "1.2.3.4");
}

private void testAccessGranted(ConditionalClientIpAddressAuthenticatorConfig config, String clientIp, String forwardedHeaderName, String... forwardedHeaderValues) {

final boolean accessGranted = test(config, clientIp, forwardedHeaderName, forwardedHeaderValues);
assertTrue(accessGranted);
}

private void testAccessDenied(ConditionalClientIpAddressAuthenticatorConfig config, String clientIp, String forwardedHeaderName, String... forwardedHeaderValues) {

final boolean accessGranted = test(config, clientIp, forwardedHeaderName, forwardedHeaderValues);
assertFalse(accessGranted);
}

private boolean test(ConditionalClientIpAddressAuthenticatorConfig config, String clientIp, String forwardedHeaderName, String... forwardedHeaderValues) {
final Map<String, List<String>> headers = new HashMap<>();
headers.put(forwardedHeaderName, asList(forwardedHeaderValues));

final AuthenticationFlowContext context = new TestAuthenticationFlowContext(clientIp, headers);
return conditionalClientIpAddressAuthenticator.matchCondition(context, config);
}

}
Loading

0 comments on commit 90b7a44

Please sign in to comment.