Automatic Delete OXObjects Per User: Difference between revisions
From Open-Xchange
No edit summary |
(Move to https://documentation.open-xchange.com/) |
||
| Line 1: | Line 1: | ||
<div class="title">How to automatically delete all objects of one user</div> | <div class="title">How to automatically delete all objects of one user</div> | ||
I just wrote the following quick&dirty hack to delete all objects and folders created by an OXHE User. It can be useful to clean up a context or to just delete all data from one user. The following JAVA file contains the logic which is needed to login/search/delete via the Open-Xchange [ | I just wrote the following quick&dirty hack to delete all objects and folders created by an OXHE User. It can be useful to clean up a context or to just delete all data from one user. The following JAVA file contains the logic which is needed to login/search/delete via the Open-Xchange [https://documentation.open-xchange.com/ HTTP API]. | ||
<pre> | <pre> | ||
Latest revision as of 13:48, 29 June 2016
How to automatically delete all objects of one user
I just wrote the following quick&dirty hack to delete all objects and folders created by an OXHE User. It can be useful to clean up a context or to just delete all data from one user. The following JAVA file contains the logic which is needed to login/search/delete via the Open-Xchange HTTP API.
package com.openexchange.tools.cleaner;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
*
* @author cutmasta
*/
public class Start {
Log LOG = LogFactory.getLog(Start.class);
private SessionObject so = null;
private String username = null;
private String password = null;
private String host = "localhost";
private String protocol = "http";
private static String CONTENT_TYPE_JSCRIPT = "text/javascript";
private static String CHARSET_JSCRIPT = "UTF-8";
private String TASK_SEARCH = "tasks";
private String CONTACT_SEARCH = "contacts";
private String CALENDAR_SEARCH = "calendar";
private String INFOSTORE_SEARCH = "infostore";
public static void main(String[] args) {
new Start(args);
}
private Start(String[] args) {
if (args.length != 4) {
LOG.info("Arguments needed: <host> <protocol> <username> <password>");
LOG.info("Example: test.org https test@sp4.com test");
exitApp();
}
host = args[0].trim();
protocol = args[1].trim();
username = args[2].trim();
password = args[3].trim();
if (protocol.equals("https")) {
Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
Protocol.registerProtocol("https", easyhttps);
}
doLogin();
try {
// search all modules and fetch the id arrays
doSearch();
} catch (IOException ex) {
LOG.error(ex);
} catch (JSONException ex) {
LOG.error("Error in process", ex);
}
}
public String getSessionID() {
return getSessionObject().getSessionid();
}
public SessionObject getSessionObject() {
return so;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getHost() {
return host;
}
private void doDeleteCreatedFolders(JSONArray rootfolders, String timestamp) throws JSONException, IOException {
/*
* In this method here we delete all folders
*
*/
// loop through all root folders
for (int i = 0; i < rootfolders.length(); i++) {
// for each root/system folder , loop and delete its subfolders
JSONObject subfolders_of_rootfolder_response = doGetSubFolders(rootfolders.getJSONArray(i).getInt(0));
JSONArray subfolders_of_rootfolder = subfolders_of_rootfolder_response.getJSONArray("data");
for (int b = 0; b < subfolders_of_rootfolder.length(); b++) {
JSONArray tmp_folder = subfolders_of_rootfolder.getJSONArray(b);
if (!tmp_folder.getString(0).equalsIgnoreCase("default")) {
LOG.debug("Deleting recursive all private folders with array: " + tmp_folder);
deleteRecursiveFolder(tmp_folder);
}
}
}
}
/**
* This delete the subfolders of the given folder and the folder itself!
* @param my_private_folder_array
* @throws java.io.IOException
* @throws org.json.JSONException
*/
private void deleteRecursiveFolder(JSONArray my_private_folder_array) throws IOException, JSONException {
JSONObject my_private_subfolders_response = doGetSubFolders(my_private_folder_array.getInt(0));
// only delete if subfolders exists
//if (my_private_subfolders_response.length() > 0) {
if (my_private_subfolders_response.getJSONArray("data").length() > 0) {
LOG.debug(my_private_subfolders_response);
JSONArray my_private_subfolders = my_private_subfolders_response.getJSONArray("data");
String my_private_subfolders_timestamp = my_private_subfolders_response.getString("timestamp");
//LOG.info("Private folders list: " +my_private_subfolders);
for (int i = 0; i < my_private_subfolders.length(); i++) {
JSONArray folder_data = my_private_subfolders.getJSONArray(i);
LOG.debug("Deleting folder with ID " + folder_data.getInt(0) + " and parent ID " + folder_data.getInt(1) + " - Tstamp " + my_private_subfolders_timestamp);
doDeleteFolder(folder_data.getInt(0), folder_data.getInt(1), my_private_subfolders_timestamp);
}
}
/* Now delete the folder itself , which could contain the subfolders before!
* We must "get" the folder data because we need the correct timestamp for deleting!
*/
JSONObject top_level_folder_data = doGetSingleFolder(my_private_folder_array.getInt(0));
if(!my_private_folder_array.isNull(0) && !my_private_folder_array.isNull(1) && !top_level_folder_data.isNull("timestamp")){
// execute delete
doDeleteFolder(my_private_folder_array.getInt(0), my_private_folder_array.getInt(1), top_level_folder_data.getString("timestamp"));
}
}
private void doDeleteFolder(int folder_id, int parent_id, String tstamp) {
try {
PutMethod deleteMethod = new PutMethod(getProtocol() + "://" + getHost() + "/ajax/folders?action=delete×tamp=" + tstamp + "&session=" + getSessionObject().getSessionid());
RequestEntity data = new StringRequestEntity("[" + folder_id + "]", CONTENT_TYPE_JSCRIPT, CHARSET_JSCRIPT);
deleteMethod.setRequestEntity(data);
getSessionObject().getOxClient().executeMethod(deleteMethod);
JSONObject responseObject = ResponseTools.reponse2JsonObject(deleteMethod);
LOG.debug("Delete folder response is: " + responseObject);
} catch (Exception ex) {
LOG.error("Error deleting folder with ID " + folder_id + " and parent ID " + parent_id, ex);
}
}
private JSONObject doGetSubFolders(int parent_folder) throws IOException, JSONException {
// 1 = id
// 20 = Object ID of the parent folder.
// 300 = Name of this folder.
// 301 = Name of the module which implements this folder.
// 302 = type // 1 private
//2 public
//3 shared
// 5 system folder
// 304 = true if this folder has subfolders.
// 305 = own_rights
try {
GetMethod folder_search = new GetMethod(getProtocol() + "://" + getHost() + "/ajax/folders?action=list&columns=1,20,300,301,302,304,305&parent=" + parent_folder + "&session=" + getSessionObject().getSessionid());
getSessionObject().getOxClient().executeMethod(folder_search);
JSONObject responseObject = ResponseTools.reponse2JsonObject(folder_search);
return responseObject;
} catch (IOException ex) {
LOG.error("Generic IO error while searching folders", ex);
throw ex;
} catch (JSONException ex) {
LOG.error("JSON error while searching folders", ex);
throw ex;
}
}
private JSONObject doGetSingleFolder(int folder_id) throws IOException, JSONException {
// 1 = id
// 20 = Object ID of the parent folder.
// 300 = Name of this folder.
// 301 = Name of the module which implements this folder.
// 302 = type // 1 private
//2 public
//3 shared
// 5 system folder
// 304 = true if this folder has subfolders.
// 305 = own_rights
try {
GetMethod folder_search = new GetMethod(getProtocol() + "://" + getHost() + "/ajax/folders?action=get&id=" + folder_id + "&columns=1,20,300,301,302,304,305&session=" + getSessionObject().getSessionid());
getSessionObject().getOxClient().executeMethod(folder_search);
JSONObject responseObject = ResponseTools.reponse2JsonObject(folder_search);
return responseObject;
} catch (IOException ex) {
LOG.error("Generic IO error while searching folders", ex);
throw ex;
} catch (JSONException ex) {
LOG.error("JSON error while searching folders", ex);
throw ex;
}
}
private void doLogin() {
LOG.info("Using " + getProtocol() + "://" + getUsername() + "@" + getHost() + " for connections!");
HttpClient client = new HttpClient();
PostMethod login_post = new PostMethod(getProtocol() + "://" + getHost() + "/ajax/login?action=login");
login_post.addParameter("name", getUsername());
login_post.addParameter("password", getPassword());
try {
client.executeMethod(login_post);
JSONObject loginObject = ResponseTools.reponse2JsonObject(login_post);
if (loginObject.has("session")) {
so = new SessionObject();
getSessionObject().setCookies(client.getState().getCookies());
getSessionObject().setSessionid((String) loginObject.get("session"));
getSessionObject().setOxClient(client);
LOG.info("Login successfull!");
} else {
String errmsg = (String) loginObject.get("error");
LOG.info("Error login into system!\n" + errmsg);
exitApp();
}
} catch (Exception exp) {
LOG.error("LOGIN ERROR", exp);
} finally {
login_post.releaseConnection();
}
}
private void doSearch() throws JSONException, IOException {
LOG.info("Starting search for objects...");
JSONObject task_objects = doSearchInModule(TASK_SEARCH);
JSONObject contact_objects = doSearchInModule(CONTACT_SEARCH);
JSONObject calendar_objects = doSearchInModule(CALENDAR_SEARCH);
JSONObject store_objects = doSearchInModule(INFOSTORE_SEARCH);
LOG.info("Search done!");
//LOG.info("Found " + task_objects.getJSONArray("data").length() + " task items");
//LOG.info("Found " + contact_objects.getJSONArray("data").length() + " contact items");
//LOG.info("Found " + calendar_objects.getJSONArray("data").length() + " calendar items");
//LOG.info("Found " + store_objects.getJSONArray("data").length() + " infostore items");
LOG.info("Starting delete process...");
doDeleteMultiple(task_objects, contact_objects, calendar_objects, store_objects);
LOG.info("Deleting Objects done!");
LOG.info("Starting delete process for folders...");
// search all folders and delete them
JSONObject rootfolders_response = doGetRootFolders();
JSONArray rootfolders = rootfolders_response.getJSONArray("data");
doDeleteCreatedFolders(rootfolders, rootfolders_response.getString("timestamp"));
LOG.info("Deleting folders done!");
}
private JSONArray buildDeleteArray(JSONObject module_objects, String MODULE) throws JSONException {
JSONArray dat_array = new JSONArray();
LOG.debug("Building delete array from json object: " + module_objects);
if (module_objects.has("data") && module_objects.has("timestamp")) {
String tstamp = module_objects.getString("timestamp");
JSONArray srv_data_ids = module_objects.getJSONArray("data");
for (int i = 0; i < srv_data_ids.length(); i++) {
JSONArray ids = (JSONArray) srv_data_ids.get(i);
JSONObject js = new JSONObject();
js.put("module", MODULE);
js.put("timestamp", tstamp);
js.put("action", "delete");
JSONObject del_ids = new JSONObject();
del_ids.put("id", ids.getInt(0));
del_ids.put("folder", ids.getInt(1));
// workaround because infostore expects an array with a 1 json object which contains the ids
if (MODULE.equals(INFOSTORE_SEARCH)) {
// send array with object
JSONArray tmp = new JSONArray();
tmp.put(del_ids);
js.put("data", tmp);
} else {
// send normal id
js.put("data", del_ids);
}
dat_array.put(js);
}
}
return dat_array;
}
private void doDeleteMultiple(JSONObject task_objects, JSONObject contact_objects, JSONObject calendar_objects, JSONObject store_objects) throws JSONException {
LOG.info("Deleting tasks...");
fireDeleteMultiple(buildDeleteArray(task_objects, TASK_SEARCH));
LOG.info("Deleting contacts...");
fireDeleteMultiple(buildDeleteArray(contact_objects, CONTACT_SEARCH));
LOG.info("Deleting appointments...");
fireDeleteMultiple(buildDeleteArray(calendar_objects, CALENDAR_SEARCH));
LOG.info("Deleting infostore objects...");
fireDeleteMultiple(buildDeleteArray(store_objects, INFOSTORE_SEARCH));
}
private JSONObject doGetRootFolders() throws IOException, JSONException {
// 1 = id
// 20 = Object ID of the parent folder.
// 300 = Name of this folder.
// 301 = Name of the module which implements this folder.
// 302 = type // 1 private
//2 public
//3 shared
// 5 system folder
// 304 = true if this folder has subfolders.
// 305 = own_rights
try {
GetMethod folder_search = new GetMethod(getProtocol() + "://" + getHost() + "/ajax/folders?action=root&columns=1,20,300,301,302,304,305&session=" + getSessionObject().getSessionid());
getSessionObject().getOxClient().executeMethod(folder_search);
return ResponseTools.reponse2JsonObject(folder_search);
} catch (IOException ex) {
LOG.error("Generic IO error while searching folders", ex);
throw ex;
} catch (JSONException ex) {
LOG.error("JSON error while searching folders", ex);
throw ex;
}
}
private void fireDeleteMultiple(JSONArray del_data_array) {
try {
//LOG.info("Sending delete array: " + del_data_array);
PutMethod deleteMethod = new PutMethod(getProtocol() + "://" + getHost() + "/ajax/multiple?continue=true&session=" + getSessionObject().getSessionid());
RequestEntity data = new StringRequestEntity(del_data_array.toString(), CONTENT_TYPE_JSCRIPT, CHARSET_JSCRIPT);
deleteMethod.setRequestEntity(data);
getSessionObject().getOxClient().executeMethod(deleteMethod);
JSONArray responseObject = ResponseTools.reponse2JsonArray(deleteMethod);
//LOG.info(responseObject);
} catch (Exception ex) {
LOG.error("Error deleting items", ex);
}
}
private JSONObject doSearchInModule(String MODULE) {
// FETCH ALL OBJECT IDS FROM ALL FOLDERS
// EXCLUDING PUBLIC ADRESSBOOK WHICH HAS ID 6
PutMethod searchMethod = new PutMethod(getProtocol() + "://" + getHost() + "/ajax/" + MODULE + "?action=search&columns=1,20&session=" + getSessionObject().getSessionid());
try {
RequestEntity data = new StringRequestEntity("{\"pattern\":\"*\"}", CONTENT_TYPE_JSCRIPT, CHARSET_JSCRIPT);
searchMethod.setRequestEntity(data);
getSessionObject().getOxClient().executeMethod(searchMethod);
return ResponseTools.reponse2JsonObject(searchMethod);
} catch (Exception ex) {
LOG.error("Error searching " + MODULE, ex);
return null;
}
}
private void exitApp() {
System.exit(1);
}
public String getProtocol() {
return protocol;
}
}