diff options
author | Peter Wu <peter@lekensteyn.nl> | 2014-04-30 10:08:29 +0200 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2014-04-30 10:08:29 +0200 |
commit | 0c26271dcbbc8986526baeb2532bd5607635a4cc (patch) | |
tree | b33417c0da1e0e5c9c68e1aa6413fe84ac217d3d /src/io/OAuthRequester.java | |
parent | 548fc2e77a3863b0563d7c6d80a7484815eeebad (diff) | |
download | TwitterDataAnalytics-0c26271dcbbc8986526baeb2532bd5607635a4cc.tar.gz |
Move classes not related to mining to io package
Diffstat (limited to 'src/io/OAuthRequester.java')
-rw-r--r-- | src/io/OAuthRequester.java | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/io/OAuthRequester.java b/src/io/OAuthRequester.java new file mode 100644 index 0000000..7646e3f --- /dev/null +++ b/src/io/OAuthRequester.java @@ -0,0 +1,123 @@ +package io; + +import java.io.IOException; +import java.net.URLConnection; +import oauth.signpost.OAuth; +import oauth.signpost.OAuthConsumer; +import oauth.signpost.basic.DefaultOAuthConsumer; +import oauth.signpost.basic.DefaultOAuthProvider; +import oauth.signpost.exception.OAuthException; +import org.json.JSONObject; +import support.ConsumerKeySecret; +import support.OAuthAccessTokenSecret; +import utils.Configuration; + +/** + * An API requester that uses OAuth to sign its requests. + * + * @author Peter Wu + */ +public class OAuthRequester extends AbstractRequester { + + /** + * Instance that signs signs HTTP requests with an OAuth token and secret. + */ + private final OAuthConsumer consumer; + + /** + * Instance that can retrieve an access token for the consumer. + */ + private final DefaultOAuthProvider provider; + + /** + * Instantiates a requester using OAuth. The caller must initialize the + * access token before requests can be sent. + * + * @param cks The consumer secrets provided by Twitter. + */ + public OAuthRequester(ConsumerKeySecret cks) { + // create a new application-specific OAuth consumer + consumer = new DefaultOAuthConsumer(cks.getKey(), cks.getSecret()); + // Note: Access tokens still require PIN + provider = new DefaultOAuthProvider(Configuration.REQUEST_TOKEN_URL, + Configuration.ACCESS_TOKEN_URL, Configuration.AUTHORIZE_URL); + } + + /** + * Set the access token to sign apps with. This access token can be + * retrieved from dev.twitter.com (see + * https://dev.twitter.com/docs/auth/tokens-devtwittercom) or via a PIN + * (https://dev.twitter.com/docs/auth/pin-based-authorization). + * + * @param secrets Access token and token secret. + */ + public void setAccessToken(OAuthAccessTokenSecret secrets) { + String token = secrets.getToken(); + String secret = secrets.getSecret(); + assert token != null; + assert secret != null; + consumer.setTokenWithSecret(token, secret); + } + + /** + * Retrieves an URL which allows an authenticated user to retrieve a PIN for + * this application. + * + * @return An URL. + * @throws IOException if an error occurred while retrieving the URL. + */ + public String getAuthURL() throws IOException { + String authUrl; + try { + authUrl = provider.retrieveRequestToken(consumer, OAuth.OUT_OF_BAND); + } catch (OAuthException ex) { + throw new IOException(ex); + } + return authUrl; + } + + /** + * Gets access tokens from a PIN (out-of-band method). The PIN can be + * retrieved by visiting the URL from {@code getAuthURL()}. See + * https://dev.twitter.com/docs/auth/pin-based-authorization + * + * @param pin The PIN as found on the page. + * @throws IOException if the PIN cannot be used to retrieve access tokens. + */ + public void supplyPINForTokens(String pin) throws IOException { + try { + provider.retrieveAccessToken(consumer, pin); + } catch (OAuthException ex) { + throw new IOException(ex); + } + } + + @Override + protected void preconnect(URLConnection conn) throws IOException { + try { + consumer.sign(conn); + } catch (OAuthException ex) { + throw new IOException(ex); + } + } + + public OAuthAccessTokenSecret getSecrets() { + String token = consumer.getToken(); + String secret = consumer.getTokenSecret(); + if (token == null || secret == null) { + return null; + } + return new OAuthAccessTokenSecret(token, secret); + } + + @Override + public boolean isValid() throws IOException { + if (consumer.getToken() == null) { + return false; + } + // NOTE: this actually contributes to the ratelimit (12/minute) + // TODO: find alternative that does not hit the ratelimit + JSONObject obj = getJSONRelax("1/application/rate_limit_status"); + return !obj.has("errors"); + } +} |