public abstract class DataHandler {

	private Request request;

	/**
	 * Initialize this instance with the request information.
	 * This constructor calls the init() method to initialize a connection
	 * to your database, a preparation of your cache and so on.
	 * @param request The request instance.
	 */
	public DataHandler(Request request) {
		this.request = request;
		init();
	}

	/**
	 * This method is called at creating this instance.
	 * You should implement an initialization procedure in this method.
	 */
	protected void init() {
	}

	/**
	 * Retrieve the request instance passed at creating this instance.
	 * @return The request instance.
	 */
	public Request getRequest() {
		return request;
	}

	/**
	 * Validate the client and return the result.
	 * This method is called at first for all grant types.
	 * You should check whether the client specified by clientId value exists
	 * or not, whether the client secret is valid or not, and whether
	 * the client supports the grant type or not. If there are other things
	 * to have to check, they must be implemented in this method.
	 * @param clientId The client ID.
	 * @param clientSecret The client secret string.
	 * @param grantType The grant type string which the client required.
	 * @return True if the client is valid.
	 */
	public abstract boolean validateClient(
			String clientId, String clientSecret, String grantType);

	/**
	 * Retrieve the user's ID from the user's credential.
	 * This method is used for the Resource Owner Password Credential Grant only.
	 * Normally, you should implement this process like retrieving the user's ID
	 * from your database and checking the password.
	 * If the null value or the empty string is returned from this method as the
	 * result, the error type "invalid_grant" will be sent to the client.
	 * @param username The user name inputed by the user his/herself.
	 * @param password The password string inputed by the user.
	 * @return The user's ID string. If the user is not found, you must return
	 * a null value or an empty string.
	 */
	public abstract String getUserId(String username, String password);

	/**
	 * Create or update an Authorization information.
	 * This method is used when the authorization information should be created
	 * or updated directly against receiving of the request in case of Client
	 * Credential grant or Resource Owner Password Credential grant.
	 * If the null value is returned from this method as the result, the error
	 * type "invalid_grant" will be sent to the client.
	 * @param clientId The client ID.
	 * @param userId The user's ID.
	 * @param scope The scope string.
	 * @return The created or updated the information about authorization.
	 */
	public abstract AuthInfo createOrUpdateAuthInfo(
			String clientId, String userId, String scope);

	/**
	 * Create or update an Access token.
	 * This method is used for all grant types. The access token is created or
	 * updated based on the authInfo's property values. In generally, this
	 * method never failed, because all validations should be passed before
	 * this method is called.
	 * @param authInfo The instance which has the information about authorization.
	 * @return The created or updated access token instance.
	 */
	public abstract AccessToken createOrUpdateAccessToken(AuthInfo authInfo);

	/**
	 * Retrieve the authorization information by the authorization code value.
	 * This method is used for an Authorization Code grant. The authorization
	 * information which should be returned as this result is needed to create
	 * at the authentication and authorization timing by the user. If the null
	 * value is returned as this result, the error type "invalid_grant" will be
	 * sent to the client.
	 * @param code The authorization code value.
	 * @return The authorization information instance.
	 */
	public abstract AuthInfo getAuthInfoByCode(String code);

	/**
	 * Retrieve the authorization information by the refresh token string.
	 * This method is used to re-issue an access token with the refresh token.
	 * The authorization information which has already been stored into your
	 * database should be specified by the refresh token. If you want to define
	 * the expiration of the refresh token, you must check it in this
	 * implementation. If the refresh token is not found, the refresh token is
	 * invalid or there is other reason which the authorization information
	 * should not be returned, this method must return the null value as the
	 * result.
	 * @param refreshToken The refresh token string.
	 * @return The authorization information instance.
	 */
	public abstract AuthInfo getAuthInfoByRefreshToken(String refreshToken);

	/**
	 * Determine an user ID representing the client itself and return it.
	 * This method is used for the Client Credentials grant. In this flow,
	 * there is no user to authorize, and OAuth2 provider trusts the client.
	 * Therefore, the user ID representing the client itself should be issued,
	 * and the ID can be distinguished whether it represents an user or a client.
	 * @param clientId The client ID.
	 * @param clientSecret The client secret string.
	 * @return The ID representing the client.
	 */
	public abstract String getClientUserId(
			String clientId, String clientSecret);

