summaryrefslogtreecommitdiff
path: root/src/io/BearerRequester.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/BearerRequester.java
parent548fc2e77a3863b0563d7c6d80a7484815eeebad (diff)
downloadTwitterDataAnalytics-0c26271dcbbc8986526baeb2532bd5607635a4cc.tar.gz
Move classes not related to mining to io package
Diffstat (limited to 'src/io/BearerRequester.java')
-rw-r--r--src/io/BearerRequester.java92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/io/BearerRequester.java b/src/io/BearerRequester.java
new file mode 100644
index 0000000..4cb554b
--- /dev/null
+++ b/src/io/BearerRequester.java
@@ -0,0 +1,92 @@
+package io;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import org.apache.commons.io.Charsets;
+import org.json.JSONException;
+import org.json.JSONObject;
+import support.ConsumerKeySecret;
+
+/**
+ * An API requester used for application-only requests. Not all requests are
+ * allowed, see https://dev.twitter.com/docs/auth/application-only-auth for
+ * details.
+ *
+ * @author Peter Wu
+ */
+public class BearerRequester extends AbstractRequester {
+
+ /**
+ * A base64-encoded access token that authenticates requests.
+ */
+ private final String access_token;
+
+ /**
+ * Instantiates a requester with the given access token. The caller should
+ * test the token for validity.
+ *
+ * @param access_token The bearer token that authenticates a request.
+ */
+ public BearerRequester(String access_token) {
+ this.access_token = access_token;
+ }
+
+ /**
+ * Instantiates an instance, requesting an access token from the provided
+ * consumer key and secret.
+ *
+ * @param secrets The consumer secrets provided by Twitter.
+ * @throws IOException if a failure occurred while acquiring a token.
+ */
+ public BearerRequester(ConsumerKeySecret secrets)
+ throws IOException {
+ String postData = "grant_type=client_credentials";
+ URL url = buildUrl("oauth2/token");
+ HttpURLConnection conn = open(url);
+ conn.setRequestMethod("POST");
+ // set request headers
+ conn.addRequestProperty("Authorization", "Basic "
+ + secrets.getBearerTokenBase64());
+ conn.addRequestProperty("Content-Type",
+ "application/x-www-form-urlencoded; charset=UTF-8");
+ conn.setFixedLengthStreamingMode(postData.length());
+ // connect and send request
+ conn.setDoOutput(true);
+ conn.getOutputStream().write(postData.getBytes(Charsets.UTF_8));
+
+ try {
+ JSONObject resp = getResponseAsJson(conn);
+ // TODO: parse resp.errors
+ if (!resp.getString("token_type").equals("bearer")) {
+ throw new IOException("Expected bearer token type");
+ }
+ access_token = resp.getString("access_token");
+ } catch (JSONException ex) {
+ // treat JSON errors as if an I/O error occurred
+ throw new IOException(ex);
+ }
+ }
+
+ @Override
+ protected void preconnect(URLConnection conn) throws IOException {
+ // requests do not have to be signed, instead rely on the Bearer token
+ conn.addRequestProperty("Authorization", "Bearer " + access_token);
+ }
+
+ /**
+ * @return the access token that authenticates requests.
+ */
+ public String getAccessToken() {
+ return access_token;
+ }
+
+ @Override
+ public boolean isValid() throws IOException {
+ // NOTE: this actually contributes to the ratelimit (12/minute)
+ // TODO: find alternative that does not hit the ratelimit
+ JSONObject obj = getJSONRelax("application/rate_limit_status");
+ return !obj.has("errors");
+ }
+}