Skip to content

Commit

Permalink
Add token_format as a parameter to the token retrieval
Browse files Browse the repository at this point in the history
  • Loading branch information
fhanik committed Apr 19, 2016
1 parent 029e594 commit 02a9b09
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 53 deletions.
Expand Up @@ -5,9 +5,11 @@
import org.cloudfoundry.identity.uaa.mock.InjectedMockContextTest; import org.cloudfoundry.identity.uaa.mock.InjectedMockContextTest;
import org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils; import org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils;
import org.cloudfoundry.identity.uaa.oauth.token.CompositeAccessToken; import org.cloudfoundry.identity.uaa.oauth.token.CompositeAccessToken;
import org.cloudfoundry.identity.uaa.oauth.token.TokenConstants;
import org.cloudfoundry.identity.uaa.scim.ScimUser; import org.cloudfoundry.identity.uaa.scim.ScimUser;
import org.cloudfoundry.identity.uaa.scim.ScimUserProvisioning; import org.cloudfoundry.identity.uaa.scim.ScimUserProvisioning;
import org.cloudfoundry.identity.uaa.scim.jdbc.JdbcScimUserProvisioning; import org.cloudfoundry.identity.uaa.scim.jdbc.JdbcScimUserProvisioning;
import org.cloudfoundry.identity.uaa.test.SnippetUtils;
import org.cloudfoundry.identity.uaa.test.TestClient; import org.cloudfoundry.identity.uaa.test.TestClient;
import org.cloudfoundry.identity.uaa.user.UaaAuthority; import org.cloudfoundry.identity.uaa.user.UaaAuthority;
import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.cloudfoundry.identity.uaa.util.JsonUtils;
Expand All @@ -16,7 +18,6 @@
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession; import org.springframework.mock.web.MockHttpSession;
import org.springframework.restdocs.request.ParameterDescriptor; import org.springframework.restdocs.request.ParameterDescriptor;
import org.springframework.restdocs.snippet.Attributes;
import org.springframework.restdocs.snippet.Snippet; import org.springframework.restdocs.snippet.Snippet;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken; import org.springframework.security.oauth2.common.OAuth2RefreshToken;
Expand All @@ -31,6 +32,7 @@
import java.util.Arrays; import java.util.Arrays;


import static org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils.utils; import static org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils.utils;
import static org.cloudfoundry.identity.uaa.test.SnippetUtils.parameterWithName;
import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED; import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED;
import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
Expand All @@ -42,9 +44,7 @@
import static org.springframework.restdocs.payload.JsonFieldType.STRING; import static org.springframework.restdocs.payload.JsonFieldType.STRING;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.requestParameters; import static org.springframework.restdocs.request.RequestDocumentation.requestParameters;
import static org.springframework.restdocs.snippet.Attributes.key;
import static org.springframework.security.oauth2.common.util.OAuth2Utils.CLIENT_ID; import static org.springframework.security.oauth2.common.util.OAuth2Utils.CLIENT_ID;
import static org.springframework.security.oauth2.common.util.OAuth2Utils.GRANT_TYPE; import static org.springframework.security.oauth2.common.util.OAuth2Utils.GRANT_TYPE;
import static org.springframework.security.oauth2.common.util.OAuth2Utils.REDIRECT_URI; import static org.springframework.security.oauth2.common.util.OAuth2Utils.REDIRECT_URI;
Expand All @@ -55,13 +55,11 @@


