diff --git a/src/main/java/com/metaweb/gridworks/oauth/FreebaseTimeCommonsHttpOAuthConsumer.java b/src/main/java/com/metaweb/gridworks/oauth/FreebaseTimeCommonsHttpOAuthConsumer.java new file mode 100644 index 000000000..c0d233a1c --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/oauth/FreebaseTimeCommonsHttpOAuthConsumer.java @@ -0,0 +1,69 @@ +package com.metaweb.gridworks.oauth; + +import java.io.IOException; + +import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FreebaseTimeCommonsHttpOAuthConsumer extends CommonsHttpOAuthConsumer { + + final static Logger logger = LoggerFactory.getLogger("oauth"); + + private static final long serialVersionUID = -4139931605235255279L; + + private static final int SOCKET_TIMEOUT = 3000; + private static final int CONNECTION_TIMEOUT = 3000; + + private static final String TIMER_URL = "http://gridworks-gadgets.freebaseapps.com/time"; + + public FreebaseTimeCommonsHttpOAuthConsumer(String consumerKey, String consumerSecret) { + super(consumerKey, consumerSecret); + } + + /** + * It might be that the user's computer's clock is not synchronized enough with the Freebase servers + * and this might result in Freebase thinking that it was under a replay attack. + * To avoid this problem we get the timestamp directly from acre that we know is synchronized. + * + * NOTE: this call is potentially vulnerable to a man-in-the-middle (MITM) attack, but the same + * could be said if we used an NTP client. + */ + protected String generateTimestamp() { + + long time = -1; + + try { + HttpParams httpParams = new BasicHttpParams(); + HttpConnectionParams.setSoTimeout(httpParams, SOCKET_TIMEOUT); + HttpConnectionParams.setConnectionTimeout(httpParams, CONNECTION_TIMEOUT); + HttpClient httpClient = new DefaultHttpClient(httpParams); + HttpGet httpget = new HttpGet(TIMER_URL); + HttpResponse response = httpClient.execute(httpget); + HttpEntity entity = response.getEntity(); + if (entity != null) { + time = Long.parseLong(EntityUtils.toString(entity),10); + logger.info("Got remote timestamp {}", time); + } + } catch (IOException e) { + logger.warn("Error obtaining the synchronized remote timestamp, defaulting to the local one",e); + } + + if (time == -1) { + time = System.currentTimeMillis(); + } + + return Long.toString(time / 1000L); + } + +} diff --git a/src/main/java/com/metaweb/gridworks/oauth/OAuthUtilities.java b/src/main/java/com/metaweb/gridworks/oauth/OAuthUtilities.java index 64cade03b..34c436ee2 100644 --- a/src/main/java/com/metaweb/gridworks/oauth/OAuthUtilities.java +++ b/src/main/java/com/metaweb/gridworks/oauth/OAuthUtilities.java @@ -7,7 +7,6 @@ import javax.servlet.http.HttpServletRequest; import oauth.signpost.OAuthConsumer; import oauth.signpost.OAuthProvider; -import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer; import oauth.signpost.commonshttp.CommonsHttpOAuthProvider; import oauth.signpost.http.HttpParameters; @@ -44,7 +43,7 @@ public class OAuthUtilities { if (provider == null) throw new RuntimeException("Provider can't be null"); String[] consumer_info = infos.get(provider.getHost()); if (consumer_info == null) throw new RuntimeException("Can't find secrets for provider '" + provider.getHost() + "'"); - OAuthConsumer oauthConsumer = new CommonsHttpOAuthConsumer(consumer_info[0],consumer_info[1]); + OAuthConsumer oauthConsumer = new FreebaseTimeCommonsHttpOAuthConsumer(consumer_info[0],consumer_info[1]); HttpParameters params = new HttpParameters(); params.put("realm", provider.getHost()); oauthConsumer.setAdditionalParameters(params);