Update discovery endpoint to respect AccessLevel

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

See gh-7108
This commit is contained in:
Madhura Bhave 2016-11-03 11:09:00 -07:00 committed by Phillip Webb
parent 340f1d5574
commit 1005feb27d
3 changed files with 37 additions and 6 deletions

View File

@ -39,6 +39,8 @@ enum AccessLevel {
*/
FULL;
private static final String REQUEST_ATTRIBUTE = "cloudFoundryAccessLevel";
private final List<String> endpointPaths;
AccessLevel(String... endpointPaths) {
@ -55,7 +57,11 @@ enum AccessLevel {
}
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);
}
}

View File

@ -54,8 +54,12 @@ class CloudFoundryDiscoveryMvcEndpoint extends AbstractMvcEndpoint {
url = url.substring(0, url.length() - 1);
}
links.put("self", Link.withHref(url));
AccessLevel accessLevel = AccessLevel.get(request);
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);
}

View File

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