From 15f018429aa43daed5f816ec113314658970082c Mon Sep 17 00:00:00 2001 From: Collin Date: Wed, 25 Sep 2024 19:50:40 +0200 Subject: [PATCH] Update Java client (finally) --- .gitignore | 1 + Java/README.md | 2 +- Java/pom.xml | 12 +- .../lona_development/java_client/LonaDB.java | 262 ++++++++++++++++++ .../lona_development/java_client/lonadb.java | 166 ----------- 5 files changed, 270 insertions(+), 173 deletions(-) create mode 100644 Java/src/main/java/org/lona_development/java_client/LonaDB.java delete mode 100644 Java/src/main/java/org/lona_development/java_client/lonadb.java diff --git a/.gitignore b/.gitignore index ae6e504..cfbe07f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ JavaScript/node_modules Java/target +Java/.m2 Python/venv Python/dist Python/buildc diff --git a/Java/README.md b/Java/README.md index 4982fbd..214cc30 100644 --- a/Java/README.md +++ b/Java/README.md @@ -9,7 +9,7 @@ You can use the LonaDB Java Client by adding it as a dependency in your Maven pr github GitHub Packages - https://maven.pkg.github.com/LonaDB/Clients + https://maven.pkg.github.com/Lona-Development/Clients ``` diff --git a/Java/pom.xml b/Java/pom.xml index 7e1975e..2b75e5e 100644 --- a/Java/pom.xml +++ b/Java/pom.xml @@ -5,20 +5,20 @@ 4.0.0 - scm:git:https://github.com/LonaDB/Clients.git - scm:git:https://github.com/LonaDB/Clients.git - https://github.com/LonaDB/Clients + scm:git:https://git.lona-development.org/Lona-Development/Clients.git + scm:git:https://git.lona-development.org/Lona-Development/Clients.git + https://git.lona-development.org/Lona-Development/Clients org.lona-development.java-client lonadb - 2.1.3 + 2.1.4 com.fasterxml.jackson.core jackson-databind - 2.13.0 + 2.15.0 @@ -47,7 +47,7 @@ github GitHub Packages - https://maven.pkg.github.com/LonaDB/Clients + https://maven.pkg.github.com/Lona-Development/Clients diff --git a/Java/src/main/java/org/lona_development/java_client/LonaDB.java b/Java/src/main/java/org/lona_development/java_client/LonaDB.java new file mode 100644 index 0000000..c4f1de5 --- /dev/null +++ b/Java/src/main/java/org/lona_development/java_client/LonaDB.java @@ -0,0 +1,262 @@ +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.io.*; +import java.net.Socket; +import java.security.MessageDigest; +import java.security.SecureRandom; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class LonaDB { + private String host; + private int port; + private String name; + private String password; + + public LonaDB(String host, int port, String name, String password) { + this.host = host; + this.port = port; + this.name = name; + this.password = password; + } + + private String makeid(int length) { + String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz"; + Random random = new Random(); + StringBuilder result = new StringBuilder(); + for (int i = 0; i < length; i++) { + result.append(characters.charAt(random.nextInt(characters.length()))); + } + return result.toString(); + } + + private String encryptPassword(String password, String key) throws Exception { + // Hash the key + MessageDigest sha = MessageDigest.getInstance("SHA-256"); + byte[] keyBuffer = sha.digest(key.getBytes()); + + // Generate IV + byte[] iv = new byte[16]; + new SecureRandom().nextBytes(iv); + + // Encrypt + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKeySpec secretKeySpec = new SecretKeySpec(keyBuffer, "AES"); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec); + byte[] encrypted = cipher.doFinal(password.getBytes()); + + // Convert to hex and concatenate IV and encrypted data + return bytesToHex(iv) + ":" + bytesToHex(encrypted); + } + + private String bytesToHex(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } + + private Map sendRequest(String action, Map data) throws Exception { + // Create socket + Socket socket = new Socket(host, port); + + // Generate ProcessID + String processID = makeid(5); + + // Encrypt password + String encryptedPassword = encryptPassword(this.password, processID); + + // Build request data + Map request = new HashMap<>(); + request.put("action", action); + Map login = new HashMap<>(); + login.put("name", this.name); + login.put("password", encryptedPassword); + request.put("login", login); + request.put("process", processID); + request.putAll(data); + + // Send request to database + OutputStream outputStream = socket.getOutputStream(); + PrintWriter writer = new PrintWriter(outputStream, true); + writer.println(new ObjectMapper().writeValueAsString(request)); + + // Read response + BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); + String response = reader.readLine(); + + // Close socket + socket.close(); + + return new ObjectMapper().readValue(response, Map.class); + } + + public Map createFunction(String name, String content) throws Exception { + Map data = new HashMap<>(); + Map functionData = new HashMap<>(); + functionData.put("name", name); + functionData.put("content", content); + data.put("function", functionData); + + return sendRequest("add_function", data); + } + + public Map executeFunction(String name) throws Exception { + Map data = new HashMap<>(); + data.put("name", name); + return sendRequest("execute_function", data); + } + + public Map getTables(String user) throws Exception { + Map data = new HashMap<>(); + data.put("user", user); + return sendRequest("get_tables", data); + } + + public Map getTableData(String table) throws Exception { + Map data = new HashMap<>(); + data.put("table", table); + return sendRequest("get_table_data", data); + } + + public Map deleteTable(String table) throws Exception { + Map data = new HashMap<>(); + Map tableData = new HashMap<>(); + tableData.put("name", table); + data.put("table", tableData); + + return sendRequest("delete_table", data); + } + + public Map createTable(String table) throws Exception { + Map data = new HashMap<>(); + Map tableData = new HashMap<>(); + tableData.put("name", table); + data.put("table", tableData); + + return sendRequest("create_table", data); + } + + public Map set(String table, String name, String value) throws Exception { + Map data = new HashMap<>(); + Map tableData = new HashMap<>(); + tableData.put("name", table); + data.put("table", tableData); + Map variable = new HashMap<>(); + variable.put("name", name); + variable.put("value", value); + data.put("variable", variable); + + return sendRequest("set_variable", data); + } + + public Map delete(String table, String name) throws Exception { + Map data = new HashMap<>(); + Map tableData = new HashMap<>(); + tableData.put("name", table); + data.put("table", tableData); + Map variable = new HashMap<>(); + variable.put("name", name); + data.put("variable", variable); + + return sendRequest("remove_variable", data); + } + + public Map get(String table, String name) throws Exception { + Map data = new HashMap<>(); + Map tableData = new HashMap<>(); + tableData.put("name", table); + data.put("table", tableData); + Map variable = new HashMap<>(); + variable.put("name", name); + data.put("variable", variable); + + return sendRequest("get_variable", data); + } + + public Map createUser(String name, String pass) throws Exception { + Map data = new HashMap<>(); + Map user = new HashMap<>(); + user.put("name", name); + user.put("password", pass); + data.put("user", user); + + return sendRequest("create_user", data); + } + + public Map deleteUser(String name) throws Exception { + Map data = new HashMap<>(); + Map user = new HashMap<>(); + user.put("name", name); + data.put("user", user); + + return sendRequest("delete_user", data); + } + + public Map checkPassword(String name, String pass) throws Exception { + Map data = new HashMap<>(); + Map checkPass = new HashMap<>(); + checkPass.put("name", name); + checkPass.put("pass", pass); + data.put("checkPass", checkPass); + + return sendRequest("check_password", data); + } + + public Map getUsers() throws Exception { + Map data = new HashMap<>(); + return sendRequest("get_users", data); + } + + public Map addPermission(String name, String permission) throws Exception { + Map data = new HashMap<>(); + Map permissionData = new HashMap<>(); + permissionData.put("user", name); + permissionData.put("name", permission); + data.put("permission", permissionData); + + return sendRequest("add_permission", data); + } + + public Map removePermission(String name, String permission) throws Exception { + Map data = new HashMap<>(); + Map permissionData = new HashMap<>(); + permissionData.put("user", name); + permissionData.put("name", permission); + data.put("permission", permissionData); + + return sendRequest("remove_permission", data); + } + + public Map checkPermission(String name, String permission) throws Exception { + Map data = new HashMap<>(); + Map permissionData = new HashMap<>(); + permissionData.put("user", name); + permissionData.put("name", permission); + data.put("permission", permissionData); + + return sendRequest("check_permission", data); + } + + public Map getPermissionsRaw(String name) throws Exception { + Map data = new HashMap<>(); + data.put("user", name); + + return sendRequest("get_permissions_raw", data); + } + + public Map eval(String func) throws Exception { + Map data = new HashMap<>(); + data.put("function", func); + + return sendRequest("eval", data); + } +} diff --git a/Java/src/main/java/org/lona_development/java_client/lonadb.java b/Java/src/main/java/org/lona_development/java_client/lonadb.java deleted file mode 100644 index f7dabf9..0000000 --- a/Java/src/main/java/org/lona_development/java_client/lonadb.java +++ /dev/null @@ -1,166 +0,0 @@ -import java.io.*; -import java.net.*; -import java.util.Base64; -import java.util.Random; -import javax.crypto.*; -import javax.crypto.spec.*; -import java.security.*; - -public class lonadb { - private String host; - private int port; - private String name; - private String password; - - public lonadb(String host, int port, String name, String password) { - this.host = host; - this.port = port; - this.name = name; - this.password = password; - } - - private String makeId(int length) { - StringBuilder result = new StringBuilder(); - String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz"; - Random rand = new Random(); - int counter = 0; - - while (counter < length) { - result.append(characters.charAt(rand.nextInt(characters.length()))); - counter++; - } - - return result.toString(); - } - - private String encryptPassword(String password, String key) throws Exception { - byte[] iv = new byte[16]; - new SecureRandom().nextBytes(iv); - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(Base64.getDecoder().decode(key), "AES"), new IvParameterSpec(iv)); - byte[] encrypted = cipher.doFinal(password.getBytes()); - return bytesToHex(iv) + ":" + bytesToHex(encrypted); - } - - private String bytesToHex(byte[] bytes) { - StringBuilder result = new StringBuilder(); - for (byte b : bytes) { - result.append(String.format("%02x", b)); - } - return result.toString(); - } - - public String sendRequest(String action, String data) throws Exception { - String processID = makeId(5); - String encryptionKey = Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA-256").digest(processID.getBytes())); - - String encryptedPassword = encryptPassword(password, encryptionKey); - - String request = String.format("{\"action\":\"%s\",\"login\":{\"name\":\"%s\",\"password\":\"%s\"},\"process\":\"%s\",%s}", action, name, encryptedPassword, processID, data); - - Socket socket = new Socket(host, port); - OutputStream out = socket.getOutputStream(); - PrintWriter writer = new PrintWriter(out, true); - writer.println(request); - - BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); - StringBuilder response = new StringBuilder(); - String line; - while ((line = in.readLine()) != null) { - response.append(line); - } - - socket.close(); - - return response.toString(); - } - - public String createFunction(String name, String content) throws Exception { - String data = String.format("{\"function\":{\"name\":\"%s\",\"content\":\"%s\"}}", name, content); - return sendRequest("add_function", data); - } - - public String executeFunction(String name) throws Exception { - String data = String.format("{\"name\":\"%s\"}", name); - return sendRequest("execute_function", data); - } - - public String getTables(String user) throws Exception { - String data = String.format("{\"user\":\"%s\"}", user); - return sendRequest("get_tables", data); - } - - public String getTableData(String table) throws Exception { - String data = String.format("{\"table\":\"%s\"}", table); - return sendRequest("get_table_data", data); - } - - public String deleteTable(String table) throws Exception { - String data = String.format("{\"table\":{\"name\":\"%s\"}}", table); - return sendRequest("delete_table", data); - } - - public String createTable(String table) throws Exception { - String data = String.format("{\"table\":{\"name\":\"%s\"}}", table); - return sendRequest("create_table", data); - } - - public String set(String table, String name, String value) throws Exception { - String data = String.format("{\"table\":{\"name\":\"%s\"},\"variable\":{\"name\":\"%s\",\"value\":\"%s\"}}", table, name, value); - return sendRequest("set_variable", data); - } - - public String delete(String table, String name) throws Exception { - String data = String.format("{\"table\":{\"name\":\"%s\"},\"variable\":{\"name\":\"%s\"}}", table, name); - return sendRequest("remove_variable", data); - } - - public String get(String table, String name) throws Exception { - String data = String.format("{\"table\":{\"name\":\"%s\"},\"variable\":{\"name\":\"%s\"}}", table, name); - return sendRequest("get_variable", data); - } - - public String getUsers() throws Exception { - return sendRequest("get_users", "{}"); - } - - public String createUser(String name, String pass) throws Exception { - String data = String.format("{\"user\":{\"name\":\"%s\",\"password\":\"%s\"}}", name, pass); - return sendRequest("create_user", data); - } - - public String deleteUser(String name) throws Exception { - String data = String.format("{\"user\":{\"name\":\"%s\"}}", name); - return sendRequest("delete_user", data); - } - - public String checkPassword(String name, String pass) throws Exception { - String data = String.format("{\"checkPass\":{\"name\":\"%s\",\"pass\":\"%s\"}}", name, pass); - return sendRequest("check_password", data); - } - - public String checkPermission(String name, String permission) throws Exception { - String data = String.format("{\"permission\":{\"user\":\"%s\",\"name\":\"%s\"}}", name, permission); - return sendRequest("check_permission", data); - } - - public String removePermission(String name, String permission) throws Exception { - String data = String.format("{\"permission\":{\"user\":\"%s\",\"name\":\"%s\"}}", name, permission); - return sendRequest("remove_permission", data); - } - - public String getPermissionsRaw(String name) throws Exception { - String data = String.format("{\"user\":\"%s\"}", name); - return sendRequest("get_permissions_raw", data); - } - - public String addPermission(String name, String permission) throws Exception { - String data = String.format("{\"permission\":{\"user\":\"%s\",\"name\":\"%s\"}}", name, permission); - return sendRequest("add_permission", data); - } - - public String eval(String func) throws Exception { - String data = String.format("{\"function\":\"%s\"}", func); - return sendRequest("eval", data); - } -}