Permalink
Browse files

CFID-233,CFID-214: changes in SECOAUTH require updates to config, and…

… spiff up integration test config

Change-Id: Ia40db61286e436e3fff63f5745bf50eb7c6d57c6
  • Loading branch information...
1 parent 7385a5f commit fb10cbebc29e432b3ae86f7c3d250b1e8ae18ffd @dsyer dsyer committed Apr 13, 2012
View
109 README.md
@@ -54,9 +54,10 @@ ruby 1.9, and bundler installed, then
(or leave out the username / password to be prompted).
-This authenticates and obtains an access token from the server using the OAuth2 implicit
-grant, similar to the approach intended for a client like VMC. The token is
-returned in stdout, so copy paste the value into this next command:
+This authenticates and obtains an access token from the server using
+the OAuth2 implicit grant, similar to the approach intended for a
+client like VMC. The token is returned in stdout, so copy paste the
+value into this next command:
$ ./gem/bin/uaa --client-id=admin --client-secret=adminclientsecret decode
@@ -68,16 +69,40 @@ token grant on stdout.
With all apps deployed into a running server on port 8080 the tests
will include integration tests (a check is done before each test that
the app is running). You can deploy them in your IDE or using the
-command line with `mvn tomcat:run -P integration`.
+command line with `mvn tomcat:run` and then run the tests as normal.
For individual modules, or for the whole project, you can also run
-integration tests from the command line in one go with
+integration tests and the server from the command line in one go with
$ mvn test -P integration
(This might require an initial `mvn install` from the parent directory
to get the wars in your local repo first.)
+To make the tests work in various environments you can modify the
+configuration of the server and the tests (e.g. the admin client)
+using a variety of mechanisms. The simplest is to provide additional
+Maven profiles on the command line, e.g.
+
+ $ (cd uaa; mvn test -P vcap)
+
+will run the integration tests against a uaa server running in a local
+vcap, so for example the service URL is set to `uaa.vcap.me` (by
+default). There are several Maven profiles to play with, and they can
+be used to run the server, or the tests or both:
+
+* `local`: runs the server on the ROOT context `http://localhost:8080/`
+
+* `vcap`: also runs the server on the ROOT context and points the
+ tests at `uaa.vcap.me`.
+
+* `devuaa`: points the tests at `http://devuaa.cloudfoundry.com` (an
+ instance of UAA deployed on cloudfoundry).
+
+All these profiles set the `CLOUD_FOUNDRY_CONFIG_PATH` to pick up a
+`uaa.yml` and (if appropriate) set the context root for running the
+server (see below for more detail on that).
+
### BVTs
There is a really simple cucumber feature spec (`--tag @uaa`) to
@@ -88,6 +113,13 @@ Typical usage for a local (`uaa.vcap.me`) instance:
$ cd vcap/tests
$ rake bvt:run_uaa
+You can change the most common important settings with environment
+variables (see below), or with a custom `uaa.yml`. N.B. `MAVEN_OPTS`
+cannot be used to set JVM system properties for the tests, but it can
+be used to set memory limits for the process etc.
+
+### Custom YAML Configuration
+
To modify the runtime parameters you can provide a `uaa.yml`, e.g.
$ cat > /tmp/uaa.yml
@@ -97,34 +129,71 @@ To modify the runtime parameters you can provide a `uaa.yml`, e.g.
username: dev@cloudfoundry.org # defaults to vcap_tester@vmware.com
password: changeme
email: dev@cloudfoundry.org
+
+then from `vcap-tests`
+
$ CLOUD_FOUNDRY_CONFIG_PATH=/tmp rake bvt:run_uaa
-The integration tests look for a Yaml file in the following locations,
-and the webapp does the same when it starts up so you can use the same
-config file for both:
+or from `uaa/uaa`
- ${UAA_CONFIG_URL}
- file:${UAA_CONFIG_FILE}
- file:${CLOUD_FOUNDRY_CONFIG_PATH}/uaa.yml
+ $ CLOUD_FOUNDRY_CONFIG_PATH=/tmp mvn test
-To test against a vcap instance use the Maven profile `vcap`:
+The integration tests look for a Yaml file in the following locations
+(later entries override earlier ones), and the webapp does the same
+when it starts up so you can use the same config file for both:
+
+ classpath:uaa.yml
+ file:${CLOUD_FOUNDRY_CONFIG_PATH}/uaa.yml
+ file:${UAA_CONFIG_FILE}
+ ${UAA_CONFIG_URL}
+
+### Using Maven with Cloud Foundry or VCAP
+
+To test against a vcap instance use the Maven profile `vcap` (it
+switches off some of the tests that create random client and user
+accounts):
$ (cd uaa; mvn test -P vcap)
-
+
To change the target server it should suffice to set
`VCAP_BVT_TARGET` (the tests prefix it with `uaa.` to form the
server url), e.g.
- $ VCAP_BVT_TARGET=appcloud21.dev.mozycloud rake bvt:run_uaa
+ $ VCAP_BVT_TARGET=appcloud21.dev.mozycloud mvn test -P vcap
+
+You can also override some of the other most important default
+settings using environment variables. The defaults as usual come from
+`uaa.yml` but tests will search first in an environment variable:
-You can also change individual properties on the command line with
-`UAA_ARGS`, which are passed on to the mvn command line, or with
-MAVEN_OPTS which are passed on to the shell executing mvn, e.g.
+* `UAA_ADMIN_CLIENT_ID` the client id for bootstrapping client
+ registrations needed for the rest of the tests.
- $ UAA_ARGS=-Duaa=uaa.appcloud21.dev.mozycloud rake bvt:run_uaa
+* `UAA_ADMIN_CLIENT_SECRET` the client secret for boottrapping client
+ registrations
+
+All other settings from `uaa.yml` can be overriden individually as
+system properties. Running in an IDE this is easy just using whatever
+features allow you to modify the JVM in test runs, but using Maven you
+have to use the `argLine` property to get settings passed onto the
+test JVM, e.g.
+
+ $ mvn -DargLine=-Duaa.test.username=foo test
+
+will create an account with `userName=foo` for testing (instead using
+the default setting from `uaa.yml`).
+
+If you prefer environment variables to system properties you can use a
+custom `uaa.yml` with placeholders for your environment variables,
+e.g.
+
+ uaa:
+ test:
+ username: ${UAA_TEST_USERNAME:marissa}
-N.B. MAVEN_OPTS cannot be used to set JVM system properties for the
-tests, but it can be used to set memory limits for the process etc.
+will look for an environment variable (or system property)
+`UAA_TEST_USERNAME` before defaulting to `marissa`. This is the trick
+used to expose `UAA_ADMIN_CLIENT_SECRET` etc. in the standard
+configuration.
## Inventory
View
6 .../src/main/java/org/cloudfoundry/identity/uaa/config/EnvironmentPropertiesFactoryBean.java
@@ -18,6 +18,8 @@
import java.util.Map;
import java.util.Properties;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.ConfigurableEnvironment;
@@ -33,6 +35,8 @@
*
*/
public class EnvironmentPropertiesFactoryBean implements FactoryBean<Map<String,?>>, EnvironmentAware {
+
+ private static Log logger = LogFactory.getLog(EnvironmentPropertiesFactoryBean.class);
private static final Collection<String> STATIC_PROPERTY_SOURCES = Arrays.asList(
StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME,
@@ -59,8 +63,10 @@ public void setEnvironment(Environment environment) {
for (Object key : defaultProperties .keySet()) {
String name = (String) key;
if (environment!=null && environment.containsProperty(name)) {
+ logger.debug("From Environment: " + name + "=" + environment.getProperty(name));
result.put(name, environment.getProperty(name));
} else {
+ logger.debug("From Defaults: " + name + "=" + defaultProperties.getProperty(name));
result.put(name, defaultProperties.get(key));
}
}
View
58 common/src/main/java/org/cloudfoundry/identity/uaa/integration/TestProfileEnvironment.java
@@ -13,10 +13,12 @@
package org.cloudfoundry.identity.uaa.integration;
import java.util.Enumeration;
+import java.util.Map;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.cloudfoundry.identity.uaa.config.EnvironmentPropertiesFactoryBean;
import org.cloudfoundry.identity.uaa.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertiesPropertySource;
@@ -33,50 +35,54 @@
private static final Log logger = LogFactory.getLog(TestProfileEnvironment.class);
- private static final String[] DEFAULT_PROFILE_CONFIG_FILE_LOCATIONS = new String[] { "${UAA_CONFIG_URL}",
- "file:${UAA_CONFIG_FILE}", "file:${CLOUD_FOUNDRY_CONFIG_PATH}/uaa.yml" };
+ private static final String[] DEFAULT_PROFILE_CONFIG_FILE_LOCATIONS = new String[] { "classpath:uaa.yml",
+ "file:${CLOUD_FOUNDRY_CONFIG_PATH}/uaa.yml", "file:${UAA_CONFIG_FILE}", "${UAA_CONFIG_URL}" };
private StandardEnvironment environment = new StandardEnvironment();
private static TestProfileEnvironment instance = new TestProfileEnvironment();
-
+
private ResourceLoader recourceLoader = new DefaultResourceLoader();
private TestProfileEnvironment() {
Resource resource = null;
+ Properties properties = new Properties();
+
for (String location : DEFAULT_PROFILE_CONFIG_FILE_LOCATIONS) {
- location = environment.resolvePlaceholders(location);
+ location = environment.resolvePlaceholders(location);
resource = recourceLoader.getResource(location);
if (resource != null && resource.exists()) {
- break;
+ YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
+ factory.setResource(resource);
+ factory.setIgnoreResourceNotFound(true);
+ properties.putAll(factory.getObject());
}
}
-
- if (resource != null) {
- YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
- factory.setResource(resource);
- factory.setIgnoreResourceNotFound(true);
- Properties properties = factory.getObject();
- logger.debug("Decoding environment properties: " + properties.size());
- if (!properties.isEmpty()) {
- for (Enumeration<?> names = properties.propertyNames(); names.hasMoreElements();) {
- String name = (String) names.nextElement();
- String value = properties.getProperty(name);
- if (value != null) {
- properties.setProperty(name, environment.resolvePlaceholders(value));
- }
- }
- logger.debug("Environment properties: " + properties);
- if (properties.containsKey("spring_profiles")) {
- properties.setProperty(StandardEnvironment.ACTIVE_PROFILES_PROPERTY_NAME,
- properties.getProperty("spring_profiles"));
+
+ logger.debug("Decoding environment properties: " + properties.size());
+ if (!properties.isEmpty()) {
+ for (Enumeration<?> names = properties.propertyNames(); names.hasMoreElements();) {
+ String name = (String) names.nextElement();
+ String value = properties.getProperty(name);
+ if (value != null) {
+ properties.setProperty(name, environment.resolvePlaceholders(value));
}
- // System properties should override the ones in the config file, so add it last
- environment.getPropertySources().addLast(new PropertiesPropertySource("uaa.yml", properties));
}
+ if (properties.containsKey("spring_profiles")) {
+ properties.setProperty(StandardEnvironment.ACTIVE_PROFILES_PROPERTY_NAME,
+ properties.getProperty("spring_profiles"));
+ }
+ // System properties should override the ones in the config file, so add it last
+ environment.getPropertySources().addLast(new PropertiesPropertySource("uaa.yml", properties));
}
+
+ EnvironmentPropertiesFactoryBean factory = new EnvironmentPropertiesFactoryBean();
+ factory.setEnvironment(environment);
+ factory.setDefaultProperties(properties);
+ Map<String, ?> debugProperties = factory.getObject();
+ logger.debug("Environment properties: " + debugProperties);
}
/**
View
4 common/src/main/java/org/cloudfoundry/identity/uaa/integration/UaaTestAccounts.java
@@ -114,7 +114,7 @@ public String getAdminClientId() {
public String getAdminClientSecret() {
return environment.getProperty("UAA_ADMIN_CLIENT_SECRET",
- environment.getProperty("oauth.clients.admin.secret", "adminclientsecret"));
+ environment.getProperty("oauth.clients.admin.secret", "adminsecret"));
}
/**
@@ -131,7 +131,7 @@ public String getVarzAuthorizationHeader() {
}
public String getBatchAuthorizationHeader() {
- return getAuthorizationHeader("batch", "batch", "batchsecret");
+ return getAuthorizationHeader("batch", "batch_user", "batch_password");
}
public String getAuthorizationHeader(String prefix, String defaultUsername, String defaultPassword) {
View
2 samples/api/src/main/webapp/WEB-INF/spring-servlet.xml
@@ -77,7 +77,7 @@
</property>
</bean>
- <oauth:resource-server id="oauth2ServiceFilter" resource-id="api" token-services-ref="tokenServices"/>
+ <oauth:resource-server id="oauth2ServiceFilter" resource-id="api" token-services-ref="tokenServices" />
<mvc:annotation-driven />
View
2 uaa/pom.xml
@@ -30,7 +30,7 @@
<profiles>
<profile>
- <id>cloud</id>
+ <id>devuaa</id>
<properties>
<CLOUD_FOUNDRY_CONFIG_PATH>src/test/resources/test/profiles/devuaa</CLOUD_FOUNDRY_CONFIG_PATH>
</properties>
View
4 uaa/src/main/webapp/WEB-INF/oauth-clients.xml
@@ -47,10 +47,10 @@
</http>
<oauth:resource-server id="tokensResourceAuthenticationFilter" token-services-ref="tokenServices"
- resource-id="tokens" />
+ resource-id="tokens" entry-point-ref="oauthAuthenticationEntryPoint"/>
<oauth:resource-server id="clientResourceAuthenticationFilter" token-services-ref="tokenServices"
- resource-id="clients" />
+ resource-id="clients" entry-point-ref="oauthAuthenticationEntryPoint"/>
<bean id="clientDetails" class="org.springframework.security.oauth2.provider.JdbcClientDetailsService">
<constructor-arg ref="dataSource" />
View
4 uaa/src/main/webapp/WEB-INF/spring-scim.xml
@@ -60,10 +60,10 @@
</http>
<oauth:resource-server id="passwordResourceAuthenticationFilter" token-services-ref="tokenServices"
- resource-id="password" />
+ resource-id="password" entry-point-ref="oauthAuthenticationEntryPoint"/>
<oauth:resource-server id="scimResourceAuthenticationFilter" token-services-ref="tokenServices"
- resource-id="scim" />
+ resource-id="scim" entry-point-ref="oauthAuthenticationEntryPoint"/>
<bean id="userEndPointRequestMatcher" class="org.cloudfoundry.identity.uaa.security.web.UaaRequestMatcher">
<constructor-arg value="/User" />
View
2 uaa/src/main/webapp/WEB-INF/spring-servlet.xml
@@ -172,7 +172,7 @@
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
<oauth:resource-server id="openidResourceAuthenticationFilter" token-services-ref="tokenServices"
- resource-id="openid" />
+ resource-id="openid" entry-point-ref="oauthAuthenticationEntryPoint"/>
<context:mbean-server id="mbeanServer" />
View
8 ...rc/test/java/org/cloudfoundry/identity/uaa/integration/BatchEndpointIntegrationTests.java
@@ -15,8 +15,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import org.junit.Assume;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.http.HttpHeaders;
@@ -33,12 +31,6 @@
public ServerRunning serverRunning = ServerRunning.isRunning();
private UaaTestAccounts testAccounts = UaaTestAccounts.standard(serverRunning);
-
- @Before
- public void checkVcap() {
- // If running against vcap we don't know the varz password
- Assume.assumeTrue(!testAccounts.isProfileActive("vcap"));
- }
/**
* tests a happy-day flow of the <code>/batch</code> endpoint
View
33 .../java/org/cloudfoundry/identity/uaa/integration/ClientAdminEndpointsIntegrationTests.java
@@ -48,7 +48,7 @@
@Rule
public TestAccountSetup testAccountSetup = TestAccountSetup.standard(serverRunning, testAccounts);
-
+
@Before
public void setUp() {
Assume.assumeTrue(!testAccounts.isProfileActive("vcap"));
@@ -57,7 +57,7 @@ public void setUp() {
@Test
public void testGetClient() throws Exception {
- OAuth2AccessToken token = getClientCredentialsAccessToken("read", "admin", "adminclientsecret");
+ OAuth2AccessToken token = getClientCredentialsAccessToken("read");
HttpHeaders headers = getAuthenticatedHeaders(token);
ResponseEntity<String> result = serverRunning.getForString("/oauth/clients/vmc", headers);
@@ -69,7 +69,7 @@ public void testGetClient() throws Exception {
@Test
public void testCreateClient() throws Exception {
- OAuth2AccessToken token = getClientCredentialsAccessToken("read,write", "admin", "adminclientsecret");
+ OAuth2AccessToken token = getClientCredentialsAccessToken("read,write");
HttpHeaders headers = getAuthenticatedHeaders(token);
BaseClientDetails client = new BaseClientDetails("", "foo,bar", "client_credentials", "ROLE_CLIENT");
@@ -83,18 +83,18 @@ public void testCreateClient() throws Exception {
@Test
public void testUpdateClient() throws Exception {
- OAuth2AccessToken token = getClientCredentialsAccessToken("read,write", "admin", "adminclientsecret");
+ OAuth2AccessToken token = getClientCredentialsAccessToken("read,write");
HttpHeaders headers = getAuthenticatedHeaders(token);
-
+
BaseClientDetails client = new BaseClientDetails("", "foo,bar", "client_credentials", "ROLE_CLIENT");
client.setClientId(new RandomValueStringGenerator().generate());
ResponseEntity<Void> result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients"),
HttpMethod.POST, new HttpEntity<BaseClientDetails>(client, headers), Void.class);
assertEquals(HttpStatus.CREATED, result.getStatusCode());
-
+
client.setResourceIds(Collections.singleton("foo"));
-
+
result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients/{client}"),
HttpMethod.PUT, new HttpEntity<BaseClientDetails>(client, headers), Void.class, client.getClientId());
assertEquals(HttpStatus.NO_CONTENT, result.getStatusCode());
@@ -104,20 +104,21 @@ public void testUpdateClient() throws Exception {
@Test
public void testDeleteClient() throws Exception {
- OAuth2AccessToken token = getClientCredentialsAccessToken("read,write", "admin", "adminclientsecret");
+ OAuth2AccessToken token = getClientCredentialsAccessToken("read,write");
HttpHeaders headers = getAuthenticatedHeaders(token);
-
+
BaseClientDetails client = new BaseClientDetails("", "foo,bar", "client_credentials", "ROLE_CLIENT");
client.setClientId(new RandomValueStringGenerator().generate());
ResponseEntity<Void> result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients"),
HttpMethod.POST, new HttpEntity<BaseClientDetails>(client, headers), Void.class);
assertEquals(HttpStatus.CREATED, result.getStatusCode());
-
+
client.setResourceIds(Collections.singleton("foo"));
-
- result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients/{client}"),
- HttpMethod.DELETE, new HttpEntity<BaseClientDetails>(client, headers), Void.class, client.getClientId());
+
+ result = serverRunning.getRestTemplate()
+ .exchange(serverRunning.getUrl("/oauth/clients/{client}"), HttpMethod.DELETE,
+ new HttpEntity<BaseClientDetails>(client, headers), Void.class, client.getClientId());
assertEquals(HttpStatus.NO_CONTENT, result.getStatusCode());
}
@@ -130,8 +131,10 @@ public HttpHeaders getAuthenticatedHeaders(OAuth2AccessToken token) {
return headers;
}
- private OAuth2AccessToken getClientCredentialsAccessToken(String scope, String clientId, String clientSecret)
- throws Exception {
+ private OAuth2AccessToken getClientCredentialsAccessToken(String scope) throws Exception {
+
+ String clientId = testAccounts.getAdminClientId();
+ String clientSecret = testAccounts.getAdminClientSecret();
MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>();
formData.add("grant_type", "client_credentials");

0 comments on commit fb10cbe

Please sign in to comment.