public class TokenEndpointDocs extends InjectedMockContextTest { public class TokenEndpointDocs extends InjectedMockContextTest {


private final Attributes.AttributeBuilder type = key("type"); private final ParameterDescriptor grantTypeParameter = parameterWithName(GRANT_TYPE).required().type(STRING).description("OAuth 2 grant type");
private final Attributes.AttributeBuilder constraints = key("constraints"); private final ParameterDescriptor responseTypeParameter = parameterWithName(RESPONSE_TYPE).required().type(STRING).description("the type of token that should be issued.");

private final ParameterDescriptor clientIdParameter = parameterWithName(CLIENT_ID).required().type(STRING).description("a unique string representing the registration information provided by the client");
private final ParameterDescriptor grantTypeParameter = parameterWithName(GRANT_TYPE).attributes(constraints.value("Required"), type.value(STRING)); private final ParameterDescriptor clientSecretParameter = parameterWithName("client_secret").required().type(STRING).description("the secret passphrase configured for the OAuth client");
private final ParameterDescriptor responseTypeParameter = parameterWithName(RESPONSE_TYPE).description("the type of token that should be issued.").attributes(constraints.value("Required"), type.value(STRING)); private final ParameterDescriptor opaqueFormatParameter = parameterWithName(TokenConstants.REQUEST_TOKEN_FORMAT).optional(null).type(STRING).description("Can be set to '"+TokenConstants.OPAQUE+"' to retrieve an opaque and revocable token.");
private final ParameterDescriptor clientIdParameter = parameterWithName(CLIENT_ID).description("a unique string representing the registration information provided by the client").attributes(constraints.value("Required"), type.value(STRING));
private final ParameterDescriptor clientSecretParameter = parameterWithName("client_secret").description("the secret passphrase configured for the OAuth client").attributes(constraints.value("Required"), type.value(STRING));


private ScimUser user; private ScimUser user;


Expand Down Expand Up @@ -101,15 +99,17 @@ public void getTokenUsingAuthCodeGrant() throws Exception {
.param(GRANT_TYPE, "authorization_code") .param(GRANT_TYPE, "authorization_code")
.param(RESPONSE_TYPE, "token") .param(RESPONSE_TYPE, "token")
.param("code", code) .param("code", code)
.param(TokenConstants.REQUEST_TOKEN_FORMAT, TokenConstants.OPAQUE)
.param(REDIRECT_URI, redirect); .param(REDIRECT_URI, redirect);


Snippet requestParameters = requestParameters( Snippet requestParameters = requestParameters(
responseTypeParameter, responseTypeParameter,
clientIdParameter, clientIdParameter,
parameterWithName(REDIRECT_URI).description("redirection URI to which the authorization server will send the user-agent back once access is granted (or denied)").attributes(constraints.value("Required if provided on authorization request"), type.value(STRING)), parameterWithName(REDIRECT_URI).description("redirection URI to which the authorization server will send the user-agent back once access is granted (or denied)").attributes(SnippetUtils.constraints.value("Required if provided on authorization request"), SnippetUtils.type.value(STRING)),
parameterWithName("code").description("the authorization code, obtained from /oauth/authorize, issued for the user").attributes(constraints.value("Required"), type.value(STRING)), parameterWithName("code").description("the authorization code, obtained from /oauth/authorize, issued for the user").attributes(SnippetUtils.constraints.value("Required"), SnippetUtils.type.value(STRING)),
grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `authorization_code`"), grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `authorization_code`"),
clientSecretParameter clientSecretParameter,
opaqueFormatParameter
); );


Snippet responseFields = responseFields( Snippet responseFields = responseFields(
Expand All @@ -134,13 +134,15 @@ public void getTokenUsingClientCredentialGrant() throws Exception {
.param(CLIENT_ID, "login") .param(CLIENT_ID, "login")
.param("client_secret", "loginsecret") .param("client_secret", "loginsecret")
.param(GRANT_TYPE, "client_credentials") .param(GRANT_TYPE, "client_credentials")
.param(TokenConstants.REQUEST_TOKEN_FORMAT, TokenConstants.OPAQUE)
.param(RESPONSE_TYPE, "token"); .param(RESPONSE_TYPE, "token");


Snippet requestParameters = requestParameters( Snippet requestParameters = requestParameters(
responseTypeParameter, responseTypeParameter,
clientIdParameter, clientIdParameter,
grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `client_credentials`"), grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `client_credentials`"),
clientSecretParameter clientSecretParameter,
opaqueFormatParameter
); );


Snippet responseFields = responseFields( Snippet responseFields = responseFields(
Expand All @@ -160,15 +162,17 @@ public void getTokenUsingClientCredentialGrantWithAuthorizationHeader() throws E


String clientAuthorization = new String(Base64.encodeBase64("login:loginsecret".getBytes())); String clientAuthorization = new String(Base64.encodeBase64("login:loginsecret".getBytes()));
MockHttpServletRequestBuilder postForToken = post("/oauth/token") MockHttpServletRequestBuilder postForToken = post("/oauth/token")
.accept(APPLICATION_JSON) .accept(APPLICATION_JSON)
.contentType(APPLICATION_FORM_URLENCODED) .contentType(APPLICATION_FORM_URLENCODED)
.param(GRANT_TYPE, "client_credentials") .param(GRANT_TYPE, "client_credentials")
.param(RESPONSE_TYPE, "token") .param(RESPONSE_TYPE, "token")
.header("Authorization", "Basic " + clientAuthorization); .param(TokenConstants.REQUEST_TOKEN_FORMAT, TokenConstants.OPAQUE)
.header("Authorization", "Basic " + clientAuthorization);


Snippet requestParameters = requestParameters( Snippet requestParameters = requestParameters(
responseTypeParameter, responseTypeParameter,
grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `client_credentials`") grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `client_credentials`"),
opaqueFormatParameter
); );


Snippet requestHeaders = requestHeaders(headerWithName("Authorization").description("Base64 encoded client details in the format: `Basic client_id:client_secret`")); Snippet requestHeaders = requestHeaders(headerWithName("Authorization").description("Base64 encoded client details in the format: `Basic client_id:client_secret`"));
Expand Down Expand Up @@ -196,15 +200,17 @@ public void getTokenUsingPasswordGrant() throws Exception {
.param(GRANT_TYPE, "password") .param(GRANT_TYPE, "password")
.param("username", user.getUserName()) .param("username", user.getUserName())
.param("password", user.getPassword()) .param("password", user.getPassword())
.param(TokenConstants.REQUEST_TOKEN_FORMAT, TokenConstants.OPAQUE)
.param(RESPONSE_TYPE, "token"); .param(RESPONSE_TYPE, "token");


Snippet requestParameters = requestParameters( Snippet requestParameters = requestParameters(
responseTypeParameter, responseTypeParameter,
clientIdParameter, clientIdParameter,
grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `password`"), grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `password`"),
clientSecretParameter, clientSecretParameter,
parameterWithName("username").description("the username for the user trying to get a token").attributes(constraints.value("Required"), type.value(STRING)), parameterWithName("username").required().type(STRING).description("the username for the user trying to get a token"),
parameterWithName("password").description("the password for the user trying to get a token").attributes(constraints.value("Required"), type.value(STRING)) parameterWithName("password").required().type(STRING).description("the password for the user trying to get a token"),
opaqueFormatParameter
); );


Snippet responseFields = responseFields( Snippet responseFields = responseFields(
Expand All @@ -231,13 +237,15 @@ public void getTokenWithClientAuthInHeader() throws Exception {
.param(GRANT_TYPE, "password") .param(GRANT_TYPE, "password")
.param("username", user.getUserName()) .param("username", user.getUserName())
.param("password", user.getPassword()) .param("password", user.getPassword())
.param(TokenConstants.REQUEST_TOKEN_FORMAT, TokenConstants.OPAQUE)
.param(RESPONSE_TYPE, "token"); .param(RESPONSE_TYPE, "token");


Snippet requestParameters = requestParameters( Snippet requestParameters = requestParameters(
responseTypeParameter, responseTypeParameter,
grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `password`"), grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `password`"),
parameterWithName("username").description("the username for the user trying to get a token").attributes(constraints.value("Required"), type.value(STRING)), parameterWithName("username").required().type(STRING).description("the username for the user trying to get a token"),
parameterWithName("password").description("the password for the user trying to get a token").attributes(constraints.value("Required"), type.value(STRING)) parameterWithName("password").required().type(STRING).description("the password for the user trying to get a token"),
opaqueFormatParameter
); );


Snippet requestHeaders = requestHeaders(headerWithName("Authorization").description("Base64 encoded client details in the format: `Basic client_id:client_secret`")); Snippet requestHeaders = requestHeaders(headerWithName("Authorization").description("Base64 encoded client details in the format: `Basic client_id:client_secret`"));
Expand Down Expand Up @@ -286,12 +294,14 @@ public void getTokenUsingPasscode() throws Exception {
.header("Authorization", "Basic " + clientAuthorization) .header("Authorization", "Basic " + clientAuthorization)
.param(GRANT_TYPE, "password") .param(GRANT_TYPE, "password")
.param("passcode", passcode) .param("passcode", passcode)
.param(TokenConstants.REQUEST_TOKEN_FORMAT, TokenConstants.OPAQUE)
.param(RESPONSE_TYPE, "token"); .param(RESPONSE_TYPE, "token");


Snippet requestParameters = requestParameters( Snippet requestParameters = requestParameters(
responseTypeParameter, responseTypeParameter,
grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `password`"), grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `password`"),
parameterWithName("passcode").description("the one-time passcode for the user which can be retrieved by going to `/passcode`").attributes(constraints.value("Required"), type.value(STRING)) parameterWithName("passcode").required().type(STRING).description("the one-time passcode for the user which can be retrieved by going to `/passcode`"),
opaqueFormatParameter
); );


Snippet responseFields = responseFields( Snippet responseFields = responseFields(
Expand All @@ -313,31 +323,34 @@ public void getTokenUsingPasscode() throws Exception {
public void refreshToken() throws Exception { public void refreshToken() throws Exception {
createUser(); createUser();
MockHttpServletRequestBuilder postForToken = post("/oauth/token") MockHttpServletRequestBuilder postForToken = post("/oauth/token")
.accept(APPLICATION_JSON) .accept(APPLICATION_JSON)
.contentType(APPLICATION_FORM_URLENCODED) .contentType(APPLICATION_FORM_URLENCODED)
.param(CLIENT_ID, "app") .param(CLIENT_ID, "app")
.param("client_secret", "appclientsecret") .param("client_secret", "appclientsecret")
.param(GRANT_TYPE, "password") .param(GRANT_TYPE, "password")
.param("username", user.getUserName()) .param("username", user.getUserName())
.param("password", user.getPassword()) .param("password", user.getPassword())
.param(RESPONSE_TYPE, "token"); .param(TokenConstants.REQUEST_TOKEN_FORMAT, TokenConstants.OPAQUE)
.param(RESPONSE_TYPE, "token");


MvcResult mvcResult = getMockMvc().perform(postForToken).andExpect(status().isOk()).andReturn(); MvcResult mvcResult = getMockMvc().perform(postForToken).andExpect(status().isOk()).andReturn();
OAuth2RefreshToken refreshToken = JsonUtils.readValue(mvcResult.getResponse().getContentAsString(), CompositeAccessToken.class).getRefreshToken(); OAuth2RefreshToken refreshToken = JsonUtils.readValue(mvcResult.getResponse().getContentAsString(), CompositeAccessToken.class).getRefreshToken();


MockHttpServletRequestBuilder postForRefreshToken = post("/oauth/token") MockHttpServletRequestBuilder postForRefreshToken = post("/oauth/token")
.accept(APPLICATION_JSON) .accept(APPLICATION_JSON)
.contentType(APPLICATION_FORM_URLENCODED) .contentType(APPLICATION_FORM_URLENCODED)
.param(CLIENT_ID, "app") .param(CLIENT_ID, "app")
.param("client_secret", "appclientsecret") .param("client_secret", "appclientsecret")
.param(GRANT_TYPE, "refresh_token") .param(GRANT_TYPE, "refresh_token")
.param("refresh_token", refreshToken.getValue()); .param(TokenConstants.REQUEST_TOKEN_FORMAT, TokenConstants.OPAQUE)
.param("refresh_token", refreshToken.getValue());


Snippet requestParameters = requestParameters( Snippet requestParameters = requestParameters(
grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `refresh_token`"), grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `refresh_token`"),
clientIdParameter, clientIdParameter,
clientSecretParameter, clientSecretParameter,
parameterWithName("refresh_token").description("the refresh_token that was returned along with the access token.").attributes(type.value(STRING), constraints.value("Required")) parameterWithName("refresh_token").required().type(STRING).description("the refresh_token that was returned along with the access token."),
opaqueFormatParameter
); );


Snippet responseFields = responseFields( Snippet responseFields = responseFields(
Expand Down Expand Up @@ -401,15 +414,17 @@ public void getIdTokenUsingAuthCodeGrant() throws Exception {
.param(GRANT_TYPE, "authorization_code") .param(GRANT_TYPE, "authorization_code")
.param(RESPONSE_TYPE, "id_token") .param(RESPONSE_TYPE, "id_token")
.param("code", code) .param("code", code)
.param(TokenConstants.REQUEST_TOKEN_FORMAT, TokenConstants.OPAQUE)
.param(REDIRECT_URI, redirect); .param(REDIRECT_URI, redirect);


Snippet requestParameters = requestParameters( Snippet requestParameters = requestParameters(
responseTypeParameter, responseTypeParameter,
clientIdParameter, clientIdParameter,
parameterWithName(REDIRECT_URI).description("redirection URI to which the authorization server will send the user-agent back once access is granted (or denied)").attributes(constraints.value("Required if provided on authorization request"), type.value(STRING)), parameterWithName(REDIRECT_URI).type(STRING).description("redirection URI to which the authorization server will send the user-agent back once access is granted (or denied)").attributes(SnippetUtils.constraints.value("Required if provided on authorization request")),
parameterWithName("code").description("the authorization code, obtained from /oauth/authorize, issued for the user").attributes(constraints.value("Required"), type.value(STRING)), parameterWithName("code").required().type(STRING).description("the authorization code, obtained from /oauth/authorize, issued for the user"),
grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `authorization_code`"), grantTypeParameter.description("the type of authentication being used to obtain the token, in this case `authorization_code`"),
clientSecretParameter clientSecretParameter,
opaqueFormatParameter
); );


Snippet responseFields = responseFields( Snippet responseFields = responseFields(
Expand Down
@@ -1,12 +1,20 @@
package org.cloudfoundry.identity.uaa.test; package org.cloudfoundry.identity.uaa.test;


import org.springframework.restdocs.payload.FieldDescriptor; import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.restdocs.payload.JsonFieldType;
import org.springframework.restdocs.request.ParameterDescriptor; import org.springframework.restdocs.request.ParameterDescriptor;
import org.springframework.restdocs.snippet.Attributes; import org.springframework.restdocs.snippet.Attributes;


import static org.springframework.restdocs.snippet.Attributes.key; import static org.springframework.restdocs.snippet.Attributes.key;


public final class SnippetUtils { public final class SnippetUtils {

public static final Attributes.AttributeBuilder type = key("type");
public static final Attributes.AttributeBuilder constraints = key("constraints");
public static final Attributes.AttributeBuilder defaultvalue = key("default");
public static final String REQUIRED = "Required";
public static final String OPTIONAL = "Optional";

private SnippetUtils() {} private SnippetUtils() {}


public static ConstrainableParameter parameterWithName(String name) { public static ConstrainableParameter parameterWithName(String name) {
Expand All @@ -22,17 +30,22 @@ private ConstrainableParameter(String name) {
super(name); super(name);
} }


public ParameterDescriptor required() { public ConstrainableParameter required() {
return attributes(key("constraints").value("Required")); return (ConstrainableParameter)attributes(constraints.value(REQUIRED));
} }


public ParameterDescriptor optional(Object defaultValue) { public ConstrainableParameter optional(Object defaultValue) {
if(defaultValue == null) { if(defaultValue == null) {
defaultValue = ""; defaultValue = "";
} }
Attributes.Attribute[] attrs = new Attributes.Attribute[] { key("constraints").value("Optional"), key("default").value(defaultValue) }; Attributes.Attribute[] attrs = new Attributes.Attribute[] { constraints.value(OPTIONAL), defaultvalue.value(defaultValue) };
return attributes(attrs); return (ConstrainableParameter)attributes(attrs);
}

public ConstrainableParameter type(JsonFieldType fieldType) {
return (ConstrainableParameter)attributes(type.value(fieldType));
} }

} }




Expand All @@ -41,16 +54,21 @@ private ConstrainableField(String name) {
super(name); super(name);
} }


public FieldDescriptor required() { public ConstrainableField required() {
return attributes(key("constraints").value("Required")); return (ConstrainableField)attributes(constraints.value(REQUIRED));
} }


public FieldDescriptor optional(Object defaultValue) { public ConstrainableField optional(Object defaultValue) {
super.optional();
if(defaultValue == null) { if(defaultValue == null) {
defaultValue = ""; defaultValue = "";
} }
Attributes.Attribute[] attrs = new Attributes.Attribute[] { key("constraints").value("Optional"), key("default").value(defaultValue) }; Attributes.Attribute[] attrs = new Attributes.Attribute[] {constraints.value(OPTIONAL), defaultvalue.value(defaultValue) };
return attributes(attrs); return (ConstrainableField)attributes(attrs);
}
public ConstrainableField type(JsonFieldType fieldType) {
return (ConstrainableField)attributes(type.value(fieldType));
} }

} }
} }

0 comments on commit 02a9b09

Please sign in to comment.