blob: 7646e3f0226869cb5ab99814e5dd3f25e674abe1 (
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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");
}
}
|