Skip to content

Commit

Permalink
Merge branch 'releases/3.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
fhanik committed Mar 7, 2016
2 parents 9b5c13d + d690c67 commit 769e651
Show file tree
Hide file tree
Showing 167 changed files with 10,632 additions and 1,049 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,9 @@ Here are some ways for you to get involved in the community:
want to contribute code this way, please reference an existing issue
if there is one as well covering the specific issue you are
addressing. Always submit pull requests to the "develop" branch.
We strictly adhere to test driven development. We kindly ask that
pull requests are accompanied with test cases that would be failing
if ran separately from the pull request.
* Watch for upcoming articles on Cloud Foundry by
[subscribing](http://blog.cloudfoundry.org) to the cloudfoundry.org
blog
Expand Down
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,6 @@ project.gradle.taskGraph.whenReady { TaskExecutionGraph graph ->
//property 'uaa.allowUnverifiedUsers', 'false'
property 'smtp.host', 'localhost'
property 'smtp.port', 2525
property 'login.invitationsEnabled', 'true'
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.UnsupportedGrantTypeException;
import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpMessageConverterExtractor;
import org.springframework.web.client.ResponseExtractor;
Expand Down Expand Up @@ -146,10 +145,19 @@ public UaaContext authenticate(TokenRequest request) {
protected UaaContext authenticateAuthCode(final TokenRequest tokenRequest) {
AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
details.setPreEstablishedRedirectUri(tokenRequest.getRedirectUriRedirectUri().toString());
details.setUserAuthorizationUri(tokenRequest.getAuthorizationEndpoint().toString());
configureResourceDetails(tokenRequest, details);
setClientCredentials(tokenRequest, details);
setRequestScopes(tokenRequest, details);
OAuth2RestTemplate template = new OAuth2RestTemplate(details,new DefaultOAuth2ClientContext());

//begin - work around for not having UI for now
DefaultOAuth2ClientContext oAuth2ClientContext = new DefaultOAuth2ClientContext();
oAuth2ClientContext.getAccessTokenRequest().setStateKey(tokenRequest.getState());
oAuth2ClientContext.setPreservedState(tokenRequest.getState(), details.getPreEstablishedRedirectUri());
oAuth2ClientContext.getAccessTokenRequest().setCurrentUri(details.getPreEstablishedRedirectUri());
//end - work around for not having UI for now

OAuth2RestTemplate template = new OAuth2RestTemplate(details, oAuth2ClientContext);
template.getAccessToken();
throw new UnsupportedOperationException(AUTHORIZATION_CODE +" is not yet implemented");
}
Expand All @@ -176,9 +184,8 @@ protected ResponseExtractor<OAuth2AccessToken> getResponseExtractor() {
setRequestScopes(tokenRequest, details);
details.setUserAuthorizationUri(tokenRequest.getAuthorizationEndpoint().toString());
DefaultOAuth2ClientContext oAuth2ClientContext = new DefaultOAuth2ClientContext();
String state = new RandomValueStringGenerator().generate();
oAuth2ClientContext.getAccessTokenRequest().setStateKey(state);
oAuth2ClientContext.setPreservedState(state, details.getPreEstablishedRedirectUri());
oAuth2ClientContext.getAccessTokenRequest().setStateKey(tokenRequest.getState());
oAuth2ClientContext.setPreservedState(tokenRequest.getState(), details.getPreEstablishedRedirectUri());
oAuth2ClientContext.getAccessTokenRequest().setCurrentUri(details.getPreEstablishedRedirectUri());
Map<String, List<String>> headers = (Map<String, List<String>>) oAuth2ClientContext.getAccessTokenRequest().getHeaders();
headers.put("Authorization", Arrays.asList("bearer " + tokenRequest.getAuthCodeAPIToken()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class TokenRequest {
private boolean idToken = false;
private URI redirectUri;
private String authCodeAPIToken;
private String state;

/**
* Constructs a token request
Expand Down Expand Up @@ -99,7 +100,8 @@ public boolean isValid() {
clientSecret,
username,
password,
redirectUri
redirectUri,
state
)
);
case AUTHORIZATION_CODE_WITH_TOKEN:
Expand All @@ -112,7 +114,8 @@ public boolean isValid() {
username,
password,
redirectUri,
authCodeAPIToken
authCodeAPIToken,
state
)
);
default: return false;
Expand Down Expand Up @@ -338,6 +341,30 @@ public TokenRequest setPasscode(String passcode) {
return this;
}

/**
* Returns the state key, used with
* {@link GrantType#AUTHORIZATION_CODE} and
* {@link GrantType#IMPLICIT} and
* {@link GrantType#AUTHORIZATION_CODE_WITH_TOKEN}
* @return String representing a random string
*/
public String getState() {
return state;
}

/**
* Sets the state key, used with
* {@link GrantType#AUTHORIZATION_CODE} and
* {@link GrantType#IMPLICIT} and
* {@link GrantType#AUTHORIZATION_CODE_WITH_TOKEN}
* @param state - a random string
* @return this mutable object
*/
public TokenRequest setState(String state) {
this.state = state;
return this;
}

/**
* Returns true if the list or any item in the list is null
* @param objects a list of items to be evaluated for null references
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,16 @@
import org.cloudfoundry.identity.client.token.TokenRequest;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;

import java.net.URI;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;

import static org.cloudfoundry.identity.client.integration.ClientIntegrationTestUtilities.UAA_URI;
import static org.cloudfoundry.identity.client.token.GrantType.AUTHORIZATION_CODE;
import static org.cloudfoundry.identity.client.token.GrantType.AUTHORIZATION_CODE_WITH_TOKEN;
import static org.cloudfoundry.identity.client.token.GrantType.PASSWORD;
Expand All @@ -37,10 +41,15 @@

public class ClientAPITokenIntegrationTest {

public static String uaaURI = "http://localhost:8080/uaa";
public static String uaaURI = UAA_URI;

private UaaContextFactory factory;

private RandomValueStringGenerator generator = new RandomValueStringGenerator();

@Rule
public IsUAAListeningRule uaaListeningRule = new IsUAAListeningRule(uaaURI, false);

@Before
public void setUp() throws Exception {
factory =
Expand Down Expand Up @@ -146,14 +155,16 @@ public void test_password_token_with_passcode() throws Exception {


@Test
@Ignore //until we have decided if we want to be able to do this without a UI
@Ignore("test_auth_code_token_with_id_token ignored - No UI/browser implementation yet") //until we have decided if we want to be able to do this without a UI
public void test_auth_code_token_with_id_token() throws Exception {
TokenRequest authorizationCode = factory.tokenRequest()
.withIdToken()
.setGrantType(AUTHORIZATION_CODE)
.setRedirectUri(new URI("http://localhost/redirect"))
.setClientId("cf")
.setClientSecret("")
.setState(generator.generate())
.setScopes(Collections.singleton("openid"))
.setClientId("app")
.setClientSecret("appclientsecret")
.setUsername("marissa")
.setPassword("koala");
UaaContext context = factory.authenticate(authorizationCode);
Expand All @@ -165,13 +176,15 @@ public void test_auth_code_token_with_id_token() throws Exception {
}

@Test
@Ignore //until we have decided if we want to be able to do this without a UI
@Ignore("test_auth_code_token_without_id_token ignred - No UI/browser implementation yet") //until we have decided if we want to be able to do this without a UI
public void test_auth_code_token_without_id_token() throws Exception {
TokenRequest authorizationCode = factory.tokenRequest()
.setGrantType(AUTHORIZATION_CODE)
.setRedirectUri(new URI("http://localhost/redirect"))
.setClientId("cf")
.setClientSecret("")
.setState(generator.generate())
.setScopes(Collections.singleton("openid"))
.setClientId("app")
.setClientSecret("appclientsecret")
.setUsername("marissa")
.setPassword("koala");
UaaContext context = factory.authenticate(authorizationCode);
Expand All @@ -189,6 +202,7 @@ public void test_auth_code_token_using_api() throws Exception {
TokenRequest authorizationCode = factory.tokenRequest()
.setGrantType(AUTHORIZATION_CODE_WITH_TOKEN)
.setRedirectUri(new URI("http://localhost:8080/app/"))
.setState(generator.generate())
.setClientId("app")
.setClientSecret("appclientsecret")
.setUsername("marissa")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
Expand All @@ -38,6 +39,9 @@
public class ClientIntegrationTestUtilities {
public static final String DEFAULT_CSRF_COOKIE_NAME = "X-Uaa-Csrf";

public static String UAA_URI = "http://localhost:8080/uaa";

public static RandomValueStringGenerator GENERATOR = new RandomValueStringGenerator();

public static String extractCookieCsrf(String body) {
String pattern = "\\<input type=\\\"hidden\\\" name=\\\""+DEFAULT_CSRF_COOKIE_NAME+"\\\" value=\\\"(.*?)\\\"";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* *****************************************************************************
* Cloud Foundry
* Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved.
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product includes a number of subcomponents with
* separate copyright notices and license terms. Your use of these
* subcomponents is subject to the terms and conditions of the
* subcomponent's license, as noted in the LICENSE file.
* *****************************************************************************
*/

package org.cloudfoundry.identity.client.integration;

import org.cloudfoundry.identity.client.UaaContext;
import org.cloudfoundry.identity.client.UaaContextFactory;
import org.cloudfoundry.identity.client.token.GrantType;
import org.cloudfoundry.identity.client.token.TokenRequest;
import org.cloudfoundry.identity.uaa.zone.IdentityZone;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneConfiguration;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import java.net.URI;

import static org.cloudfoundry.identity.client.integration.ClientIntegrationTestUtilities.GENERATOR;
import static org.cloudfoundry.identity.client.integration.ClientIntegrationTestUtilities.UAA_URI;
import static org.springframework.http.HttpMethod.POST;

public class IdentityZoneConfigurationIntegrationTest {

private UaaContextFactory factory;

@Rule
public IsUAAListeningRule uaaListeningRule = new IsUAAListeningRule(UAA_URI, false);

@Before
public void setUp() throws Exception {
factory =
UaaContextFactory.factory(new URI(UAA_URI))
.authorizePath("/oauth/authorize")
.tokenPath("/oauth/token");
}

@Test
public void create_zone_without_client_api() throws Exception {
TokenRequest clientCredentials = factory.tokenRequest()
.setClientId("identity")
.setClientSecret("identitysecret")
.setGrantType(GrantType.CLIENT_CREDENTIALS);

UaaContext context = factory.authenticate(clientCredentials);

String zoneId = GENERATOR.generate();
IdentityZone zone = new IdentityZone()
.setId(zoneId)
.setName(zoneId)
.setSubdomain(zoneId)
.setConfig(new IdentityZoneConfiguration());

ResponseEntity<IdentityZone> created = context.getRestTemplate().exchange(
UAA_URI+"/identity-zones",
POST,
new HttpEntity<>(zone),
IdentityZone.class
);

Assert.assertEquals(HttpStatus.CREATED, created.getStatusCode());

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*******************************************************************************
* Cloud Foundry
* Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product includes a number of subcomponents with
* separate copyright notices and license terms. Your use of these
* subcomponents is subject to the terms and conditions of the
* subcomponent's license, as noted in the LICENSE file.
*******************************************************************************/
package org.cloudfoundry.identity.client.integration;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Assume;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.IOException;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class IsUAAListeningRule implements TestRule {
private static Log logger = LogFactory.getLog(IsUAAListeningRule.class);

private static Map<String,Boolean> sharedStatuses = new HashMap<>();

private final String baseUrl;
private final boolean forceIntegrationTests;

public IsUAAListeningRule(String baseUrl, boolean forceIntegrationTests) {
this.baseUrl = baseUrl;
this.forceIntegrationTests = forceIntegrationTests;
}

@Override
public Statement apply(Statement statement, Description description) {
Assume.assumeTrue("Test ignored as the server cannot be reached at " + baseUrl, forceIntegrationTests || getStatus());
return statement;
}

private synchronized Boolean getStatus() {
Boolean available = sharedStatuses.get(baseUrl);
if (available == null) {
available = connectionAvailable();
sharedStatuses.put(baseUrl, available);
}
return available;
}

private boolean connectionAvailable() {
UriComponents components = UriComponentsBuilder.fromHttpUrl(baseUrl).build();
String host = components.getHost();
int port = components.getPort();

logger.info("Testing connectivity for " + baseUrl);
try (Socket socket = new Socket(host, port)) {
logger.info("Connectivity test succeeded for " + baseUrl);
return true;

} catch (IOException e) {
logger.warn("Connectivity test failed for " + baseUrl, e);
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public void test_is_auth_code_grant_valid() throws Exception {
assertFalse(request.setClientSecret("client_secret").isValid());
assertFalse(request.setUsername("username").isValid());
assertFalse(request.setPassword("password").isValid());
assertFalse(request.setState("state").isValid());
assertTrue(request.setRedirectUri(new URI("http://localhost:8080/test")).isValid());
}

Expand All @@ -89,6 +90,7 @@ public void test_is_auth_code_grant_api_valid() throws Exception {
assertFalse(request.setUsername("username").isValid());
assertFalse(request.setPassword("password").isValid());
assertFalse(request.setAuthCodeAPIToken("some token").isValid());
assertFalse(request.setState("state").isValid());
assertTrue(request.setRedirectUri(new URI("http://localhost:8080/test")).isValid());
}

Expand Down
Loading

0 comments on commit 769e651

Please sign in to comment.