Update discovery endpoint to respect AccessLevel

Change `CloudFoundryDiscoveryMvcEndpoint` so that `AccessLevel` rights
are consulted so that only accessible links are returned.

See gh-7108
pull/7387/head
Madhura Bhave 8 years ago committed by Phillip Webb
parent 340f1d5574
commit 1005feb27d

@ -39,6 +39,8 @@ enum AccessLevel {
*/ */
FULL; FULL;
private static final String REQUEST_ATTRIBUTE = "cloudFoundryAccessLevel";
private final List<String> endpointPaths; private final List<String> endpointPaths;
AccessLevel(String... endpointPaths) { AccessLevel(String... endpointPaths) {
@ -55,7 +57,11 @@ enum AccessLevel {
} }
public void put(HttpServletRequest request) { public void put(HttpServletRequest request) {
request.setAttribute("cloudFoundryAccessLevel", this); request.setAttribute(REQUEST_ATTRIBUTE, this);
}
public static AccessLevel get(HttpServletRequest request) {
return (AccessLevel) request.getAttribute(REQUEST_ATTRIBUTE);
} }
} }

@ -54,8 +54,12 @@ class CloudFoundryDiscoveryMvcEndpoint extends AbstractMvcEndpoint {
url = url.substring(0, url.length() - 1); url = url.substring(0, url.length() - 1);
} }
links.put("self", Link.withHref(url)); links.put("self", Link.withHref(url));
AccessLevel accessLevel = AccessLevel.get(request);
for (NamedMvcEndpoint endpoint : this.endpoints) { for (NamedMvcEndpoint endpoint : this.endpoints) {
links.put(endpoint.getName(), Link.withHref(url + "/" + endpoint.getName())); if (accessLevel != null && accessLevel.isAccessAllowed(endpoint.getPath())) {
links.put(endpoint.getName(),
Link.withHref(url + "/" + endpoint.getName()));
}
} }
return Collections.singletonMap("_links", links); return Collections.singletonMap("_links", links);
} }

@ -39,12 +39,14 @@ public class CloudFoundryDiscoveryMvcEndpointTests {
private CloudFoundryDiscoveryMvcEndpoint endpoint; private CloudFoundryDiscoveryMvcEndpoint endpoint;
private Set<NamedMvcEndpoint> endpoints;
@Before @Before
public void setup() { public void setup() {
NamedMvcEndpoint testMvcEndpoint = new TestMvcEndpoint(new TestEndpoint("a")); NamedMvcEndpoint endpoint = new TestMvcEndpoint(new TestEndpoint("a"));
Set<NamedMvcEndpoint> endpoints = new LinkedHashSet<NamedMvcEndpoint>(); this.endpoints = new LinkedHashSet<NamedMvcEndpoint>();
endpoints.add(testMvcEndpoint); this.endpoints.add(endpoint);
this.endpoint = new CloudFoundryDiscoveryMvcEndpoint(endpoints); this.endpoint = new CloudFoundryDiscoveryMvcEndpoint(this.endpoints);
} }
@Test @Test
@ -56,6 +58,7 @@ public class CloudFoundryDiscoveryMvcEndpointTests {
public void linksResponseWhenRequestUriHasNoTrailingSlash() throws Exception { public void linksResponseWhenRequestUriHasNoTrailingSlash() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("GET", MockHttpServletRequest request = new MockHttpServletRequest("GET",
"/cloudfoundryapplication"); "/cloudfoundryapplication");
AccessLevel.FULL.put(request);
Map<String, CloudFoundryDiscoveryMvcEndpoint.Link> links = this.endpoint Map<String, CloudFoundryDiscoveryMvcEndpoint.Link> links = this.endpoint
.links(request).get("_links"); .links(request).get("_links");
assertThat(links.get("self").getHref()) assertThat(links.get("self").getHref())
@ -68,6 +71,7 @@ public class CloudFoundryDiscoveryMvcEndpointTests {
public void linksResponseWhenRequestUriHasTrailingSlash() throws Exception { public void linksResponseWhenRequestUriHasTrailingSlash() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("GET", MockHttpServletRequest request = new MockHttpServletRequest("GET",
"/cloudfoundryapplication/"); "/cloudfoundryapplication/");
AccessLevel.FULL.put(request);
Map<String, CloudFoundryDiscoveryMvcEndpoint.Link> links = this.endpoint Map<String, CloudFoundryDiscoveryMvcEndpoint.Link> links = this.endpoint
.links(request).get("_links"); .links(request).get("_links");
assertThat(links.get("self").getHref()) assertThat(links.get("self").getHref())
@ -76,6 +80,23 @@ public class CloudFoundryDiscoveryMvcEndpointTests {
.isEqualTo("http://localhost/cloudfoundryapplication/a"); .isEqualTo("http://localhost/cloudfoundryapplication/a");
} }
@Test
public void linksResponseWhenRequestHasAccessLevelRestricted() throws Exception {
NamedMvcEndpoint testHealthMvcEndpoint = new TestMvcEndpoint(
new TestEndpoint("health"));
this.endpoints.add(testHealthMvcEndpoint);
MockHttpServletRequest request = new MockHttpServletRequest("GET",
"/cloudfoundryapplication/");
AccessLevel.RESTRICTED.put(request);
Map<String, CloudFoundryDiscoveryMvcEndpoint.Link> links = this.endpoint
.links(request).get("_links");
assertThat(links.get("self").getHref())
.isEqualTo("http://localhost/cloudfoundryapplication");
assertThat(links.get("health").getHref())
.isEqualTo("http://localhost/cloudfoundryapplication/health");
assertThat(links.get("a")).isNull();
}
private static class TestEndpoint extends AbstractEndpoint<Object> { private static class TestEndpoint extends AbstractEndpoint<Object> {
TestEndpoint(String id) { TestEndpoint(String id) {

Loading…
Cancel
Save