Merge branch '2.7.x' into 3.0.x

Closes gh-38364
This commit is contained in:
Andy Wilkinson 2023-11-15 15:57:39 +00:00
commit ff555c5ceb
2 changed files with 36 additions and 35 deletions

View File

@ -75,22 +75,23 @@ import static org.mockito.Mockito.mock;
*/
class CloudFoundryWebFluxEndpointIntegrationTests {
private static final ReactiveTokenValidator tokenValidator = mock(ReactiveTokenValidator.class);
private final ReactiveTokenValidator tokenValidator = mock(ReactiveTokenValidator.class);
private static final ReactiveCloudFoundrySecurityService securityService = mock(
ReactiveCloudFoundrySecurityService.class);
private final ReactiveCloudFoundrySecurityService securityService = mock(ReactiveCloudFoundrySecurityService.class);
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner(
AnnotationConfigReactiveWebServerApplicationContext::new)
.withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class, HttpHandlerAutoConfiguration.class,
ReactiveWebServerFactoryAutoConfiguration.class))
.withUserConfiguration(TestEndpointConfiguration.class)
.withBean(ReactiveTokenValidator.class, () -> this.tokenValidator)
.withBean(ReactiveCloudFoundrySecurityService.class, () -> this.securityService)
.withPropertyValues("server.port=0");
@Test
void operationWithSecurityInterceptorForbidden() {
given(tokenValidator.validate(any())).willReturn(Mono.empty());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication/test")
.accept(MediaType.APPLICATION_JSON)
@ -102,8 +103,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
@Test
void operationWithSecurityInterceptorSuccess() {
given(tokenValidator.validate(any())).willReturn(Mono.empty());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication/test")
.accept(MediaType.APPLICATION_JSON)
@ -131,8 +132,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
@Test
void linksToOtherEndpointsWithFullAccess() {
given(tokenValidator.validate(any())).willReturn(Mono.empty());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
@ -169,7 +170,7 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
void linksToOtherEndpointsForbidden() {
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
"invalid-token");
willThrow(exception).given(tokenValidator).validate(any());
willThrow(exception).given(this.tokenValidator).validate(any());
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
@ -181,8 +182,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
@Test
void linksToOtherEndpointsWithRestrictedAccess() {
given(tokenValidator.validate(any())).willReturn(Mono.empty());
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
this.contextRunner.run(withWebTestClient((client) -> client.get()
.uri("/cfApplication")
.accept(MediaType.APPLICATION_JSON)
@ -232,7 +233,8 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
static class CloudFoundryReactiveConfiguration {
@Bean
CloudFoundrySecurityInterceptor interceptor() {
CloudFoundrySecurityInterceptor interceptor(ReactiveTokenValidator tokenValidator,
ReactiveCloudFoundrySecurityService securityService) {
return new CloudFoundrySecurityInterceptor(tokenValidator, securityService, "app-id");
}

View File

@ -43,6 +43,7 @@ import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.ApplicationContext;
@ -70,13 +71,13 @@ import static org.mockito.Mockito.mock;
*/
class CloudFoundryMvcWebEndpointIntegrationTests {
private static final TokenValidator tokenValidator = mock(TokenValidator.class);
private final TokenValidator tokenValidator = mock(TokenValidator.class);
private static final CloudFoundrySecurityService securityService = mock(CloudFoundrySecurityService.class);
private final CloudFoundrySecurityService securityService = mock(CloudFoundrySecurityService.class);
@Test
void operationWithSecurityInterceptorForbidden() {
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
load(TestEndpointConfiguration.class,
(client) -> client.get()
.uri("/cfApplication/test")
@ -89,7 +90,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
@Test
void operationWithSecurityInterceptorSuccess() {
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
load(TestEndpointConfiguration.class,
(client) -> client.get()
.uri("/cfApplication/test")
@ -119,7 +120,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
@Test
void linksToOtherEndpointsWithFullAccess() {
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
load(TestEndpointConfiguration.class,
(client) -> client.get()
.uri("/cfApplication")
@ -157,7 +158,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
void linksToOtherEndpointsForbidden() {
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
"invalid-token");
willThrow(exception).given(tokenValidator).validate(any());
willThrow(exception).given(this.tokenValidator).validate(any());
load(TestEndpointConfiguration.class,
(client) -> client.get()
.uri("/cfApplication")
@ -170,7 +171,7 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
@Test
void linksToOtherEndpointsWithRestrictedAccess() {
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
load(TestEndpointConfiguration.class,
(client) -> client.get()
.uri("/cfApplication")
@ -198,26 +199,23 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
.doesNotExist());
}
private AnnotationConfigServletWebServerApplicationContext createApplicationContext(Class<?>... config) {
return new AnnotationConfigServletWebServerApplicationContext(config);
private void load(Class<?> configuration, Consumer<WebTestClient> clientConsumer) {
BiConsumer<ApplicationContext, WebTestClient> consumer = (context, client) -> clientConsumer.accept(client);
new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new)
.withUserConfiguration(configuration, CloudFoundryMvcConfiguration.class)
.withBean(TokenValidator.class, () -> this.tokenValidator)
.withBean(CloudFoundrySecurityService.class, () -> this.securityService)
.run((context) -> consumer.accept(context, WebTestClient.bindToServer()
.baseUrl("http://localhost:" + getPort(
(AnnotationConfigServletWebServerApplicationContext) context.getSourceApplicationContext()))
.responseTimeout(Duration.ofMinutes(5))
.build()));
}
private int getPort(AnnotationConfigServletWebServerApplicationContext context) {
return context.getWebServer().getPort();
}
private void load(Class<?> configuration, Consumer<WebTestClient> clientConsumer) {
BiConsumer<ApplicationContext, WebTestClient> consumer = (context, client) -> clientConsumer.accept(client);
try (AnnotationConfigServletWebServerApplicationContext context = createApplicationContext(configuration,
CloudFoundryMvcConfiguration.class)) {
consumer.accept(context,
WebTestClient.bindToServer()
.baseUrl("http://localhost:" + getPort(context))
.responseTimeout(Duration.ofMinutes(5))
.build());
}
}
private String mockAccessToken() {
return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b3B0YWwu"
+ "Y29tIiwiZXhwIjoxNDI2NDIwODAwLCJhd2Vzb21lIjp0cnVlfQ."
@ -229,7 +227,8 @@ class CloudFoundryMvcWebEndpointIntegrationTests {
static class CloudFoundryMvcConfiguration {
@Bean
CloudFoundrySecurityInterceptor interceptor() {
CloudFoundrySecurityInterceptor interceptor(TokenValidator tokenValidator,
CloudFoundrySecurityService securityService) {
return new CloudFoundrySecurityInterceptor(tokenValidator, securityService, "app-id");
}