Browse files

[cfid-42] Add refresh_token grant automatically

When a client is created which has authorization_code grant type but is
missing refresh_token, the latter will be silently added. This prevents
problems when users accidentally forget to ask for this grant type when they
actually need it. [Fixes #35577857].

Change-Id: I1f5a87753256d82f244dc067ad3314d978864c68
  • Loading branch information...
1 parent 3579d4f commit 5140fe8d6b6ecf221c3d8f9825896fd2d329c187 @tekul tekul committed Nov 21, 2012
View
3 common/src/main/java/org/cloudfoundry/identity/uaa/oauth/ClientAdminBootstrap.java
@@ -149,6 +149,9 @@ private void addNewClients() throws Exception {
if (client.getAuthorities().isEmpty()) {
client.setAuthorities(Collections.singleton(UaaAuthority.UAA_NONE));
}
+ if (client.getAuthorizedGrantTypes().contains("authorization_code")) {
+ client.getAuthorizedGrantTypes().add("refresh_token");
+ }
for (String key : Arrays.asList("resource-ids", "scope", "authorized-grant-types", "authorities",
"redirect-uri", "secret", "id", "override", "access-token-validity", "refresh-token-validity")) {
info.remove(key);
View
18 common/src/main/java/org/cloudfoundry/identity/uaa/oauth/ClientAdminEndpoints.java
@@ -58,7 +58,7 @@
/**
* Controller for listing and manipulating OAuth2 clients.
- *
+ *
* @author Dave Syer
*/
@Controller
@@ -221,7 +221,7 @@ public SimpleMessage changeSecret(@PathVariable String client, @RequestBody Secr
clientRegistrationService.updateClientSecret(client, change.getSecret());
clientSecretChanges.incrementAndGet();
-
+
return new SimpleMessage("ok", "secret updated");
}
@@ -261,7 +261,7 @@ private void incrementErrorCounts(Exception e) {
private ClientDetails validateClient(ClientDetails prototype, boolean create) {
BaseClientDetails client = new BaseClientDetails(prototype);
-
+
client.setAdditionalInformation(prototype.getAdditionalInformation());
String clientId = client.getClientId();
@@ -282,6 +282,12 @@ private ClientDetails validateClient(ClientDetails prototype, boolean create) {
}
}
+ if (requestedGrantTypes.contains("authorization_code") && !requestedGrantTypes.contains("refresh_token")) {
+ logger.info("authorization_code client missing refresh_token: " + clientId);
+
+ requestedGrantTypes.add("refresh_token");
+ }
+
if (!securityContextAccessor.isAdmin()) {
// Not admin, so be strict with grant types and scopes
@@ -356,7 +362,7 @@ private ClientDetails validateClient(ClientDetails prototype, boolean create) {
// The UAA does not allow or require resource ids to be registered because they are determined dynamically
client.setResourceIds(Collections.singleton("none"));
-
+
if (client.getScope().isEmpty()) {
client.setScope(Collections.singleton("uaa.none"));
}
@@ -458,7 +464,7 @@ private ClientDetails syncWithExisting(ClientDetails existing, ClientDetails inp
if (details.getScope() == null || details.getScope().isEmpty()) {
details.setScope(existing.getScope());
}
-
+
Map<String, Object> additionalInformation = new HashMap<String, Object>(input.getAdditionalInformation());
additionalInformation.putAll(existing.getAdditionalInformation());
for (String key : Collections.unmodifiableSet(additionalInformation.keySet())) {
@@ -467,7 +473,7 @@ private ClientDetails syncWithExisting(ClientDetails existing, ClientDetails inp
}
}
details.setAdditionalInformation(additionalInformation);
-
+
return details;
}
View
2 common/src/test/java/org/cloudfoundry/identity/uaa/oauth/ClientAdminBootstrapTests.java
@@ -53,7 +53,7 @@ public void testSimpleAddClient() throws Exception {
map.put("scope", "openid");
map.put("authorized-grant-types", "authorization_code");
map.put("authorities", "uaa.none");
- BaseClientDetails output = new BaseClientDetails("foo", "none", "openid", "authorization_code", "uaa.none");
+ BaseClientDetails output = new BaseClientDetails("foo", "none", "openid", "authorization_code,refresh_token", "uaa.none");
output.setClientSecret("bar");
doSimpleTest(map, output);
}
View
4 common/src/test/java/org/cloudfoundry/identity/uaa/oauth/ClientAdminEndpointsTests.java
@@ -42,7 +42,7 @@
/**
* @author Dave Syer
- *
+ *
*/
public class ClientAdminEndpointsTests {
@@ -71,6 +71,8 @@ public void setUp() throws Exception {
input.setAuthorizedGrantTypes(Arrays.asList("authorization_code"));
details = new BaseClientDetails(input);
details.setResourceIds(Arrays.asList("none"));
+ // refresh token is added automatically by endpoint validation
+ details.setAuthorizedGrantTypes(Arrays.asList("authorization_code","refresh_token"));
details.setScope(Arrays.asList("uaa.none"));
details.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList("uaa.none"));
endpoints.afterPropertiesSet();
View
102 .../java/org/cloudfoundry/identity/uaa/integration/ClientAdminEndpointsIntegrationTests.java
@@ -57,28 +57,27 @@
@Rule
public TestAccountSetup testAccountSetup = TestAccountSetup.standard(serverRunning, testAccounts);
+ private OAuth2AccessToken token;
+ private HttpHeaders headers;
+
@Before
- public void setUp() {
+ public void setUp() throws Exception {
Assume.assumeTrue(!testAccounts.isProfileActive("vcap"));
+ token = getClientCredentialsAccessToken("clients.read,clients.write");
+ headers = getAuthenticatedHeaders(token);
}
@Test
public void testGetClient() throws Exception {
-
- OAuth2AccessToken token = getClientCredentialsAccessToken("clients.read");
-
- HttpHeaders headers = getAuthenticatedHeaders(token);
+ HttpHeaders headers = getAuthenticatedHeaders(getClientCredentialsAccessToken("clients.read"));
ResponseEntity<String> result = serverRunning.getForString("/oauth/clients/vmc", headers);
assertEquals(HttpStatus.OK, result.getStatusCode());
assertTrue(result.getBody().contains("vmc"));
}
@Test
public void testListClients() throws Exception {
-
- OAuth2AccessToken token = getClientCredentialsAccessToken("clients.read");
-
- HttpHeaders headers = getAuthenticatedHeaders(token);
+ HttpHeaders headers = getAuthenticatedHeaders(getClientCredentialsAccessToken("clients.read"));
ResponseEntity<String> result = serverRunning.getForString("/oauth/clients", headers);
assertEquals(HttpStatus.OK, result.getStatusCode());
// System.err.println(result.getBody());
@@ -88,16 +87,7 @@ public void testListClients() throws Exception {
@Test
public void testCreateClient() throws Exception {
-
- OAuth2AccessToken token = getClientCredentialsAccessToken("clients.read,clients.write");
-
- HttpHeaders headers = getAuthenticatedHeaders(token);
- BaseClientDetails client = new BaseClientDetails(new RandomValueStringGenerator().generate(), "", "foo,bar", "client_credentials", "uaa.none");
- client.setClientSecret("clientSecret");
- ResponseEntity<Void> result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients"),
- HttpMethod.POST, new HttpEntity<BaseClientDetails>(client, headers), Void.class);
- assertEquals(HttpStatus.CREATED, result.getStatusCode());
-
+ createClient("client_credentials");
}
@Test
@@ -114,8 +104,6 @@ public void nonImplicitGrantClientWithoutSecretIsRejected() throws Exception {
@Test
public void implicitAndAuthCodeGrantClient() throws Exception {
- OAuth2AccessToken token = getClientCredentialsAccessToken("clients.read,clients.write");
- HttpHeaders headers = getAuthenticatedHeaders(token);
BaseClientDetails client = new BaseClientDetails(new RandomValueStringGenerator().generate(), "", "foo,bar", "implicit,authorization_code", "uaa.none");
ResponseEntity<UaaException> result = serverRunning.getRestTemplate().exchange(
serverRunning.getUrl("/oauth/clients"), HttpMethod.POST,
@@ -126,8 +114,6 @@ public void implicitAndAuthCodeGrantClient() throws Exception {
@Test
public void implicitGrantClientWithoutSecretIsOk() throws Exception {
- OAuth2AccessToken token = getClientCredentialsAccessToken("clients.read,clients.write");
- HttpHeaders headers = getAuthenticatedHeaders(token);
BaseClientDetails client = new BaseClientDetails(new RandomValueStringGenerator().generate(), "", "foo,bar", "implicit", "uaa.none");
ResponseEntity<Void> result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients"),
HttpMethod.POST, new HttpEntity<BaseClientDetails>(client, headers), Void.class);
@@ -136,23 +122,23 @@ public void implicitGrantClientWithoutSecretIsOk() throws Exception {
}
@Test
- public void testUpdateClient() throws Exception {
+ public void authzCodeGrantAutomaticallyAddsRefreshToken() throws Exception {
+ BaseClientDetails client = createClient("authorization_code");
- OAuth2AccessToken token = getClientCredentialsAccessToken("clients.read,clients.write");
-
- HttpHeaders headers = getAuthenticatedHeaders(token);
+ ResponseEntity<String> result = serverRunning.getForString("/oauth/clients/" + client.getClientId(), headers);
+ assertEquals(HttpStatus.OK, result.getStatusCode());
+ assertTrue(result.getBody().contains("\"authorized_grant_types\":[\"authorization_code\",\"refresh_token\"]"));
+ }
- BaseClientDetails client = new BaseClientDetails(new RandomValueStringGenerator().generate(), "", "foo,bar", "client_credentials", "uaa.none");
- client.setClientSecret("clientSecret");
- ResponseEntity<Void> result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients"),
- HttpMethod.POST, new HttpEntity<BaseClientDetails>(client, headers), Void.class);
- assertEquals(HttpStatus.CREATED, result.getStatusCode());
+ @Test
+ public void testUpdateClient() throws Exception {
+ BaseClientDetails client = createClient("client_credentials");
client.setResourceIds(Collections.singleton("foo"));
client.setClientSecret(null);
client.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList("some.crap"));
- result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients/{client}"),
+ ResponseEntity<Void> result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients/{client}"),
HttpMethod.PUT, new HttpEntity<BaseClientDetails>(client, headers), Void.class, client.getClientId());
assertEquals(HttpStatus.OK, result.getStatusCode());
@@ -165,63 +151,35 @@ public void testUpdateClient() throws Exception {
@Test
public void testChangeSecret() throws Exception {
-
- OAuth2AccessToken token = getClientCredentialsAccessToken("clients.read,clients.write,clients.secret");
-
- HttpHeaders headers = getAuthenticatedHeaders(token);
-
- BaseClientDetails client = new BaseClientDetails(new RandomValueStringGenerator().generate(), "", "foo,bar", "client_credentials", "uaa.none");
- client.setClientSecret("secret");
- ResponseEntity<Void> result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients"),
- HttpMethod.POST, new HttpEntity<BaseClientDetails>(client, headers), Void.class);
- assertEquals(HttpStatus.CREATED, result.getStatusCode());
+ headers = getAuthenticatedHeaders(getClientCredentialsAccessToken("clients.read,clients.write,clients.secret"));
+ BaseClientDetails client = createClient("client_credentials");
client.setResourceIds(Collections.singleton("foo"));
SecretChangeRequest change = new SecretChangeRequest();
change.setOldSecret(client.getClientSecret());
change.setSecret("newsecret");
- result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients/{client}/secret"),
+ ResponseEntity<Void> result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients/{client}/secret"),
HttpMethod.PUT, new HttpEntity<SecretChangeRequest>(change, headers), Void.class, client.getClientId());
assertEquals(HttpStatus.OK, result.getStatusCode());
-
}
@Test
public void testDeleteClient() throws Exception {
-
- OAuth2AccessToken token = getClientCredentialsAccessToken("clients.read,clients.write");
-
- HttpHeaders headers = getAuthenticatedHeaders(token);
-
- BaseClientDetails client = new BaseClientDetails(new RandomValueStringGenerator().generate(), "", "foo,bar", "client_credentials", "uaa.none");
- client.setClientSecret("clientSecret");
- ResponseEntity<Void> result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients"),
- HttpMethod.POST, new HttpEntity<BaseClientDetails>(client, headers), Void.class);
- assertEquals(HttpStatus.CREATED, result.getStatusCode());
+ BaseClientDetails client = createClient("client_credentials");
client.setResourceIds(Collections.singleton("foo"));
- result = serverRunning.getRestTemplate()
+ ResponseEntity<Void> result = serverRunning.getRestTemplate()
.exchange(serverRunning.getUrl("/oauth/clients/{client}"), HttpMethod.DELETE,
new HttpEntity<BaseClientDetails>(client, headers), Void.class, client.getClientId());
assertEquals(HttpStatus.OK, result.getStatusCode());
-
}
@Test
// CFID-372
public void testCreateExistingClientFails() throws Exception {
-
- OAuth2AccessToken token = getClientCredentialsAccessToken("clients.read,clients.write");
-
- HttpHeaders headers = getAuthenticatedHeaders(token);
-
- BaseClientDetails client = new BaseClientDetails(new RandomValueStringGenerator().generate(), "", "foo,bar", "client_credentials", "uaa.none");
- client.setClientSecret("clientSecret");
- ResponseEntity<Void> result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients"),
- HttpMethod.POST, new HttpEntity<BaseClientDetails>(client, headers), Void.class);
- assertEquals(HttpStatus.CREATED, result.getStatusCode());
+ BaseClientDetails client = createClient("client_credentials");
@SuppressWarnings("rawtypes")
ResponseEntity<Map> attempt = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients"),
@@ -232,6 +190,16 @@ public void testCreateExistingClientFails() throws Exception {
assertEquals("invalid_client", map.get("error"));
}
+ private BaseClientDetails createClient(String grantTypes) throws Exception {
+ BaseClientDetails client = new BaseClientDetails(new RandomValueStringGenerator().generate(), "", "foo,bar", grantTypes, "uaa.none");
+ client.setClientSecret("secret");
+ ResponseEntity<Void> result = serverRunning.getRestTemplate().exchange(serverRunning.getUrl("/oauth/clients"),
+ HttpMethod.POST, new HttpEntity<BaseClientDetails>(client, headers), Void.class);
+ assertEquals(HttpStatus.CREATED, result.getStatusCode());
+ return client;
+ }
+
+
public HttpHeaders getAuthenticatedHeaders(OAuth2AccessToken token) {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

0 comments on commit 5140fe8

Please sign in to comment.