Skip to content

Commit e612739

Browse files
author
Steve Powell
committed
Merge 114249337-openid-connect-token to master
[#114249337]
2 parents 827b667 + 387f8ba commit e612739

File tree

7 files changed

+252
-0
lines changed

7 files changed

+252
-0
lines changed

cloudfoundry-client-spring/src/main/java/org/cloudfoundry/reactor/uaa/tokens/ReactorTokens.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import org.cloudfoundry.uaa.tokens.GetTokenByAuthorizationCodeResponse;
2626
import org.cloudfoundry.uaa.tokens.GetTokenByClientCredentialsRequest;
2727
import org.cloudfoundry.uaa.tokens.GetTokenByClientCredentialsResponse;
28+
import org.cloudfoundry.uaa.tokens.GetTokenByOpenIdRequest;
29+
import org.cloudfoundry.uaa.tokens.GetTokenByOpenIdResponse;
2830
import org.cloudfoundry.uaa.tokens.GetTokenByPasswordRequest;
2931
import org.cloudfoundry.uaa.tokens.GetTokenByPasswordResponse;
3032
import org.cloudfoundry.uaa.tokens.GetTokenKeyRequest;
@@ -80,6 +82,12 @@ public Mono<GetTokenByClientCredentialsResponse> getByClientCredentials(GetToken
8082
function((builder, validRequest) -> builder.pathSegment("oauth", "token").queryParam("grant_type", "client_credentials").queryParam("response_type", "token")));
8183
}
8284

