From 2ab0e0ede99c33a4e0485907a3c2c97af64f6f28 Mon Sep 17 00:00:00 2001 From: Collin Date: Fri, 15 Mar 2024 16:41:48 +0000 Subject: [PATCH] Add Java Client --- .gitignore | 1 + Java/pom.xml | 45 +++++ .../lona_development/java_client/LonaDB.java | 166 ++++++++++++++++++ 3 files changed, 212 insertions(+) create mode 100644 Java/pom.xml create mode 100644 Java/src/main/java/org/lona_development/java_client/LonaDB.java diff --git a/.gitignore b/.gitignore index 80598f8..9dd40bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ JavaScript/node_modules +Java/target Python/venv Python/dist Python/buildc diff --git a/Java/pom.xml b/Java/pom.xml new file mode 100644 index 0000000..84920c9 --- /dev/null +++ b/Java/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + + scm:git:https://github.com/LonaDB/Clients.git + scm:git:https://github.com/LonaDB/Clients.git + https://github.com/LonaDB/Clients + + + org.lona-development.java-client + LonaDB + 2.1.3 + + + + com.fasterxml.jackson.core + jackson-databind + 2.13.0 + + + + junit + junit + 4.13.1 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + + 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..f482fcc --- /dev/null +++ b/Java/src/main/java/org/lona_development/java_client/LonaDB.java @@ -0,0 +1,166 @@ +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); + } +}