Permalink
Browse files

CFID-41, CFID-214: again don't make any assumptions about the database

Change-Id: Ic1a77410831350867f2b7e4d0f7f5a58c456f412
  • Loading branch information...
1 parent 7d6e5ed commit 07d476217d01b55a661831c7869d4e928537ca35 @dsyer dsyer committed Mar 26, 2012
Showing with 1,116 additions and 1,238 deletions.
  1. +74 −64 README.md
  2. +1 −1 gem/lib/uaa/client.rb
  3. +4 −2 pom.xml
  4. +39 −5 samples/api/pom.xml
  5. +18 −14 samples/api/src/test/java/org/cloudfoundry/identity/api/web/AppsIntegrationTests.java
  6. +38 −35 samples/api/src/test/java/org/cloudfoundry/identity/api/web/ServerRunning.java
  7. +45 −21 samples/app/pom.xml
  8. +14 −27 samples/app/src/main/webapp/WEB-INF/spring-servlet.xml
  9. +8 −14 samples/app/src/main/webapp/WEB-INF/web.xml
  10. +13 −6 ...s/app/src/test/java/org/cloudfoundry/identity/app/integration/AuthenticationIntegrationTests.java
  11. +50 −6 samples/app/src/test/java/org/cloudfoundry/identity/app/integration/ServerRunning.java
  12. +38 −19 uaa/pom.xml
  13. +8 −14 uaa/src/main/java/org/cloudfoundry/identity/uaa/config/YamlMapFactoryBean.java
  14. +1 −1 uaa/src/main/java/org/cloudfoundry/identity/uaa/config/YamlServletProfileInitializer.java
  15. +8 −4 uaa/src/main/java/org/cloudfoundry/identity/uaa/oauth/ClientAdminBootstrap.java
  16. +20 −1 uaa/src/main/java/org/cloudfoundry/identity/uaa/oauth/ClientAdminEndpoints.java
  17. +0 −165 uaa/src/main/java/org/cloudfoundry/identity/uaa/user/JdbcUaaAdminUserBootstrap.java
  18. +0 −33 uaa/src/main/resources/uaa.yml
  19. +27 −7 uaa/src/main/webapp/WEB-INF/oauth-clients.xml
  20. +0 −14 uaa/src/main/webapp/WEB-INF/spring-scim.xml
  21. +1 −1 uaa/src/test/java/org/cloudfoundry/identity/uaa/config/YamlMapFactoryBeanTests.java
  22. +5 −2 ...c/test/java/org/cloudfoundry/identity/uaa/integration/AuthorizationCodeGrantIntegrationTests.java
  23. +4 −4 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/BatchEndpointIntegrationTests.java
  24. +0 −31 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/BeforeOAuth2Context.java
  25. +4 −4 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/CheckTokenEndpointIntegrationTests.java
  26. +4 −1 ...src/test/java/org/cloudfoundry/identity/uaa/integration/ClientAdminEndpointsIntegrationTests.java
  27. +4 −1 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ImplicitTokenGrantIntegrationTests.java
  28. +4 −1 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/NativeApplicationIntegrationTests.java
  29. +0 −37 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/OAuth2ContextConfiguration.java
  30. +0 −235 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/OAuth2ContextSetup.java
  31. +4 −1 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/RefreshTokenSupportIntegrationTests.java
  32. +24 −42 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ScimUserEndpointIntegrationTests.java
  33. +26 −4 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/ServerRunning.java
  34. +212 −0 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/TestAccountSetup.java
  35. +0 −165 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/TestAccounts.java
  36. +21 −11 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/TestProfileEnvironment.java
  37. +44 −114 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/TokenAdminEndpointsIntegrationTests.java
  38. +267 −0 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/UaaTestAccounts.java
  39. +17 −4 ...java/org/cloudfoundry/identity/uaa/integration/{OAuth2ContextSetupCallback.java → UrlHelper.java}
  40. +10 −8 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/UserInfoEndpointIntegrationTests.java
  41. +4 −4 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/VarzEndpointIntegrationTests.java
  42. +20 −33 uaa/src/test/java/org/cloudfoundry/identity/uaa/integration/VmcScimUserEndpointIntegrationTests.java
  43. +0 −36 uaa/src/test/java/org/cloudfoundry/identity/uaa/user/JdbcUaaAdminUserBootstrapTests.java
  44. +6 −37 uaa/src/test/resources/test/profiles/postgresql/uaa.yml
  45. +29 −9 uaa/src/test/resources/test/profiles/vcap/uaa.yml
