blob: 442f62a0bfd7198f91380eb58d312a696bc31fb5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
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);
try {
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);
}
} finally {
conn.disconnect();
}
}
@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");
}
}
|