85+
@Override
86+
public Mono<GetTokenByOpenIdResponse> getByOpenId(GetTokenByOpenIdRequest request) {
87+
return post(request, GetTokenByOpenIdResponse.class,
88+
function((builder, validRequest) -> builder.pathSegment("oauth", "token").queryParam("grant_type", "authorization_code").queryParam("response_type", "id_token")));
89+
}
90+
8391
@Override
8492
public Mono<GetTokenByPasswordResponse> getByPassword(GetTokenByPasswordRequest request) {
8593
return post(request, GetTokenByPasswordResponse.class,

cloudfoundry-client-spring/src/test/java/org/cloudfoundry/reactor/uaa/tokens/ReactorTokensTest.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import org.cloudfoundry.uaa.tokens.GetTokenByAuthorizationCodeResponse;
2727
import org.cloudfoundry.uaa.tokens.GetTokenByClientCredentialsRequest;
2828
import org.cloudfoundry.uaa.tokens.GetTokenByClientCredentialsResponse;
29+
import org.cloudfoundry.uaa.tokens.GetTokenByOpenIdRequest;
30+
import org.cloudfoundry.uaa.tokens.GetTokenByOpenIdResponse;
2931
import org.cloudfoundry.uaa.tokens.GetTokenByPasswordRequest;
3032
import org.cloudfoundry.uaa.tokens.GetTokenByPasswordResponse;
3133
import org.cloudfoundry.uaa.tokens.GetTokenKeyRequest;
@@ -249,6 +251,55 @@ protected Mono<GetTokenByClientCredentialsResponse> invoke(GetTokenByClientCrede
249251

250252
}
251253

254+
public static final class GetTokenByOpenId extends AbstractUaaApiTest<GetTokenByOpenIdRequest, GetTokenByOpenIdResponse> {
255+
256+
private final ReactorTokens tokens = new ReactorTokens(AUTHORIZATION_PROVIDER, CLIENT_ID, CLIENT_SECRET, HTTP_CLIENT, OBJECT_MAPPER, this.root);
257+
258+
@Override
259+
protected InteractionContext getInteractionContext() {
260+
return InteractionContext.builder()
261+
.request(TestRequest.builder()
262+
.method(POST).path("/oauth/token?code=NAlA1d&client_id=app&client_secret=appclientsecret&redirect_uri=https://uaa.cloudfoundry.com/redirect/cf&token_format=opaque" +
263+
"&grant_type=authorization_code&response_type=id_token")
264+
.build())
265+
.response(TestResponse.builder()
266+
.status(OK)
267+
.payload("fixtures/uaa/tokens/GET_response_OI.json")
268+
.build())
269+
.build();
270+
}
271+
272+
@Override
273+
protected GetTokenByOpenIdResponse getResponse() {
274+
return GetTokenByOpenIdResponse.builder()
275+
.accessToken("53a58e6581ee49d08f9e572f673bc8db")
276+
.tokenType("bearer")
277+
.openIdToken("eyJhbGciOiJIUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLC")
278+
.refreshToken("53a58e6581ee49d08f9e572f673bc8db-r")
279+
.expiresInSeconds(43199)
280+
.scopes("openid oauth.approvals")
281+
.tokenId("53a58e6581ee49d08f9e572f673bc8db")
282+
.build();
283+
}
284+
285+
@Override
286+
protected GetTokenByOpenIdRequest getValidRequest() {
287+
return GetTokenByOpenIdRequest.builder()
288+
.clientId("app")
289+
.clientSecret("appclientsecret")
290+
.authorizationCode("NAlA1d")
291+
.redirectUri("https://uaa.cloudfoundry.com/redirect/cf")
292+
.tokenFormat(TokenFormat.OPAQUE)
293+
.build();
294+
}
295+
296+
@Override
297+
protected Mono<GetTokenByOpenIdResponse> invoke(GetTokenByOpenIdRequest request) {
298+
return this.tokens.getByOpenId(request);
299+
}
300+
301+
}
302+
252303
public static final class GetTokenByPassword extends AbstractUaaApiTest<GetTokenByPasswordRequest, GetTokenByPasswordResponse> {
253304

254305
private final ReactorTokens tokens = new ReactorTokens(AUTHORIZATION_PROVIDER, CLIENT_ID, CLIENT_SECRET, HTTP_CLIENT, OBJECT_MAPPER, this.root);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"access_token": "53a58e6581ee49d08f9e572f673bc8db",
3+
"token_type": "bearer",
4+
"id_token": "eyJhbGciOiJIUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLC",
5+
"refresh_token": "53a58e6581ee49d08f9e572f673bc8db-r",
6+
"expires_in": 43199,
7+
"scope": "openid oauth.approvals",
8+
"jti": "53a58e6581ee49d08f9e572f673bc8db"
9+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2013-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.cloudfoundry.uaa.tokens;
18+
19+
import org.cloudfoundry.Nullable;
20+
import org.cloudfoundry.QueryParameter;
21+
import org.immutables.value.Value;
22+
23+
/**
24+
* The request payload for the get token by OpenId operation
25+
*/
26+
@Value.Immutable
27+
abstract class AbstractGetTokenByOpenIdRequest {
28+
29+
/**
30+
* The authorization code
31+
*/
32+
@QueryParameter("code")
33+
abstract String getAuthorizationCode();
34+
35+
/**
36+
* The client identifier
37+
*/
38+
@QueryParameter("client_id")
39+
abstract String getClientId();
40+
41+
/**
42+
* The client's secret passphrase
43+
*/
44+
@QueryParameter("client_secret")
45+
abstract String getClientSecret();
46+
47+
/**
48+
* The redirection URI
49+
*/
50+
@Nullable
51+
@QueryParameter("redirect_uri")
52+
abstract String getRedirectUri();
53+
54+
/**
55+
* The token format
56+
*/
57+
@Nullable
58+
@QueryParameter("token_format")
59+
abstract TokenFormat getTokenFormat();
60+
61+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2013-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.cloudfoundry.uaa.tokens;
18+
19+
import com.fasterxml.jackson.annotation.JsonProperty;
20+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
21+
import org.immutables.value.Value;
22+
23+
/**
24+
* The response from the get token by OpenId request
25+
*/
26+
@JsonDeserialize
27+
@Value.Immutable
28+
abstract class AbstractGetTokenByOpenIdResponse extends AbstractToken {
29+
30+
/**
31+
* The OpenId token
32+
*/
33+
@JsonProperty("id_token")
34+
abstract String getOpenIdToken();
35+
36+
/**
37+
* The refresh token
38+
*/
39+
@JsonProperty("refresh_token")
40+
abstract String getRefreshToken();
41+
42+
}

cloudfoundry-client/src/main/java/org/cloudfoundry/uaa/tokens/Tokens.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ public interface Tokens {
4747
*/
4848
Mono<GetTokenByClientCredentialsResponse> getByClientCredentials(GetTokenByClientCredentialsRequest request);
4949

50+
/**
51+
* Makes the <a href="http://docs.cloudfoundry.com/uaa/#openid-connect">OpenID Connect</a> request
52+
*
53+
* @param request the OpenId request
54+
* @return the response from the OpenId request
55+
*/
56+
Mono<GetTokenByOpenIdResponse> getByOpenId(GetTokenByOpenIdRequest request);
57+
5058
/**
5159
* Makes the <a href="http://docs.cloudfoundry.com/uaa/#password-grant">Password Grant</a> request
5260
*
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2013-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.cloudfoundry.uaa.tokens;
18+
19+
import org.junit.Test;
20+
21+
public final class GetTokenByOpenIdRequestTest {
22+
23+
@Test(expected = IllegalStateException.class)
24+
public void noAuthorizationCode() {
25+
GetTokenByOpenIdRequest.builder()
26+
.clientId("test-client-id")
27+
.clientSecret("test-client-secret")
28+
.redirectUri("test-redirect-uri")
29+
.tokenFormat(TokenFormat.OPAQUE)
30+
.build();
31+
}
32+
33+
@Test(expected = IllegalStateException.class)
34+
public void noClientId() {
35+
GetTokenByOpenIdRequest.builder()
36+
.authorizationCode("test-authorization-code")
37+
.clientSecret("test-client-secret")
38+
.redirectUri("test-redirect-uri")
39+
.tokenFormat(TokenFormat.OPAQUE)
40+
.build();
41+
}
42+
43+
@Test(expected = IllegalStateException.class)
44+
public void noClientSecret() {
45+
GetTokenByOpenIdRequest.builder()
46+
.authorizationCode("test-authorization-code")
47+
.clientId("test-client-id")
48+
.redirectUri("test-redirect-uri")
49+
.tokenFormat(TokenFormat.OPAQUE)
50+
.build();
51+
}
52+
53+
@Test
54+
public void validMax() {
55+
GetTokenByOpenIdRequest.builder()
56+
.authorizationCode("test-authorization-code")
57+
.clientId("test-client-id")
58+
.clientSecret("test-client-secret")
59+
.redirectUri("test-redirect-uri")
60+
.tokenFormat(TokenFormat.OPAQUE)
61+
.build();
62+
}
63+
64+
@Test
65+
public void validMin() {
66+
GetTokenByOpenIdRequest.builder()
67+
.authorizationCode("test-authorization-code")
68+
.clientId("test-client-id")
69+
.clientSecret("test-client-secret")
70+
.build();
71+
}
72+
73+
}

0 commit comments

Comments
 (0)