	/**
	 * Validate the client specified by the client ID.
	 * This method is used to check the client at accessing a protected resource.
	 * When the access token passed from the client is valid, the client status
	 * may be invalid in the OAuth provider side. In this case, this method must
	 * return false to refuse the access to all API endpoints.
	 * @param clientId The client ID.
	 * @return If the client status is invalid, return false, otherwise, return
	 * true.
	 */
	public abstract boolean validateClientById(String clientId);

	/**
	 * Validate the user specified by the user ID.
	 * This method is used to check the user at accessing a protected resource.
	 * When the access token passed from the client is valid, the user status
	 * may be invalid or may be left in the OAuth provider side. In these case,
	 * this method must return false to refuse the access to all API endpoints.
	 * @param userId The user's ID.
	 * @return If the user's status is invalid, return false, otherwise, return
	 * true.
	 */
	public abstract boolean validateUserById(String userId);

	/**
	 * Retrieve the access token from the token string.
	 * This method is used at accessing a protected resource. This sub class
	 * should fetch the access token information from your database or etc and
	 * return it. If the access token has been revoked by the user or there is
	 * other reason, this method must return the null value to refuse the access
	 * to all API endpoints.
	 * @param token The access token string.
	 * @return The object which has the information for the access token.
	 */
	public abstract AccessToken getAccessToken(String token);