View
138 README.md
@@ -31,8 +31,22 @@ First run the uaa server as described above:
$ cd uaa
$ mvn tomcat:run
-Then start another terminal and from the project base directory, run:
+Then start another terminal and from the project base directory, and ask
+the login endpoint to tell you about the system:
+
+ $ curl -H "Accept: application/json" localhost:8080/uaa/login
+ {
+ "timestamp":"2012-03-28T18:25:49+0100",
+ "commit_id":"111274e",
+ "prompts":{"username":["text","Username"],
+ "password":["password","Password"]
+ }
+ }
+
+Then you can try logging in with the UAA ruby gem. Make sure you have
+ruby 1.9, and bundler installed, then
+ $ (cd gem/; bundle)
$ ./gem/bin/uaa target localhost:8080/uaa
$ ./gem/bin/uaa login marissa koala
@@ -42,7 +56,7 @@ This authenticates and obtains an access token from the server using the OAuth2
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 --client_id=app --client_secret=appclientsecret decode <token>
+ $ ./gem/bin/uaa --client-id=admin --client-secret=adminclientsecret decode
and you should see your username and the client id of the original
token grant on stdout.
@@ -52,28 +66,27 @@ 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`.
+command line with `mvn tomcat:run -P integration`.
For individual modules, or for the whole project, you can also run
integration tests from the command line in one go with
- $ mvn integration-test
+ $ mvn integration-test -P integration
(This might require an initial `mvn install` from the parent directory
to get the wars in your local repo first.)
### BVTs
There is a really simple cucumber feature spec (`--tag @uaa`) to
-verify that the UAS server is there. There is also a rake task to
+verify that the UAA server is there. There is also a rake task to
launch the integration tests from the `uaa` submodule in `vcap`.
Typical usage for a local (`uaa.vcap.me`) instance:
$ cd vcap/tests
$ rake bvt:run_uaa
-To modify the runtime parameters you can provide a `uaa.yml` and set the
-env var `CLOUD_FOUNDRY_CONFIG_PATH`, e.g.
+To modify the runtime parameters you can provide a `uaa.yml`, e.g.
$ cat > /tmp/uaa.yml
uaa:
@@ -83,20 +96,31 @@ env var `CLOUD_FOUNDRY_CONFIG_PATH`, e.g.
password: changeme
email: dev@cloudfoundry.org
$ 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:
-The tests will usually fail on the first run because of the 1 sec
-granularity of the timestamp on the tokens in the cloud_controller (so
-duplicate tokens will be rejected by the server). When you run the
-second and subsequent times they should pass because new token values
-will be obtained from the server.
+ ${UAA_CONFIG_URL}
+ file:${UAA_CONFIG_FILE}
+ file:${CLOUD_FOUNDRY_CONFIG_PATH}/uaa.yml
+
+To test against a vcap instance use the Maven profile `vcap`:
+
+ $ (cd uaa; mvn test -P vcap)
+
+To change the target server it should suffice to set
+`BVT_TARGET_DOMAIN` (the tests prefix it with `uaa.` to form the
+server url).
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_ARGS=-Duaa=uaa.appcloud21.dev.mozycloud rake bvt:run_uaa
-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.
+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.
## Inventory
@@ -159,69 +183,55 @@ There is a `uaa.yml` in the application which provides defaults to the
placeholders in the Spring XML. Wherever you see
`${placeholder.name}` in the XML there is an opportunity to override
it either by providing a System property (`-D` to JVM) with the same
-name, or an environment-specific `uaa.yml` under
-`env['CLOUD_FOUNDRY_CONFIG_PATH']/uaa.yml`. When vcap is deployed the
-`CLOUD_FOUNDRY_CONFIG_PATH` is defined according to the way it was
-installed.
+name, or a custom `uaa.yml` (as desceibed above).
-All passwords and client secrets in the config files must be encypted
-using BCrypt. In Java you can do it like this (with
-`spring-securty-crypto` on the classpath):
-
- String password = BCrypt.hashpw("plaintext");
-
-In ruby you can do it like this:
-
- require 'bcrypt'
- password = BCrypt::Password.create('plaintext')
+All passwords and client secrets in the config files are plain text,
+but they will be inserted into the UAA database encrypted with BCrypt.
### User Account Data
-The default is to use an in-memory, hash-based user store that is
-pre-populated with some test users: e.g. `dale` has password
-`password` and `marissa` has password `koala`.
+The default is to use an in-memory RDBMS user store that is
+pre-populated with a single test users: `marissa` has password
+`koala`.
-To use a RDBMS for user data, activate the Spring profiles `jdbc` and
-one of `hsqldb` or `postgresql`. The opposite is `!jdbc` which needs
-to be specified explicitly if any other profiles are active. The
-`hsqldb` profile will start up with an in-memory RDBMS by default.
+To use Postgresql for user data, activate one of the Spring profiles
+`hsqldb` or `postgresql`.
-The active profiles can be configured by passing the
-`spring.profiles.active` parameter to the JVM. For, example to run
-with an embedded HSQL database:
+The active profiles can be configured in `uaa.yml` using
+
+ spring_profiles: postgresql
+
+or by passing the `spring.profiles.active` parameter to the JVM. For,
+example to run with an embedded HSQL database:
- mvn -Dspring.profiles.active=jdbc,hsqldb,!legacy tomcat:run
+ mvn -Dspring.profiles.active=hsqldb tomcat:run
Or to use PostgreSQL instead of HSQL:
- mvn -Dspring.profiles.active=jdbc,postgresql,!legacy tomcat:run
+ mvn -Dspring.profiles.active=postgresql tomcat:run
-To bootstrap a microcloud type environment you need an admin user.
+To bootstrap a microcloud type environment you need an admin client.
For this there is a database initializer component that inserts an
-admin user if it finds an empty database on startup. Override the
-default settings (username/password=admin/admin) in `uaa.yml`:
-
- bootstrap:
- admin:
- username: foo
- password: $2a$10$yHj...
- email: admin@test.com
- family_name: Piper
- given_name: Peter
-
-(the password has to be bcrypted).
-
-### Legacy Mode
-
-There is a legacy mode where the CF.com cloud controller is used for
-the authentication and token generation. To use this, launch the app
-with Spring profile `legacy` (a Maven profile with the same name is
-provided for convenience as well). The opposite is `!legacy` which
-needs to be specified explicitly if any other profiles are active.
-The cloud controller login URL defaults to
-`http://api.cloudfoundry.com/users/{username}/tokens` - to override it
-provide a System property or `uaa.yml` entry for
-`cloud_controller.login_url`.
+admin client. If the default profile is active (i.e. not
+`postgresql`) there is also a `vmc` client so that the gem login works
+out of the box. You can override the default settings and add
+additional clients in `uaa.yml`:
+
+ oauth:
+ clients:
+ admin:
+ authorized-grant-types: client_credentials
+ scope: read,write,password
+ authorities: ROLE_CLIENT,ROLE_ADMIN
+ id: admin
+ secret: adminclientsecret
+ resource-ids: clients
+
+The admin client can be used to create additional clients (but not to
+do anything much else). A client with read/write access to the `scim`
+resource will be needed to create user accounts. The integration
+tests take care of this automatically, inserting client and user
+accounts as necessary to make the tests work.
## The API Application
View
@@ -43,7 +43,7 @@ def initialize
@client_secret = nil
@grant_type = "implicit"
@scope = ["read"]
- @redirect_uri = "http://vmc.cloudfoundry.com/redirect"
+ @redirect_uri = "http://uaa.cloudfoundry.com/redirect/vmc"
end
# Get the prompts (login info) required by the UAA server. The response
View
@@ -8,7 +8,7 @@
<version>1.0.0.BUILD-SNAPSHOT</version>
<modules>
<module>uaa</module>
- <module>samples</module>
+ <!--module>samples</module-->
</modules>
<properties>
<spring.version>3.1.1.RELEASE</spring.version>
@@ -142,7 +142,9 @@
</goals>
</pluginExecutionFilter>
<action>
- <execute/>
+ <execute>
+ <runOnIncremental>false</runOnIncremental>
+ </execute>
</action>
</pluginExecution>
</pluginExecutions>
View
@@ -38,12 +38,21 @@
</configuration>
</execution>
</executions>
- <configuration>
- <addContextWarDependencies>true</addContextWarDependencies>
- </configuration>
+ <configuration>
+ <addContextWarDependencies>true</addContextWarDependencies>
+ </configuration>
</plugin>
</plugins>
</build>
+ <dependencies>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>uaa</artifactId>
+ <version>${pom.version}</version>
+ <type>war</type>
+ <scope>tomcat</scope>
+ </dependency>
+ </dependencies>
</profile>
</profiles>
@@ -117,16 +126,41 @@
<dependency>
<groupId>${pom.groupId}</groupId>
- <artifactId>uaa</artifactId>
+ <artifactId>cloudfoundry-identity-uaa</artifactId>
<version>${pom.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <!-- Only needed by wtp? -->
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>cloudfoundry-identity-uaa</artifactId>
<type>war</type>
- <scope>tomcat</scope>
+ <version>${pom.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>cloudfoundry-identity-uaa</artifactId>
+ <version>${pom.version}</version>
+ <classifier>classes</classifier>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>${spring.security.oauth.version}</version>
+ <exclusions>
+ <exclusion>
+ <artifactId>spring-jdbc</artifactId>
+ <groupId>org.springframework</groupId>
+ </exclusion>
+ <exclusion>
+ <artifactId>spring-aop</artifactId>
+ <groupId>org.springframework</groupId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
@@ -16,41 +16,45 @@
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
-import java.util.Arrays;
-
+import org.cloudfoundry.identity.uaa.integration.TestAccountSetup;
+import org.cloudfoundry.identity.uaa.integration.UaaTestAccounts;
import org.junit.Rule;
import org.junit.Test;
-import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
-import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration;
+import org.springframework.security.oauth2.client.test.OAuth2ContextSetup;
+import org.springframework.web.client.RestOperations;
/**
* @author Dave Syer
*/
+@OAuth2ContextConfiguration
public class AppsIntegrationTests {
@Rule
public ServerRunning serverRunning = ServerRunning.isRunning();
+ private UaaTestAccounts testAccounts = UaaTestAccounts.standard(serverRunning);
+
+ @Rule
+ public OAuth2ContextSetup context = OAuth2ContextSetup.withTestAccounts(serverRunning, testAccounts);
+
+ @Rule
+ public TestAccountSetup testAccountSetup = TestAccountSetup.standard(serverRunning, testAccounts);
+
/**
* tests a happy-day flow of the native application profile.
*/
@Test
public void testHappyDay() throws Exception {
- OAuth2AccessToken accessToken = serverRunning.getToken();
- // now try and use the token to access a protected resource.
-
+ RestOperations restTemplate = serverRunning.createRestTemplate();
+ ResponseEntity<String> response = restTemplate.getForEntity(serverRunning.getUrl("/api/apps"), String.class);
// first make sure the resource is actually protected.
- assertNotSame(HttpStatus.OK, serverRunning.getStatusCode("/api/apps"));
+ assertNotSame(HttpStatus.OK, response.getStatusCode());
- // then make sure an authorized request is valid.
- HttpHeaders headers = new HttpHeaders();
- headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
- headers.set("Authorization", String.format("%s %s", OAuth2AccessToken.BEARER_TYPE, accessToken.getValue()));
- ResponseEntity<String> result = serverRunning.getForString("/api/apps", headers);
+ ResponseEntity<String> result = serverRunning.getForString("/api/apps");
assertEquals(HttpStatus.OK, result.getStatusCode());
String body = result.getBody();
assertTrue("Wrong response: "+body, body.contains("dsyerapi.cloudfoundry.com"));
Oops, something went wrong.

0 comments on commit 07d4762

Please sign in to comment.