Commit 9192444c authored by Phillip Webb's avatar Phillip Webb

Polish

parent 99101bae
......@@ -63,7 +63,7 @@ import static org.mockito.Mockito.verify;
*/
public abstract class AbstractWebEndpointIntegrationTests<T extends ConfigurableApplicationContext> {
private static final Duration TIMEOUT = Duration.ofSeconds(30);
private static final Duration TIMEOUT = Duration.ofMinutes(2);
private final Class<?> exporterConfiguration;
......
......@@ -30,7 +30,8 @@ import org.springframework.core.type.AnnotationMetadata;
* @author Stephane Nicoll
*/
@Configuration
@Import({ DataSourceInitializerInvoker.class, DataSourceInitializationConfiguration.Registrar.class })
@Import({ DataSourceInitializerInvoker.class,
DataSourceInitializationConfiguration.Registrar.class })
class DataSourceInitializationConfiguration {
/**
......
......@@ -119,7 +119,6 @@ class DataSourceInitializer {
String username = this.properties.getDataUsername();
String password = this.properties.getDataPassword();
runScripts(scripts, username, password);
}
}
......
......@@ -37,7 +37,8 @@ import org.springframework.context.ApplicationListener;
class DataSourceInitializerInvoker
implements ApplicationListener<DataSourceSchemaCreatedEvent>, InitializingBean {
private static final Log logger = LogFactory.getLog(DataSourceInitializerInvoker.class);
private static final Log logger = LogFactory
.getLog(DataSourceInitializerInvoker.class);
private final ObjectProvider<DataSource> dataSource;
......@@ -50,8 +51,7 @@ class DataSourceInitializerInvoker
private boolean initialized;
DataSourceInitializerInvoker(ObjectProvider<DataSource> dataSource,
DataSourceProperties properties,
ApplicationContext applicationContext) {
DataSourceProperties properties, ApplicationContext applicationContext) {
this.dataSource = dataSource;
this.properties = properties;
this.applicationContext = applicationContext;
......@@ -63,24 +63,27 @@ class DataSourceInitializerInvoker
if (initializer != null) {
boolean schemaCreated = this.dataSourceInitializer.createSchema();
if (schemaCreated) {
try {
this.applicationContext
.publishEvent(new DataSourceSchemaCreatedEvent(
initializer.getDataSource()));
// The listener might not be registered yet, so don't rely on it.
if (!this.initialized) {
this.dataSourceInitializer.initSchema();
this.initialized = true;
}
}
catch (IllegalStateException ex) {
logger.warn("Could not send event to complete DataSource initialization ("
+ ex.getMessage() + ")");
}
initialize(initializer);
}
}
}
private void initialize(DataSourceInitializer initializer) {
try {
this.applicationContext.publishEvent(
new DataSourceSchemaCreatedEvent(initializer.getDataSource()));
// The listener might not be registered yet, so don't rely on it.
if (!this.initialized) {
this.dataSourceInitializer.initSchema();
this.initialized = true;
}
}
catch (IllegalStateException ex) {
logger.warn("Could not send event to complete DataSource initialization ("
+ ex.getMessage() + ")");
}
}
@Override
public void onApplicationEvent(DataSourceSchemaCreatedEvent event) {
// NOTE the event can happen more than once and
......
......@@ -26,7 +26,8 @@ import org.springframework.context.ApplicationEvent;
* are executed or when Hibernate initializes the database.
*
* @author Dave Syer
* @since 1.1.0
* @author Stephane Nicoll
* @since 2.0.0
*/
@SuppressWarnings("serial")
public class DataSourceSchemaCreatedEvent extends ApplicationEvent {
......
......@@ -53,7 +53,7 @@ import org.springframework.util.ClassUtils;
@Conditional(HibernateEntityManagerCondition.class)
@EnableConfigurationProperties(JpaProperties.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class })
@Import(JpaHibernateConfiguration.class)
@Import(HibernateJpaConfiguration.class)
public class HibernateJpaAutoConfiguration {
@Order(Ordered.HIGHEST_PRECEDENCE + 20)
......
......@@ -50,10 +50,9 @@ import org.springframework.util.ClassUtils;
*/
@Configuration
@ConditionalOnSingleCandidate(DataSource.class)
public class JpaHibernateConfiguration extends JpaBaseConfiguration {
class HibernateJpaConfiguration extends JpaBaseConfiguration {
private static final Log logger = LogFactory
.getLog(JpaHibernateConfiguration.class);
private static final Log logger = LogFactory.getLog(HibernateJpaConfiguration.class);
private static final String JTA_PLATFORM = "hibernate.transaction.jta.platform";
......@@ -74,8 +73,7 @@ public class JpaHibernateConfiguration extends JpaBaseConfiguration {
private final HibernateDefaultDdlAutoProvider defaultDdlAutoProvider;
public JpaHibernateConfiguration(DataSource dataSource,
JpaProperties jpaProperties,
HibernateJpaConfiguration(DataSource dataSource, JpaProperties jpaProperties,
ObjectProvider<JtaTransactionManager> jtaTransactionManager,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers,
ObjectProvider<List<SchemaManagementProvider>> providers) {
......
......@@ -99,7 +99,8 @@ public enum CommonOAuth2Provider {
protected final ClientRegistration.Builder getBuilder(String registrationId,
ClientAuthenticationMethod method, String redirectUri) {
ClientRegistration.Builder builder = new ClientRegistration.Builder(registrationId);
ClientRegistration.Builder builder = new ClientRegistration.Builder(
registrationId);
builder.clientAuthenticationMethod(method);
builder.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
builder.redirectUri(redirectUri);
......
......@@ -42,4 +42,3 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
public class OAuth2ClientAutoConfiguration {
}
......@@ -98,8 +98,7 @@ public class OAuth2ClientProperties {
private ClientAuthenticationMethod clientAuthenticationMethod;
/**
* Authorization grant type. May be left bank then using a pre-defined
* provider.
* Authorization grant type. May be left bank then using a pre-defined provider.
*/
private AuthorizationGrantType authorizationGrantType;
......@@ -204,8 +203,8 @@ public class OAuth2ClientProperties {
private String userInfoUri;
/**
* Name of the attribute that will be used to extract the username from the
* call to 'userInfoUri'.
* Name of the attribute that will be used to extract the username from the call
* to 'userInfoUri'.
*/
private String userNameAttribute;
......
......@@ -51,10 +51,9 @@ final class OAuth2ClientPropertiesRegistrationAdapter {
return clientRegistrations;
}
private static ClientRegistration getClientRegistration(String registrationId, Registration properties,
Map<String, Provider> providers) {
Builder builder = getBuilder(registrationId, properties.getProvider(),
providers);
private static ClientRegistration getClientRegistration(String registrationId,
Registration properties, Map<String, Provider> providers) {
Builder builder = getBuilder(registrationId, properties.getProvider(), providers);
copyIfNotNull(properties::getClientId, builder::clientId);
copyIfNotNull(properties::getClientSecret, builder::clientSecret);
copyIfNotNull(properties::getClientAuthenticationMethod,
......@@ -75,7 +74,8 @@ final class OAuth2ClientPropertiesRegistrationAdapter {
if (provider == null && !providers.containsKey(providerId)) {
throw new IllegalStateException("Unknown provider ID '" + providerId + "'");
}
Builder builder = (provider != null ? provider.getBuilder(registrationId) : new Builder(registrationId));
Builder builder = (provider != null ? provider.getBuilder(registrationId)
: new Builder(registrationId));
if (providers.containsKey(providerId)) {
return getBuilder(builder, providers.get(providerId));
}
......
......@@ -54,8 +54,7 @@ class OAuth2ClientRegistrationRepositoryConfiguration {
private final OAuth2ClientProperties properties;
OAuth2ClientRegistrationRepositoryConfiguration(
OAuth2ClientProperties properties) {
OAuth2ClientRegistrationRepositoryConfiguration(OAuth2ClientProperties properties) {
this.properties = properties;
}
......@@ -103,4 +102,3 @@ class OAuth2ClientRegistrationRepositoryConfiguration {
}
}
......@@ -36,7 +36,8 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
class OAuth2WebSecurityConfiguration {
@Configuration
static class OAuth2WebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
static class OAuth2WebSecurityConfigurationAdapter
extends WebSecurityConfigurerAdapter {
private final ClientRegistrationRepository clientRegistrationRepository;
......@@ -47,15 +48,10 @@ class OAuth2WebSecurityConfiguration {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated().and()
.oauth2Login()
http.authorizeRequests().anyRequest().authenticated().and().oauth2Login()
.clients(this.clientRegistrationRepository);
}
}
}
......@@ -44,86 +44,97 @@ import static org.assertj.core.api.Assertions.assertThat;
public class MessageSourceAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(
MessageSourceAutoConfiguration.class));
.withConfiguration(
AutoConfigurations.of(MessageSourceAutoConfiguration.class));
@Test
public void testDefaultMessageSource() {
this.contextRunner.run((context) ->
assertThat(context.getMessage("foo", null, "Foo message", Locale.UK))
this.contextRunner.run((context) -> assertThat(
context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("Foo message"));
}
@Test
public void testMessageSourceCreated() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
.run((context) -> assertThat(context.getMessage(
"foo", null, "Foo message", Locale.UK)).isEqualTo("bar"));
.run((context) -> assertThat(
context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("bar"));
}
@Test
public void testEncodingWorks() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/swedish")
.run((context) -> assertThat(context.getMessage(
"foo", null, "Foo message", Locale.UK)).isEqualTo(
"Some text with some swedish öäå!"));
.run((context) -> assertThat(
context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("Some text with some swedish öäå!"));
}
@Test
public void testMultipleMessageSourceCreated() {
this.contextRunner.withPropertyValues(
"spring.messages.basename:test/messages,test/messages2").run((context) -> {
assertThat(context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("bar");
assertThat(context.getMessage("foo-foo", null, "Foo-Foo message", Locale.UK))
.isEqualTo("bar-bar");
});
this.contextRunner
.withPropertyValues(
"spring.messages.basename:test/messages,test/messages2")
.run((context) -> {
assertThat(context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("bar");
assertThat(context.getMessage("foo-foo", null, "Foo-Foo message",
Locale.UK)).isEqualTo("bar-bar");
});
}
@Test
public void testBadEncoding() {
// Bad encoding just means the messages are ignored
this.contextRunner.withPropertyValues("spring.messages.encoding:rubbish")
.run((context) -> assertThat(context.getMessage(
"foo", null, "blah", Locale.UK)).isEqualTo("blah"));
.run((context) -> assertThat(
context.getMessage("foo", null, "blah", Locale.UK))
.isEqualTo("blah"));
}
@Test
@Ignore("Expected to fail per gh-1075")
public void testMessageSourceFromPropertySourceAnnotation() {
this.contextRunner.withUserConfiguration(Config.class).run((context) ->
assertThat(context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("bar"));
this.contextRunner.withUserConfiguration(Config.class)
.run((context) -> assertThat(
context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("bar"));
}
@Test
public void testFallbackDefault() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
.run((context) -> assertThat(isFallbackToSystemLocale(
context.getBean(MessageSource.class))).isTrue());
.run((context) -> assertThat(
isFallbackToSystemLocale(context.getBean(MessageSource.class)))
.isTrue());
}
@Test
public void testFallbackTurnOff() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages",
"spring.messages.fallback-to-system-locale:false").run((context) ->
assertThat(isFallbackToSystemLocale(context.getBean(MessageSource.class)))
.isFalse());
this.contextRunner
.withPropertyValues("spring.messages.basename:test/messages",
"spring.messages.fallback-to-system-locale:false")
.run((context) -> assertThat(
isFallbackToSystemLocale(context.getBean(MessageSource.class)))
.isFalse());
}
@Test
public void testFormatMessageDefault() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
.run((context) -> assertThat(isAlwaysUseMessageFormat(
context.getBean(MessageSource.class))).isFalse());
.run((context) -> assertThat(
isAlwaysUseMessageFormat(context.getBean(MessageSource.class)))
.isFalse());
}
@Test
public void testFormatMessageOn() throws Exception {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages",
"spring.messages.always-use-message-format:true").run((context) ->
assertThat(isAlwaysUseMessageFormat(context.getBean(MessageSource.class)))
.isTrue());
this.contextRunner
.withPropertyValues("spring.messages.basename:test/messages",
"spring.messages.always-use-message-format:true")
.run((context) -> assertThat(
isAlwaysUseMessageFormat(context.getBean(MessageSource.class)))
.isTrue());
}
private boolean isFallbackToSystemLocale(MessageSource messageSource) {
......@@ -139,16 +150,19 @@ public class MessageSourceAutoConfigurationTests {
@Test
public void testUseCodeAsDefaultMessageDefault() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages")
.run((context) -> assertThat(isUseCodeAsDefaultMessage(
context.getBean(MessageSource.class))).isFalse());
.run((context) -> assertThat(
isUseCodeAsDefaultMessage(context.getBean(MessageSource.class)))
.isFalse());
}
@Test
public void testUseCodeAsDefaultMessageOn() {
this.contextRunner.withPropertyValues("spring.messages.basename:test/messages",
"spring.messages.use-code-as-default-message:true").run((context) ->
assertThat(isUseCodeAsDefaultMessage(
context.getBean(MessageSource.class))).isTrue());
this.contextRunner
.withPropertyValues("spring.messages.basename:test/messages",
"spring.messages.use-code-as-default-message:true")
.run((context) -> assertThat(
isUseCodeAsDefaultMessage(context.getBean(MessageSource.class)))
.isTrue());
}
private boolean isUseCodeAsDefaultMessage(MessageSource messageSource) {
......@@ -167,8 +181,9 @@ public class MessageSourceAutoConfigurationTests {
public void existingMessageSourceInParentIsIgnored() {
this.contextRunner.run((parent) -> this.contextRunner.withParent(parent)
.withPropertyValues("spring.messages.basename:test/messages")
.run((context) -> assertThat(context.getMessage(
"foo", null, "Foo message", Locale.UK)).isEqualTo("bar")));
.run((context) -> assertThat(
context.getMessage("foo", null, "Foo message", Locale.UK))
.isEqualTo("bar")));
}
@Configuration
......
......@@ -114,8 +114,8 @@ public class HttpMessageConvertersTests {
@Override
protected List<HttpMessageConverter<?>> postProcessConverters(
List<HttpMessageConverter<?>> converters) {
converters.removeIf((
converter) -> converter instanceof MappingJackson2XmlHttpMessageConverter);
converters.removeIf(
MappingJackson2XmlHttpMessageConverter.class::isInstance);
return converters;
}
......@@ -141,8 +141,8 @@ public class HttpMessageConvertersTests {
@Override
protected List<HttpMessageConverter<?>> postProcessPartConverters(
List<HttpMessageConverter<?>> converters) {
converters.removeIf((
converter) -> converter instanceof MappingJackson2XmlHttpMessageConverter);
converters.removeIf(
MappingJackson2XmlHttpMessageConverter.class::isInstance);
return converters;
}
......
......@@ -58,16 +58,14 @@ import static org.junit.Assert.fail;
public class DataSourceInitializerInvokerTests {
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(
AutoConfigurations.of(DataSourceAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
.withPropertyValues("spring.datasource.initialize=false",
"spring.datasource.url:jdbc:hsqldb:mem:init-"
+ UUID.randomUUID().toString());
@Test
public void dataSourceInitialized() {
this.contextRunner
.withPropertyValues("spring.datasource.initialize:true")
this.contextRunner.withPropertyValues("spring.datasource.initialize:true")
.run((context) -> {
assertThat(context).hasSingleBean(DataSource.class);
DataSource dataSource = context.getBean(DataSource.class);
......@@ -76,11 +74,9 @@ public class DataSourceInitializerInvokerTests {
});
}
@Test
public void initializationAppliesToCustomDataSource() {
this.contextRunner
.withUserConfiguration(OneDataSource.class)
this.contextRunner.withUserConfiguration(OneDataSource.class)
.withPropertyValues("spring.datasource.initialize:true")
.run((context) -> {
assertThat(context).hasSingleBean(DataSource.class);
......@@ -88,11 +84,10 @@ public class DataSourceInitializerInvokerTests {
});
}
private void assertDataSourceIsInitialized(DataSource dataSource) {
JdbcOperations template = new JdbcTemplate(dataSource);
assertThat(template.queryForObject("SELECT COUNT(*) from BAR",
Integer.class)).isEqualTo(1);
assertThat(template.queryForObject("SELECT COUNT(*) from BAR", Integer.class))
.isEqualTo(1);
}
@Test
......@@ -133,13 +128,11 @@ public class DataSourceInitializerInvokerTests {
@Test
public void dataSourceInitializedWithExplicitSqlScriptEncoding() {
this.contextRunner
.withPropertyValues("spring.datasource.initialize:true",
"spring.datasource.sqlScriptEncoding:UTF-8",
"spring.datasource.schema:"
+ getRelativeLocationFor("encoding-schema.sql"),
"spring.datasource.data:"
+ getRelativeLocationFor("encoding-data.sql"))
this.contextRunner.withPropertyValues("spring.datasource.initialize:true",
"spring.datasource.sqlScriptEncoding:UTF-8",
"spring.datasource.schema:"
+ getRelativeLocationFor("encoding-schema.sql"),
"spring.datasource.data:" + getRelativeLocationFor("encoding-data.sql"))
.run((context) -> {
DataSource dataSource = context.getBean(DataSource.class);
assertThat(dataSource).isInstanceOf(HikariDataSource.class);
......@@ -161,15 +154,14 @@ public class DataSourceInitializerInvokerTests {
@Test
public void initializationDoesNotApplyWithSeveralDataSources() {
this.contextRunner
.withUserConfiguration(TwoDataSources.class)
this.contextRunner.withUserConfiguration(TwoDataSources.class)
.withPropertyValues("spring.datasource.initialize:true")
.run((context) -> {
assertThat(context.getBeanNamesForType(DataSource.class)).hasSize(2);
assertDataSourceNotInitialized(context.getBean(
"oneDataSource", DataSource.class));
assertDataSourceNotInitialized(context.getBean(
"twoDataSource", DataSource.class));
assertDataSourceNotInitialized(
context.getBean("oneDataSource", DataSource.class));
assertDataSourceNotInitialized(
context.getBean("twoDataSource", DataSource.class));
});
}
......@@ -185,8 +177,7 @@ public class DataSourceInitializerInvokerTests {
private void assertDataSourceNotInitialized(DataSource dataSource) {
JdbcOperations template = new JdbcTemplate(dataSource);
try {
template.queryForObject("SELECT COUNT(*) from BAR",
Integer.class);
template.queryForObject("SELECT COUNT(*) from BAR", Integer.class);
fail("Query should have failed as BAR table does not exist");
}
catch (BadSqlGrammarException ex) {
......@@ -199,16 +190,13 @@ public class DataSourceInitializerInvokerTests {
@Test
public void dataSourceInitializedWithSchemaCredentials() {
this.contextRunner
.withPropertyValues("spring.datasource.initialize:true",
"spring.datasource.sqlScriptEncoding:UTF-8",
"spring.datasource.schema:"
+ getRelativeLocationFor("encoding-schema.sql"),
"spring.datasource.data:"
+ getRelativeLocationFor("encoding-data.sql"),
"spring.datasource.schema-username:admin",
"spring.datasource.schema-password:admin")
.run((context) -> {
this.contextRunner.withPropertyValues("spring.datasource.initialize:true",
"spring.datasource.sqlScriptEncoding:UTF-8",
"spring.datasource.schema:"
+ getRelativeLocationFor("encoding-schema.sql"),
"spring.datasource.data:" + getRelativeLocationFor("encoding-data.sql"),
"spring.datasource.schema-username:admin",
"spring.datasource.schema-password:admin").run((context) -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.isInstanceOf(BeanCreationException.class);
......@@ -217,16 +205,13 @@ public class DataSourceInitializerInvokerTests {
@Test
public void dataSourceInitializedWithDataCredentials() {
this.contextRunner
.withPropertyValues("spring.datasource.initialize:true",
"spring.datasource.sqlScriptEncoding:UTF-8",
"spring.datasource.schema:"
+ getRelativeLocationFor("encoding-schema.sql"),
"spring.datasource.data:"
+ getRelativeLocationFor("encoding-data.sql"),
"spring.datasource.data-username:admin",
"spring.datasource.data-password:admin")
.run((context) -> {
this.contextRunner.withPropertyValues("spring.datasource.initialize:true",
"spring.datasource.sqlScriptEncoding:UTF-8",
"spring.datasource.schema:"
+ getRelativeLocationFor("encoding-schema.sql"),
"spring.datasource.data:" + getRelativeLocationFor("encoding-data.sql"),
"spring.datasource.data-username:admin",
"spring.datasource.data-password:admin").run((context) -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.isInstanceOf(BeanCreationException.class);
......
......@@ -113,13 +113,13 @@ public abstract class AbstractJpaAutoConfigurationTests {
@Test
public void configuredWithSingleCandidateDataSource() {
this.contextRunner.withUserConfiguration(
TestTwoDataSourcesAndPrimaryConfiguration.class).run((context) -> {
assertThat(context).getBeans(DataSource.class).hasSize(2);
assertThat(context).hasSingleBean(JpaTransactionManager.class);
assertThat(context).hasSingleBean(EntityManagerFactory.class);
});
this.contextRunner
.withUserConfiguration(TestTwoDataSourcesAndPrimaryConfiguration.class)
.run((context) -> {
assertThat(context).getBeans(DataSource.class).hasSize(2);
assertThat(context).hasSingleBean(JpaTransactionManager.class);
assertThat(context).hasSingleBean(EntityManagerFactory.class);
});
}
@Test
......@@ -240,18 +240,16 @@ public abstract class AbstractJpaAutoConfigurationTests {
});
}
@Configuration
protected static class TestTwoDataSourcesConfiguration {
@Bean
public DataSource firstDataSource() {
public DataSource firstDataSource() {
return createRandomDataSource();
}
@Bean
public DataSource secondDataSource() {
public DataSource secondDataSource() {
return createRandomDataSource();
}
......@@ -267,12 +265,12 @@ public abstract class AbstractJpaAutoConfigurationTests {
@Bean
@Primary
public DataSource firstDataSource() {
public DataSource firstDataSource() {
return createRandomDataSource();
}
@Bean
public DataSource secondDataSource() {
public DataSource secondDataSource() {
return createRandomDataSource();
}
......
......@@ -75,12 +75,12 @@ public class HibernateJpaAutoConfigurationTests
contextRunner().withPropertyValues("spring.datasource.data:classpath:/city.sql",
// Missing:
"spring.datasource.schema:classpath:/ddl.sql").run((context) -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.hasMessageContaining("ddl.sql");
assertThat(context.getStartupFailure())
.hasMessageContaining("spring.datasource.schema");
});
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.hasMessageContaining("ddl.sql");
assertThat(context.getStartupFailure())
.hasMessageContaining("spring.datasource.schema");
});
}
@Test
......@@ -105,7 +105,7 @@ public class HibernateJpaAutoConfigurationTests
"spring.datasource.data:classpath:/city.sql")
.run((context) -> assertThat(
context.getBean(TestInitializedJpaConfiguration.class).called)
.isTrue());
.isTrue());
}
@Test
......@@ -164,7 +164,7 @@ public class HibernateJpaAutoConfigurationTests
.getJpaPropertyMap();
assertThat((String) jpaPropertyMap
.get("hibernate.transaction.jta.platform"))
.isEqualTo(TestJtaPlatform.class.getName());
.isEqualTo(TestJtaPlatform.class.getName());
});
}
......@@ -183,13 +183,15 @@ public class HibernateJpaAutoConfigurationTests
@Test
public void autoConfigurationBacksOffWithSeveralDataSources() {
contextRunner().withConfiguration(
AutoConfigurations.of(DataSourceTransactionManagerAutoConfiguration.class,
XADataSourceAutoConfiguration.class, JtaAutoConfiguration.class)
).withUserConfiguration(TestTwoDataSourcesConfiguration.class).run((context) -> {
assertThat(context).hasNotFailed();
assertThat(context).doesNotHaveBean(EntityManagerFactory.class);
});
contextRunner()
.withConfiguration(AutoConfigurations.of(
DataSourceTransactionManagerAutoConfiguration.class,
XADataSourceAutoConfiguration.class, JtaAutoConfiguration.class))
.withUserConfiguration(TestTwoDataSourcesConfiguration.class)
.run((context) -> {
assertThat(context).hasNotFailed();
assertThat(context).doesNotHaveBean(EntityManagerFactory.class);
});
}
@Configuration
......
......@@ -116,7 +116,8 @@ public class CommonOAuth2ProviderTests {
assertThat(providerDetails.getAuthorizationUri())
.isEqualTo("http://example.com/auth");
assertThat(providerDetails.getTokenUri()).isEqualTo("http://example.com/token");
assertThat(providerDetails.getUserInfoEndpoint().getUri()).isEqualTo("http://example.com/info");
assertThat(providerDetails.getUserInfoEndpoint().getUri())
.isEqualTo("http://example.com/info");
assertThat(providerDetails.getUserInfoEndpoint().getUserNameAttributeName())
.isEqualTo(null);
assertThat(providerDetails.getJwkSetUri()).isNull();
......@@ -136,9 +137,7 @@ public class CommonOAuth2ProviderTests {
}
private Builder builder(CommonOAuth2Provider provider) {
return provider.getBuilder("123")
.clientId("abcd")
.clientSecret("secret");
return provider.getBuilder("123").clientId("abcd").clientSecret("secret");
}
}
......@@ -67,7 +67,8 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
assertThat(adaptedProvider.getAuthorizationUri())
.isEqualTo("http://example.com/auth");
assertThat(adaptedProvider.getTokenUri()).isEqualTo("http://example.com/token");
assertThat(adaptedProvider.getUserInfoEndpoint().getUri()).isEqualTo("http://example.com/info");
assertThat(adaptedProvider.getUserInfoEndpoint().getUri())
.isEqualTo("http://example.com/info");
assertThat(adaptedProvider.getJwkSetUri()).isEqualTo("http://example.com/jkw");
assertThat(adapted.getRegistrationId()).isEqualTo("registration");
assertThat(adapted.getClientId()).isEqualTo("clientId");
......
......@@ -64,4 +64,5 @@ public class OAuth2ClientPropertiesTests {
this.thrown.expectMessage("Provider must not be empty.");
this.properties.validate();
}
}
......@@ -36,20 +36,29 @@ public class OAuth2ClientRegistrationRepositoryConfigurationTests {
private static final String REGISTRATION_PREFIX = "spring.security.oauth2.client.registration";
@Test
public void clientRegistrationRepositoryBeanShouldNotBeCreatedWhenPropertiesAbsent() throws Exception {
this.contextRunner.withUserConfiguration(OAuth2ClientRegistrationRepositoryConfiguration.class)
.run(context -> assertThat(context).doesNotHaveBean(ClientRegistrationRepository.class));
public void clientRegistrationRepositoryBeanShouldNotBeCreatedWhenPropertiesAbsent()
throws Exception {
this.contextRunner
.withUserConfiguration(
OAuth2ClientRegistrationRepositoryConfiguration.class)
.run(context -> assertThat(context)
.doesNotHaveBean(ClientRegistrationRepository.class));
}
@Test
public void clientRegistrationRepositoryBeanShouldBeCreatedWhenPropertiesPresent() throws Exception {
this.contextRunner.withUserConfiguration(OAuth2ClientRegistrationRepositoryConfiguration.class)
public void clientRegistrationRepositoryBeanShouldBeCreatedWhenPropertiesPresent()
throws Exception {
this.contextRunner
.withUserConfiguration(
OAuth2ClientRegistrationRepositoryConfiguration.class)
.withPropertyValues(REGISTRATION_PREFIX + ".foo.client-id=abcd",
REGISTRATION_PREFIX + ".foo.client-secret=secret",
REGISTRATION_PREFIX + ".foo.provider=github")
.run(context -> {
ClientRegistrationRepository repository = context.getBean(ClientRegistrationRepository.class);
ClientRegistration registration = repository.findByRegistrationId("foo");
ClientRegistrationRepository repository = context
.getBean(ClientRegistrationRepository.class);
ClientRegistration registration = repository
.findByRegistrationId("foo");
assertThat(registration).isNotNull();
assertThat(registration.getClientSecret()).isEqualTo("secret");
});
......
......@@ -55,59 +55,80 @@ public class OAuth2WebSecurityConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
@Test
@SuppressWarnings("unchecked")
public void securityConfigurerRegistersClientRegistrations() throws Exception {
this.contextRunner.withUserConfiguration(
ClientRepositoryConfiguration.class, OAuth2WebSecurityConfiguration.class)
.run(context -> {
ClientRegistrationRepository expected = context.getBean(ClientRegistrationRepository.class);
ClientRegistrationRepository actual = (ClientRegistrationRepository) ReflectionTestUtils.getField(
getAuthCodeFilters(context).get(0), "clientRegistrationRepository");
assertThat(isEqual(expected.findByRegistrationId("first"),
actual.findByRegistrationId("first"))).isTrue();
assertThat(isEqual(expected.findByRegistrationId("second"),
actual.findByRegistrationId("second"))).isTrue();
});
this.contextRunner.withUserConfiguration(ClientRepositoryConfiguration.class,
OAuth2WebSecurityConfiguration.class).run((context) -> {
ClientRegistrationRepository expected = context
.getBean(ClientRegistrationRepository.class);
ClientRegistrationRepository actual = (ClientRegistrationRepository) ReflectionTestUtils
.getField(getAuthCodeFilters(context).get(0),
"clientRegistrationRepository");
assertThat(isEqual(expected.findByRegistrationId("first"),
actual.findByRegistrationId("first"))).isTrue();
assertThat(isEqual(expected.findByRegistrationId("second"),
actual.findByRegistrationId("second"))).isTrue();
});
}
@Test
public void securityConfigurerBacksOffWhenClientRegistrationBeanAbsent() throws Exception {
this.contextRunner.withUserConfiguration(TestConfig.class, OAuth2WebSecurityConfiguration.class)
.run(context -> assertThat(getAuthCodeFilters(context)).isEmpty());
public void securityConfigurerBacksOffWhenClientRegistrationBeanAbsent()
throws Exception {
this.contextRunner
.withUserConfiguration(TestConfig.class,
OAuth2WebSecurityConfiguration.class)
.run((context) -> assertThat(getAuthCodeFilters(context)).isEmpty());
}
@Test
public void securityConfigurerBacksOffWhenOtherWebSecurityAdapterPresent() throws Exception {
this.contextRunner.withUserConfiguration(TestWebSecurityConfigurerConfig.class, OAuth2WebSecurityConfiguration.class)
.run(context -> assertThat(getAuthCodeFilters(context)).isEmpty());
public void securityConfigurerBacksOffWhenOtherWebSecurityAdapterPresent()
throws Exception {
this.contextRunner
.withUserConfiguration(TestWebSecurityConfigurerConfig.class,
OAuth2WebSecurityConfiguration.class)
.run((context) -> assertThat(getAuthCodeFilters(context)).isEmpty());
}
@SuppressWarnings("unchecked")
@SuppressWarnings({ "unchecked", "cast" })
private List<Filter> getAuthCodeFilters(AssertableApplicationContext context) {
FilterChainProxy filterChain = (FilterChainProxy) context.getBean("springSecurityFilterChain");
FilterChainProxy filterChain = (FilterChainProxy) context
.getBean("springSecurityFilterChain");
List<SecurityFilterChain> filterChains = filterChain.getFilterChains();
List<Filter> filters = (List<Filter>) ReflectionTestUtils.getField(((List) filterChains).get(0), "filters");
List<Filter> oauth2Filters = filters.stream().filter(
f -> f instanceof AuthorizationCodeAuthenticationProcessingFilter ||
f instanceof AuthorizationCodeRequestRedirectFilter).collect(Collectors.toList());
return oauth2Filters.stream().filter(f -> f instanceof AuthorizationCodeAuthenticationProcessingFilter)
List<Filter> filters = (List<Filter>) ReflectionTestUtils
.getField(filterChains.get(0), "filters");
List<Filter> oauth2Filters = filters.stream()
.filter((
f) -> f instanceof AuthorizationCodeAuthenticationProcessingFilter
|| f instanceof AuthorizationCodeRequestRedirectFilter)
.collect(Collectors.toList());
return oauth2Filters.stream()
.filter((
f) -> f instanceof AuthorizationCodeAuthenticationProcessingFilter)
.collect(Collectors.toList());
}
private boolean isEqual(ClientRegistration reg1, ClientRegistration reg2) {
boolean result = ObjectUtils.nullSafeEquals(reg1.getClientId(), reg2.getClientId());
result = result && ObjectUtils.nullSafeEquals(reg1.getClientName(), reg2.getClientName());
result = result && ObjectUtils.nullSafeEquals(reg1.getClientSecret(), reg2.getClientSecret());
boolean result = ObjectUtils.nullSafeEquals(reg1.getClientId(),
reg2.getClientId());
result = result
&& ObjectUtils.nullSafeEquals(reg1.getClientName(), reg2.getClientName());
result = result && ObjectUtils.nullSafeEquals(reg1.getClientSecret(),
reg2.getClientSecret());
result = result && ObjectUtils.nullSafeEquals(reg1.getScope(), reg2.getScope());
result = result && ObjectUtils.nullSafeEquals(reg1.getRedirectUri(), reg2.getRedirectUri());
result = result && ObjectUtils.nullSafeEquals(reg1.getRegistrationId(), reg2.getRegistrationId());
result = result && ObjectUtils.nullSafeEquals(reg1.getAuthorizationGrantType(), reg2.getAuthorizationGrantType());
result = result && ObjectUtils.nullSafeEquals(reg1.getProviderDetails().getAuthorizationUri(),
result = result && ObjectUtils.nullSafeEquals(reg1.getRedirectUri(),
reg2.getRedirectUri());
result = result && ObjectUtils.nullSafeEquals(reg1.getRegistrationId(),
reg2.getRegistrationId());
result = result && ObjectUtils.nullSafeEquals(reg1.getAuthorizationGrantType(),
reg2.getAuthorizationGrantType());
result = result && ObjectUtils.nullSafeEquals(
reg1.getProviderDetails().getAuthorizationUri(),
reg2.getProviderDetails().getAuthorizationUri());
result = result && ObjectUtils.nullSafeEquals(reg1.getProviderDetails().getUserInfoEndpoint(),
result = result && ObjectUtils.nullSafeEquals(
reg1.getProviderDetails().getUserInfoEndpoint(),
reg2.getProviderDetails().getUserInfoEndpoint());
result = result && ObjectUtils.nullSafeEquals(reg1.getProviderDetails().getTokenUri(),
reg2.getProviderDetails().getTokenUri());
result = result
&& ObjectUtils.nullSafeEquals(reg1.getProviderDetails().getTokenUri(),
reg2.getProviderDetails().getTokenUri());
return result;
}
......@@ -136,16 +157,14 @@ public class OAuth2WebSecurityConfigurationTests {
private ClientRegistration getClientRegistration(String id, String userInfoUri) {
ClientRegistration.Builder builder = new ClientRegistration.Builder(id);
builder.clientName("foo")
.clientId("foo")
.clientAuthenticationMethod(org.springframework.security.oauth2.core.ClientAuthenticationMethod.BASIC)
builder.clientName("foo").clientId("foo")
.clientAuthenticationMethod(
org.springframework.security.oauth2.core.ClientAuthenticationMethod.BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.scope("read")
.clientSecret("secret")
.scope("read").clientSecret("secret")
.redirectUri("http://redirect-uri.com")
.authorizationUri("http://authorization-uri.com")
.tokenUri("http://token-uri.com")
.userInfoUri(userInfoUri)
.tokenUri("http://token-uri.com").userInfoUri(userInfoUri)
.userNameAttributeName("login");
return builder.build();
}
......
......@@ -2754,54 +2754,52 @@ explicitly configure the paths that you do want to override.
=== OAuth2
=== Client
If you have `spring-security-oauth2-client` on your classpath you can take advantage of
some auto-configuration to make it easy to set up an OAuth2 Client. This configuration
makes use of the properties under `OAuth2ClientProperties`.
If you have `spring-security-oauth2-client` on your classpath you can take advantage of some
auto-configuration to make it easy to set up an OAuth2 Client. This configuration makes use of
the properties under `OAuth2ClientProperties`.
You can register multiple OAuth2 clients and providers under the `spring.security.oauth2.client` prefix.
For example,
You can register multiple OAuth2 clients and providers under the
`spring.security.oauth2.client` prefix. For example:
[source,yaml,indent=0]
----
# application.yml
spring:
security:
oauth2:
client:
registration:
my-client-1:
client-id: abcd
client-secret: password
client-name: Client for user scope
provider: my-oauth-provider
scope: user
redirect-uri: http://my-redirect-uri.com
authentication-method: basic
authorization-grant-type: authorization_code
my-client2:
client-id: abcd
client-secret: password
client-name: Client for email scope
provider: my-oauth-provider
scope: email
redirect-uri: http://my-redirect-uri.com
authentication-method: basic
authorization-grant-type: authorization_code
provider:
my-oauth-provider:
authorization-uri: http://my-auth-server/oauth/authorize
token-uri: http://my-auth-server/oauth/token
user-info-uri: http://my-auth-server/userinfo
jwk-set-uri: http://my-auth-server/token_keys
user-name-attribute: name
# additional configuration as required
----
NOTE: For common OAuth2 and OpenID providers such as Google, Github, Facebook and Okta, we provide a set of
provider defaults. If you don't need to customize these providers, you do not need to provide the `provider`
configuration. The client registration `provider` key should reference one these providers.
spring:
security:
oauth2:
client:
registration:
my-client-1:
client-id: abcd
client-secret: password
client-name: Client for user scope
provider: my-oauth-provider
scope: user
redirect-uri: http://my-redirect-uri.com
authentication-method: basic
authorization-grant-type: authorization_code
my-client2:
client-id: abcd
client-secret: password
client-name: Client for email scope
provider: my-oauth-provider
scope: email
redirect-uri: http://my-redirect-uri.com
authentication-method: basic
authorization-grant-type: authorization_code
provider:
my-oauth-provider:
authorization-uri: http://my-auth-server/oauth/authorize
token-uri: http://my-auth-server/oauth/token
user-info-uri: http://my-auth-server/userinfo
jwk-set-uri: http://my-auth-server/token_keys
user-name-attribute: name
----
NOTE: For common OAuth2 and OpenID providers such as Google, Github, Facebook and Okta,
we provide a set of provider defaults. If you don't need to customize these providers, you
do not need to provide the `provider` configuration. The client registration `provider`
key should reference one these providers.
[[boot-features-security-actuator]]
......
......@@ -73,6 +73,7 @@ public class DevToolsIntegrationTests {
@Before
public void launchApplication() throws Exception {
this.serverPortFile.delete();
System.out.println("Launching " + this.javaLauncher.getClass());
this.launchedApplication = this.applicationLauncher
.launchApplication(this.javaLauncher);
}
......@@ -139,6 +140,7 @@ public class DevToolsIntegrationTests {
private int awaitServerPort() throws Exception {
long end = System.currentTimeMillis() + 30000;
while (this.serverPortFile.length() == 0) {
System.out.println("Getting server port " + this.serverPortFile.length());
if (System.currentTimeMillis() > end) {
throw new IllegalStateException(String.format(
"server.port file was not written within 30 seconds. "
......@@ -153,6 +155,7 @@ public class DevToolsIntegrationTests {
FileReader portReader = new FileReader(this.serverPortFile);
int port = Integer.valueOf(FileCopyUtils.copyToString(portReader));
this.serverPortFile.delete();
System.out.println("Got port " + port);
return port;
}
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<!-- Your own application should inherit from spring-boot-starter-parent -->
......
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.oauth2.client;
import java.security.Principal;
......@@ -5,9 +21,6 @@ import java.security.Principal;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Madhura Bhave
*/
@RestController
public class ExampleController {
......
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.oauth2.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Madhura Bhave
*/
@SpringBootApplication
public class SampleOAuth2ClientApplication {
......
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.oauth2.client;
import java.net.URI;
......@@ -16,11 +32,6 @@ import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for an OAuth2 client application.
*
* @author Madhura Bhave
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
"APP-CLIENT-ID=my-client-id", "APP-CLIENT-SECRET=my-client-secret" })
......@@ -43,10 +54,13 @@ public class SampleOAuth2ClientApplicationTests {
@Test
public void loginShouldHaveBothOAuthClientsToChooseFrom() throws Exception {
ResponseEntity<String> entity = this.restTemplate.getForEntity("/login", String.class);
ResponseEntity<String> entity = this.restTemplate.getForEntity("/login",
String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).contains("/oauth2/authorization/code/github-client-1");
assertThat(entity.getBody()).contains("/oauth2/authorization/code/github-client-2");
assertThat(entity.getBody())
.contains("/oauth2/authorization/code/github-client-1");
assertThat(entity.getBody())
.contains("/oauth2/authorization/code/github-client-2");
}
}
\ No newline at end of file
}
......@@ -148,8 +148,7 @@ public class TestRestTemplate {
interceptors = Collections.emptyList();
}
interceptors = new ArrayList<>(interceptors);
interceptors.removeIf(
(interceptor) -> interceptor instanceof BasicAuthorizationInterceptor);
interceptors.removeIf(BasicAuthorizationInterceptor.class::isInstance);
interceptors.add(new BasicAuthorizationInterceptor(username, password));
restTemplate.setInterceptors(interceptors);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment