package com.github.scribejava.core.oauth; import java.io.IOException; import java.util.Map; import java.util.concurrent.Future; import com.github.scribejava.core.builder.api.DefaultApi10a; import com.github.scribejava.core.builder.api.OAuth1SignatureType; import com.github.scribejava.core.model.OAuth1AccessToken; import com.github.scribejava.core.model.OAuth1RequestToken; import com.github.scribejava.core.model.OAuthAsyncRequestCallback; import com.github.scribejava.core.model.OAuthConfig; import com.github.scribejava.core.model.OAuthConstants; import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.services.Base64Encoder; import com.github.scribejava.core.utils.MapUtils; import java.util.concurrent.ExecutionException; /** * OAuth 1.0a implementation of {@link OAuthService} */ public class OAuth10aService extends OAuthService<OAuth1AccessToken> { private static final String VERSION = "1.0"; private final DefaultApi10a api; /** * Default constructor * * @param api OAuth1.0a api information * @param config OAuth 1.0a configuration param object */ public OAuth10aService(DefaultApi10a api, OAuthConfig config) { super(config); this.api = api; } public final OAuth1RequestToken getRequestToken() throws IOException, InterruptedException, ExecutionException { final OAuthConfig config = getConfig(); config.log("obtaining request token from " + api.getRequestTokenEndpoint()); final OAuthRequest request = prepareRequestTokenRequest(); config.log("sending request..."); final Response response = execute(request); final String body = response.getBody(); config.log("response status code: " + response.getCode()); config.log("response body: " + body); return api.getRequestTokenExtractor().extract(response); } public final Future<OAuth1RequestToken> getRequestTokenAsync() { return getRequestTokenAsync(null); } public final Future<OAuth1RequestToken> getRequestTokenAsync( OAuthAsyncRequestCallback<OAuth1RequestToken> callback) { final OAuthConfig config = getConfig(); config.log("async obtaining request token from " + api.getRequestTokenEndpoint()); final OAuthRequest request = prepareRequestTokenRequest(); return execute(request, callback, new OAuthRequest.ResponseConverter<OAuth1RequestToken>() { @Override public OAuth1RequestToken convert(Response response) throws IOException { return getApi().getRequestTokenExtractor().extract(response); } }); } protected OAuthRequest prepareRequestTokenRequest() { final OAuthRequest request = new OAuthRequest(api.getRequestTokenVerb(), api.getRequestTokenEndpoint()); final OAuthConfig config = getConfig(); config.log("setting oauth_callback to " + config.getCallback()); request.addOAuthParameter(OAuthConstants.CALLBACK, config.getCallback()); addOAuthParams(request, ""); appendSignature(request); return request; } protected void addOAuthParams(OAuthRequest request, String tokenSecret) { final OAuthConfig config = getConfig(); request.addOAuthParameter(OAuthConstants.TIMESTAMP, api.getTimestampService().getTimestampInSeconds()); request.addOAuthParameter(OAuthConstants.NONCE, api.getTimestampService().getNonce()); request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, config.getApiKey()); request.addOAuthParameter(OAuthConstants.SIGN_METHOD, api.getSignatureService().getSignatureMethod()); request.addOAuthParameter(OAuthConstants.VERSION, getVersion()); final String scope = config.getScope(); if (scope != null) { request.addOAuthParameter(OAuthConstants.SCOPE, scope); } request.addOAuthParameter(OAuthConstants.SIGNATURE, getSignature(request, tokenSecret)); config.log("appended additional OAuth parameters: " + MapUtils.toString(request.getOauthParameters())); } public final OAuth1AccessToken getAccessToken(OAuth1RequestToken requestToken, String oauthVerifier) throws IOException, InterruptedException, ExecutionException { getConfig().log("obtaining access token from " + api.getAccessTokenEndpoint()); final OAuthRequest request = prepareAccessTokenRequest(requestToken, oauthVerifier); final Response response = execute(request); return api.getAccessTokenExtractor().extract(response); } public final Future<OAuth1AccessToken> getAccessTokenAsync(OAuth1RequestToken requestToken, String oauthVerifier) { return getAccessTokenAsync(requestToken, oauthVerifier, null); } /** * Start the request to retrieve the access token. The optionally provided * callback will be called with the Token when it is available. * * @param requestToken request token (obtained previously or null) * @param oauthVerifier oauth_verifier * @param callback optional callback * @return Future */ public final Future<OAuth1AccessToken> getAccessTokenAsync(OAuth1RequestToken requestToken, String oauthVerifier, OAuthAsyncRequestCallback<OAuth1AccessToken> callback) { final OAuthConfig config = getConfig(); config.log("async obtaining access token from " + api.getAccessTokenEndpoint()); final OAuthRequest request = prepareAccessTokenRequest(requestToken, oauthVerifier); return execute(request, callback, new OAuthRequest.ResponseConverter<OAuth1AccessToken>() { @Override public OAuth1AccessToken convert(Response response) throws IOException { return getApi().getAccessTokenExtractor().extract(response); } }); } protected OAuthRequest prepareAccessTokenRequest(OAuth1RequestToken requestToken, String oauthVerifier) { final OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint()); final OAuthConfig config = getConfig(); request.addOAuthParameter(OAuthConstants.TOKEN, requestToken.getToken()); request.addOAuthParameter(OAuthConstants.VERIFIER, oauthVerifier); config.log("setting token to: " + requestToken + " and verifier to: " + oauthVerifier); addOAuthParams(request, requestToken.getTokenSecret()); appendSignature(request); return request; } @Override public void signRequest(OAuth1AccessToken token, OAuthRequest request) { final OAuthConfig config = getConfig(); config.log("signing request: " + request.getCompleteUrl()); if (!token.isEmpty() || api.isEmptyOAuthTokenParamIsRequired()) { request.addOAuthParameter(OAuthConstants.TOKEN, token.getToken()); } config.log("setting token to: " + token); addOAuthParams(request, token.getTokenSecret()); appendSignature(request); } @Override public String getVersion() { return VERSION; } /** * Returns the URL where you should redirect your users to authenticate your * application. * * @param requestToken the request token you need to authorize * @return the URL where you should redirect your users */ public String getAuthorizationUrl(OAuth1RequestToken requestToken) { return api.getAuthorizationUrl(requestToken); } private String getSignature(OAuthRequest request, String tokenSecret) { final OAuthConfig config = getConfig(); config.log("generating signature..."); config.log("using base64 encoder: " + Base64Encoder.type()); final String baseString = api.getBaseStringExtractor().extract(request); final String signature = api.getSignatureService().getSignature(baseString, config.getApiSecret(), tokenSecret); config.log("base string is: " + baseString); config.log("signature is: " + signature); return signature; } protected void appendSignature(OAuthRequest request) { final OAuthConfig config = getConfig(); final OAuth1SignatureType signatureType = api.getSignatureType(); switch (signatureType) { case Header: config.log("using Http Header signature"); final String oauthHeader = api.getHeaderExtractor().extract(request); request.addHeader(OAuthConstants.HEADER, oauthHeader); break; case QueryString: config.log("using Querystring signature"); for (Map.Entry<String, String> entry : request.getOauthParameters().entrySet()) { request.addQuerystringParameter(entry.getKey(), entry.getValue()); } break; default: throw new IllegalStateException("Unknown new Signature Type '" + signatureType + "'."); } } public DefaultApi10a getApi() { return api; } }