summaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2020-07-24 13:38:20 +0200
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2020-08-18 10:53:06 +0200
commitca57e9c2cf1b72701f3ed2d454f0d59c7f56a63a (patch)
tree6747eabeedec01ac294bcc66ef01adf02ec0a657 /config-model
parent9953983bbc43ebfbf62b353aa043543c7b3ef5c9 (diff)
Bind access control filter to all paths on port 4443
Exclude bindings with separate filter chain. Do not bind access control filter to port 4080. Simplify AccessControl interface to a 'configure()' method.
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/http/AccessControl.java107
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/HttpBuilder.java9
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java16
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/xml/AccessControlTest.java217
4 files changed, 133 insertions, 216 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/AccessControl.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/AccessControl.java
index 87c6d41c80d..4884c4f0277 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/AccessControl.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/AccessControl.java
@@ -3,22 +3,22 @@ package com.yahoo.vespa.model.container.http;
import com.yahoo.component.ComponentId;
import com.yahoo.component.ComponentSpecification;
+import com.yahoo.component.chain.dependencies.Dependencies;
+import com.yahoo.component.chain.model.ChainedComponentModel;
+import com.yahoo.container.bundle.BundleInstantiationSpecification;
import com.yahoo.vespa.model.container.ApplicationContainerCluster;
import com.yahoo.vespa.model.container.ContainerCluster;
import com.yahoo.vespa.model.container.component.BindingPattern;
import com.yahoo.vespa.model.container.component.FileStatusHandlerComponent;
import com.yahoo.vespa.model.container.component.Handler;
-import com.yahoo.vespa.model.container.component.Servlet;
import com.yahoo.vespa.model.container.component.SystemBindingPattern;
+import com.yahoo.vespa.model.container.component.chain.Chain;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
/**
* Helper class for http access control.
@@ -26,11 +26,15 @@ import java.util.stream.Stream;
* @author gjoranv
* @author bjorncs
*/
-public final class AccessControl {
+public class AccessControl {
public static final ComponentId ACCESS_CONTROL_CHAIN_ID = ComponentId.fromString("access-control-chain");
+ public static final ComponentId ACCESS_CONTROL_EXCLUDED_CHAIN_ID = ComponentId.fromString("access-control-excluded-chain");
- public static final List<String> UNPROTECTED_HANDLERS = List.of(
+ private static final int HOSTED_CONTAINER_PORT = 4443;
+
+ // Handlers that are excluded from access control
+ private static final List<String> EXCLUDED_HANDLERS = List.of(
FileStatusHandlerComponent.CLASS,
ContainerCluster.APPLICATION_STATUS_HANDLER_CLASS,
ContainerCluster.BINDINGS_OVERVIEW_HANDLER_CLASS,
@@ -40,13 +44,12 @@ public final class AccessControl {
ApplicationContainerCluster.PROMETHEUS_V1_HANDLER_CLASS
);
- public static final class Builder {
- private String domain;
+ public static class Builder {
+ private final String domain;
private boolean readEnabled = false;
private boolean writeEnabled = true;
private final Set<BindingPattern> excludeBindings = new LinkedHashSet<>();
private Collection<Handler<?>> handlers = Collections.emptyList();
- private Collection<Servlet> servlets = Collections.emptyList();
public Builder(String domain) {
this.domain = domain;
@@ -57,8 +60,8 @@ public final class AccessControl {
return this;
}
- public Builder writeEnabled(boolean writeEnalbed) {
- this.writeEnabled = writeEnalbed;
+ public Builder writeEnabled(boolean writeEnabled) {
+ this.writeEnabled = writeEnabled;
return this;
}
@@ -69,13 +72,11 @@ public final class AccessControl {
public Builder setHandlers(ApplicationContainerCluster cluster) {
this.handlers = cluster.getHandlers();
- this.servlets = cluster.getAllServlets();
return this;
}
public AccessControl build() {
- return new AccessControl(domain, writeEnabled, readEnabled,
- excludeBindings, servlets, handlers);
+ return new AccessControl(domain, writeEnabled, readEnabled, excludeBindings, handlers);
}
}
@@ -84,69 +85,75 @@ public final class AccessControl {
public final boolean writeEnabled;
private final Set<BindingPattern> excludedBindings;
private final Collection<Handler<?>> handlers;
- private final Collection<Servlet> servlets;
private AccessControl(String domain,
boolean writeEnabled,
boolean readEnabled,
Set<BindingPattern> excludedBindings,
- Collection<Servlet> servlets,
Collection<Handler<?>> handlers) {
this.domain = domain;
this.readEnabled = readEnabled;
this.writeEnabled = writeEnabled;
this.excludedBindings = Collections.unmodifiableSet(excludedBindings);
this.handlers = handlers;
- this.servlets = servlets;
}
- public List<FilterBinding> getBindings() {
- return Stream.concat(getHandlerBindings(), getServletBindings())
- .collect(Collectors.toCollection(ArrayList::new));
+ public void configure(Http http) {
+ http.setAccessControl(this);
+ addAccessControlFilterChain(http);
+ addAccessControlExcludedChain(http);
}
public static boolean hasHandlerThatNeedsProtection(ApplicationContainerCluster cluster) {
- return cluster.getHandlers().stream().anyMatch(AccessControl::handlerNeedsProtection);
- }
-
- private Stream<FilterBinding> getHandlerBindings() {
- return handlers.stream()
- .filter(this::shouldHandlerBeProtected)
- .flatMap(handler -> handler.getServerBindings().stream())
- .map(binding -> accessControlBinding(binding));
- }
-
- private Stream<FilterBinding> getServletBindings() {
- return servlets.stream()
- .filter(this::shouldServletBeProtected)
- .flatMap(AccessControl::servletBindings)
- .map(binding -> accessControlBinding(binding));
+ return cluster.getHandlers().stream()
+ .anyMatch(handler -> ! isExcludedHandler(handler) && hasNonMbusBinding(handler));
}
- private boolean shouldHandlerBeProtected(Handler<?> handler) {
- return ! isBuiltinGetOnly(handler)
- && handler.getServerBindings().stream().noneMatch(excludedBindings::contains);
+ private void addAccessControlFilterChain(Http http) {
+ http.getFilterChains().add(createChain(ACCESS_CONTROL_CHAIN_ID));
+ http.getBindings().addAll(List.of(createAccessControlBinding("/"), createAccessControlBinding("/*")));
}
- private static boolean isBuiltinGetOnly(Handler<?> handler) {
- return UNPROTECTED_HANDLERS.contains(handler.getClassId().getName());
+ private void addAccessControlExcludedChain(Http http) {
+ Chain<Filter> chain = createChain(ACCESS_CONTROL_EXCLUDED_CHAIN_ID);
+ chain.addInnerComponent(
+ new Filter(
+ new ChainedComponentModel(
+ new BundleInstantiationSpecification(
+ new ComponentSpecification("com.yahoo.jdisc.http.filter.security.misc.NoopFilter"),
+ null,
+ new ComponentSpecification("jdisc-security-filters")),
+ Dependencies.emptyDependencies())));
+ http.getFilterChains().add(chain);
+ for (BindingPattern excludedBinding : excludedBindings) {
+ http.getBindings().add(createAccessControlExcludedBinding(excludedBinding));
+ }
+ for (Handler<?> handler : handlers) {
+ if (isExcludedHandler(handler)) {
+ for (BindingPattern binding : handler.getServerBindings()) {
+ http.getBindings().add(createAccessControlExcludedBinding(binding));
+ }
+ }
+ }
}
- private boolean shouldServletBeProtected(Servlet servlet) {
- return servletBindings(servlet).noneMatch(excludedBindings::contains);
+ private static FilterBinding createAccessControlBinding(String path) {
+ return FilterBinding.create(
+ new ComponentSpecification(ACCESS_CONTROL_CHAIN_ID.stringValue()),
+ SystemBindingPattern.fromPortAndPath(Integer.toString(HOSTED_CONTAINER_PORT), path));
}
- private static FilterBinding accessControlBinding(BindingPattern binding) {
- return FilterBinding.create(new ComponentSpecification(ACCESS_CONTROL_CHAIN_ID.stringValue()), binding);
+ private static FilterBinding createAccessControlExcludedBinding(BindingPattern excludedBinding) {
+ BindingPattern rewrittenBinding = SystemBindingPattern.fromPortAndPath(
+ Integer.toString(HOSTED_CONTAINER_PORT), excludedBinding.path()); // only keep path from excluded binding
+ return FilterBinding.create(
+ new ComponentSpecification(ACCESS_CONTROL_EXCLUDED_CHAIN_ID.stringValue()),
+ rewrittenBinding);
}
- private static Stream<BindingPattern> servletBindings(Servlet servlet) {
- return Stream.of(SystemBindingPattern.fromHttpPath("/" + servlet.bindingPath));
- }
+ private static Chain<Filter> createChain(ComponentId id) { return new Chain<>(FilterChains.emptyChainSpec(id)); }
- private static boolean handlerNeedsProtection(Handler<?> handler) {
- return ! isBuiltinGetOnly(handler) && hasNonMbusBinding(handler);
- }
+ private static boolean isExcludedHandler(Handler<?> handler) { return EXCLUDED_HANDLERS.contains(handler.getClassId().getName()); }
private static boolean hasNonMbusBinding(Handler<?> handler) {
return handler.getServerBindings().stream().anyMatch(binding -> ! binding.scheme().equals("mbus"));
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/HttpBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/HttpBuilder.java
index 9d5fead7dfb..429cc45325b 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/HttpBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/HttpBuilder.java
@@ -14,7 +14,6 @@ import com.yahoo.vespa.model.builder.xml.dom.VespaDomBuilder;
import com.yahoo.vespa.model.container.ApplicationContainerCluster;
import com.yahoo.vespa.model.container.Container;
import com.yahoo.vespa.model.container.component.UserBindingPattern;
-import com.yahoo.vespa.model.container.component.chain.Chain;
import com.yahoo.vespa.model.container.http.AccessControl;
import com.yahoo.vespa.model.container.http.FilterBinding;
import com.yahoo.vespa.model.container.http.FilterChains;
@@ -26,8 +25,6 @@ import java.util.List;
import java.util.Optional;
import java.util.logging.Level;
-import static com.yahoo.vespa.model.container.http.AccessControl.ACCESS_CONTROL_CHAIN_ID;
-
/**
* @author Tony Vaagenes
* @author gjoranv
@@ -48,8 +45,6 @@ public class HttpBuilder extends VespaDomBuilder.DomConfigProducerBuilder<Http>
Element accessControlElem = XML.getChild(filteringElem, "access-control");
if (accessControlElem != null) {
accessControl = buildAccessControl(deployState, ancestor, accessControlElem);
- bindings.addAll(accessControl.getBindings());
- filterChains.add(new Chain<>(FilterChains.emptyChainSpec(ACCESS_CONTROL_CHAIN_ID)));
}
} else {
filterChains = new FilterChainsBuilder().newChainsInstance(ancestor);
@@ -57,8 +52,10 @@ public class HttpBuilder extends VespaDomBuilder.DomConfigProducerBuilder<Http>
Http http = new Http(filterChains);
http.getBindings().addAll(bindings);
- http.setAccessControl(accessControl);
http.setHttpServer(new JettyHttpServerBuilder().build(deployState, ancestor, spec));
+ if (accessControl != null) {
+ accessControl.configure(http);
+ }
return http;
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
index d11e0f9a891..1234a4ebc48 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
@@ -94,7 +94,6 @@ import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import static com.yahoo.vespa.model.container.http.AccessControl.ACCESS_CONTROL_CHAIN_ID;
import static java.util.logging.Level.WARNING;
/**
@@ -371,15 +370,12 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
if (http.getAccessControl().isPresent()) return; // access control added explicitly
AthenzDomain tenantDomain = deployState.getProperties().athenzDomain().orElse(null);
if (tenantDomain == null) return; // tenant domain not present, cannot add access control. this should eventually be a failure.
- AccessControl accessControl =
- new AccessControl.Builder(tenantDomain.value())
- .setHandlers(cluster)
- .readEnabled(false)
- .writeEnabled(false)
- .build();
- http.getFilterChains().add(new Chain<>(FilterChains.emptyChainSpec(ACCESS_CONTROL_CHAIN_ID)));
- http.setAccessControl(accessControl);
- http.getBindings().addAll(accessControl.getBindings());
+ new AccessControl.Builder(tenantDomain.value())
+ .setHandlers(cluster)
+ .readEnabled(false)
+ .writeEnabled(false)
+ .build()
+ .configure(http);
}
private Http buildHttp(DeployState deployState, ApplicationContainerCluster cluster, Element httpElement) {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/AccessControlTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/AccessControlTest.java
index e054698d40b..e6e4367c4a2 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/AccessControlTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/AccessControlTest.java
@@ -11,53 +11,39 @@ import com.yahoo.vespa.model.container.ContainerCluster;
import com.yahoo.vespa.model.container.component.BindingPattern;
import com.yahoo.vespa.model.container.component.SystemBindingPattern;
import com.yahoo.vespa.model.container.component.UserBindingPattern;
+import com.yahoo.vespa.model.container.component.chain.Chain;
import com.yahoo.vespa.model.container.http.AccessControl;
-import com.yahoo.vespa.model.container.http.FilterBinding;
+import com.yahoo.vespa.model.container.http.Filter;
+import com.yahoo.vespa.model.container.http.FilterChains;
import com.yahoo.vespa.model.container.http.Http;
import com.yahoo.vespa.model.container.http.xml.HttpBuilder;
-import com.yahoo.vespa.model.container.jersey.Jersey2Servlet;
import org.junit.Test;
import org.w3c.dom.Element;
import java.util.Collection;
-import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
-import static com.yahoo.config.model.test.TestUtil.joinLines;
import static com.yahoo.vespa.defaults.Defaults.getDefaults;
import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* @author gjoranv
+ * @author bjorncs
*/
public class AccessControlTest extends ContainerModelBuilderTestBase {
- private static final Set<BindingPattern> REQUIRED_HANDLER_BINDINGS =
- Set.of(
- UserBindingPattern.fromHttpPath("/custom-handler/*"),
- SystemBindingPattern.fromHttpPath("/search/*"),
- SystemBindingPattern.fromHttpPath("/document/v1/*"),
- SystemBindingPattern.fromHttpPath("/reserved-for-internal-use/feedapi"));
-
- private static final Set<BindingPattern> FORBIDDEN_HANDLER_BINDINGS =
- Set.of(
- SystemBindingPattern.fromHttpPath("/ApplicationStatus"),
- SystemBindingPattern.fromHttpPath("/status.html"),
- SystemBindingPattern.fromHttpPath("/statistics/"),
- SystemBindingPattern.fromHttpPath("/state/v1"),
- SystemBindingPattern.fromHttpPath("/"));
-
@Test
- public void access_control_filter_chain_is_set_up() {
+ public void access_control_filter_chains_are_set_up() {
Element clusterElem = DomBuilderTest.parse(
" <http>",
" <filtering>",
@@ -68,7 +54,15 @@ public class AccessControlTest extends ContainerModelBuilderTestBase {
Http http = new HttpBuilder().build(root.getDeployState(), root, clusterElem);
root.freezeModelTopology();
- assertTrue(http.getFilterChains().hasChain(AccessControl.ACCESS_CONTROL_CHAIN_ID));
+ FilterChains filterChains = http.getFilterChains();
+ assertTrue(filterChains.hasChain(AccessControl.ACCESS_CONTROL_CHAIN_ID));
+ assertTrue(filterChains.hasChain(AccessControl.ACCESS_CONTROL_EXCLUDED_CHAIN_ID));
+
+ Chain<Filter> excludedChain = filterChains.allChains().getComponent(AccessControl.ACCESS_CONTROL_EXCLUDED_CHAIN_ID);
+ Collection<Filter> innerComponents = excludedChain.getInnerComponents();
+ assertThat(innerComponents, hasSize(1));
+ String accessControlExcludedChain = innerComponents.iterator().next().getClassId().stringValue();
+ assertEquals("com.yahoo.jdisc.http.filter.security.misc.NoopFilter", accessControlExcludedChain);
}
@Test
@@ -120,129 +114,66 @@ public class AccessControlTest extends ContainerModelBuilderTestBase {
}
@Test
- public void access_control_filter_chain_has_correct_handler_bindings() {
- Element clusterElem = DomBuilderTest.parse(
+ public void access_control_excluded_filter_chain_has_all_bindings_from_excluded_handlers() {
+ Http http = createModelAndGetHttp(
"<container version='1.0'>",
- " <search/>",
- " <document-api/>",
- " <handler id='custom.Handler'>",
- " <binding>http://*/custom-handler/*</binding>",
- " </handler>",
" <http>",
" <filtering>",
- " <access-control domain='foo' />",
+ " <access-control/>",
" </filtering>",
" </http>",
"</container>");
- Http http = getHttp(clusterElem);
-
- Set<BindingPattern> foundRequiredBindings = REQUIRED_HANDLER_BINDINGS.stream()
- .filter(requiredBinding -> containsBinding(http.getBindings(), requiredBinding))
- .collect(Collectors.toSet());
- Set<BindingPattern> missingRequiredBindings = new HashSet<>(REQUIRED_HANDLER_BINDINGS);
- missingRequiredBindings.removeAll(foundRequiredBindings);
- assertTrue("Access control chain was not bound to: " + prettyString(missingRequiredBindings),
- missingRequiredBindings.isEmpty());
-
- FORBIDDEN_HANDLER_BINDINGS.forEach(forbiddenBinding -> {
- http.getBindings().forEach(
- binding -> assertNotEquals("Access control chain was bound to: " + binding.binding(), binding.binding(), forbiddenBinding));
- });
+ Set<String> actualBindings = getFilterBindings(http, AccessControl.ACCESS_CONTROL_EXCLUDED_CHAIN_ID);
+ assertThat(actualBindings, containsInAnyOrder(
+ "http://*:4443/ApplicationStatus",
+ "http://*:4443/status.html",
+ "http://*:4443/state/v1",
+ "http://*:4443/state/v1/*",
+ "http://*:4443/prometheus/v1",
+ "http://*:4443/prometheus/v1/*",
+ "http://*:4443/metrics/v2",
+ "http://*:4443/metrics/v2/*",
+ "http://*:4443/"));
}
@Test
- public void handler_can_be_excluded_by_excluding_one_of_its_bindings() {
- BindingPattern notExcludedBinding = UserBindingPattern.fromHttpPath("/custom-handler/*");
- BindingPattern excludedBinding = SystemBindingPattern.fromHttpPath("/excluded/*");
- Element clusterElem = DomBuilderTest.parse(
+ public void access_control_excluded_filter_chain_has_user_provided_excluded_bindings() {
+ Http http = createModelAndGetHttp(
"<container version='1.0'>",
- httpWithExcludedBinding(excludedBinding),
- " <handler id='custom.Handler'>",
- " <binding>" + notExcludedBinding.patternString() + "</binding>",
- " <binding>" + excludedBinding.patternString() + "</binding>",
- " </handler>",
- "</container>");
-
- Http http = getHttp(clusterElem);
- assertFalse("Excluded binding was not removed.",
- containsBinding(http.getBindings(), excludedBinding));
- assertFalse("Not all bindings of an excluded handler were removed.",
- containsBinding(http.getBindings(), notExcludedBinding));
-
- }
-
- @Test
- public void access_control_filter_chain_has_all_servlet_bindings() {
- final String servletPath = "servlet/path";
- final String restApiPath = "api/v0";
- Element clusterElem = DomBuilderTest.parse(
- "<container version='1.0'>",
- " <servlet id='foo' class='bar' bundle='baz'>",
- " <path>" + servletPath + "</path>",
- " </servlet>",
- " <rest-api jersey2='true' path='" + restApiPath + "' />",
" <http>",
+ " <handler id='custom.Handler'>",
+ " <binding>http://*/custom-handler/*</binding>",
+ " </handler>",
" <filtering>",
- " <access-control domain='foo' />",
+ " <access-control>",
+ " <exclude>",
+ " <binding>http://*/custom-handler/*</binding>",
+ " <binding>http://*/search/*</binding>",
+ " </exclude>",
+ " </access-control>",
" </filtering>",
" </http>",
"</container>");
- Http http = getHttp(clusterElem);
-
- Set<BindingPattern> requiredBindings = Set.of(
- SystemBindingPattern.fromHttpPath("/" + servletPath),
- SystemBindingPattern.fromHttpPath("/" + restApiPath + "/*"));
- Set<BindingPattern> missingRequiredBindings = requiredBindings.stream()
- .filter(requiredBinding -> ! containsBinding(http.getBindings(), requiredBinding))
- .collect(Collectors.toSet());
-
- assertTrue("Access control chain was not bound to: " + prettyString(missingRequiredBindings),
- missingRequiredBindings.isEmpty());
+ Set<String> actualBindings = getFilterBindings(http, AccessControl.ACCESS_CONTROL_EXCLUDED_CHAIN_ID);
+ assertThat(actualBindings, hasItems("http://*:4443/custom-handler/*", "http://*:4443/search/*", "http://*:4443/status.html"));
}
@Test
- public void servlet_can_be_excluded_by_excluding_one_of_its_bindings() {
- String servletPath = "servlet/path";
- BindingPattern notExcludedBinding = SystemBindingPattern.fromPattern("http://*:8081/" + servletPath);
- BindingPattern excludedBinding = SystemBindingPattern.fromPattern("http://*:8080/" + servletPath);
- Element clusterElem = DomBuilderTest.parse(
+ public void access_control_filter_chain_contains_catchall_bindings() {
+ Http http = createModelAndGetHttp(
"<container version='1.0'>",
- httpWithExcludedBinding(excludedBinding),
- " <servlet id='foo' class='bar' bundle='baz'>",
- " <path>" + servletPath + "</path>",
- " </servlet>",
- "</container>");
-
- Http http = getHttp(clusterElem);
- assertFalse("Excluded binding was not removed.",
- containsBinding(http.getBindings(), excludedBinding));
- assertFalse("Not all bindings of an excluded servlet were removed.",
- containsBinding(http.getBindings(), notExcludedBinding));
-
- }
-
- @Test
- public void rest_api_can_be_excluded_by_excluding_one_of_its_bindings() {
- String restApiPath = "api/v0";
- BindingPattern notExcludedBinding = SystemBindingPattern.fromPattern("http://*:8081/" + restApiPath + Jersey2Servlet.BINDING_SUFFIX);
- BindingPattern excludedBinding = SystemBindingPattern.fromPattern("http://*:8080/" + restApiPath + Jersey2Servlet.BINDING_SUFFIX);;
- Element clusterElem = DomBuilderTest.parse(
- "<container version='1.0'>",
- httpWithExcludedBinding(excludedBinding),
- " <rest-api jersey2='true' path='" + restApiPath + "' />",
+ " <http>",
+ " <filtering>",
+ " <access-control/>",
+ " </filtering>",
+ " </http>",
"</container>");
-
- Http http = getHttp(clusterElem);
- assertFalse("Excluded binding was not removed.",
- containsBinding(http.getBindings(), excludedBinding));
- assertFalse("Not all bindings of an excluded rest-api were removed.",
- containsBinding(http.getBindings(), notExcludedBinding));
-
+ Set<String> actualBindings = getFilterBindings(http, AccessControl.ACCESS_CONTROL_CHAIN_ID);
+ assertThat(actualBindings, containsInAnyOrder("http://*:4443/", "http://*:4443/*"));
}
-
@Test
public void access_control_is_implicitly_added_for_hosted_apps() {
Element clusterElem = DomBuilderTest.parse(
@@ -293,36 +224,22 @@ public class AccessControlTest extends ContainerModelBuilderTestBase {
assertThat(http.getFilterChains().hasChain(ComponentId.fromString("myChain")), is(true));
}
- private static String prettyString(Set<BindingPattern> missingRequiredBindings) {
- return missingRequiredBindings.stream().map(BindingPattern::patternString).collect(Collectors.joining(", "));
- }
-
- private String httpWithExcludedBinding(BindingPattern excludedBinding) {
- return joinLines(
- " <http>",
- " <filtering>",
- " <access-control domain='foo'>",
- " <exclude>",
- " <binding>" + excludedBinding.patternString() + "</binding>",
- " </exclude>",
- " </access-control>",
- " </filtering>",
- " </http>");
+ private Http createModelAndGetHttp(String... servicesXml) {
+ AthenzDomain tenantDomain = AthenzDomain.from("my-tenant-domain");
+ DeployState state = new DeployState.Builder().properties(
+ new TestProperties()
+ .setAthenzDomain(tenantDomain)
+ .setHostedVespa(true))
+ .build();
+ createModel(root, state, null, DomBuilderTest.parse(servicesXml));
+ return ((ApplicationContainer) root.getProducer("container/container.0")).getHttp();
}
- private Http getHttp(Element clusterElem) {
- createModel(root, clusterElem);
- ContainerCluster cluster = (ContainerCluster) root.getChildren().get("container");
- Http http = cluster.getHttp();
- assertNotNull(http);
- return http;
+ private static Set<String> getFilterBindings(Http http, ComponentId filerChain) {
+ return http.getBindings().stream()
+ .filter(binding -> binding.filterId().toId().equals(filerChain))
+ .map(binding -> binding.binding().patternString())
+ .collect(Collectors.toSet());
}
- private boolean containsBinding(Collection<FilterBinding> bindings, BindingPattern binding) {
- for (FilterBinding b : bindings) {
- if (b.binding().equals(binding))
- return true;
- }
- return false;
- }
}