/****************************************************************************************
* Copyright 2012 IBM Corp. *
* *
* Licensed 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 com.ibm.sbt.security.authentication.oauth.consumer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.util.Date;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import com.ibm.commons.Platform;
import com.ibm.commons.runtime.Context;
import com.ibm.commons.util.StringUtil;
import com.ibm.commons.util.io.StreamUtil;
import com.ibm.commons.util.profiler.Profiler;
import com.ibm.commons.util.profiler.ProfilerAggregator;
import com.ibm.commons.util.profiler.ProfilerType;
import com.ibm.sbt.core.configuration.Configuration;
import com.ibm.sbt.plugin.SbtCoreLogger;
import com.ibm.sbt.security.authentication.oauth.OAuthException;
import com.ibm.sbt.security.credential.store.CredentialStore;
import com.ibm.sbt.security.credential.store.CredentialStoreException;
import com.ibm.sbt.security.credential.store.CredentialStoreFactory;
import com.ibm.sbt.services.util.AnonymousCredentialStore;
import com.ibm.sbt.services.util.SSLUtil;
/**
* @author Vimal Dhupar
* @author Manish Kataria
*/
public class OAuth1Handler extends OAuthHandler implements Serializable{
private static final long serialVersionUID = 1L;
private static final ProfilerType profilerLoadCredentialStore = new ProfilerType("OAuth: Load a token from the store"); //$NON-NLS-1$
private static final ProfilerType profilerAcquireToken = new ProfilerType("OAuth: Acquire a token from the service"); //$NON-NLS-1$
private static final ProfilerType profilerRenewToken = new ProfilerType("OAuth: Renew a token from the provider"); //$NON-NLS-1$
private static final ProfilerType profilerDeleteToken = new ProfilerType("OAuth: Delete a token from the store"); //$NON-NLS-1$
private static final ProfilerType profilerReadTempToken = new ProfilerType("OAuth: Acquire a temporary token from the provider"); //$NON-NLS-1$
private static final ProfilerType profilerReadToken = new ProfilerType("OAuth: Read a token with verifier from the provider"); //$NON-NLS-1$
private static final int BYTE_ARRAY_SIZE = ((23 * 5) / 8) + 1;
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
public static final int EXPIRE_THRESHOLD = 60; // 60sec = 1min
public static final String ACCESS_TOKEN_STORE_TYPE = "OAUTH1_ACCESS_TOKEN_STORE";
public static final String CONSUMER_TOKEN_STORE_TYPE = "OAUTH1_CONSUMER_TOKEN_STORE";
protected String OAuthCallbackConfirmed;
protected String requestToken;
private String requestTokenSecret;
protected String verifierCode;
private String accessTokenSecret;
private String accessToken;
private String expiresIn;
private String authorizationExpiresIn;
private String oauth_session_handle;
private int expireThreshold;
private String applicationPage;
private boolean storeRead;
protected String appId;
protected String serviceName;
protected String credentialStore;
protected String consumerKey;
protected String consumerSecret;
protected String requestTokenURL;
protected String authorizationURL;
protected String accessTokenURL;
protected String signatureMethod;
protected boolean forceTrustSSLCertificate;
protected AccessToken accessTokenObject;
public OAuth1Handler() {
this.expireThreshold = EXPIRE_THRESHOLD;
}
public String getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(String expiresIn) {
this.expiresIn = expiresIn;
}
public String getAuthorizationExpiresIn() {
return authorizationExpiresIn;
}
public void setAuthorizationExpiresIn(String authorizationExpiresIn) {
this.authorizationExpiresIn = authorizationExpiresIn;
}
/**
* Get a Request token from the resource server by sending a HTTP Post call
*
* Http call has the following data format:
* POST /manage/oauth/getRequestToken HTTP/1.1
* Host: lotuslive
* Authorization: OAuth
* oauth_consumer_key="<con key>",
* oauth_signature="<signature>"
* oauth_signature_method="PLAINTEXT",
* oauth_timestamp="<timestamp>",
* oauth_nonce="<nonce>",
* oauth_version="1.0",
* oauth_callback="<callback url>"
*
* @throws Exception
*/
public void getRequestTokenFromServer() throws Exception {
HttpGet method = null;
int responseCode = HttpStatus.SC_OK;
String responseBody = null;
InputStream content = null;
Context context = Context.get();
try {
HttpClient client = new DefaultHttpClient();
if (getForceTrustSSLCertificate()) {
client = SSLUtil.wrapHttpClient((DefaultHttpClient) client);
}
StringBuilder url = new StringBuilder();
url.append(getRequestTokenURL()).append("?");
url.append(Configuration.CONSUMER_KEY).append('=')
.append(URLEncoder.encode(getConsumerKey(), "UTF-8")).append('&');
url.append(Configuration.SIGNATURE).append('=')
.append(URLEncoder.encode(buildSignature(getConsumerSecret(), ""), "UTF-8"))
.append('&');
url.append(Configuration.SIGNATURE_METHOD).append('=')
.append(URLEncoder.encode(Configuration.PLAINTEXT_SIGNATURE, "UTF-8")).append('&');
url.append(Configuration.TIMESTAMP).append('=')
.append(URLEncoder.encode(getTimestamp(), "UTF-8")).append('&');
url.append(Configuration.NONCE).append('=').append(URLEncoder.encode(getNonce(), "UTF-8"))
.append('&');
url.append(Configuration.VERSION).append('=')
.append(URLEncoder.encode(Configuration.OAUTH_VERSION1, "UTF-8")).append('&');
url.append(Configuration.CALLBACK).append('=')
.append(URLEncoder.encode(getCallbackUrl(context), "UTF-8"));
method = new HttpGet(url.toString());
HttpResponse httpResponse = client.execute(method);
responseCode = httpResponse.getStatusLine().getStatusCode();
content = httpResponse.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
try {
responseBody = StreamUtil.readString(reader);
} finally {
StreamUtil.close(reader);
}
} catch (Exception e) {
throw new OAuthException(e, "Internal error - getRequestToken failed Exception: <br>");
} finally {
if(content!=null) {
content.close();
}
}
if (responseCode != HttpStatus.SC_OK) {
String exceptionDetail = buildErrorMessage(responseCode, responseBody);
if (exceptionDetail != null) {
throw new OAuthException(null,
"OAuth1Handler.java : getRequestToken failed. " + exceptionDetail);
}
} else {
setRequestToken(getTokenValue(responseBody, Configuration.OAUTH_TOKEN));
setRequestTokenSecret(getTokenValue(responseBody, Configuration.OAUTH_TOKEN_SECRET));
getTokenValue(responseBody, Configuration.OAUTH1_ISSUEDON);
setExpiresIn(getTokenValue(responseBody, Configuration.OAUTH1_EXPIRESIN));
}
}
/*
* (non-Javadoc)
* @see com.ibm.sbt.security.authentication.oauth.consumer.OAuthHandler#getAccessTokenFromServer()
*/
public void getAccessTokenFromServer() throws Exception {
HttpGet method = null;
int responseCode = HttpStatus.SC_OK;
String responseBody = null;
try {
HttpClient client = new DefaultHttpClient();
if (getForceTrustSSLCertificate()) {
client = SSLUtil.wrapHttpClient((DefaultHttpClient) client);
}
StringBuilder url = new StringBuilder();
url.append(getAccessTokenURL()).append("?");
url.append(Configuration.CONSUMER_KEY).append('=')
.append(URLEncoder.encode(getConsumerKey(), "UTF-8")).append('&');
url.append(Configuration.OAUTH_TOKEN).append('=')
.append(URLEncoder.encode(requestToken, "UTF-8")).append('&');
// services like dropbox do not use verifier code, adding a check
if(verifierCode!=null){
url.append(Configuration.OAUTH_VERIFIER).append('=')
.append(URLEncoder.encode(verifierCode, "UTF-8")).append('&');
}
url.append(Configuration.SIGNATURE)
.append('=')
.append(URLEncoder.encode(
buildSignature(getConsumerSecret(), requestTokenSecret), "UTF-8"))
.append('&');
url.append(Configuration.SIGNATURE_METHOD).append('=')
.append(URLEncoder.encode(Configuration.PLAINTEXT_SIGNATURE, "UTF-8")).append('&');
url.append(Configuration.TIMESTAMP).append('=')
.append(URLEncoder.encode(getTimestamp(), "UTF-8")).append('&');
url.append(Configuration.NONCE).append('=').append(URLEncoder.encode(getNonce(), "UTF-8"))
.append('&');
url.append(Configuration.VERSION).append('=')
.append(URLEncoder.encode(Configuration.OAUTH_VERSION1, "UTF-8"));
method = new HttpGet(url.toString());
HttpResponse httpResponse = client.execute(method);
responseCode = httpResponse.getStatusLine().getStatusCode();
InputStream content = httpResponse.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
try {
responseBody = StreamUtil.readString(reader);
} finally {
StreamUtil.close(reader);
}
} catch (Exception e) {
Platform.getInstance().log(e);
throw new OAuthException(e, "Internal error - getAccessToken failed Exception: <br>" + e);
}
if (responseCode != HttpStatus.SC_OK) {
String exceptionDetail = buildErrorMessage(responseCode, responseBody);
if (exceptionDetail != null) {
throw new OAuthException(null,
"OAuth1Handler.java : getAccessToken failed. " + exceptionDetail);
}
} else {
setAccessToken(getTokenValue(responseBody, Configuration.OAUTH_TOKEN));
setAccessTokenSecret(getTokenValue(responseBody, Configuration.OAUTH_TOKEN_SECRET));
getTokenValue(responseBody, Configuration.OAUTH1_ISSUEDON);
setExpiresIn(getTokenValue(responseBody, Configuration.OAUTH1_EXPIRESIN));
}
}
public String getAccessTokenURL() {
if (getServerUrl() != null) {
return getServerUrl() + accessTokenURL;
} else {
return accessTokenURL;
}
}
public String getRequestTokenURL() {
if (getServerUrl() != null) {
return getServerUrl() + requestTokenURL;
} else {
return requestTokenURL;
}
}
public String getNonce() {
byte[] genNonceBytes = new byte[BYTE_ARRAY_SIZE];
SECURE_RANDOM.nextBytes(genNonceBytes);
// use URL-friendly Base64 encoding
return (Base64Url.encode(genNonceBytes));
}
private String buildSignature(String consumerSecret, String tokenSecret) {
return consumerSecret + "&" + tokenSecret;
}
public String getTimestamp() {
long ts = System.currentTimeMillis() / 1000;
return (String.valueOf(ts));
}
/*
* (non-Javadoc)
* @see com.ibm.sbt.security.authentication.oauth.consumer.OAuthHandler#createAuthorizationHeader()
*/
@Override
public String createAuthorizationHeader() {
StringBuilder authHdr = new StringBuilder(1024);
authHdr.append("OAuth ");
authHdr.append(Configuration.CONSUMER_KEY).append("=\"").append(percentEncode(getConsumerKey())).append("\",");
authHdr.append(Configuration.OAUTH_TOKEN).append("=\"").append(percentEncode(accessToken)).append("\",");
authHdr.append(Configuration.SIGNATURE_METHOD).append("=\"").append(Configuration.PLAINTEXT_SIGNATURE).append("\",");
authHdr.append(Configuration.SIGNATURE).append("=\"").append(percentEncode(buildSignature(getConsumerSecret(), getAccessTokenSecret()))).append("\",");
authHdr.append(Configuration.TIMESTAMP).append("=\"").append(percentEncode(getTimestamp())).append("\",");
authHdr.append(Configuration.NONCE).append("=\"").append(percentEncode(getNonce())).append("\",");
authHdr.append(Configuration.VERSION).append("=\"").append(Configuration.OAUTH_VERSION1).append("\"");
return authHdr.toString();
}
public String getRequestTokenSecret() {
return requestTokenSecret;
}
public String getVerifierCode() {
return verifierCode;
}
public void setVerifierCode(String verifierCode) {
this.verifierCode = verifierCode;
}
public String getAccessTokenSecret() {
return accessTokenSecret;
}
public void setRequestToken(String requestToken) {
this.requestToken = requestToken;
}
public void setRequestTokenSecret(String requestTokenSecret) {
this.requestTokenSecret = requestTokenSecret;
}
public String getOAuthCallbackConfirmed() {
return OAuthCallbackConfirmed;
}
public void setOAuthCallbackConfirmed(String oAuthCallbackConfirmed) {
OAuthCallbackConfirmed = oAuthCallbackConfirmed;
}
public void setAccessTokenSecret(String accessTokenSecret) {
this.accessTokenSecret = accessTokenSecret;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getOauth_session_handle() {
return oauth_session_handle;
}
public void setOauth_session_handle(String oauth_session_handle) {
this.oauth_session_handle = oauth_session_handle;
}
@Override
public String getAccessToken() {
return accessToken;
}
public String getRequestToken() {
return requestToken;
}
public AccessToken getAccessTokenObject() {
return accessTokenObject;
}
public void setAccessTokenObject(AccessToken accessTokenObject) {
this.accessTokenObject = accessTokenObject;
}
/*
* (non-Javadoc)
* @see com.ibm.sbt.security.authentication.oauth.consumer.OAuthHandler#doPreAuthorizationFlow()
*/
@Override
public void doPreAuthorizationFlow() throws Exception {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
* @see com.ibm.sbt.security.authentication.oauth.consumer.OAuthHandler#doPostAuthorizationFlow()
*/
@Override
public void doPostAuthorizationFlow() throws Exception {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
* @see com.ibm.sbt.security.authentication.oauth.consumer.OAuthHandler#isInitialized()
*/
@Override
public boolean isInitialized() {
// TODO Auto-generated method stub
return false;
}
/*
* (non-Javadoc)
* @see com.ibm.sbt.security.authentication.oauth.consumer.OAuthHandler#getAuthType()
*/
@Override
public String getAuthType() {
return Configuration.AUTH_TYPE_OAUTH1;
}
public String getCredentialStore() {
return credentialStore;
}
public void setCredentialStore(String credentialStore) {
this.credentialStore = credentialStore;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public String getConsumerKey() {
return consumerKey;
}
public void setConsumerKey(String consumerKey) {
this.consumerKey = consumerKey;
}
public String getConsumerSecret() {
return consumerSecret;
}
public void setConsumerSecret(String consumerSecret) {
this.consumerSecret = consumerSecret;
}
public void setRequestTokenURL(String requestTokenURL) {
this.requestTokenURL = requestTokenURL;
}
@Override
public String getAuthorizationURL() {
return authorizationURL;
}
public void setAuthorizationURL(String authorizationURL) {
this.authorizationURL = authorizationURL;
}
public void setAccessTokenURL(String accessTokenURL) {
this.accessTokenURL = accessTokenURL;
}
public String getSignatureMethod() {
return signatureMethod;
}
public void setSignatureMethod(String signatureMethod) {
this.signatureMethod = signatureMethod;
}
public int getExpireThreshold() {
return expireThreshold;
}
public void setExpireThreshold(int expireThreshold) {
this.expireThreshold = expireThreshold;
}
public boolean getForceTrustSSLCertificate() {
return forceTrustSSLCertificate;
}
public void setForceTrustSSLCertificate(boolean forceTrustSSLCertificate) {
this.forceTrustSSLCertificate = forceTrustSSLCertificate;
}
private void readConsumerToken() throws OAuthException {
if (!storeRead) {
try {
CredentialStore factory = CredentialStoreFactory.getCredentialStore(getCredentialStore());
if (factory != null) {
ConsumerToken consumerToken = (ConsumerToken) factory.load(getServiceName(), CONSUMER_TOKEN_STORE_TYPE, null);
if (consumerToken != null) {
storeRead = true;
if (StringUtil.isNotEmpty(consumerToken.getConsumerKey())) {
setConsumerKey(consumerToken.getConsumerKey());
}
if (StringUtil.isNotEmpty(consumerToken.getConsumerSecret())) {
setConsumerSecret(consumerToken.getConsumerSecret());
}
if (StringUtil.isNotEmpty(consumerToken.getRequestTokenUri())) {
setRequestTokenURL(consumerToken.getRequestTokenUri());
}
if (StringUtil.isNotEmpty(consumerToken.getAuthorizationUri())) {
setAuthorizationURL(consumerToken.getAuthorizationUri());
}
if (StringUtil.isNotEmpty(consumerToken.getAccessTokenUri())) {
setAccessTokenURL(consumerToken.getAccessTokenUri());
}
if (StringUtil.isNotEmpty(consumerToken.getSignatureMethod())) {
setSignatureMethod(consumerToken.getSignatureMethod());
}
}
}
} catch (CredentialStoreException cse) {
throw new OAuthException(cse, cse.getMessage());
}
}
}
// ==========================================================
// Token management
// ==========================================================
public boolean isTokenExpired() throws OAuthException {
return isTokenExpired(null);
}
public boolean isTokenExpired(AccessToken token) throws OAuthException {
// We do not automatically renew/acquire it - we just get it from the
// store
if (token == null) {
token = _findTokenFromStore(Context.get(), null);
if (token == null) {
throw new OAuthException(null, "No user token is available");
}
}
return token.isExpired();
}
public boolean shouldRenewToken() throws OAuthException {
return shouldRenewToken(null);
}
public boolean shouldRenewToken(AccessToken token) throws OAuthException {
// We do not automatically renew/acquire it - we just get it from the
// store
if (token == null) {
token = _findTokenFromStore(Context.get(), null);
if (token == null) {
throw new OAuthException(null, "No user token is available");
}
}
return token.isExpired(getExpireThreshold());
}
public AccessToken acquireToken() throws OAuthException {
return acquireToken(false);
}
public AccessToken acquireToken(boolean login) throws OAuthException {
return acquireToken(login, false);
}
public AccessToken acquireToken(boolean login, boolean force) throws OAuthException {
if (Profiler.isEnabled()) {
ProfilerAggregator agg = Profiler.startProfileBlock(profilerAcquireToken, "");
long ts = Profiler.getCurrentTime();
try {
return _acquireToken(login, force);
} finally {
Profiler.endProfileBlock(agg, ts);
}
} else {
return _acquireToken(login, force);
}
}
public AccessToken _acquireToken(boolean login, boolean force) throws OAuthException {
Context context = Context.get();
AccessToken tk;
// If force is used, then login must be requested
if (force) {
login = true;
}
String userId = getUserId();
// Look for a token in the store
// If the user is anonymous, then the token might had been stored in the session
if (!force) {
if (getAccessTokenObject() != null) {
// if cred store is not defined in end point return from bean
tk = getAccessTokenObject();
}else{
tk = context.isCurrentUserAnonymous() ? (AccessToken) AnonymousCredentialStore
.loadCredentials(context, getAppId(), getServiceName()) : findTokenFromStore(context,
userId);
}
// check if token needs to be renewed
if (tk != null) {
setAccessToken(tk);
if (shouldRenewToken(tk)) {
return renewToken(tk);
}
return tk;
}
}
// Ok, we should then play the OAuth dance if requested
if (login) {
// Here if we are forced to start an OAuth dance, we clear the Store from any existing tokens for this application and fetch new tokens.
deleteToken();
setAccessTokenObject(null);
setApplicationPage(getApplicationPage(context));
try {
// This sends a signal
performOAuth1Dance();
} catch (Exception ex) {
throw new OAuthException(ex, "Error while acquiring OAuth token");
}
}
return null;
}
/**
* Request a temporary token for the application and redirect to a callback
* page.
*/
public synchronized void performOAuth1Dance() throws OAuthException {
if (Profiler.isEnabled()) {
ProfilerAggregator agg = Profiler.startProfileBlock(
profilerReadTempToken, "");
long ts = Profiler.getCurrentTime();
try {
_performOAuth1Dance();
} finally {
Profiler.endProfileBlock(agg, ts);
}
} else {
_performOAuth1Dance();
}
}
protected synchronized void _performOAuth1Dance() throws OAuthException {
try {
// Call the OAuth1Handler's method to get the Request token by
// making network call.
getRequestTokenFromServer();
String redirectUrl = getAuthorizationURL() + "?" + OAConstants.OAUTH_TOKEN + "=" + getRequestToken();
// tbd: is there a better way to handle this DropboxFiles specific parameter?
if (redirectUrl.contains("dropbox")) {
redirectUrl = redirectUrl + "&" + OAConstants.OAUTH_CALLBACK
+ "=" + getCallbackUrl(Context.get());
}
// Look if there are paththough parameters
String pass = (String) Context.get().getRequestParameterMap().get("oaredirect");
if (StringUtil.isNotEmpty(pass)) {
// Commenting this logic of modification of URL, as this creates
// a URL for OAuth1.0 which includes unsupported parameters, and
// error is thrown by Smartcloud.
// Testing this removal of code, to check if it breaks anything.
// Preliminary testing results in OK status(things work without
// this code).
// redirectUrl = redirectUrl + "&oaredirect=" +
// URLEncoder.encode(pass,"utf-8");
}
Context.get().getSessionMap().put(Configuration.OAUTH1_HANDLER, this);
// URL redirection
Context.get().sendRedirect(redirectUrl);
// throw new RedirectSignal();
// throw new RedirectSignal(redirectUrl);
} catch (IOException e) {
throwOAuthException(e, "_performOAuth1Dance", "Failed to get request token.");
} catch (OAuthException e) {
throwOAuthException(e, "_performOAuth1Dance", "Failed to get request token.");
} catch (URISyntaxException e) {
throwOAuthException(e, "_performOAuth1Dance", "Failed to get request token.");
} catch (Exception e) {
throwOAuthException(e, "_performOAuth1Dance", "Failed to get request token.");
}
}
private void throwOAuthException(Exception e, String method, String message) throws OAuthException {
String callback = null;
String secret = null;
String key = null;
String requestUrl = null;
String authorizeUrl = null;
String accessUrl = null;
boolean shortKey = false;
boolean shortSecret = false;
Context context = Context.get();
// if (oaProvider != null) {
callback = getCallbackUrl(context);
secret = getConsumerSecret();
if (StringUtil.isNotEmpty(secret)) {
int pre = 0;
if (secret.length() > 12) {
pre = 4;
} else if (secret.length() > 9) {
pre = 3;
} else {
shortSecret = true;
if (secret.length() > 6) {
pre = 2;
} else {
secret = StringUtil
.format("secret is too short to display, {0} characters long",
secret.length());
}
}
if (pre >= 2) {
String tmp = secret.substring(0, pre);
tmp = tmp + "....";
tmp = tmp + secret.substring(secret.length() - pre);
secret = tmp;
}
}
key = getConsumerKey();
if (StringUtil.isNotEmpty(key)) {
int pre = 0;
if (key.length() > 12) {
pre = 4;
} else if (key.length() > 9) {
pre = 3;
} else {
shortKey = true;
if (key.length() > 6) {
pre = 2;
} else {
key = StringUtil
.format("key is too short to display, {0} characters long",
key.length());
}
}
if (pre >= 2) {
String tmp = key.substring(0, pre);
tmp = tmp + "....";
tmp = tmp + key.substring(key.length() - pre);
key = tmp;
}
}
requestUrl = getRequestTokenURL();
authorizeUrl = getAuthorizationURL();
accessUrl = getAccessTokenURL();
// }
String formattedString = StringUtil
.format(" requestUrl:{0}, authorizeUrl: {1}, accessUrl: {2}, callback: {3}, truncated key:{4}, truncated secret:{5}.",
requestUrl, authorizeUrl, accessUrl, callback, key,
secret);
StringBuffer extraInfo = new StringBuffer(" ");
if (StringUtil.isEmpty(requestUrl)) {
extraInfo
.append("OAuth requestUrl is empty, please check your application definition in the the web security store is correct.\n");
}
if (StringUtil.isEmpty(authorizeUrl)) {
extraInfo
.append("OAuth authorizeUrl is empty, please check your application definition in the the web security store is correct.\n");
}
if (StringUtil.isEmpty(accessUrl)) {
extraInfo
.append("OAuth accessUrl is empty, please check your application definition in the the web security store is correct.\n");
}
if (StringUtil.isEmpty(callback)) {
extraInfo
.append("OAuth callback is empty, please check with your application vendor to ensure a callback is not required.\n");
}
if (shortKey) {
extraInfo
.append("The value supplied for the OAuth user key is short (less than 9 characters), please ensure it has been entered correctly.\n");
}
if (shortSecret) {
extraInfo
.append("The value supplied for the OAuth user secret is short (less than 9 characters) please ensure it has been entered correctly.\n");
}
if (SbtCoreLogger.SBT.isErrorEnabled()) {
SbtCoreLogger.SBT.errorp(this, method, e, message + formattedString
+ extraInfo.toString());
}
throw new OAuthException(e, message + formattedString
+ extraInfo.toString());
}
protected AccessToken findTokenFromStore(Context context, String userId) throws OAuthException {
if (Profiler.isEnabled()) {
ProfilerAggregator agg = Profiler.startProfileBlock(profilerLoadCredentialStore, "");
long ts = Profiler.getCurrentTime();
try {
return _findTokenFromStore(context, userId);
} finally {
Profiler.endProfileBlock(agg, ts);
}
} else {
return _findTokenFromStore(context, userId);
}
}
protected AccessToken _findTokenFromStore(Context context, String userId) throws OAuthException {
readConsumerToken();
if (StringUtil.isEmpty(userId)) {
userId = getUserId();
// Anonymous is not valid
if (StringUtil.isEmpty(userId)) {
return null;
}
}
try {
CredentialStore credStore = CredentialStoreFactory.getCredentialStore(getCredentialStore());
if (credStore != null) {
// Find the token for this user
AccessToken token = (AccessToken) credStore.load(getServiceName(), ACCESS_TOKEN_STORE_TYPE, userId);
if(token!=null) {
return token;
}
}
} catch (CredentialStoreException cse) {
throw new OAuthException(cse, "Error finding credentials from the store");
}
return null;
}
private void setAccessToken(AccessToken token) {
//Setting the access token and access token secret in Handler, when token is fetched from the store.
setAccessToken(token.getAccessToken());
setAccessTokenSecret(token.getTokenSecret());
}
public CredentialStore findCredentialStore() throws OAuthException {
CredentialStore credStore = null;
try {
credStore = CredentialStoreFactory.getCredentialStore(getCredentialStore());
} catch (CredentialStoreException cse) {
throw new OAuthException(cse, "Error finding credentials from the store");
}
return credStore;
}
// ==========================================================
// Renew the token
// ==========================================================
public AccessToken renewToken() throws OAuthException {
return renewToken(null);
}
public AccessToken renewToken(AccessToken token) throws OAuthException {
if (Profiler.isEnabled()) {
ProfilerAggregator agg = Profiler.startProfileBlock(profilerRenewToken, "");
long ts = Profiler.getCurrentTime();
try {
return _renewToken(token);
} finally {
Profiler.endProfileBlock(agg, ts);
}
} else {
return _renewToken(token);
}
}
protected AccessToken _renewToken(AccessToken token) throws OAuthException {
readConsumerToken();
if (token == null) {
token = acquireToken();
if (token == null) {
throw new OAuthException(null, "No user token is available");
}
}
Context context = Context.get();
try {
getAccessTokenFromServer();
token = createToken(getAppId(), getServiceName(), this, token.getUserId());
setAccessTokenObject(token);
if (!Context.get().isCurrentUserAnonymous()) {
CredentialStore credStore = findCredentialStore();
if (credStore != null) {
try {
// if the token is already present, and was expired due to which we have fetched a new
// token, then we remove the token from the store first and then add this new token.
deleteToken();
credStore.store(getServiceName(), ACCESS_TOKEN_STORE_TYPE, getUserId(), token);
} catch (CredentialStoreException cse) {
throw new OAuthException(cse);
}
}
} else {
AnonymousCredentialStore.storeCredentials(Context.get(), token, getAppId(), getServiceName());
}
//
} catch (IOException e) {
throw new OAuthException(e);
} catch (URISyntaxException e) {
throw new OAuthException(e);
} catch (OAuthException e) {
// We cannot renew the token, so we ask for a brand new one...
Platform.getInstance().log(e);
acquireToken(true, true);
return null;
} catch (CredentialStoreException cse) {
throw new OAuthException(cse, "Error trying to renew Token.");
} catch (Exception e) {
throw new OAuthException(e);
}
return token;
}
// ==========================================================
// Delete the token
// ==========================================================
public void deleteToken() throws OAuthException {
if (Profiler.isEnabled()) {
ProfilerAggregator agg = Profiler.startProfileBlock(profilerDeleteToken, "");
long ts = Profiler.getCurrentTime();
try {
_deleteToken(Context.get(), null);
} finally {
Profiler.endProfileBlock(agg, ts);
}
} else {
_deleteToken(Context.get(), null);
}
}
protected void _deleteToken(Context context, String userId) throws OAuthException {
readConsumerToken();
if (StringUtil.isEmpty(userId)) {
userId = getUserId();
// Anonymous is not valid
if (StringUtil.isEmpty(userId)) {
return;
}
}
if (StringUtil.equals(userId, "anonymous")) {
AnonymousCredentialStore.deleteCredentials(context, getAppId(), getServiceName());
} else {
try {
CredentialStore credStore = CredentialStoreFactory.getCredentialStore(getCredentialStore());
if (credStore != null) {
// Find the token for this user
credStore.remove(getServiceName(), ACCESS_TOKEN_STORE_TYPE, getUserId());
}
} catch (CredentialStoreException cse) {
throw new OAuthException(cse, "Error trying to delete Token.");
}
}
}
// ==========================================================
// Utilities
// ==========================================================
/**
* @param appId
* @param serviceName
* @param handler
* @param userId
* @return
* @throws OAuthException
*/
public AccessToken createToken(String appId, String serviceName, OAuth1Handler handler, String userId)
throws OAuthException {
long now = System.currentTimeMillis();
String expirationinterval = handler.getExpiresIn();
Date expiresIn = null;
if (StringUtil.isNotEmpty(expirationinterval)) {
expiresIn = new Date(now + Long.parseLong(expirationinterval) * 1000);
}
Date authorizationExpiresIn = null;
String oauth_authorization_expires_in = handler.getAuthorizationExpiresIn();
if (StringUtil.isNotEmpty(oauth_authorization_expires_in)) {
authorizationExpiresIn = new Date(now + Long.parseLong(oauth_authorization_expires_in) * 1000);
}
return new AccessToken(appId, serviceName, getConsumerKey(), handler.getAccessToken(),
handler.getAccessTokenSecret(), userId, expiresIn, authorizationExpiresIn,
handler.getOauth_session_handle()
);
}
/**
* Read the OAuth token from the verifier.
*/
public AccessToken readToken(String token, String verifier)
throws OAuthException {
if (Profiler.isEnabled()) {
ProfilerAggregator agg = Profiler.startProfileBlock(
profilerReadToken, "");
long ts = Profiler.getCurrentTime();
try {
return _readToken(token, verifier);
} finally {
Profiler.endProfileBlock(agg, ts);
}
} else {
return _readToken(token, verifier);
}
}
protected AccessToken _readToken(String token, String verifier) throws OAuthException {
// first we set the Verifier which will be used to get the Access Token
// setVerifierCode(verifier);
try {
getAccessTokenFromServer();
} catch (IOException e) {
throwOAuthException(e, "_readToken", "Failed to get access token.");
} catch (OAuthException e) {
throwOAuthException(e, "_readToken", "Failed to get access token.");
} catch (URISyntaxException e) {
throwOAuthException(e, "_readToken", "Failed to get access token.");
} catch (Exception e) {
throwOAuthException(e, "_readToken", "Failed to get access token.");
}
return createToken(getAppId(), getServiceName(), this, getUserId());
}
public String getApplicationPage() {
return applicationPage;
}
public void setApplicationPage(String applicationPage) {
this.applicationPage = applicationPage;
}
}