	/**
	 * Retrieve the authorization information by the ID.
	 * This method is used at accessing a protected resource. The getAccessTkoken()
	 * method is called before this method calling. The result has a ID of the
	 * authorization information. The ID is passed to this method as an
	 * argument. This sub class must return the authorization information instance
	 * to the client. If the ID has already been invalid or there is other reason,
	 * this implementation must return the null value.
	 * @param id The ID to specify the authorization information.
	 * @return The object which has the information about the authorization.
	 */
	public abstract AuthInfo getAuthInfoById(String id);

} public interface DataHandlerFactory {

	/**
	 * Create a DataHandler instance and return it.
	 * This implementation method must create the instance based on a concrete
	 * class of the DataHandler abstract class.
	 * @param request The request object to provide some information passed from
	 * client.
	 * @return The DataHandler instance.
	 */
	public DataHandler create(Request request);

} public class Token {

	private DataHandlerFactory dataHandlerFactory;
	private GrantHandlerProvider grantHandlerProvider;
	private ClientCredentialFetcher clientCredentialFetcher;

	/**
	 * Set the DataHandlerFactory instance.
	 * This class gets a DataHandler instance using this factory object.
	 * The factory instance must be passed using this method before calling
	 * the handlerRequest() method.
	 * @param dataHandlerFactory The DataHandlerFactory instance.
	 */
	public void setDataHandlerFactory(DataHandlerFactory dataHandlerFactory) {
		this.dataHandlerFactory = dataHandlerFactory;
	}

	/**
	 * Set the GrantHandlerProvider instance.
	 * This class gets a GrantHandler instance using this provider object.
	 * The GrantHandlerProvider can determine what handler should be used
	 * to issue the token. The provider instance must be passed using this method
	 * before calling the handlerRequest() method.
	 * @param grantHandlerProvider The GrantHandlerProvider instance.
	 */
	public void setGrantHandlerProvider(GrantHandlerProvider grantHandlerProvider) {
		this.grantHandlerProvider = grantHandlerProvider;
	}

	/**
	 * Set the ClientCredentialFetcher instance.
	 * This class doesn't have an ability to fetch a client credential information
	 * from the request, instead delegates this ClientCredentialFetcher instance.
	 * The fetcher instance must be passed using this method before calling the
	 * handlerRequest() method.
	 * @param clientCredentialFetcher The ClientCredentialFetcher instance.
	 */
	public void setClientCredentialFetcher(ClientCredentialFetcher clientCredentialFetcher) {
		this.clientCredentialFetcher = clientCredentialFetcher;
	}

	/**
	 * Handle the request and issue a token.
	 * This class is an entry point to issue the token. When this method receives
	 * the request, then this checks the request, determines the grant type,
	 * fetches the client credential information, and issues the token based
	 * on the content of the request. The result is composed of the status code
	 * and the JSON string. The status code will be 200 when the issuing token
	 * is succeeded. If an error occurs, the code will be the 300 series value.
	 * The JSON string has the access token, refresh token, expires_in value and
	 * the scope string.
	 * @param request The request instance.
	 * @return The response object which has the status code and JSON string.
	 */
	public Response handleRequest(Request request) {
		try {
			String type = request.getParameter("grant_type");
			if (StringUtils.isEmpty(type)) {
				throw new OAuthError.InvalidRequest("'grant_type' not found");
			}
			GrantHandler handler = grantHandlerProvider.getHandler(type);
			if (handler == null) {
				throw new OAuthError.UnsupportedGrantType("");
			}
			DataHandler dataHandler = dataHandlerFactory.create(request);
			ClientCredential clientCredential =
					clientCredentialFetcher.fetch(request);
			String clientId = clientCredential.getClientId();
			if (StringUtils.isEmpty(clientId)) {
				throw new OAuthError.InvalidRequest("'client_id' not found");
			}
			String clientSecret = clientCredential.getClientSecret();
			if (StringUtils.isEmpty(clientSecret)) {
				throw new OAuthError.InvalidRequest("'client_secret' not found");
			}
			if (!dataHandler.validateClient(clientId, clientSecret, type)) {
				throw new OAuthError.InvalidClient("");
			}
			GrantHandlerResult handlerResult = handler.handleRequest(dataHandler);
			return new Response(200, Util.toJson(handlerResult));
		} catch (OAuthError e) {
			return new Response(e.getCode(), Util.toJson(e));
		}
	}

	/**
	 * This class has two properties: A status code and JSON string as the result
	 * of issuing a token.
	 * 
	 * @author Yoichiro Tanaka
	 *
	 */
	public static class Response {

		private int code;
		private String body;

		/**
		 * Initialize this instance with arguments passed.
		 * @param code The status code as the result of issuing a token.
		 * @param body The JSON string which has a token information.
		 */
		public Response(int code, String body) {
			super();
			this.code = code;
			this.body = body;
		}

		/**
		 * Retrieve the status code value.
		 * This status code will be 200 when the issuing token is succeeded.
		 * If an error occurs, the code will be the 300 series value.
		 * @return The HTTP status code value.
		 */
		public int getCode() {
			return code;
		}

		/**
		 * Retrieve the JSON string which has a token information.
		 * The JSON string has the access token, refresh token, expires_in
		 * value and the scope string. If the issuing a token failed,
		 * this json string has the error type and description.
		 * @return The JSON string value.
		 */
		public String getBody() {
			return body;
		}

	}

} public static class Response {

	private int code;
	private String body;

	/**
	 * Initialize this instance with arguments passed.
	 * @param code The status code as the result of issuing a token.
	 * @param body The JSON string which has a token information.
	 */
	public Response(int code, String body) {
		super();
		this.code = code;
		this.body = body;
	}

	/**
	 * Retrieve the status code value.
	 * This status code will be 200 when the issuing token is succeeded.
	 * If an error occurs, the code will be the 300 series value.
	 * @return The HTTP status code value.
	 */
	public int getCode() {
		return code;
	}

	/**
	 * Retrieve the JSON string which has a token information.
	 * The JSON string has the access token, refresh token, expires_in
	 * value and the scope string. If the issuing a token failed,
	 * this json string has the error type and description.
	 * @return The JSON string value.
	 */
	public String getBody() {
		return body;
	}

} public class ClientCredentialFetcherImpl implements ClientCredentialFetcher {

	private static final Pattern REGEXP_BASIC =
			Pattern.compile("^\\s*(Basic)\\s+(.*)$");

	/**
	 * Fetch a client credential sent from the client as a request header
	 * or request parameters. First, this method attempts to fetch it from
	 * the Authorization request header. For instance, it is expected as the
	 * format "Basic [Base64 encoded]". The encoded value actually has two
	 * parameter "Client ID" and "Client secret" delimited by ":" character.
	 * If it does not exist, this method attempt to fetch it from request
	 * parameter named "client_id" and "client_secret".
	 * 
	 * @param request The request object.
	 * @return The client credential information.
	 */
	@Override
	public ClientCredential fetch(Request request) {
		String header = request.getHeader("Authorization");
		if (header != null) {
			Matcher matcher = REGEXP_BASIC.matcher(header);
			if (matcher.find()) {
				String decoded = Util.decodeBase64(matcher.group(2));
				if (decoded.indexOf(':') > 0) {
					String[] credential = decoded.split(":", 2);
					return new ClientCredential(credential[0], credential[1]);
				}
			}
		}
		return new ClientCredential(
			request.getParameter("client_id"),
			request.getParameter("client_secret"));
	}

} public interface GrantHandler {

	/**
	 * Handle a request to issue a token and issue it.
	 * This method should be implemented for each grant type of OAuth2
	 * specification. For instance, the procedure uses a DataHandler instance
	 * to access to your database. Each grant type has some validation rule,
	 * if the validation is failed, this method will throw an OAuthError
	 * exception.
	 * 
	 * @param dataHandler The DataHandler instance to access to your database.
	 * @return The issued token information as the result of calling this method.
	 * @throws OAuthError If the validation was failed.
	 */
	public GrantHandlerResult handleRequest(DataHandler dataHandler) throws OAuthError;

	/**
	 * This class has the information about issued token.
	 * 
	 * @author Yoichiro Tanaka
	 *
	 */
	@JsonSerialize(include = Inclusion.NON_NULL)
	@JsonPropertyOrder({"token_type",
		"access_token",
		"refresh_token",
		"expires_in",
		"scope"})
	public static class GrantHandlerResult {

		@JsonProperty("token_type")
		private String tokenType;
		@JsonProperty("access_token")
		private String accessToken;
		@JsonProperty("expires_in")
		private Long expiresIn;
		@JsonProperty("refresh_token")
		private String refreshToken;
		private String scope;

		/**
		 * Initialize this instance with these arguments.
		 * These parameters is required.
		 * 
		 * @param tokenType The token type string.
		 * @param accessToken The access token string.
		 */
		public GrantHandlerResult(String tokenType, String accessToken) {
			super();
			this.tokenType = tokenType;
			this.accessToken = accessToken;
		}

		/**
		 * Retrieve the token type.
		 * @return The issued token's type.
		 */
		public String getTokenType() {
			return tokenType;
		}

		/**
		 * Retrieve the access token.
		 * @return The issued access token string.
		 */
		public String getAccessToken() {
			return accessToken;
		}

		/**
		 * Set the expires_in parameter's value.
		 * An unit of this value is second.
		 * @param expiresIn The expires_in value.
		 */
		public void setExpiresIn(Long expiresIn) {
			this.expiresIn = expiresIn;
		}

		/**
		 * Retrieve the expires_in value.
		 * @return The expires_in value (this unit is second).
		 */
		public Long getExpiresIn() {
			return expiresIn;
		}

		/**
		 * Set the refresh token.
		 * If a grant type which issues the refresh token is specified,
		 * the issued refresh token is passed to the client via this method.
		 * @param refreshToken The refresh token string.
		 */
		public void setRefreshToken(String refreshToken) {
			this.refreshToken = refreshToken;
		}

		/**
		 * Retrieve the refresh token.
		 * @return The issued refresh token string.
		 */
		public String getRefreshToken() {
			return refreshToken;
		}

		/**
		 * Set the scope string.
		 * This scope string specified by the client is passed to
		 * this method untouched.
		 * @param scope The scope string.
		 */
		public void setScope(String scope) {
			this.scope = scope;
		}

		/**
		 * Retrieve the scope string.
		 * @return The scope string.
		 */
		public String getScope() {
			return scope;
		}

	}

} public class GrantHandlerProvider {

	private Map<String, GrantHandler> handlers;

	/**
	 * Retrieve the grant handler instance for the specified grant type.
	 * 
	 * @param type The grant type string.
	 * @return The grant handler instance. The null is returned when the target
	 * grant handler is not found for the specified grant type.
	 */
	public GrantHandler getHandler(String type) {
		return handlers.get(type);
	}
	
	/**
	 * Retrieve the map instance which has grant handlers
	 * This method is provided for an unit test.
	 * @return The map object which has grant handlers.
	 */
	public Map<String, GrantHandler> getHandlers() {
		return handlers;
	}

	/**
	 * Set the map instance which has grant handlers.
	 * The key means a grant type. The value is each grant handler instance.
	 * @param handlers The map object which has grant handlers.
	 */
	public void setGrantHandlers(Map<String, GrantHandler> handlers) {
		this.handlers = handlers;
	}

} public class RefreshToken extends AbstractGrantHandler {

	/*
	 * (non-Javadoc)
	 * @see jp.eisbahn.oauth2.server.granttype.GrantHandler#handleRequest(jp.eisbahn.oauth2.server.data.DataHandler)
	 */
	@Override
	public GrantHandlerResult handleRequest(DataHandler dataHandler) throws OAuthError {
		Request request = dataHandler.getRequest();

		ClientCredential clientCredential = getClientCredentialFetcher().fetch(request);
		String clientId = clientCredential.getClientId();

		String refreshToken = getParameter(request, "refresh_token");

		AuthInfo authInfo = dataHandler.getAuthInfoByRefreshToken(refreshToken);
		if (authInfo == null) {
			throw new OAuthError.InvalidGrant("");
		}
		if (!authInfo.getClientId().equals(clientId)) {
			throw new OAuthError.InvalidClient("");
		}

		return issueAccessToken(dataHandler, authInfo);
	}

} public class AccessToken {

	private String authId;
	private String token;
	private long expiresIn;
	private Date createdOn;

	/**
	 * Set the ID of the authorization information to relate between the
	 * information and this access token.
	 * @param authId The ID of the authorization information.
	 */
	public void setAuthId(String authId) {
		this.authId = authId;
	}

	/**
	 * Retrieve the ID of the authorization information.
	 * @return The ID string.
	 */
	public String getAuthId() {
		return authId;
	}

	/**
	 * Set the issued access token.
	 * @param token The access token string.
	 */
	public void setToken(String token) {
		this.token = token;
	}

	/**
	 * Retrieve the access token.
	 * @return The access token string.
	 */
	public String getToken() {
		return token;
	}

	/**
	 * Set the expiration time of this access token.
	 * If this access token has a time limitation, this value must be positive.
	 * @param expiresIn The expiration time value. The unit is second.
	 */
	public void setExpiresIn(long expiresIn) {
		this.expiresIn = expiresIn;
	}

	/**
	 * Retrieve the expiration time of this access token.
	 * @return The expiration time value. This unit is second.
	 */
	public long getExpiresIn() {
		return expiresIn;
	}

	/**
	 * Set the time when this access token is created.
	 * @param createdOn The date and time value.
	 */
	public void setCreatedOn(Date createdOn) {
		this.createdOn = createdOn;
	}

	/**
	 * Retrieve the time when this access token is created.
	 * @return The date and time value when this is created.
	 */
	public Date getCreatedOn() {
		return createdOn;
	}

} public class AuthInfo {

	private String id;
	private String userId;
	private String clientId;
	private String scope;
	private String refreshToken;
	private String code;
	private String redirectUri;

	/**
	 * Set the ID of this model.
	 * This ID value will be kept by some access token's information.
	 * @param id The ID value.
	 */
	public void setId(String id) {
		this.id = id;
	}

	/**
	 * Retrieve the ID of this model.
	 * @return The ID string value.
	 */
	public String getId() {
		return id;
	}

	/**
	 * Set the user's ID who is authenticated.
	 * @param userId The user's ID value.
	 */
	public void setUserId(String userId) {
		this.userId = userId;
	}

	/**
	 * Retrieve the user's ID.
	 * @return The user's ID string.
	 */
	public String getUserId() {
		return userId;
	}

	/**
	 * Set the client ID.
	 * @param clientId The client ID.
	 */
	public void setClientId(String clientId) {
		this.clientId = clientId;
	}

	/**
	 * Retrieve the client ID.
	 * @return The client ID string.
	 */
	public String getClientId() {
		return clientId;
	}

	/**
	 * Set the scope string.
	 * This scope string has some scope identifiers delimited by a whitespace.
	 * @param scope The scope string.
	 */
	public void setScope(String scope) {
		this.scope = scope;
	}

	/**
	 * Retrieve the scope string.
	 * @return The scope string.
	 */
	public String getScope() {
		return scope;
	}

	/**
	 * Set the refresh token.
	 * If the specified grant type should not return a refresh token,
	 * this method must be set with a null as an argument.
	 * @param refreshToken The refresh token string.
	 */
	public void setRefreshToken(String refreshToken) {
		this.refreshToken = refreshToken;
	}

	/**
	 * Retrieve the refresh token.
	 * @return The refresh token string.
	 */
	public String getRefreshToken() {
		return refreshToken;
	}

	/**
	 * Set the authorization code.
	 * If the grant type which doesn't need the authorization code is required,
	 * this method must not be called.
	 * @param code The authorization code value.
	 */
	public void setCode(String code) {
		this.code = code;
	}

	/**
	 * Retrieve the authorization code.
	 * @return The authorization code value.
	 */
	public String getCode() {
		return code;
	}

	/**
	 * Set the redirect_uri string.
	 * @param redirectUri The redirect_uri string.
	 */
	public void setRedirectUri(String redirectUri) {
		this.redirectUri = redirectUri;
	}

	/**
	 * Retrieve the redirect_uri string.
	 * @return The redirect_uri string.
	 */
	public String getRedirectUri() {
		return redirectUri;
	}

} public interface Request {

	/**
	 * Retrieve the parameter value specified by the parameter name
	 * from the request.
	 * @param name The parameter name.
	 * @return The value against the name.
	 */
	public String getParameter(String name);

	/**
	 * Retrieve all parameter names and values from the request as a Map instance.
	 * @return  The map instance which has all parameter names and values.
	 */
	public Map<String, String> getParameterMap();
	
	/**
	 * Retrieve the request header value from the request.
	 * @param name The header's name.
	 * @return The value against the name.
	 */
	public String getHeader(String name);

}
import jp.eisbahn.oauth2.server.fetcher.clientcredential.ClientCredentialFetcherImpl;
import jp.eisbahn.oauth2.server.granttype.GrantHandler;
import jp.eisbahn.oauth2.server.granttype.GrantHandlerProvider;
import jp.eisbahn.oauth2.server.granttype.impl.RefreshToken;
import jp.eisbahn.oauth2.server.models.AccessToken;
import jp.eisbahn.oauth2.server.models.AuthInfo;
import jp.eisbahn.oauth2.server.models.Request;
import org.junit.Test;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import java.util.HashMap;
import jp.eisbahn.oauth2.server.data.DataHandler;
import jp.eisbahn.oauth2.server.data.DataHandlerFactory;
import jp.eisbahn.oauth2.server.endpoint.Token;
import jp.eisbahn.oauth2.server.endpoint.Token.Response;
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

