package br.com.livro.rest;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import org.glassfish.jersey.client.oauth1.AccessToken;
import org.glassfish.jersey.client.oauth1.ConsumerCredentials;
import org.glassfish.jersey.client.oauth1.OAuth1AuthorizationFlow;
import org.glassfish.jersey.client.oauth1.OAuth1Builder.FlowBuilder;
import org.glassfish.jersey.client.oauth1.OAuth1ClientSupport;
import twitter.TwitterStatus;
@Path("/twitter")
public class TwitterResource {
// Consumer Key e Consumer Secret criados no Provedor do OAuth (Twitter)
String CONSUMER_KEY = "yKffgFE3MjleOzXjTH7YA5ntW";
String CONSUMER_SECRET = "LrcTj8hPw1CBM9LxwIL4Bx831iVhzT69HUEqiAhXcpizY1JDTU";
// URL que vai receber o código verificador do OAuth
String CALLBACK_URI = "http://localhost:8080/HelloTwitter/rest/twitter/verify";
@Context
private HttpServletRequest request;
@GET
@Produces(MediaType.TEXT_PLAIN+";charset=utf-8")
public String get() {
return "Olá Twitter";
}
// Cria a classe por controlar o Fluxo de autorização
private OAuth1AuthorizationFlow getAuthorizationFlow(String callbackUri) {
// Tenta obter a classe da sessão do browser
OAuth1AuthorizationFlow authFlow = (OAuth1AuthorizationFlow) request.getSession().getAttribute("authFlow");
if (authFlow != null) {
// Já foi criada, apenas retorna
return authFlow;
}
// Cria as credenciais de acessso
ConsumerCredentials consumerCredentials = new ConsumerCredentials(
CONSUMER_KEY, CONSUMER_SECRET);
// Cria o OAuth1AuthorizationFlow
FlowBuilder builder = OAuth1ClientSupport.builder(consumerCredentials)
.authorizationFlow(
"https://api.twitter.com/oauth/request_token",
"https://api.twitter.com/oauth/access_token",
"https://api.twitter.com/oauth/authorize");
// Configura a URL de callback se necessário
if (callbackUri != null) {
builder.callbackUri(callbackUri);
}
authFlow = builder.build();
// Armazena este objeto na sessão do browser
request.getSession().setAttribute("authFlow", authFlow);
return authFlow;
}
@GET
@Path("/auth")
public String auth() throws IOException {
// limpa o flow
request.getSession().removeAttribute("authFlow");
// Cria o fluxo de autorização
OAuth1AuthorizationFlow authFlow = getAuthorizationFlow(null);
// O método start obtem o Token
String authorizationUri = authFlow.start();
// Retorna a URL do provedor do serviço (Twitter)
return authorizationUri;
}
@GET
@Path("/authRedirect")
public Response authRedirect() {
// limpa o flow
request.getSession().removeAttribute("authFlow");
OAuth1AuthorizationFlow authFlow = getAuthorizationFlow(CALLBACK_URI);
String authorizationUri = authFlow.start();
// Idem método auth() mas este redireciona automaticamente
Response redirect = Response.seeOther(
UriBuilder.fromUri(authorizationUri).build()).build();
return redirect;
}
@GET
@Path("/verify/{verifier}")
public String verify(@PathParam("verifier") String verifier) {
// Recupera da sessão o objeto que controla o fluxo de autorização
OAuth1AuthorizationFlow authFlow = getAuthorizationFlow(null);
// Recebe o código verificador e valida a requisição
AccessToken accessToken = authFlow.finish(verifier);
// Obtem o Token e Token Secret
String token = accessToken.getToken();
String tokenSecret = accessToken.getAccessTokenSecret();
// Remove o objeto que controla o fluxo de autenticação da sessão
request.getSession().removeAttribute("authFlow");
// Retorna o Token em formato de texto para ser lido por um programa
return String.format("token=%s&tokenSecret=%s", token, tokenSecret);
}
@GET
@Path("/verify")
public String verify(@QueryParam("oauth_token") String oauth_token,
@QueryParam("oauth_verifier") String oauth_verifier) {
// Verifica se o código verificador de retorno do provedor (Twitter)
// está correto
String s = verify(oauth_verifier);
// Retorna o Token.
return s;
}
@GET
@Path("/timeline")
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public String timeline(@QueryParam("token") String token,
@QueryParam("tokenSecret") String tokenSecret) {
// Demonstra como criar um Token informando os códigos manualmente.
AccessToken accessToken = new AccessToken(token, tokenSecret);
Client client = getClient(accessToken);
if (client == null) {
return "not authorized";
}
// Utiliza a API REST para ler a timeline do Twitter
Response response = client
.target("https://api.twitter.com/1.1/statuses/user_timeline.json")
.request().get();
// Lê uma lista de TwitterStatus em formato String
String json = response.readEntity(String.class);
// Retorna o json
return json;
}
@GET
@Path("/ultimoTweet")
@Produces(MediaType.TEXT_PLAIN + ";charset=utf-8")
public String ultimoTweet(@QueryParam("token") String token,
@QueryParam("tokenSecret") String tokenSecret) {
// Demonstra como criar um Token informando os códigos manualmente.
AccessToken accessToken = new AccessToken(token, tokenSecret);
Client client = getClient(accessToken);
if (client == null) {
return "not authorized";
}
// Utiliza a API REST para ler a timeline do Twitter
Response response = client
.target("https://api.twitter.com/1.1/statuses/user_timeline.json")
.request().get();
// Lê uma lista de TwitterStatus
final List<TwitterStatus> list = response
.readEntity(new GenericType<List<TwitterStatus>>() {
});
// Retorna o primeiro tweet da lista
TwitterStatus s = list.get(0);
return s.getUser().getName() + " >> " + s.getText();
}
// Cria o objeto Client da API REST do Jersey
private Client getClient(AccessToken accessToken) {
// Utiliza as credenciais de acesso OAuth do provedor (Twitter)
ConsumerCredentials credentials = new ConsumerCredentials(CONSUMER_KEY,
CONSUMER_SECRET);
Feature feature = OAuth1ClientSupport.builder(credentials).feature()
.accessToken(accessToken).build();
Client client = ClientBuilder.newClient();
client.register(feature);
// Habilita o Google-GSON
client.register(GsonMessageBodyHandler.class);
return client;
}
}