Polish
This commit is contained in:
parent
6eabe8235c
commit
ba86b68484
|
@ -51,33 +51,38 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
|||
UserDetailsService.class })
|
||||
public class AuthenticationManagerConfiguration {
|
||||
|
||||
private final Pattern pattern = Pattern.compile("^\\{.+}.*$");
|
||||
private static final String NOOP_PASSWORD_PREFIX = "{noop}";
|
||||
|
||||
private static final Pattern PASSWORD_ALGORITHM_PATTERN = Pattern
|
||||
.compile("^\\{.+}.*$");
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(AuthenticationManagerConfiguration.class);
|
||||
|
||||
private static final String NOOP_PREFIX = "{noop}";
|
||||
|
||||
@Bean
|
||||
public InMemoryUserDetailsManager inMemoryUserDetailsManager(SecurityProperties properties,
|
||||
public InMemoryUserDetailsManager inMemoryUserDetailsManager(
|
||||
SecurityProperties properties,
|
||||
ObjectProvider<PasswordEncoder> passwordEncoder) throws Exception {
|
||||
SecurityProperties.User user = properties.getUser();
|
||||
if (user.isPasswordGenerated()) {
|
||||
logger.info(String.format("%n%nUsing generated security password: %s%n", user.getPassword()));
|
||||
}
|
||||
String password = deducePassword(passwordEncoder, user.getPassword());
|
||||
List<String> roles = user.getRoles();
|
||||
return new InMemoryUserDetailsManager(
|
||||
User.withUsername(user.getName()).password(password)
|
||||
.roles(roles.toArray(new String[roles.size()])).build());
|
||||
User.withUsername(user.getName())
|
||||
.password(getOrDeducePassword(user,
|
||||
passwordEncoder.getIfAvailable()))
|
||||
.roles(roles.toArray(new String[roles.size()])).build());
|
||||
}
|
||||
|
||||
private String deducePassword(ObjectProvider<PasswordEncoder> passwordEncoder, String password) {
|
||||
if (passwordEncoder.getIfAvailable() == null &&
|
||||
!this.pattern.matcher(password).matches()) {
|
||||
return NOOP_PREFIX + password;
|
||||
public String getOrDeducePassword(SecurityProperties.User user,
|
||||
PasswordEncoder encoder) {
|
||||
String password = user.getPassword();
|
||||
if (user.isPasswordGenerated()) {
|
||||
logger.info(String.format("%n%nUsing generated security password: %s%n",
|
||||
user.getPassword()));
|
||||
}
|
||||
return password;
|
||||
if (encoder != null || PASSWORD_ALGORITHM_PATTERN.matcher(password).matches()) {
|
||||
return password;
|
||||
}
|
||||
return NOOP_PASSWORD_PREFIX + password;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,9 +51,10 @@ import org.springframework.security.crypto.password.PasswordEncoder;
|
|||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
|
||||
class ReactiveAuthenticationManagerConfiguration {
|
||||
|
||||
private final Pattern pattern = Pattern.compile("^\\{.+}.*$");
|
||||
private static final String NOOP_PASSWORD_PREFIX = "{noop}";
|
||||
|
||||
private static final String NOOP_PREFIX = "{noop}";
|
||||
private static final Pattern PASSWORD_ALGORITHM_PATTERN = Pattern
|
||||
.compile("^\\{.+}.*$");
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(ReactiveAuthenticationManagerConfiguration.class);
|
||||
|
@ -63,28 +64,28 @@ class ReactiveAuthenticationManagerConfiguration {
|
|||
SecurityProperties properties,
|
||||
ObjectProvider<PasswordEncoder> passwordEncoder) {
|
||||
SecurityProperties.User user = properties.getUser();
|
||||
if (user.isPasswordGenerated()) {
|
||||
logger.info(String.format("%n%nUsing default security password: %s%n",
|
||||
user.getPassword()));
|
||||
}
|
||||
String password = deducePassword(passwordEncoder, user.getPassword());
|
||||
UserDetails userDetails = getUserDetails(user, password);
|
||||
UserDetails userDetails = getUserDetails(user,
|
||||
getOrDeducePassword(user, passwordEncoder.getIfAvailable()));
|
||||
return new MapReactiveUserDetailsService(userDetails);
|
||||
}
|
||||
|
||||
private String deducePassword(ObjectProvider<PasswordEncoder> passwordEncoder, String password) {
|
||||
if (passwordEncoder.getIfAvailable() == null &&
|
||||
!this.pattern.matcher(password).matches()) {
|
||||
return NOOP_PREFIX + password;
|
||||
}
|
||||
return password;
|
||||
}
|
||||
|
||||
private UserDetails getUserDetails(SecurityProperties.User user,
|
||||
String password) {
|
||||
private UserDetails getUserDetails(SecurityProperties.User user, String password) {
|
||||
List<String> roles = user.getRoles();
|
||||
return User.withUsername(user.getName()).password(password)
|
||||
.roles(roles.toArray(new String[roles.size()])).build();
|
||||
}
|
||||
|
||||
private String getOrDeducePassword(SecurityProperties.User user,
|
||||
PasswordEncoder encoder) {
|
||||
String password = user.getPassword();
|
||||
if (user.isPasswordGenerated()) {
|
||||
logger.info(String.format("%n%nUsing default security password: %s%n",
|
||||
user.getPassword()));
|
||||
}
|
||||
if (encoder != null || PASSWORD_ALGORITHM_PATTERN.matcher(password).matches()) {
|
||||
return password;
|
||||
}
|
||||
return NOOP_PASSWORD_PREFIX + password;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,35 +34,35 @@ import org.springframework.util.ClassUtils;
|
|||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.format.support.FormattingConversionService} dedicated
|
||||
* to web applications for formatting and converting values to/from the web.
|
||||
*
|
||||
* <p>This service replaces the default implementations provided by
|
||||
* {@link org.springframework.web.servlet.config.annotation.EnableWebMvc}
|
||||
* and {@link org.springframework.web.reactive.config.EnableWebFlux}.
|
||||
* {@link org.springframework.format.support.FormattingConversionService} dedicated to web
|
||||
* applications for formatting and converting values to/from the web.
|
||||
* <p>
|
||||
* This service replaces the default implementations provided by
|
||||
* {@link org.springframework.web.servlet.config.annotation.EnableWebMvc} and
|
||||
* {@link org.springframework.web.reactive.config.EnableWebFlux}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class WebConversionService extends DefaultFormattingConversionService {
|
||||
|
||||
private static final boolean jsr354Present = ClassUtils
|
||||
.isPresent("javax.money.MonetaryAmount", WebConversionService.class.getClassLoader());
|
||||
private static final boolean jsr354Present = ClassUtils.isPresent(
|
||||
"javax.money.MonetaryAmount", WebConversionService.class.getClassLoader());
|
||||
|
||||
private static final boolean jodaTimePresent = ClassUtils
|
||||
.isPresent("org.joda.time.LocalDate", WebConversionService.class.getClassLoader());
|
||||
private static final boolean jodaTimePresent = ClassUtils.isPresent(
|
||||
"org.joda.time.LocalDate", WebConversionService.class.getClassLoader());
|
||||
|
||||
private String dateFormat;
|
||||
private final String dateFormat;
|
||||
|
||||
/**
|
||||
* Create a new WebConversionService that configures formatters with the provided date format,
|
||||
* or register the default ones if no custom format is provided.
|
||||
* Create a new WebConversionService that configures formatters with the provided date
|
||||
* format, or register the default ones if no custom format is provided.
|
||||
* @param dateFormat the custom date format to use for date conversions
|
||||
*/
|
||||
public WebConversionService(String dateFormat) {
|
||||
super(false);
|
||||
if (StringUtils.hasText(dateFormat)) {
|
||||
this.dateFormat = dateFormat;
|
||||
this.dateFormat = (StringUtils.hasText(dateFormat) ? dateFormat : null);
|
||||
if (this.dateFormat != null) {
|
||||
addFormatters();
|
||||
}
|
||||
else {
|
||||
|
@ -70,13 +70,13 @@ public class WebConversionService extends DefaultFormattingConversionService {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void addFormatters() {
|
||||
addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
|
||||
if (jsr354Present) {
|
||||
addFormatter(new CurrencyUnitFormatter());
|
||||
addFormatter(new MonetaryAmountFormatter());
|
||||
addFormatterForFieldAnnotation(new Jsr354NumberFormatAnnotationFormatterFactory());
|
||||
addFormatterForFieldAnnotation(
|
||||
new Jsr354NumberFormatAnnotationFormatterFactory());
|
||||
}
|
||||
registerJsr310();
|
||||
if (jodaTimePresent) {
|
||||
|
@ -88,10 +88,8 @@ public class WebConversionService extends DefaultFormattingConversionService {
|
|||
private void registerJsr310() {
|
||||
DateTimeFormatterRegistrar dateTime = new DateTimeFormatterRegistrar();
|
||||
if (this.dateFormat != null) {
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter
|
||||
.ofPattern(this.dateFormat)
|
||||
.withResolverStyle(ResolverStyle.STRICT);
|
||||
dateTime.setDateFormatter(dateTimeFormatter);
|
||||
dateTime.setDateFormatter(DateTimeFormatter.ofPattern(this.dateFormat)
|
||||
.withResolverStyle(ResolverStyle.STRICT));
|
||||
}
|
||||
dateTime.registerFormatters(this);
|
||||
}
|
||||
|
@ -99,10 +97,8 @@ public class WebConversionService extends DefaultFormattingConversionService {
|
|||
private void registerJodaTime() {
|
||||
JodaTimeFormatterRegistrar jodaTime = new JodaTimeFormatterRegistrar();
|
||||
if (this.dateFormat != null) {
|
||||
org.joda.time.format.DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder()
|
||||
.appendPattern(this.dateFormat)
|
||||
.toFormatter();
|
||||
jodaTime.setDateFormatter(dateTimeFormatter);
|
||||
jodaTime.setDateFormatter(new DateTimeFormatterBuilder()
|
||||
.appendPattern(this.dateFormat).toFormatter());
|
||||
}
|
||||
jodaTime.registerFormatters(this);
|
||||
}
|
||||
|
@ -115,4 +111,5 @@ public class WebConversionService extends DefaultFormattingConversionService {
|
|||
}
|
||||
dateFormatterRegistrar.registerFormatters(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -223,7 +223,8 @@ public class WebFluxAutoConfiguration {
|
|||
@Bean
|
||||
@Override
|
||||
public FormattingConversionService webFluxConversionService() {
|
||||
WebConversionService conversionService = new WebConversionService(this.webFluxProperties.getDateFormat());
|
||||
WebConversionService conversionService = new WebConversionService(
|
||||
this.webFluxProperties.getDateFormat());
|
||||
addFormatters(conversionService);
|
||||
return conversionService;
|
||||
}
|
||||
|
|
|
@ -301,8 +301,8 @@ public class WebMvcAutoConfiguration {
|
|||
return;
|
||||
}
|
||||
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
|
||||
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol()
|
||||
.toHttpCacheControl();
|
||||
CacheControl cacheControl = this.resourceProperties.getCache()
|
||||
.getCachecontrol().toHttpCacheControl();
|
||||
if (!registry.hasMappingForPattern("/webjars/**")) {
|
||||
customizeResourceHandlerRegistration(
|
||||
registry.addResourceHandler("/webjars/**")
|
||||
|
@ -475,7 +475,8 @@ public class WebMvcAutoConfiguration {
|
|||
@Bean
|
||||
@Override
|
||||
public FormattingConversionService mvcConversionService() {
|
||||
WebConversionService conversionService = new WebConversionService(this.mvcProperties.getDateFormat());
|
||||
WebConversionService conversionService = new WebConversionService(
|
||||
this.mvcProperties.getDateFormat());
|
||||
addFormatters(conversionService);
|
||||
return conversionService;
|
||||
}
|
||||
|
|
|
@ -40,22 +40,27 @@ public class AuthenticationManagerConfigurationTests {
|
|||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
|
||||
|
||||
@Test
|
||||
public void userDetailsServiceWhenPasswordEncoderAbsentAndDefaultPassword() throws Exception {
|
||||
public void userDetailsServiceWhenPasswordEncoderAbsentAndDefaultPassword()
|
||||
throws Exception {
|
||||
this.contextRunner.withUserConfiguration(TestSecurityConfiguration.class,
|
||||
AuthenticationManagerConfiguration.class).run((context -> {
|
||||
InMemoryUserDetailsManager userDetailsService = context.getBean(InMemoryUserDetailsManager.class);
|
||||
String password = userDetailsService.loadUserByUsername("user").getPassword();
|
||||
assertThat(password).startsWith("{noop}");
|
||||
}));
|
||||
InMemoryUserDetailsManager userDetailsService = context
|
||||
.getBean(InMemoryUserDetailsManager.class);
|
||||
String password = userDetailsService.loadUserByUsername("user")
|
||||
.getPassword();
|
||||
assertThat(password).startsWith("{noop}");
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userDetailsServiceWhenPasswordEncoderAbsentAndRawPassword() throws Exception {
|
||||
public void userDetailsServiceWhenPasswordEncoderAbsentAndRawPassword()
|
||||
throws Exception {
|
||||
testPasswordEncoding(TestSecurityConfiguration.class, "secret", "{noop}secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userDetailsServiceWhenPasswordEncoderAbsentAndEncodedPassword() throws Exception {
|
||||
public void userDetailsServiceWhenPasswordEncoderAbsentAndEncodedPassword()
|
||||
throws Exception {
|
||||
String password = "{bcrypt}$2a$10$sCBi9fy9814vUPf2ZRbtp.fR5/VgRk2iBFZ.ypu5IyZ28bZgxrVDa";
|
||||
testPasswordEncoding(TestSecurityConfiguration.class, password, password);
|
||||
}
|
||||
|
@ -65,14 +70,19 @@ public class AuthenticationManagerConfigurationTests {
|
|||
testPasswordEncoding(TestConfigWithPasswordEncoder.class, "secret", "secret");
|
||||
}
|
||||
|
||||
private void testPasswordEncoding(Class<?> configClass, String providedPassword, String expectedPassword) {
|
||||
this.contextRunner.withUserConfiguration(configClass,
|
||||
AuthenticationManagerConfiguration.class)
|
||||
.withPropertyValues("spring.security.user.password=" + providedPassword).run((context -> {
|
||||
InMemoryUserDetailsManager userDetailsService = context.getBean(InMemoryUserDetailsManager.class);
|
||||
String password = userDetailsService.loadUserByUsername("user").getPassword();
|
||||
assertThat(password).isEqualTo(expectedPassword);
|
||||
}));
|
||||
private void testPasswordEncoding(Class<?> configClass, String providedPassword,
|
||||
String expectedPassword) {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(configClass,
|
||||
AuthenticationManagerConfiguration.class)
|
||||
.withPropertyValues("spring.security.user.password=" + providedPassword)
|
||||
.run((context -> {
|
||||
InMemoryUserDetailsManager userDetailsService = context
|
||||
.getBean(InMemoryUserDetailsManager.class);
|
||||
String password = userDetailsService.loadUserByUsername("user")
|
||||
.getPassword();
|
||||
assertThat(password).isEqualTo(expectedPassword);
|
||||
}));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
@ -92,4 +102,5 @@ public class AuthenticationManagerConfigurationTests {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,22 +41,29 @@ public class ReactiveAuthenticationManagerConfigurationTests {
|
|||
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner();
|
||||
|
||||
@Test
|
||||
public void userDetailsServiceWhenPasswordEncoderAbsentAndDefaultPassword() throws Exception {
|
||||
this.contextRunner.withUserConfiguration(TestSecurityConfiguration.class,
|
||||
ReactiveAuthenticationManagerConfiguration.class).run((context -> {
|
||||
MapReactiveUserDetailsService userDetailsService = context.getBean(MapReactiveUserDetailsService.class);
|
||||
String password = userDetailsService.findByUsername("user").block().getPassword();
|
||||
assertThat(password).startsWith("{noop}");
|
||||
}));
|
||||
public void userDetailsServiceWhenPasswordEncoderAbsentAndDefaultPassword()
|
||||
throws Exception {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(TestSecurityConfiguration.class,
|
||||
ReactiveAuthenticationManagerConfiguration.class)
|
||||
.run((context -> {
|
||||
MapReactiveUserDetailsService userDetailsService = context
|
||||
.getBean(MapReactiveUserDetailsService.class);
|
||||
String password = userDetailsService.findByUsername("user").block()
|
||||
.getPassword();
|
||||
assertThat(password).startsWith("{noop}");
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userDetailsServiceWhenPasswordEncoderAbsentAndRawPassword() throws Exception {
|
||||
public void userDetailsServiceWhenPasswordEncoderAbsentAndRawPassword()
|
||||
throws Exception {
|
||||
testPasswordEncoding(TestSecurityConfiguration.class, "secret", "{noop}secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userDetailsServiceWhenPasswordEncoderAbsentAndEncodedPassword() throws Exception {
|
||||
public void userDetailsServiceWhenPasswordEncoderAbsentAndEncodedPassword()
|
||||
throws Exception {
|
||||
String password = "{bcrypt}$2a$10$sCBi9fy9814vUPf2ZRbtp.fR5/VgRk2iBFZ.ypu5IyZ28bZgxrVDa";
|
||||
testPasswordEncoding(TestSecurityConfiguration.class, password, password);
|
||||
}
|
||||
|
@ -66,14 +73,19 @@ public class ReactiveAuthenticationManagerConfigurationTests {
|
|||
testPasswordEncoding(TestConfigWithPasswordEncoder.class, "secret", "secret");
|
||||
}
|
||||
|
||||
private void testPasswordEncoding(Class<?> configClass, String providedPassword, String expectedPassword) {
|
||||
this.contextRunner.withUserConfiguration(configClass,
|
||||
ReactiveAuthenticationManagerConfiguration.class)
|
||||
.withPropertyValues("spring.security.user.password=" + providedPassword).run((context -> {
|
||||
MapReactiveUserDetailsService userDetailsService = context.getBean(MapReactiveUserDetailsService.class);
|
||||
String password = userDetailsService.findByUsername("user").block().getPassword();
|
||||
assertThat(password).isEqualTo(expectedPassword);
|
||||
}));
|
||||
private void testPasswordEncoding(Class<?> configClass, String providedPassword,
|
||||
String expectedPassword) {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(configClass,
|
||||
ReactiveAuthenticationManagerConfiguration.class)
|
||||
.withPropertyValues("spring.security.user.password=" + providedPassword)
|
||||
.run((context -> {
|
||||
MapReactiveUserDetailsService userDetailsService = context
|
||||
.getBean(MapReactiveUserDetailsService.class);
|
||||
String password = userDetailsService.findByUsername("user").block()
|
||||
.getPassword();
|
||||
assertThat(password).isEqualTo(expectedPassword);
|
||||
}));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
|
|
@ -34,17 +34,14 @@ public class WebConversionServiceTests {
|
|||
@Test
|
||||
public void customDateFormat() {
|
||||
WebConversionService conversionService = new WebConversionService("dd*MM*yyyy");
|
||||
|
||||
Date date = new DateTime(2018, 1, 1, 20, 30).toDate();
|
||||
assertThat(conversionService.convert(date, String.class))
|
||||
.isEqualTo("01*01*2018");
|
||||
|
||||
assertThat(conversionService.convert(date, String.class)).isEqualTo("01*01*2018");
|
||||
LocalDate jodaDate = LocalDate.fromDateFields(date);
|
||||
assertThat(conversionService.convert(jodaDate, String.class))
|
||||
.isEqualTo("01*01*2018");
|
||||
|
||||
java.time.LocalDate localDate = java.time.LocalDate.of(2018, 1, 1);
|
||||
assertThat(conversionService.convert(localDate, String.class))
|
||||
.isEqualTo("01*01*2018");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -69,8 +69,7 @@ import static org.mockito.Mockito.verify;
|
|||
*/
|
||||
public class WebFluxAutoConfigurationTests {
|
||||
|
||||
private static final MockReactiveWebServerFactory mockReactiveWebServerFactory
|
||||
= new MockReactiveWebServerFactory();
|
||||
private static final MockReactiveWebServerFactory mockReactiveWebServerFactory = new MockReactiveWebServerFactory();
|
||||
|
||||
private ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class))
|
||||
|
@ -80,8 +79,10 @@ public class WebFluxAutoConfigurationTests {
|
|||
public void shouldNotProcessIfExistingWebReactiveConfiguration() {
|
||||
this.contextRunner.withUserConfiguration(WebFluxConfigurationSupport.class)
|
||||
.run(context -> {
|
||||
assertThat(context).getBeans(RequestMappingHandlerMapping.class).hasSize(1);
|
||||
assertThat(context).getBeans(RequestMappingHandlerAdapter.class).hasSize(1);
|
||||
assertThat(context).getBeans(RequestMappingHandlerMapping.class)
|
||||
.hasSize(1);
|
||||
assertThat(context).getBeans(RequestMappingHandlerAdapter.class)
|
||||
.hasSize(1);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -99,28 +100,30 @@ public class WebFluxAutoConfigurationTests {
|
|||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void shouldRegisterCustomHandlerMethodArgumentResolver() {
|
||||
this.contextRunner.withUserConfiguration(CustomArgumentResolvers.class).run(context -> {
|
||||
RequestMappingHandlerAdapter adapter = context
|
||||
.getBean(RequestMappingHandlerAdapter.class);
|
||||
List<HandlerMethodArgumentResolver> customResolvers =
|
||||
(List<HandlerMethodArgumentResolver>) ReflectionTestUtils
|
||||
.getField(adapter.getArgumentResolverConfigurer(), "customResolvers");
|
||||
assertThat(customResolvers).contains(
|
||||
context.getBean("firstResolver",
|
||||
HandlerMethodArgumentResolver.class),
|
||||
context.getBean("secondResolver",
|
||||
HandlerMethodArgumentResolver.class));
|
||||
});
|
||||
this.contextRunner.withUserConfiguration(CustomArgumentResolvers.class)
|
||||
.run(context -> {
|
||||
RequestMappingHandlerAdapter adapter = context
|
||||
.getBean(RequestMappingHandlerAdapter.class);
|
||||
List<HandlerMethodArgumentResolver> customResolvers = (List<HandlerMethodArgumentResolver>) ReflectionTestUtils
|
||||
.getField(adapter.getArgumentResolverConfigurer(),
|
||||
"customResolvers");
|
||||
assertThat(customResolvers).contains(
|
||||
context.getBean("firstResolver",
|
||||
HandlerMethodArgumentResolver.class),
|
||||
context.getBean("secondResolver",
|
||||
HandlerMethodArgumentResolver.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCustomizeCodecs() {
|
||||
this.contextRunner.withUserConfiguration(CustomCodecCustomizers.class).run(context -> {
|
||||
CodecCustomizer codecCustomizer = context.getBean("firstCodecCustomizer",
|
||||
CodecCustomizer.class);
|
||||
assertThat(codecCustomizer).isNotNull();
|
||||
verify(codecCustomizer).customize(any(ServerCodecConfigurer.class));
|
||||
});
|
||||
this.contextRunner.withUserConfiguration(CustomCodecCustomizers.class)
|
||||
.run(context -> {
|
||||
CodecCustomizer codecCustomizer = context
|
||||
.getBean("firstCodecCustomizer", CodecCustomizer.class);
|
||||
assertThat(codecCustomizer).isNotNull();
|
||||
verify(codecCustomizer).customize(any(ServerCodecConfigurer.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -129,7 +132,8 @@ public class WebFluxAutoConfigurationTests {
|
|||
SimpleUrlHandlerMapping hm = context.getBean("resourceHandlerMapping",
|
||||
SimpleUrlHandlerMapping.class);
|
||||
assertThat(hm.getUrlMap().get("/**")).isInstanceOf(ResourceWebHandler.class);
|
||||
ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap().get("/**");
|
||||
ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap()
|
||||
.get("/**");
|
||||
assertThat(staticHandler.getLocations()).hasSize(4);
|
||||
assertThat(hm.getUrlMap().get("/webjars/**"))
|
||||
.isInstanceOf(ResourceWebHandler.class);
|
||||
|
@ -143,7 +147,8 @@ public class WebFluxAutoConfigurationTests {
|
|||
|
||||
@Test
|
||||
public void shouldMapResourcesToCustomPath() {
|
||||
this.contextRunner.withPropertyValues("spring.webflux.static-path-pattern:/static/**")
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.webflux.static-path-pattern:/static/**")
|
||||
.run(context -> {
|
||||
SimpleUrlHandlerMapping hm = context.getBean("resourceHandlerMapping",
|
||||
SimpleUrlHandlerMapping.class);
|
||||
|
@ -170,11 +175,16 @@ public class WebFluxAutoConfigurationTests {
|
|||
.run(context -> {
|
||||
SimpleUrlHandlerMapping hm = context.getBean("resourceHandlerMapping",
|
||||
SimpleUrlHandlerMapping.class);
|
||||
assertThat(hm.getUrlMap().get("/**")).isInstanceOf(ResourceWebHandler.class);
|
||||
ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap().get("/**");
|
||||
assertThat(staticHandler.getResourceResolvers()).extractingResultOf("getClass")
|
||||
.containsOnly(CachingResourceResolver.class, PathResourceResolver.class);
|
||||
assertThat(staticHandler.getResourceTransformers()).extractingResultOf("getClass")
|
||||
assertThat(hm.getUrlMap().get("/**"))
|
||||
.isInstanceOf(ResourceWebHandler.class);
|
||||
ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap()
|
||||
.get("/**");
|
||||
assertThat(staticHandler.getResourceResolvers())
|
||||
.extractingResultOf("getClass")
|
||||
.containsOnly(CachingResourceResolver.class,
|
||||
PathResourceResolver.class);
|
||||
assertThat(staticHandler.getResourceTransformers())
|
||||
.extractingResultOf("getClass")
|
||||
.containsOnly(CachingResourceTransformer.class);
|
||||
});
|
||||
}
|
||||
|
@ -216,29 +226,35 @@ public class WebFluxAutoConfigurationTests {
|
|||
|
||||
@Test
|
||||
public void validatorWhenNoValidatorShouldUseDefault() {
|
||||
this.contextRunner
|
||||
.run(context -> {
|
||||
assertThat(context).doesNotHaveBean(ValidatorFactory.class);
|
||||
assertThat(context).doesNotHaveBean(javax.validation.Validator.class);
|
||||
assertThat(context).getBeanNames(Validator.class).containsExactly("webFluxValidator");
|
||||
});
|
||||
this.contextRunner.run(context -> {
|
||||
assertThat(context).doesNotHaveBean(ValidatorFactory.class);
|
||||
assertThat(context).doesNotHaveBean(javax.validation.Validator.class);
|
||||
assertThat(context).getBeanNames(Validator.class)
|
||||
.containsExactly("webFluxValidator");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validatorWhenNoCustomizationShouldUseAutoConfigured() {
|
||||
this.contextRunner.withConfiguration(
|
||||
AutoConfigurations.of(ValidationAutoConfiguration.class))
|
||||
this.contextRunner
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(ValidationAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context).getBeanNames(javax.validation.Validator.class)
|
||||
.containsExactly("defaultValidator");
|
||||
assertThat(context).getBeanNames(Validator.class)
|
||||
.containsExactlyInAnyOrder("defaultValidator", "webFluxValidator");
|
||||
Validator validator = context.getBean("webFluxValidator", Validator.class);
|
||||
.containsExactlyInAnyOrder("defaultValidator",
|
||||
"webFluxValidator");
|
||||
Validator validator = context.getBean("webFluxValidator",
|
||||
Validator.class);
|
||||
assertThat(validator).isInstanceOf(ValidatorAdapter.class);
|
||||
Object defaultValidator = context.getBean("defaultValidator");
|
||||
assertThat(((ValidatorAdapter) validator).getTarget()).isSameAs(defaultValidator);
|
||||
// Primary Spring validator is the one used by WebFlux behind the scenes
|
||||
assertThat(context.getBean(Validator.class)).isEqualTo(defaultValidator);
|
||||
assertThat(((ValidatorAdapter) validator).getTarget())
|
||||
.isSameAs(defaultValidator);
|
||||
// Primary Spring validator is the one used by WebFlux behind the
|
||||
// scenes
|
||||
assertThat(context.getBean(Validator.class))
|
||||
.isEqualTo(defaultValidator);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -250,15 +266,14 @@ public class WebFluxAutoConfigurationTests {
|
|||
assertThat(context).doesNotHaveBean(javax.validation.Validator.class);
|
||||
assertThat(context).getBeanNames(Validator.class)
|
||||
.containsOnly("webFluxValidator");
|
||||
assertThat(context.getBean("webFluxValidator"))
|
||||
.isSameAs(context.getBean(ValidatorWebFluxConfigurer.class).validator);
|
||||
assertThat(context.getBean("webFluxValidator")).isSameAs(
|
||||
context.getBean(ValidatorWebFluxConfigurer.class).validator);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validatorWithConfigurerDoesNotExposeJsr303() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(ValidatorJsr303WebFluxConfigurer.class)
|
||||
this.contextRunner.withUserConfiguration(ValidatorJsr303WebFluxConfigurer.class)
|
||||
.run(context -> {
|
||||
assertThat(context).doesNotHaveBean(ValidatorFactory.class);
|
||||
assertThat(context).doesNotHaveBean(javax.validation.Validator.class);
|
||||
|
@ -267,24 +282,28 @@ public class WebFluxAutoConfigurationTests {
|
|||
Validator validator = context.getBean("webFluxValidator",
|
||||
Validator.class);
|
||||
assertThat(validator).isInstanceOf(ValidatorAdapter.class);
|
||||
assertThat(((ValidatorAdapter) validator).getTarget()).isSameAs(
|
||||
context.getBean(ValidatorJsr303WebFluxConfigurer.class).validator);
|
||||
assertThat(((ValidatorAdapter) validator).getTarget())
|
||||
.isSameAs(context.getBean(
|
||||
ValidatorJsr303WebFluxConfigurer.class).validator);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validationCustomConfigurerTakesPrecedence() {
|
||||
this.contextRunner
|
||||
.withConfiguration(AutoConfigurations.of(ValidationAutoConfiguration.class))
|
||||
.withUserConfiguration(ValidatorWebFluxConfigurer.class)
|
||||
.run(context -> {
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(ValidationAutoConfiguration.class))
|
||||
.withUserConfiguration(ValidatorWebFluxConfigurer.class).run(context -> {
|
||||
assertThat(context).getBeans(ValidatorFactory.class).hasSize(1);
|
||||
assertThat(context).getBeans(javax.validation.Validator.class).hasSize(1);
|
||||
assertThat(context).getBeans(javax.validation.Validator.class)
|
||||
.hasSize(1);
|
||||
assertThat(context).getBeanNames(Validator.class)
|
||||
.containsExactlyInAnyOrder("defaultValidator", "webFluxValidator");
|
||||
.containsExactlyInAnyOrder("defaultValidator",
|
||||
"webFluxValidator");
|
||||
assertThat(context.getBean("webFluxValidator")).isSameAs(
|
||||
context.getBean(ValidatorWebFluxConfigurer.class).validator);
|
||||
// Primary Spring validator is the auto-configured one as the WebFlux one has been
|
||||
// Primary Spring validator is the auto-configured one as the WebFlux
|
||||
// one has been
|
||||
// customized via a WebFluxConfigurer
|
||||
assertThat(context.getBean(Validator.class))
|
||||
.isEqualTo(context.getBean("defaultValidator"));
|
||||
|
@ -294,19 +313,24 @@ public class WebFluxAutoConfigurationTests {
|
|||
@Test
|
||||
public void validatorWithCustomSpringValidatorIgnored() {
|
||||
this.contextRunner
|
||||
.withConfiguration(AutoConfigurations.of(ValidationAutoConfiguration.class))
|
||||
.withUserConfiguration(CustomSpringValidator.class)
|
||||
.run(context -> {
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(ValidationAutoConfiguration.class))
|
||||
.withUserConfiguration(CustomSpringValidator.class).run(context -> {
|
||||
assertThat(context).getBeanNames(javax.validation.Validator.class)
|
||||
.containsExactly("defaultValidator");
|
||||
assertThat(context).getBeanNames(Validator.class)
|
||||
.containsExactlyInAnyOrder("customValidator", "defaultValidator", "webFluxValidator");
|
||||
Validator validator = context.getBean("webFluxValidator", Validator.class);
|
||||
.containsExactlyInAnyOrder("customValidator",
|
||||
"defaultValidator", "webFluxValidator");
|
||||
Validator validator = context.getBean("webFluxValidator",
|
||||
Validator.class);
|
||||
assertThat(validator).isInstanceOf(ValidatorAdapter.class);
|
||||
Object defaultValidator = context.getBean("defaultValidator");
|
||||
assertThat(((ValidatorAdapter) validator).getTarget()).isSameAs(defaultValidator);
|
||||
// Primary Spring validator is the one used by WebFlux behind the scenes
|
||||
assertThat(context.getBean(Validator.class)).isEqualTo(defaultValidator);
|
||||
assertThat(((ValidatorAdapter) validator).getTarget())
|
||||
.isSameAs(defaultValidator);
|
||||
// Primary Spring validator is the one used by WebFlux behind the
|
||||
// scenes
|
||||
assertThat(context.getBean(Validator.class))
|
||||
.isEqualTo(defaultValidator);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -322,8 +346,9 @@ public class WebFluxAutoConfigurationTests {
|
|||
Validator validator = context.getBean(Validator.class);
|
||||
assertThat(validator).isInstanceOf(ValidatorAdapter.class);
|
||||
Validator target = ((ValidatorAdapter) validator).getTarget();
|
||||
assertThat(new DirectFieldAccessor(target).getPropertyValue("targetValidator"))
|
||||
.isSameAs(context.getBean("customValidator"));
|
||||
assertThat(new DirectFieldAccessor(target)
|
||||
.getPropertyValue("targetValidator"))
|
||||
.isSameAs(context.getBean("customValidator"));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue