package com.toopher; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.List; import oauth.signpost.OAuthConsumer; import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.HttpResponseException; import org.apache.http.client.ResponseHandler; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.HttpProtocolParams; import org.apache.http.util.EntityUtils; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.json.JSONTokener; /** * A Java binding for the Toopher API * */ public class ToopherAPI { /** * The ToopherJava binding library version */ public static final String VERSION = "1.0.0"; /** * Create an API object with the supplied credentials * * @param consumerKey * The consumer key for a requester (obtained from the developer portal) * @param consumerSecret * The consumer secret for a requester (obtained from the developer portal) */ public ToopherAPI(String consumerKey, String consumerSecret) { httpClient = new DefaultHttpClient(); HttpProtocolParams.setUserAgent(httpClient.getParams(), String.format("ToopherJava/%s", VERSION)); consumer = new CommonsHttpOAuthConsumer(consumerKey, consumerSecret); } /** * Create a pairing * * @param pairingPhrase * The pairing phrase supplied by the user * @param userName * A user-facing descriptive name for the user (displayed in requests) * @return A PairingStatus object * @throws RequestError * Thrown when an exceptional condition is encountered */ public PairingStatus pair(String pairingPhrase, String userName) throws RequestError { final String endpoint = "pairings/create"; List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("pairing_phrase", pairingPhrase)); params.add(new BasicNameValuePair("user_name", userName)); try { JSONObject json = post(endpoint, params); return PairingStatus.fromJSON(json); } catch (Exception e) { throw new RequestError(e); } } /** * Retrieve the current status of a pairing request * * @param pairingRequestId * The unique id for a pairing request * @return A PairingStatus object * @throws RequestError * Thrown when an exceptional condition is encountered */ public PairingStatus getPairingStatus(String pairingRequestId) throws RequestError { final String endpoint = String.format("pairings/%s", pairingRequestId); try { JSONObject json = get(endpoint); return PairingStatus.fromJSON(json); } catch (Exception e) { throw new RequestError(e); } } /** * Initiate a login authentication request * * @param pairingId * The pairing id indicating to whom the request should be sent * @param terminalName * The user-facing descriptive name for the terminal from which the request originates * @return An AuthenticationStatus object * @throws RequestError * Thrown when an exceptional condition is encountered */ public AuthenticationStatus authenticate(String pairingId, String terminalName) throws RequestError { return authenticate(pairingId, terminalName, null); } /** * Initiate an authentication request * * @param pairingId * The pairing id indicating to whom the request should be sent * @param terminalName * The user-facing descriptive name for the terminal from which the request originates * @param actionName * The user-facing descriptive name for the action which is being authenticated * @return An AuthenticationStatus object * @throws RequestError * Thrown when an exceptional condition is encountered */ public AuthenticationStatus authenticate(String pairingId, String terminalName, String actionName) throws RequestError { final String endpoint = "authentication_requests/initiate"; List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("pairing_id", pairingId)); params.add(new BasicNameValuePair("terminal_name", terminalName)); if (actionName != null && actionName.length() > 0) { params.add(new BasicNameValuePair("action_name", actionName)); } try { JSONObject json = post(endpoint, params); return AuthenticationStatus.fromJSON(json); } catch (Exception e) { throw new RequestError(e); } } /** * Retrieve status information for an authentication request * * @param authenticationRequestId * The authentication request ID * @return An AuthenticationStatus object * @throws RequestError * Thrown when an exceptional condition is encountered */ public AuthenticationStatus getAuthenticationStatus(String authenticationRequestId) throws RequestError { final String endpoint = String.format("authentication_requests/%s", authenticationRequestId); try { JSONObject json = get(endpoint); return AuthenticationStatus.fromJSON(json); } catch (Exception e) { throw new RequestError(e); } } private JSONObject get(String endpoint) throws Exception { URI uri = new URIBuilder().setScheme(URI_SCHEME).setHost(URI_HOST) .setPath(URI_BASE + endpoint).build(); HttpGet get = new HttpGet(uri); consumer.sign(get); return httpClient.execute(get, jsonHandler); } private JSONObject post(String endpoint, List<NameValuePair> params) throws Exception { URI uri = new URIBuilder().setScheme(URI_SCHEME).setHost(URI_HOST) .setPath(URI_BASE + endpoint).build(); HttpPost post = new HttpPost(uri); if (params != null && params.size() > 0) { post.setEntity(new UrlEncodedFormEntity(params)); } consumer.sign(post); return httpClient.execute(post, jsonHandler); } private static ResponseHandler<JSONObject> jsonHandler = new ResponseHandler<JSONObject>() { @Override public JSONObject handleResponse(HttpResponse response) throws ClientProtocolException, IOException { StatusLine statusLine = response.getStatusLine(); if (statusLine.getStatusCode() >= 300) { throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase()); } HttpEntity entity = response.getEntity(); // TODO: check entity == null String json = EntityUtils.toString(entity); try { return (JSONObject) new JSONTokener(json).nextValue(); } catch (JSONException e) { throw new ClientProtocolException("Could not interpret response as JSON", e); } } }; private static final String URI_SCHEME = "https"; private static final String URI_HOST = "api.toopher.com"; private static final String URI_BASE = "/v1/"; private final HttpClient httpClient; private final OAuthConsumer consumer; }