package external.services;
import play.libs.F.Function;
import play.libs.F.Promise;
import play.libs.F.Tuple;
import play.libs.OAuth;
import play.libs.OAuth.ConsumerKey;
import play.libs.OAuth.OAuthCalculator;
import play.libs.OAuth.RequestToken;
import play.libs.OAuth.ServiceInfo;
import play.libs.WS;
import play.libs.WS.Response;
import play.libs.WS.WSRequestHolder;
import com.fasterxml.jackson.databind.JsonNode;
import com.ning.http.util.Base64;
import common.Functions;
public class TwitterOAuthService implements OAuthService {
private final String consumerKey;
private final String consumerSecret;
private final ConsumerKey key;
private final OAuth oauthHelper;
public TwitterOAuthService(String consumerKey, String consumerSecret) {
this.consumerKey = consumerKey;
this.consumerSecret = consumerSecret;
this.key = new ConsumerKey(consumerKey, consumerSecret);
this.oauthHelper = new OAuth(new ServiceInfo(
"https://api.twitter.com/oauth/request_token",
"https://api.twitter.com/oauth/access_token",
"https://api.twitter.com/oauth/authorize",
this.key
));
}
@Override
public Tuple<String, RequestToken> retrieveRequestToken(String callbackUrl) {
RequestToken rt = oauthHelper.retrieveRequestToken(callbackUrl);
return new Tuple<String, RequestToken>(oauthHelper.redirectUrl(rt.token), rt);
}
@Override
public Promise<JsonNode> registeredUserProfile(RequestToken token,
String authVerifier) {
RequestToken accessToken = oauthHelper.retrieveAccessToken(token, authVerifier);
WSRequestHolder request = WS.url("https://api.twitter.com/1.1/account/settings.json");
Promise<Response> result = request.sign(new OAuthCalculator(key, accessToken)).get();
Promise<JsonNode> promiseOfJson = result.map(Functions.responseToJson);
Promise<String> screenName = promiseOfJson.map(Functions.findTextElement("screen_name"));
return screenName.flatMap(userProfile);
}
public Function<String, Promise<JsonNode>> userProfile = new Function<String, Promise<JsonNode>>() {
public Promise<JsonNode> apply(final String screenName) {
Promise<String> response = authenticateApplication().map(
Functions.responseToJson).map(Functions.findTextElement("access_token"));
return response.flatMap(fetchProfile(screenName)).recover(Functions.fetchUserError);
}
};
private static Function<String, Promise<JsonNode>> fetchProfile(
final String screenName) {
return new Function<String, Promise<JsonNode>>() {
public Promise<JsonNode> apply(String accessToken) {
WSRequestHolder req = WS
.url("https://api.twitter.com/1.1/users/show.json")
.setQueryParameter("screen_name", screenName)
.setHeader("Authorization", "Bearer " + accessToken);
Promise<Response> promise = req.get();
return promise.map(Functions.responseToJson);
}
};
}
private Promise<Response> authenticateApplication() {
WSRequestHolder req = WS
.url("https://api.twitter.com/oauth2/token")
.setHeader("Authorization", "Basic " + bearerToken())
.setContentType(
"application/x-www-form-urlencoded;charset=UTF-8");
return req.post("grant_type=client_credentials");
}
private String bearerToken() {
return Base64.encode((consumerKey + ":" + consumerSecret).getBytes());
}
}