/** * */ package com.insready.drupalcloud; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Random; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Hex; 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.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.json.JSONException; import org.json.JSONObject; import android.content.Context; import android.content.SharedPreferences; /** * Services Server output formats that are currently supported: * * @author Jingsheng Wang */ public class JSONServerClient implements Client { public HttpPost mSERVER; public static String mAPI_KEY; public static String mDOMAIN; public static String mALGORITHM; public static Long mSESSION_LIFETIME; private HttpClient mClient = new DefaultHttpClient(); private List<NameValuePair> mPairs = new ArrayList<NameValuePair>(15); private Context mCtx; private final String mPREFS_AUTH; /** * * @param _ctx * Context * @param _prefs_auth * Preference storage * @param _server * Server address * @param _api_key * API_Key * @param _domain * Domain name * @param _algorithm * Encrypition algorithm * @param _session_lifetime * Session lifetime */ public JSONServerClient(Context _ctx, String _prefs_auth, String _server, String _api_key, String _domain, String _algorithm, Long _session_lifetime) { mPREFS_AUTH = _prefs_auth; mSERVER = new HttpPost(_server); mSERVER.setHeader("User-Agent", "DrupalCloud-1.x"); mAPI_KEY = _api_key; mDOMAIN = _domain; mALGORITHM = _algorithm; mSESSION_LIFETIME = _session_lifetime; mCtx = _ctx; } private String getSessionID() throws ServiceNotAvailableException { SharedPreferences auth = mCtx.getSharedPreferences(mPREFS_AUTH, 0); Long timestamp = auth.getLong("sessionid_timestamp", 0); Long currenttime = new Date().getTime() / 100; String sessionid = auth.getString("sessionid", null); if (sessionid == null || (currenttime - timestamp) >= mSESSION_LIFETIME) { systemConnect(); return getSessionID(); } else return sessionid; } /** * Generic request * * @param method * Request name * @param parameters * Parameters * @return result string */ public String call(String method, BasicNameValuePair[] parameters) throws ServiceNotAvailableException { String sessid = this.getSessionID(); mPairs.clear(); String nonce = Integer.toString(new Random().nextInt()); Mac hmac; try { hmac = Mac.getInstance(JSONServerClient.mALGORITHM); final Long timestamp = new Date().getTime() / 100; final String time = timestamp.toString(); hmac.init(new SecretKeySpec(JSONServerClient.mAPI_KEY.getBytes(), JSONServerClient.mALGORITHM)); String message = time + ";" + JSONServerClient.mDOMAIN + ";" + nonce + ";" + method; hmac.update(message.getBytes()); String hmac_value = new String(Hex.encodeHex(hmac.doFinal())); mPairs.add(new BasicNameValuePair("hash", hmac_value)); mPairs.add(new BasicNameValuePair("domain_name", JSONServerClient.mDOMAIN)); mPairs.add(new BasicNameValuePair("domain_time_stamp", time)); mPairs.add(new BasicNameValuePair("nonce", nonce)); mPairs.add(new BasicNameValuePair("method", method)); mPairs.add(new BasicNameValuePair("api_key", JSONServerClient.mAPI_KEY)); mPairs.add(new BasicNameValuePair("sessid", sessid)); for (int i = 0; i < parameters.length; i++) { mPairs.add(parameters[i]); } mSERVER.setEntity(new UrlEncodedFormEntity(mPairs)); HttpResponse response = mClient.execute(mSERVER); InputStream is = response.getEntity().getContent(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String result = br.readLine(); JSONObject jso; jso = new JSONObject(result); boolean error = jso.getBoolean("#error"); if (error) { String errorMsg = jso.getString("#data"); throw new ServiceNotAvailableException(this, errorMsg); } return result; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); throw new ServiceNotAvailableException("Remote server is not available"); } return null; } /** * system.connect request for Key Auth */ private void systemConnect() throws ServiceNotAvailableException { // Cloud server hand shake mPairs.add(new BasicNameValuePair("method", "system.connect")); try { mSERVER.setEntity(new UrlEncodedFormEntity(mPairs)); HttpResponse response = mClient.execute(mSERVER); InputStream result = response.getEntity().getContent(); BufferedReader br = new BufferedReader( new InputStreamReader(result)); JSONObject jso = new JSONObject(br.readLine()); boolean error = jso.getBoolean("#error"); String data = jso.getString("#data"); if (error) { throw new ServiceNotAvailableException(this, data); } jso = new JSONObject(data); // Save the sessionid to storage SharedPreferences auth = mCtx.getSharedPreferences(mPREFS_AUTH, 0); SharedPreferences.Editor editor = auth.edit(); editor.putString("sessionid", jso.getString("sessid")); editor.putLong("sessionid_timestamp", new Date().getTime() / 100); editor.commit(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } } @Override public String userLogin(String username, String password) throws ServiceNotAvailableException { BasicNameValuePair[] parameters = new BasicNameValuePair[2]; parameters[0] = new BasicNameValuePair("username", username); parameters[1] = new BasicNameValuePair("password", password); return call("user.login", parameters); } @Override public String userLogout(String sessionID) throws ServiceNotAvailableException { BasicNameValuePair[] parameters = new BasicNameValuePair[1]; parameters[0] = new BasicNameValuePair("sessid", sessionID); return call("user.logout", parameters); } @Override public String nodeGet(int nid, String fields) throws ServiceNotAvailableException { BasicNameValuePair[] parameters = new BasicNameValuePair[2]; parameters[0] = new BasicNameValuePair("nid", String.valueOf(nid)); parameters[1] = new BasicNameValuePair("fields", fields); String result = call("node.get", parameters); /* * try { JSONObject jso = new JSONObject(temp); jso = new * JSONObject(jso.getString("#data")); JSONArray nameArray = * jso.names(); JSONArray valArray = jso.toJSONArray(nameArray); for * (int i=0;i<valArray.length();i++){ * Log.i("Testing","<jsonmae"+i+">\n"+ * nameArray.getString(i)+"\n</jsonname"+i+">\n" * +"<jsonvalue"+i+">\n"+valArray.getString(i)+"\n</jsonvalue"+i+">"); } * } catch (JSONException e) { e.printStackTrace(); } */ return result; } @Override public String viewsGet(String view_name, String display_id, String args, int offset, int limit) throws ServiceNotAvailableException { BasicNameValuePair[] parameters = new BasicNameValuePair[5]; parameters[0] = new BasicNameValuePair("view_name", view_name); parameters[1] = new BasicNameValuePair("args", args); parameters[2] = new BasicNameValuePair("display_id", display_id); parameters[3] = new BasicNameValuePair("offset", offset + ""); parameters[4] = new BasicNameValuePair("limit", limit + ""); return call("views.get", parameters); } @Override public int commentSave(String comment) throws ServiceNotAvailableException { BasicNameValuePair[] parameters = new BasicNameValuePair[1]; parameters[0] = new BasicNameValuePair("comment", comment); String result = call("comment.save", parameters); JSONObject jso; try { jso = new JSONObject(result); int cid = jso.getInt("#data"); return cid; } catch (JSONException e) { e.printStackTrace(); } return -1; } @Override public String commentLoadNodeComments(int nid, int count, int start) throws ServiceNotAvailableException { BasicNameValuePair[] parameters = new BasicNameValuePair[3]; parameters[0] = new BasicNameValuePair("nid", String.valueOf(nid)); parameters[1] = new BasicNameValuePair("count", String.valueOf(count)); parameters[2] = new BasicNameValuePair("start", String.valueOf(start)); String result = call("comment.loadNodeComments", parameters); // Convert other line breaks to Unix line breaks result = result.replaceAll("(\\\\r\\\\n|\\\\r)", "\\\\n"); return result; } @Override public String commentLoad(int cid) throws ServiceNotAvailableException { BasicNameValuePair[] parameters = new BasicNameValuePair[1]; parameters[0] = new BasicNameValuePair("cid", String.valueOf(cid)); String result = call("comment.load", parameters); return result; } @Override public boolean flagFlag(String flagName, int contentId, int uid, boolean action, boolean skipPermissionCheck) throws ServiceNotAvailableException { BasicNameValuePair[] parameters = new BasicNameValuePair[5]; parameters[0] = new BasicNameValuePair("flag_name", flagName); parameters[1] = new BasicNameValuePair("content_id", String .valueOf(contentId)); parameters[2] = new BasicNameValuePair("uid", String.valueOf(uid)); String actionName = (action) ? "flag" : "unflag"; parameters[3] = new BasicNameValuePair("action", actionName); String skipPermissionCheckName = (skipPermissionCheck) ? "TRUE" : "FALSE"; parameters[4] = new BasicNameValuePair("skip_permission_check", skipPermissionCheckName); String result = call("flag.flag", parameters); JSONObject jso; try { jso = new JSONObject(result); boolean flag = jso.getBoolean("#data"); return flag; } catch (JSONException e) { e.printStackTrace(); } return false; } @Override public boolean flagIsFlagged(String flagName, int contentId, int uid) throws ServiceNotAvailableException { BasicNameValuePair[] parameters = new BasicNameValuePair[3]; parameters[0] = new BasicNameValuePair("flag_name", flagName); parameters[1] = new BasicNameValuePair("content_id", String .valueOf(contentId)); parameters[2] = new BasicNameValuePair("uid", String.valueOf(uid)); String result = call("flag.is_flagged", parameters); JSONObject jso; try { jso = new JSONObject(result); boolean flag = jso.getBoolean("#data"); return flag; } catch (JSONException e) { e.printStackTrace(); } return false; } }