summaryrefslogtreecommitdiff
path: root/src/io/OAuthRequester.java
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-04-30 10:08:29 +0200
committerPeter Wu <peter@lekensteyn.nl>2014-04-30 10:08:29 +0200
commit0c26271dcbbc8986526baeb2532bd5607635a4cc (patch)
treeb33417c0da1e0e5c9c68e1aa6413fe84ac217d3d /src/io/OAuthRequester.java
parent548fc2e77a3863b0563d7c6d80a7484815eeebad (diff)
downloadTwitterDataAnalytics-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.java123
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");
+ }
+}