Java tutorial
/** * OAUTHnesia for Java Android Class * * @package OAUTHnesia * @subpackage Java Android * @category OAUTH Client * @author Batista R. Harahap <tista@urbanesia.com> * @link http://www.bango29.com * @license MIT License - http://www.opensource.org/licenses/mit-license.php * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; 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.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.json.JSONException; import org.json.JSONObject; import android.util.Base64; import com.bango.jajan.Logger; import com.bango.jajan.Utils; public class OAUTHnesia { protected static final String BASE_URL = "http://api1.urbanesia.com/"; protected static final String CONSUMER_KEY = "", CONSUMER_SECRET = ""; private String API_URI = "", USER_KEY = "", USER_SECRET = ""; public String call(String uri, Map<String, String> post, Map<String, String> get) throws OAUTHnesiaException, InvalidKeyException, NoSuchAlgorithmException, ClientProtocolException, IOException { // API URI init API_URI = uri; // Merge default posts with post Map<String, String> defaultPosts = getDefaultPosts(); if (post.isEmpty()) { post.putAll(defaultPosts); } else { for (Entry<String, String> incomingItem : defaultPosts.entrySet()) { String incomingKey = incomingItem.getKey(); String incomingValue = incomingItem.getValue(); String postValue = post.get(incomingKey); if (postValue != null && !postValue.equals("")) { post.remove(incomingKey); post.put(incomingKey, incomingValue); } else { post.put(incomingKey, incomingValue); } } } // Merge posts + gets and sort using TreeMap Map<String, String> postget = new TreeMap<String, String>(); if (get.isEmpty()) { postget.putAll(post); } else { // Start from post first postget.putAll(post); // Continue with get for (Entry<String, String> incomingItem : get.entrySet()) { String incomingKey = incomingItem.getKey(); String incomingValue = incomingItem.getValue(); postget.put(incomingKey, incomingValue); } } // Encode postget values Map<String, String> sanitizedPostget = new TreeMap<String, String>(); for (Entry<String, String> item : postget.entrySet()) { String key = URLEncoder.encode(item.getKey(), "UTF-8"); String value = URLEncoder.encode(Utils.spaceToPercentEncoding(item.getValue()), "UTF-8"); sanitizedPostget.put(key, value); } // Replace postget with sanitized version postget = sanitizedPostget; sanitizedPostget = null; // Generate Base Signature String base_sig = generateBaseSignature(postget); Logger.v("Base Signature: " + base_sig); // Sign the request String signature = sha1(base_sig, CONSUMER_SECRET + "&").replace("\n", ""); Logger.v("Signature: " + signature); // Build URL String oauth_sig = String.format("?oauth_signature=%s", URLEncoder.encode(signature)); String url = String.format("%s%s%s&%s", BASE_URL, API_URI, oauth_sig, OAUTHnesia.mapToStringClean(get)); Logger.v("URL: " + url); return OAUTHnesia.sendRequest(url, OAUTHnesia.mapToString(post)); } public JSONObject callJson(String uri, Map<String, String> post, Map<String, String> get) throws JSONException, OAUTHnesiaException, InvalidKeyException, NoSuchAlgorithmException, ClientProtocolException, IOException { String result = this.call(uri, post, get); return result != null && !result.equals("") ? new JSONObject(result) : null; } public String callWithUserTokens(String uri, Map<String, String> post, Map<String, String> get, String user_key, String user_secret) throws InvalidKeyException, NoSuchAlgorithmException, ClientProtocolException, IOException, OAUTHnesiaException { // Check user Tokens if (!(user_key != null && !user_key.equals("") && user_secret != null && !user_secret.equals(""))) { throw new OAUTHnesiaException(); } else { USER_KEY = user_key; USER_SECRET = user_secret; } // API URI init API_URI = uri; // Merge default posts with post Map<String, String> defaultPosts = getDefaultPosts(); if (post.isEmpty()) { post.putAll(defaultPosts); } else { for (Entry<String, String> incomingItem : defaultPosts.entrySet()) { String incomingKey = incomingItem.getKey(); String incomingValue = incomingItem.getValue(); String postValue = post.get(incomingKey); if (postValue != null && !postValue.equals("")) { post.remove(incomingKey); post.put(incomingKey, incomingValue); } else { post.put(incomingKey, incomingValue); } } // Add User Key post.put("oauth_token", USER_KEY); } // Merge posts + gets and sort using TreeMap Map<String, String> postget = new TreeMap<String, String>(); if (get.isEmpty()) { postget.putAll(post); } else { // Start from post first postget.putAll(post); // Continue with get for (Entry<String, String> incomingItem : get.entrySet()) { String incomingKey = incomingItem.getKey(); String incomingValue = incomingItem.getValue(); postget.put(incomingKey, incomingValue); } } // Encode postget values Map<String, String> sanitizedPostget = new TreeMap<String, String>(); for (Entry<String, String> item : postget.entrySet()) { String key = URLEncoder.encode(item.getKey(), "UTF-8"); String value = URLEncoder.encode(Utils.spaceToPercentEncoding(item.getValue()), "UTF-8"); sanitizedPostget.put(key, value); } // Replace postget with sanitized version postget = sanitizedPostget; sanitizedPostget = null; // Generate Base Signature String base_sig = generateBaseSignature(postget); Logger.v("Base Signature: " + base_sig); // Sign the request String signature = sha1(base_sig, String.format("%s&%s", CONSUMER_SECRET, USER_SECRET)).replace("\n", ""); Logger.v("Signature: " + signature); // Build URL String oauth_sig = String.format("?oauth_signature=%s", URLEncoder.encode(signature)); String url = String.format("%s%s%s&%s", BASE_URL, API_URI, oauth_sig, OAUTHnesia.mapToString(get)); Logger.v("URL: " + url); return OAUTHnesia.sendRequest(url, OAUTHnesia.mapToString(post)); } public JSONObject callWithUserTokensJson(String uri, Map<String, String> post, Map<String, String> get, String user_key, String user_secret) throws JSONException, InvalidKeyException, NoSuchAlgorithmException, ClientProtocolException, IOException, OAUTHnesiaException { String result = this.callWithUserTokens(uri, post, get, user_key, user_secret); return result != null && !result.equals("") ? new JSONObject(result) : null; } public Map<String, String> xauth(String username, String password) throws ClientProtocolException, IOException, InvalidKeyException, NoSuchAlgorithmException, JSONException { // API URI init API_URI = "oauth/access_token"; // Get Default posts and add xAuth attributes Map<String, String> post = getDefaultPosts(); post.put("x_auth_username", username); post.put("x_auth_password", password); post.put("x_auth_mode", "client_auth"); // Merge posts + gets and sort using TreeMap Map<String, String> postget = new TreeMap<String, String>(); postget.putAll(post); // Encode postget values Map<String, String> sanitizedPostget = new TreeMap<String, String>(); for (Entry<String, String> item : postget.entrySet()) { String key = URLEncoder.encode(item.getKey(), "UTF-8"); String value = URLEncoder.encode(Utils.spaceToPercentEncoding(item.getValue()), "UTF-8"); sanitizedPostget.put(key, value); } // Replace postget with sanitized version postget = sanitizedPostget; sanitizedPostget = null; // Generate Base Signature String base_sig = generateBaseSignature(postget); Logger.v("Base Signature: " + base_sig); // Sign the request String signature = sha1(base_sig, CONSUMER_SECRET + "&").replace("\n", ""); Logger.v("Signature: " + signature); // Build URL String oauth_sig = String.format("?oauth_signature=%s", URLEncoder.encode(signature)); String url = String.format("%s%s%s", BASE_URL, API_URI, oauth_sig); Logger.v("URL: " + url); Map<String, String> ret = new HashMap<String, String>(); JSONObject json = new JSONObject(OAUTHnesia.sendRequest(url, OAUTHnesia.mapToString(post))) .getJSONObject("result"); ret.put("user_key", json.getString("oauth_token_key")); ret.put("user_secret", json.getString("oauth_token_secret")); ret.put("first_name", json.getString("first_name")); ret.put("last_name", json.getString("last_name")); ret.put("account_id", json.getString("account_id")); return ret; } private Map<String, String> getDefaultPosts() { Map<String, String> defaultPosts = new HashMap<String, String>(); defaultPosts.put("oauth_consumer_key", OAUTHnesia.CONSUMER_KEY); defaultPosts.put("oauth_nonce", OAUTHnesia.getNonce()); defaultPosts.put("oauth_signature_method", "HMAC-SHA1"); defaultPosts.put("oauth_timestamp", OAUTHnesia.getTime()); defaultPosts.put("oauth_version", "1.0"); defaultPosts.put("safe_encode", "1"); return defaultPosts; } private String generateBaseSignature(Map<String, String> postget) { return String.format("POST&%s&%s", URLEncoder.encode(BASE_URL + API_URI), URLEncoder.encode(OAUTHnesia.mapToString(postget))); } private static String mapToString(Map<String, String> map) { String s = ""; boolean first = true; for (Entry<String, String> item : map.entrySet()) { s = first ? String.format("%s=%s", item.getKey(), item.getValue()) : String.format("%s&%s=%s", s, item.getKey(), item.getValue()); first = false; } return s; } private static String mapToStringClean(Map<String, String> map) { String s = ""; boolean first = true; for (Entry<String, String> item : map.entrySet()) { s = first ? String.format("%s=%s", item.getKey(), URLEncoder.encode(item.getValue())) : String.format("%s&%s=%s", s, item.getKey(), URLEncoder.encode(item.getValue())); first = false; } return s; } private static String getNonce() { return md5(Long.toString(System.currentTimeMillis())); } private static String getTime() { return Long.toString(System.currentTimeMillis() / 1000); } private static String sha1(String s, String keyString) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException { SecretKeySpec key = new SecretKeySpec((keyString).getBytes("UTF-8"), "HmacSHA1"); Mac mac = Mac.getInstance("HmacSHA1"); mac.init(key); byte[] bytes = mac.doFinal(s.getBytes("UTF-8")); return new String(Base64.encode(bytes, Base64.DEFAULT)); } private static String md5(String s) { try { // Create MD5 Hash MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); digest.update(s.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuffer hexString = new StringBuffer(); for (int i = 0; i < messageDigest.length; i++) hexString.append(Integer.toHexString(0xFF & messageDigest[i])); return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } private static String sendRequest(String url, String postString) throws ClientProtocolException, IOException { HttpClient client = new DefaultHttpClient(); if (postString.compareTo("") != 0) { // GET & POST Request HttpPost post = new HttpPost(url); // Create POST List List<NameValuePair> pairs = new ArrayList<NameValuePair>(); String[] exp = postString.split("&"); int max = exp.length; for (int i = 0; i < max; i++) { String[] kv = exp[i].split("="); pairs.add(new BasicNameValuePair(kv[0], kv[1])); } post.setEntity(new UrlEncodedFormEntity(pairs)); // Get HTTP Response & Parse it HttpResponse response = client.execute(post); HttpEntity entity = response.getEntity(); if (entity != null) { InputStream instream = entity.getContent(); String result = convertStreamToString(instream); instream.close(); return result; } } else { // GET Request HttpGet get = new HttpGet(url); HttpResponse response = client.execute(get); HttpEntity entity = response.getEntity(); if (entity != null) { InputStream instream = entity.getContent(); String result = convertStreamToString(instream); instream.close(); return result; } } return ""; } private static String convertStreamToString(InputStream is) { BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder sb = new StringBuilder(); String line = null; try { while ((line = reader.readLine()) != null) { sb.append(line); } } catch (IOException e) { e.printStackTrace(); } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } return sb.toString(); } public class OAUTHnesiaException extends Exception { /** * */ private static final long serialVersionUID = -5159892704662170668L; } }