blob: ddf62f24de11e40a3e6cb54b169f6558b35428b1 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to you 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 org.apache.knox.gateway.util;
import org.apache.knox.gateway.config.GatewayConfig;
import org.easymock.EasyMock;
import org.junit.Test;
import javax.annotation.RegEx;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class WhitelistUtilsTest {
private static final List<String> LOCALHOST_NAMES = Arrays.asList("localhost", "127.0.0.1", "0:0:0:0:0:0:0:1", "::1");
@Test
public void testDefault() throws Exception {
String whitelist = doTestGetDispatchWhitelist(createMockGatewayConfig(Collections.emptyList(), null), "TEST");
assertNull("The test service role is not configured to honor the whitelist, so there should be none returned.",
whitelist);
}
/**
* KNOXSSO is implicitly included in the set of service roles for which the whitelist will be applied.
*/
@Test
public void testDefaultKnoxSSO() throws Exception {
String whitelist = doTestGetDispatchWhitelist(createMockGatewayConfig(Collections.emptyList(), null), "KNOXSSO");
assertNotNull(whitelist);
}
@Test
public void testDefaultForAffectedServiceRole() throws Exception {
final String serviceRole = "TEST";
GatewayConfig config = createMockGatewayConfig(Collections.singletonList(serviceRole), null);
// Check localhost by name
String whitelist = doTestGetDispatchWhitelist(config, serviceRole);
assertNotNull(whitelist);
assertEquals(shouldExpectLocalhost(), whitelist.contains("localhost"));
// Check localhost by loopback address
whitelist = doTestGetDispatchWhitelist(config, "127.0.0.1", serviceRole);
assertNotNull(whitelist);
assertEquals(shouldExpectLocalhost(), whitelist.contains("localhost"));
}
@Test
public void testDefaultDomainWhitelist() throws Exception {
final String serviceRole = "TEST";
String whitelist =
doTestGetDispatchWhitelist(createMockGatewayConfig(Collections.singletonList(serviceRole), null),
"host0.test.org",
serviceRole);
assertNotNull(whitelist);
assertTrue(whitelist.contains("\\.test\\.org"));
}
@Test
public void testDefaultDomainWhitelistLocalhostDisallowed() throws Exception {
String whitelist = doTestDeriveDomainBasedWhitelist("host.test.org");
assertNotNull(whitelist);
// localhost names should be excluded from the whitelist when the Knox host domain can be determined
for (String name : LOCALHOST_NAMES) {
assertFalse(RegExUtils.checkWhitelist(whitelist, name));
}
}
@Test
public void testDefaultDomainWhitelistWithXForwardedHost() throws Exception {
final String serviceRole = "TEST";
String whitelist =
doTestGetDispatchWhitelist(createMockGatewayConfig(Collections.singletonList(serviceRole), null),
"host0.test.org",
"lb.external.test.org",
serviceRole);
assertNotNull(whitelist);
assertTrue(whitelist.contains("\\.external\\.test\\.org"));
}
@Test
public void testDefaultDomainWhitelistWithXForwardedHostAndPort() throws Exception {
final String serviceRole = "TEST";
String whitelist =
doTestGetDispatchWhitelist(createMockGatewayConfig(Collections.singletonList(serviceRole), null),
"host0.test.org",
"lb.external.test.org:9090",
serviceRole);
assertNotNull(whitelist);
assertTrue(whitelist.contains("\\.external\\.test\\.org"));
assertFalse(whitelist.contains("9090"));
}
@Test
public void testConfiguredWhitelist() throws Exception {
final String serviceRole = "TEST";
final String WHITELIST = "^.*\\.my\\.domain\\.com.*$";
String whitelist =
doTestGetDispatchWhitelist(createMockGatewayConfig(Collections.singletonList(serviceRole), WHITELIST),
serviceRole);
assertNotNull(whitelist);
assertTrue(whitelist.equals(WHITELIST));
}
@Test
public void testExplicitlyConfiguredDefaultWhitelist() throws Exception {
final String serviceRole = "TEST";
final String WHITELIST = "DEFAULT";
String whitelist =
doTestGetDispatchWhitelist(createMockGatewayConfig(Collections.singletonList(serviceRole), WHITELIST),
serviceRole);
assertNotNull(whitelist);
assertEquals(shouldExpectLocalhost(),
RegExUtils.checkWhitelist(whitelist, "http://localhost:9099/"));
}
private static boolean shouldExpectLocalhost() throws Exception {
return InetAddress.getLocalHost().getCanonicalHostName().equalsIgnoreCase("localhost");
}
private String doTestGetDispatchWhitelist(GatewayConfig config, String serviceRole) {
return doTestGetDispatchWhitelist(config, "localhost", serviceRole);
}
private String doTestGetDispatchWhitelist(GatewayConfig config,
String serverName,
String serviceRole) {
return doTestGetDispatchWhitelist(config, serverName, null, serviceRole);
}
private String doTestGetDispatchWhitelist(GatewayConfig config,
String serverName,
String xForwardedHost,
String serviceRole) {
ServletContext sc = EasyMock.createNiceMock(ServletContext.class);
EasyMock.expect(sc.getAttribute("org.apache.knox.gateway.config")).andReturn(config).anyTimes();
EasyMock.replay(sc);
HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
if (xForwardedHost != null && !xForwardedHost.isEmpty()) {
EasyMock.expect(request.getHeader("X-Forwarded-Host")).andReturn(xForwardedHost).anyTimes();
}
EasyMock.expect(request.getAttribute("targetServiceRole")).andReturn(serviceRole).anyTimes();
EasyMock.expect(request.getServletContext()).andReturn(sc).anyTimes();
EasyMock.replay(request);
String result = null;
if (serverName != null && !serverName.isEmpty() && !isLocalhostServerName(serverName) && xForwardedHost == null) {
try {
result = doTestDeriveDomainBasedWhitelist(serverName);
} catch (Exception e) {
e.printStackTrace();
}
} else if (xForwardedHost != null && !xForwardedHost.isEmpty()) {
try {
Method method = WhitelistUtils.class.getDeclaredMethod("deriveDefaultDispatchWhitelist", HttpServletRequest.class);
method.setAccessible(true);
result = (String) method.invoke(null, request);
} catch (Exception e) {
e.printStackTrace();
}
} else {
result = WhitelistUtils.getDispatchWhitelist(request);
}
return result;
}
private static String doTestDeriveDomainBasedWhitelist(final String serverName) throws Exception {
Method method = WhitelistUtils.class.getDeclaredMethod("deriveDomainBasedWhitelist", String.class);
method.setAccessible(true);
return (String) method.invoke(null, serverName);
}
private static boolean isLocalhostServerName(final String serverName) {
return LOCALHOST_NAMES.contains(serverName.toLowerCase());
}
private static GatewayConfig createMockGatewayConfig(final List<String> serviceRoles, final String whitelist) {
GatewayConfig config = EasyMock.createNiceMock(GatewayConfig.class);
EasyMock.expect(config.getDispatchWhitelistServices()).andReturn(serviceRoles).anyTimes();
EasyMock.expect(config.getDispatchWhitelist()).andReturn(whitelist).anyTimes();
EasyMock.replay(config);
return config;
}
}