package jp.eisbahn.oauth2.server.endpoint;





public class TokenTest {

	@Test
	public void testHandleRequestGrantTypeNotFound() throws Exception {
		Request request = createMock(Request.class);
		expect(request.getParameter("grant_type")).andReturn(null);
		replay(request);
		Token target = new Token();
		Response response = target.handleRequest(request);
		assertEquals(400, response.getCode());
		assertEquals(
			"{\"error\":\"invalid_request\","
				+ "\"error_description\":\"'grant_type' not found\"}",
			response.getBody());
		verify(request);
	}

	@Test
	public void testHandleRequestGrantTypeNotSupported() throws Exception {
		Request request = createMock(Request.class);
		expect(request.getParameter("grant_type")).andReturn("evil");
		DataHandlerFactory factory = createMock(DataHandlerFactory.class);
		replay(request, factory);
		Token target = createToken(factory);
		Response response = target.handleRequest(request);
		assertEquals(400, response.getCode());
		assertEquals(
			"{\"error\":\"unsupported_grant_type\"}",
			response.getBody());
		verify(request, factory);
	}

	@Test
	public void testHandleRequestClientIdNotFound() throws Exception {
		Request request = createMock(Request.class);
		expect(request.getParameter("grant_type")).andReturn("refresh_token");
		expect(request.getHeader("Authorization")).andReturn(null);
		expect(request.getParameter("client_id")).andReturn(null);
		expect(request.getParameter("client_secret")).andReturn(null);
		DataHandlerFactory factory = createMock(DataHandlerFactory.class);
		expect(factory.create(request)).andReturn(null);
		replay(request, factory);
		Token target = createToken(factory);
		Response response = target.handleRequest(request);
		assertEquals(400, response.getCode());
		assertEquals(
			"{\"error\":\"invalid_request\","
				+ "\"error_description\":\"'client_id' not found\"}",
			response.getBody());
		verify(request, factory);
	}

