Skip to content

Commit bd76057

Browse files
author
Steve Powell
committed
Merge 114249337-one-password-token to master
[Completes #114249337]
2 parents e612739 + d32ebcb commit bd76057

File tree

7 files changed

+233
-0
lines changed

7 files changed

+233
-0
lines changed

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

Lines changed: 9 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.GetTokenByOneTimePasscodeRequest;
29+
import org.cloudfoundry.uaa.tokens.GetTokenByOneTimePasscodeResponse;
2830
import org.cloudfoundry.uaa.tokens.GetTokenByOpenIdRequest;
2931
import org.cloudfoundry.uaa.tokens.GetTokenByOpenIdResponse;
3032
import org.cloudfoundry.uaa.tokens.GetTokenByPasswordRequest;
@@ -82,6 +84,13 @@ public Mono<GetTokenByClientCredentialsResponse> getByClientCredentials(GetToken
8284
function((builder, validRequest) -> builder.pathSegment("oauth", "token").queryParam("grant_type", "client_credentials").queryParam("response_type", "token")));
8385
}
8486

87+
@Override
88+
public Mono<GetTokenByOneTimePasscodeResponse> getByOneTimePasscode(GetTokenByOneTimePasscodeRequest request) {
89+
return post(request, GetTokenByOneTimePasscodeResponse.class,
90+
function((builder, validRequest) -> builder.pathSegment("oauth", "token").queryParam("grant_type", "password").queryParam("response_type", "token")),
91+
function((outbound, validRequest) -> basicAuth(outbound, validRequest.getClientId(), validRequest.getClientSecret())));
92+
}
93+
8594
@Override
8695
public Mono<GetTokenByOpenIdResponse> getByOpenId(GetTokenByOpenIdRequest request) {
8796
return post(request, GetTokenByOpenIdResponse.class,

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

Lines changed: 48 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.GetTokenByOneTimePasscodeRequest;
30+
import org.cloudfoundry.uaa.tokens.GetTokenByOneTimePasscodeResponse;
2931
import org.cloudfoundry.uaa.tokens.GetTokenByOpenIdRequest;
3032
import org.cloudfoundry.uaa.tokens.GetTokenByOpenIdResponse;
3133
import org.cloudfoundry.uaa.tokens.GetTokenByPasswordRequest;
@@ -251,6 +253,52 @@ protected Mono<GetTokenByClientCredentialsResponse> invoke(GetTokenByClientCrede
251253

252254
}
253255

256+
public static final class GetTokenByOneTimePasscode extends AbstractUaaApiTest<GetTokenByOneTimePasscodeRequest, GetTokenByOneTimePasscodeResponse> {
257+
258+
private final ReactorTokens tokens = new ReactorTokens(AUTHORIZATION_PROVIDER, CLIENT_ID, CLIENT_SECRET, HTTP_CLIENT, OBJECT_MAPPER, this.root);
259+
260+
@Override
261+
protected InteractionContext getInteractionContext() {
262+
return InteractionContext.builder()
263+
.request(TestRequest.builder()
264+
.method(POST).path("/oauth/token?passcode=qcZNkd&token_format=opaque&grant_type=password&response_type=token")
265+
.build())
266+
.response(TestResponse.builder()
267+
.status(OK)
268+
.payload("fixtures/uaa/tokens/GET_response_OT.json")
269+
.build())
270+
.build();
271+
}
272+
273+
@Override
274+
protected GetTokenByOneTimePasscodeResponse getResponse() {
275+
return GetTokenByOneTimePasscodeResponse.builder()
276+
.accessToken("0ddcada64ef742a28badaf4750ef435f")
277+
.tokenType("bearer")
278+
.refreshToken("0ddcada64ef742a28badaf4750ef435f-r")
279+
.expiresInSeconds(43199)
280+
.scopes("scim.userids openid cloud_controller.read password.write cloud_controller.write")
281+
.tokenId("0ddcada64ef742a28badaf4750ef435f")
282+
.build();
283+
}
284+
285+
@Override
286+
protected GetTokenByOneTimePasscodeRequest getValidRequest() {
287+
return GetTokenByOneTimePasscodeRequest.builder()
288+
.clientId("app")
289+
.clientSecret("appclientsecret")
290+
.passcode("qcZNkd")
291+
.tokenFormat(TokenFormat.OPAQUE)
292+
.build();
293+
}
294+
295+
@Override
296+
protected Mono<GetTokenByOneTimePasscodeResponse> invoke(GetTokenByOneTimePasscodeRequest request) {
297+
return this.tokens.getByOneTimePasscode(request);
298+
}
299+
300+
}
301+
254302
public static final class GetTokenByOpenId extends AbstractUaaApiTest<GetTokenByOpenIdRequest, GetTokenByOpenIdResponse> {
255303

256304
private final ReactorTokens tokens = new ReactorTokens(AUTHORIZATION_PROVIDER, CLIENT_ID, CLIENT_SECRET, HTTP_CLIENT, OBJECT_MAPPER, this.root);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"access_token": "0ddcada64ef742a28badaf4750ef435f",
3+
"token_type": "bearer",
4+
"refresh_token": "0ddcada64ef742a28badaf4750ef435f-r",
5+
"expires_in": 43199,
6+
"scope": "scim.userids openid cloud_controller.read password.write cloud_controller.write",
7+
"jti": "0ddcada64ef742a28badaf4750ef435f"
8+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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.JsonIgnore;
20+
import org.cloudfoundry.Nullable;
21+
import org.cloudfoundry.QueryParameter;
22+
import org.immutables.value.Value;
23+
24+
/**
25+
* The request payload for the get token by one-time passcode operation
26+
*/
27+
@Value.Immutable
28+
abstract class AbstractGetTokenByOneTimePasscodeRequest {
29+
30+
/**
31+
* The client identifier
32+
*/
33+
@JsonIgnore
34+
abstract String getClientId();
35+
36+
/**
37+
* The client's secret passphrase
38+
*/
39+
@JsonIgnore
40+
abstract String getClientSecret();
41+
42+
/**
43+
* The passcode
44+
*/
45+
@QueryParameter("passcode")
46+
abstract String getPasscode();
47+
48+
/**
49+
* The token format
50+
*/
51+
@Nullable
52+
@QueryParameter("token_format")
53+
abstract TokenFormat getTokenFormat();
54+
55+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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 passcode operation
25+
*/
26+
@JsonDeserialize
27+
@Value.Immutable
28+
abstract class AbstractGetTokenByOneTimePasscodeResponse extends AbstractToken {
29+
30+
/**
31+
* The refresh token
32+
*/
33+
@JsonProperty("refresh_token")
34+
abstract String getRefreshToken();
35+
36+
}

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
@@ -55,6 +55,14 @@ public interface Tokens {
5555
*/
5656
Mono<GetTokenByOpenIdResponse> getByOpenId(GetTokenByOpenIdRequest request);
5757

58+
/**
59+
* Makes the <a href="http://docs.cloudfoundry.com/uaa/#one-time-passcode">One-time Passcode</a> request
60+
*
61+
* @param request the One Time Passcode token request
62+
* @return the response from the One Time Passcode token request
63+
*/
64+
Mono<GetTokenByOneTimePasscodeResponse> getByOneTimePasscode(GetTokenByOneTimePasscodeRequest request);
65+
5866
/**
5967
* Makes the <a href="http://docs.cloudfoundry.com/uaa/#password-grant">Password Grant</a> request
6068
*
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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 GetTokenByOneTimePasscodeRequestTest {
22+
23+
@Test(expected = IllegalStateException.class)
24+
public void noClientId() {
25+
GetTokenByOneTimePasscodeRequest.builder()
26+
.clientSecret("test-client-secret")
27+
.passcode("test-passcode")
28+
.tokenFormat(TokenFormat.OPAQUE)
29+
.build();
30+
}
31+
32+
@Test(expected = IllegalStateException.class)
33+
public void noClientSecret() {
34+
GetTokenByOneTimePasscodeRequest.builder()
35+
.clientId("test-client-id")
36+
.passcode("test-passcode")
37+
.tokenFormat(TokenFormat.OPAQUE)
38+
.build();
39+
}
40+
41+
@Test(expected = IllegalStateException.class)
42+
public void noPasscode() {
43+
GetTokenByOneTimePasscodeRequest.builder()
44+
.clientId("test-client-id")
45+
.clientSecret("test-client-secret")
46+
.tokenFormat(TokenFormat.OPAQUE)
47+
.build();
48+
}
49+
50+
@Test
51+
public void validMax() {
52+
GetTokenByOneTimePasscodeRequest.builder()
53+
.clientId("test-client-id")
54+
.clientSecret("test-client-secret")
55+
.passcode("test-passcode")
56+
.tokenFormat(TokenFormat.OPAQUE)
57+
.build();
58+
}
59+
60+
@Test
61+
public void validMin() {
62+
GetTokenByOneTimePasscodeRequest.builder()
63+
.clientId("test-client-id")
64+
.clientSecret("test-client-secret")
65+
.passcode("test-passcode")
66+
.build();
67+
}
68+
69+
}

0 commit comments

Comments
 (0)