summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-04-24 18:36:35 +0200
committerPeter Wu <peter@lekensteyn.nl>2014-04-25 01:40:09 +0200
commit35026b912bec0a20cd421d0ffc1bfe93ffe8777f (patch)
tree80ec5d7a2d7198ea56a73a95057bf5f05d88acad
parent83d74919db151c972a8c195c3c56c391accccabf (diff)
downloadTwitterDataAnalytics-35026b912bec0a20cd421d0ffc1bfe93ffe8777f.tar.gz
Extend TwitterApi with a method for OAuth-signed requests
-rw-r--r--src/mining/OAuthRequester.java9
-rw-r--r--src/mining/TwitterApi.java64
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,