	@Test
	public void testHandleRequestClientSecretNotFound() throws Exception {
		Request request = createMock(Request.class);
		expect(request.getParameter("grant_type")).andReturn("refresh_token");
		expect(request.getHeader("Authorization")).andReturn(null);
		expect(request.getParameter("client_id")).andReturn("clientId1");
		expect(request.getParameter("client_secret")).andReturn(null);
		DataHandlerFactory factory = createMock(DataHandlerFactory.class);
		expect(factory.create(request)).andReturn(null);
		replay(request, factory);
		Token target = createToken(factory);
		Response response = target.handleRequest(request);
		assertEquals(400, response.getCode());
		assertEquals(
			"{\"error\":\"invalid_request\","
				+ "\"error_description\":\"'client_secret' not found\"}",
			response.getBody());
		verify(request, factory);
	}

	@Test
	public void testHandleRequestClientInvalid() throws Exception {
		Request request = createMock(Request.class);
		expect(request.getParameter("grant_type")).andReturn("refresh_token");
		expect(request.getHeader("Authorization")).andReturn(null);
		expect(request.getParameter("client_id")).andReturn("clientId1");
		expect(request.getParameter("client_secret")).andReturn("clientSecret1");
		DataHandlerFactory factory = createMock(DataHandlerFactory.class);
		DataHandler dataHandler = createMock(DataHandler.class);
		expect(dataHandler.validateClient(
			"clientId1", "clientSecret1", "refresh_token")).andReturn(false);
		expect(factory.create(request)).andReturn(dataHandler);
		replay(request, factory, dataHandler);
		Token target = createToken(factory);
		Response response = target.handleRequest(request);
		assertEquals(401, response.getCode());
		assertEquals(
			"{\"error\":\"invalid_client\"}",
			response.getBody());
		verify(request, factory, dataHandler);
	}

	@Test
	public void testHandleRequestSimple() throws Exception {
		Request request = createMock(Request.class);
		expect(request.getParameter("grant_type")).andReturn("refresh_token");
		expect(request.getHeader("Authorization")).andReturn(null).times(2);
		expect(request.getParameter("client_id")).andReturn("clientId1").times(2);
		expect(request.getParameter("client_secret")).andReturn("clientSecret1").times(2);
		expect(request.getParameter("refresh_token")).andReturn("refreshToken1");
		DataHandlerFactory factory = createMock(DataHandlerFactory.class);
		DataHandler dataHandler = createMock(DataHandler.class);
		expect(dataHandler.validateClient(
			"clientId1", "clientSecret1", "refresh_token")).andReturn(true);
		expect(dataHandler.getRequest()).andReturn(request);
		AuthInfo authInfo = new AuthInfo();