diff options
author | Peter Wu <peter@lekensteyn.nl> | 2014-04-24 18:36:35 +0200 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2014-04-25 01:40:09 +0200 |
commit | 35026b912bec0a20cd421d0ffc1bfe93ffe8777f (patch) | |
tree | 80ec5d7a2d7198ea56a73a95057bf5f05d88acad | |
parent | 83d74919db151c972a8c195c3c56c391accccabf (diff) | |
download | TwitterDataAnalytics-35026b912bec0a20cd421d0ffc1bfe93ffe8777f.tar.gz |
Extend TwitterApi with a method for OAuth-signed requests
-rw-r--r-- | src/mining/OAuthRequester.java | 9 | ||||
-rw-r--r-- | src/mining/TwitterApi.java | 64 |
2 files changed, 71 insertions, 2 deletions
diff --git a/src/mining/OAuthRequester.java b/src/mining/OAuthRequester.java index 76d21c4..f740916 100644 --- a/src/mining/OAuthRequester.java +++ b/src/mining/OAuthRequester.java @@ -99,6 +99,15 @@ public class OAuthRequester extends AbstractRequester { } } + 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) { diff --git a/src/mining/TwitterApi.java b/src/mining/TwitterApi.java index e45f7b7..7ea4e57 100644 --- a/src/mining/TwitterApi.java +++ b/src/mining/TwitterApi.java @@ -10,6 +10,7 @@ import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.message.BasicNameValuePair; import org.json.JSONObject; import support.ConsumerKeySecret; +import support.OAuthAccessTokenSecret; import utils.Configuration; /** @@ -18,6 +19,8 @@ import utils.Configuration; public class TwitterApi { private static final String CFG_BEARER_TOKEN = "bearer-token"; + private static final String CFG_OAUTH_TOKEN = "oauth-token"; + private static final String CFG_OAUTH_SECRET = "oauth-secret"; private final Requester requester; public TwitterApi(Requester requester) { @@ -25,8 +28,7 @@ public class TwitterApi { } /** - * Establishes an instance using application-only authentication using a - * file as cache. + * Establishes an instance using application-only authentication. * * @return An API context usable for requests using app-only auth. * @throws IOException @@ -53,6 +55,64 @@ public class TwitterApi { return new TwitterApi(breq); } + /** + * Establishes an instance using a user context (OAuth signing). + * + * @param ps A supplier of the PIN for a given URL. May be null if not + * supported. + * @return An API context usable for requests using OAuth. + * @throws IOException if no usable context can be instantiated. + */ + public static TwitterApi getOAuth(PinSupplier ps) throws IOException { + Configuration cfg = Configuration.getConfig(); + OAuthAccessTokenSecret secrets = null; + ConsumerKeySecret cks = getConsumerKeySecret(); + OAuthRequester oreq = new OAuthRequester(cks); + + /* check if the stored access tokens are still valid */ + { + String token, secret; + token = cfg.getProperty(CFG_OAUTH_TOKEN); + secret = cfg.getProperty(CFG_OAUTH_SECRET); + if (token != null && secret != null) { + secrets = new OAuthAccessTokenSecret(token, secret); + oreq.setAccessToken(secrets); + if (!oreq.isValid()) { + Logger.getLogger(TwitterApi.class.getName()) + .info("OAuth access tokens invalid"); + secrets = null; + } + } + } + /* if no valid secrets are available, request a new access token */ + if (secrets == null) { + if (ps == null) { + throw new IOException("Unable to retrieve an access token"); + } + String authUrl = oreq.getAuthURL(); + oreq.supplyPINForTokens(ps.requestPin(authUrl)); + secrets = oreq.getSecrets(); + assert secrets != null : "PIN accepted, but no access tokens?"; + cfg.setProperty(CFG_OAUTH_TOKEN, secrets.getToken()); + cfg.setProperty(CFG_OAUTH_SECRET, secrets.getSecret()); + cfg.save(); + } + return new TwitterApi(oreq); + } + + public interface PinSupplier { + + /** + * Given a URL, the pin supplier must synchronously request a PIN. + * + * @param url The URL to be presented to the user. + * @return A non-null string that can be exchanged for access tokens. + * @throws IOException if the PIN could not be retrieved. + */ + public String requestPin(String url) throws IOException; + + } + private static ConsumerKeySecret getConsumerKeySecret() { // static consumer keys retrieved from dev.twitter.com return new ConsumerKeySecret(Configuration.CONSUMER_KEY, |