2727
2828import okhttp3 .mockwebserver .MockResponse ;
2929import okhttp3 .mockwebserver .MockWebServer ;
30+ import org .assertj .core .api .InstanceOfAssertFactories ;
3031import org .junit .jupiter .api .AfterEach ;
3132import org .junit .jupiter .api .Test ;
3233import reactor .netty .http .HttpResources ;
4344import org .springframework .boot .actuate .endpoint .EndpointId ;
4445import org .springframework .boot .actuate .endpoint .annotation .Endpoint ;
4546import org .springframework .boot .actuate .endpoint .annotation .ReadOperation ;
46- import org .springframework .boot .actuate .endpoint .web .EndpointMapping ;
4747import org .springframework .boot .actuate .endpoint .web .ExposableWebEndpoint ;
4848import org .springframework .boot .actuate .endpoint .web .WebOperation ;
4949import org .springframework .boot .actuate .endpoint .web .WebOperationRequestPredicate ;
7474import org .springframework .security .core .userdetails .User ;
7575import org .springframework .security .web .server .SecurityWebFilterChain ;
7676import org .springframework .security .web .server .WebFilterChainProxy ;
77- import org .springframework .test .util .ReflectionTestUtils ;
7877import org .springframework .test .web .reactive .server .WebTestClient ;
7978import org .springframework .web .cors .CorsConfiguration ;
8079import org .springframework .web .reactive .function .client .WebClient ;
@@ -121,16 +120,16 @@ void cloudFoundryPlatformActive() {
121120 "vcap.application.cf_api:https://my-cloud-controller.com" )
122121 .run ((context ) -> {
123122 CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping (context );
124- EndpointMapping endpointMapping = ( EndpointMapping ) ReflectionTestUtils . getField ( handlerMapping ,
125- "endpointMapping" );
126- assertThat ( endpointMapping . getPath ()). isEqualTo ( "/cloudfoundryapplication" );
127- CorsConfiguration corsConfiguration = ( CorsConfiguration ) ReflectionTestUtils . getField ( handlerMapping ,
128- " corsConfiguration" );
129- assertThat (corsConfiguration .getAllowedOrigins ()). contains ( "*" );
130- assertThat ( corsConfiguration . getAllowedMethods ())
131- . containsAll ( Arrays . asList ( HttpMethod . GET . name (), HttpMethod . POST . name ()));
132- assertThat ( corsConfiguration . getAllowedHeaders ())
133- . containsAll ( Arrays . asList ( "Authorization" , "X-Cf-App-Instance" , "Content-Type" ) );
123+ assertThat ( handlerMapping ). extracting ( "endpointMapping.path" ). isEqualTo ( "/cloudfoundryapplication" );
124+ assertThat ( handlerMapping )
125+ . extracting ( "corsConfiguration" , InstanceOfAssertFactories . type ( CorsConfiguration . class ))
126+ . satisfies (( corsConfiguration ) -> {
127+ assertThat ( corsConfiguration . getAllowedOrigins ()). contains ( "* " );
128+ assertThat (corsConfiguration .getAllowedMethods ())
129+ . containsAll ( Arrays . asList ( HttpMethod . GET . name (), HttpMethod . POST . name ()));
130+ assertThat ( corsConfiguration . getAllowedHeaders ())
131+ . containsAll ( Arrays . asList ( "Authorization" , "X-Cf-App-Instance" , "Content-Type" ));
132+ } );
134133 });
135134 }
136135
@@ -150,41 +149,27 @@ void cloudFoundryPlatformActiveSetsApplicationId() {
150149 this .contextRunner
151150 .withPropertyValues ("VCAP_APPLICATION:---" , "vcap.application.application_id:my-app-id" ,
152151 "vcap.application.cf_api:https://my-cloud-controller.com" )
153- .run ((context ) -> {
154- CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping (context );
155- Object interceptor = ReflectionTestUtils .getField (handlerMapping , "securityInterceptor" );
156- String applicationId = (String ) ReflectionTestUtils .getField (interceptor , "applicationId" );
157- assertThat (applicationId ).isEqualTo ("my-app-id" );
158- });
152+ .run ((context ) -> assertThat (getHandlerMapping (context )).extracting ("securityInterceptor.applicationId" )
153+ .isEqualTo ("my-app-id" ));
159154 }
160155
161156 @ Test
162157 void cloudFoundryPlatformActiveSetsCloudControllerUrl () {
163158 this .contextRunner
164159 .withPropertyValues ("VCAP_APPLICATION:---" , "vcap.application.application_id:my-app-id" ,
165160 "vcap.application.cf_api:https://my-cloud-controller.com" )
166- .run ((context ) -> {
167- CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping (context );
168- Object interceptor = ReflectionTestUtils .getField (handlerMapping , "securityInterceptor" );
169- Object interceptorSecurityService = ReflectionTestUtils .getField (interceptor ,
170- "cloudFoundrySecurityService" );
171- String cloudControllerUrl = (String ) ReflectionTestUtils .getField (interceptorSecurityService ,
172- "cloudControllerUrl" );
173- assertThat (cloudControllerUrl ).isEqualTo ("https://my-cloud-controller.com" );
174- });
161+ .run ((context ) -> assertThat (getHandlerMapping (context ))
162+ .extracting ("securityInterceptor.cloudFoundrySecurityService.cloudControllerUrl" )
163+ .isEqualTo ("https://my-cloud-controller.com" ));
175164 }
176165
177166 @ Test
178167 void cloudFoundryPlatformActiveAndCloudControllerUrlNotPresent () {
179168 this .contextRunner .withPropertyValues ("VCAP_APPLICATION:---" , "vcap.application.application_id:my-app-id" )
180- .run ((context ) -> {
181- CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = context .getBean (
182- "cloudFoundryWebFluxEndpointHandlerMapping" , CloudFoundryWebFluxEndpointHandlerMapping .class );
183- Object securityInterceptor = ReflectionTestUtils .getField (handlerMapping , "securityInterceptor" );
184- Object interceptorSecurityService = ReflectionTestUtils .getField (securityInterceptor ,
185- "cloudFoundrySecurityService" );
186- assertThat (interceptorSecurityService ).isNull ();
187- });
169+ .run ((context ) -> assertThat (context .getBean ("cloudFoundryWebFluxEndpointHandlerMapping" ,
170+ CloudFoundryWebFluxEndpointHandlerMapping .class ))
171+ .extracting ("securityInterceptor.cloudFoundrySecurityService" )
172+ .isNull ());
188173 }
189174
190175 @ Test
@@ -194,30 +179,30 @@ void cloudFoundryPathsIgnoredBySpringSecurity() {
194179 .withPropertyValues ("VCAP_APPLICATION:---" , "vcap.application.application_id:my-app-id" ,
195180 "vcap.application.cf_api:https://my-cloud-controller.com" )
196181 .run ((context ) -> {
197- WebFilterChainProxy chainProxy = context .getBean (WebFilterChainProxy .class );
198- List <SecurityWebFilterChain > filters = (List <SecurityWebFilterChain >) ReflectionTestUtils
199- .getField (chainProxy , "filters" );
200- Boolean cfBaseRequestMatches = getMatches (filters , BASE_PATH );
201- Boolean cfBaseWithTrailingSlashRequestMatches = getMatches (filters , BASE_PATH + "/" );
202- Boolean cfRequestMatches = getMatches (filters , BASE_PATH + "/test" );
203- Boolean cfRequestWithAdditionalPathMatches = getMatches (filters , BASE_PATH + "/test/a" );
204- Boolean otherCfRequestMatches = getMatches (filters , BASE_PATH + "/other-path" );
205- Boolean otherRequestMatches = getMatches (filters , "/some-other-path" );
206- assertThat (cfBaseRequestMatches ).isTrue ();
207- assertThat (cfBaseWithTrailingSlashRequestMatches ).isTrue ();
208- assertThat (cfRequestMatches ).isTrue ();
209- assertThat (cfRequestWithAdditionalPathMatches ).isTrue ();
210- assertThat (otherCfRequestMatches ).isFalse ();
211- assertThat (otherRequestMatches ).isFalse ();
212- otherRequestMatches = filters .get (1 )
213- .matches (MockServerWebExchange .from (MockServerHttpRequest .get ("/some-other-path" ).build ()))
214- .block (Duration .ofSeconds (30 ));
215- assertThat (otherRequestMatches ).isTrue ();
182+ assertThat (context .getBean (WebFilterChainProxy .class ))
183+ .extracting ("filters" , InstanceOfAssertFactories .list (SecurityWebFilterChain .class ))
184+ .satisfies ((filters ) -> {
185+ Boolean cfBaseRequestMatches = getMatches (filters , BASE_PATH );
186+ Boolean cfBaseWithTrailingSlashRequestMatches = getMatches (filters , BASE_PATH + "/" );
187+ Boolean cfRequestMatches = getMatches (filters , BASE_PATH + "/test" );
188+ Boolean cfRequestWithAdditionalPathMatches = getMatches (filters , BASE_PATH + "/test/a" );
189+ Boolean otherCfRequestMatches = getMatches (filters , BASE_PATH + "/other-path" );
190+ Boolean otherRequestMatches = getMatches (filters , "/some-other-path" );
191+ assertThat (cfBaseRequestMatches ).isTrue ();
192+ assertThat (cfBaseWithTrailingSlashRequestMatches ).isTrue ();
193+ assertThat (cfRequestMatches ).isTrue ();
194+ assertThat (cfRequestWithAdditionalPathMatches ).isTrue ();
195+ assertThat (otherCfRequestMatches ).isFalse ();
196+ assertThat (otherRequestMatches ).isFalse ();
197+ otherRequestMatches = filters .get (1 )
198+ .matches (MockServerWebExchange .from (MockServerHttpRequest .get ("/some-other-path" ).build ()))
199+ .block (Duration .ofSeconds (30 ));
200+ assertThat (otherRequestMatches ).isTrue ();
201+ });
216202 });
217-
218203 }
219204
220- private static Boolean getMatches (List <SecurityWebFilterChain > filters , String urlTemplate ) {
205+ private static Boolean getMatches (List <? extends SecurityWebFilterChain > filters , String urlTemplate ) {
221206 return filters .get (0 )
222207 .matches (MockServerWebExchange .from (MockServerHttpRequest .get (urlTemplate ).build ()))
223208 .block (Duration .ofSeconds (30 ));
@@ -322,20 +307,17 @@ void skipSslValidation() throws IOException {
322307 .withPropertyValues ("VCAP_APPLICATION:---" , "vcap.application.application_id:my-app-id" ,
323308 "vcap.application.cf_api:https://my-cloud-controller.com" ,
324309 "management.cloudfoundry.skip-ssl-validation:true" )
325- .run ((context ) -> {
326- CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping (context );
327- Object interceptor = ReflectionTestUtils .getField (handlerMapping , "securityInterceptor" );
328- Object interceptorSecurityService = ReflectionTestUtils .getField (interceptor ,
329- "cloudFoundrySecurityService" );
330- WebClient webClient = (WebClient ) ReflectionTestUtils .getField (interceptorSecurityService ,
331- "webClient" );
332- ResponseEntity <Void > response = webClient .get ()
333- .uri (server .url ("/" ).uri ())
334- .retrieve ()
335- .toBodilessEntity ()
336- .block (Duration .ofSeconds (30 ));
337- assertThat (response .getStatusCode ()).isEqualTo (HttpStatusCode .valueOf (204 ));
338- });
310+ .run ((context ) -> assertThat (getHandlerMapping (context ))
311+ .extracting ("securityInterceptor.cloudFoundrySecurityService.webClient" ,
312+ InstanceOfAssertFactories .type (WebClient .class ))
313+ .satisfies ((webClient ) -> {
314+ ResponseEntity <Void > response = webClient .get ()
315+ .uri (server .url ("/" ).uri ())
316+ .retrieve ()
317+ .toBodilessEntity ()
318+ .block (Duration .ofSeconds (30 ));
319+ assertThat (response .getStatusCode ()).isEqualTo (HttpStatusCode .valueOf (204 ));
320+ }));
339321 }
340322 }
341323
@@ -351,21 +333,16 @@ void sslValidationNotSkippedByDefault() throws IOException {
351333 this .contextRunner .withConfiguration (AutoConfigurations .of (HealthEndpointAutoConfiguration .class ))
352334 .withPropertyValues ("VCAP_APPLICATION:---" , "vcap.application.application_id:my-app-id" ,
353335 "vcap.application.cf_api:https://my-cloud-controller.com" )
354- .run ((context ) -> {
355- CloudFoundryWebFluxEndpointHandlerMapping handlerMapping = getHandlerMapping (context );
356- Object interceptor = ReflectionTestUtils .getField (handlerMapping , "securityInterceptor" );
357- Object interceptorSecurityService = ReflectionTestUtils .getField (interceptor ,
358- "cloudFoundrySecurityService" );
359- WebClient webClient = (WebClient ) ReflectionTestUtils .getField (interceptorSecurityService ,
360- "webClient" );
361- assertThatExceptionOfType (RuntimeException .class )
336+ .run ((context ) -> assertThat (getHandlerMapping (context ))
337+ .extracting ("securityInterceptor.cloudFoundrySecurityService.webClient" ,
338+ InstanceOfAssertFactories .type (WebClient .class ))
339+ .satisfies ((webClient ) -> assertThatExceptionOfType (RuntimeException .class )
362340 .isThrownBy (() -> webClient .get ()
363341 .uri (server .url ("/" ).uri ())
364342 .retrieve ()
365343 .toBodilessEntity ()
366344 .block (Duration .ofSeconds (30 )))
367- .withCauseInstanceOf (SSLException .class );
368- });
345+ .withCauseInstanceOf (SSLException .class )));
369346 }
370347 }
371348
0 commit comments