Update Java client (finally)

This commit is contained in:
Collin 2024-09-25 19:50:40 +02:00
parent 1b11741450
commit 15f018429a
5 changed files with 270 additions and 173 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
JavaScript/node_modules
Java/target
Java/.m2
Python/venv
Python/dist
Python/buildc

View File

@ -9,7 +9,7 @@ You can use the LonaDB Java Client by adding it as a dependency in your Maven pr
<repository>
<id>github</id>
<name>GitHub Packages</name>
<url>https://maven.pkg.github.com/LonaDB/Clients</url>
<url>https://maven.pkg.github.com/Lona-Development/Clients</url>
</repository>
</repositories>
```

View File

@ -5,20 +5,20 @@
<modelVersion>4.0.0</modelVersion>
<scm>
<connection>scm:git:https://github.com/LonaDB/Clients.git</connection>
<developerConnection>scm:git:https://github.com/LonaDB/Clients.git</developerConnection>
<url>https://github.com/LonaDB/Clients</url>
<connection>scm:git:https://git.lona-development.org/Lona-Development/Clients.git</connection>
<developerConnection>scm:git:https://git.lona-development.org/Lona-Development/Clients.git</developerConnection>
<url>https://git.lona-development.org/Lona-Development/Clients</url>
</scm>
<groupId>org.lona-development.java-client</groupId>
<artifactId>lonadb</artifactId>
<version>2.1.3</version>
<version>2.1.4</version>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
<version>2.15.0</version>
</dependency>
<dependency>
@ -47,7 +47,7 @@
<repository>
<id>github</id>
<name>GitHub Packages</name>
<url>https://maven.pkg.github.com/LonaDB/Clients</url>
<url>https://maven.pkg.github.com/Lona-Development/Clients</url>
</repository>
</distributionManagement>

View File

@ -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<String, Object> sendRequest(String action, Map<String, Object> 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<String, Object> request = new HashMap<>();
request.put("action", action);
Map<String, String> 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<String, Object> createFunction(String name, String content) throws Exception {
Map<String, Object> data = new HashMap<>();
Map<String, String> functionData = new HashMap<>();
functionData.put("name", name);
functionData.put("content", content);
data.put("function", functionData);
return sendRequest("add_function", data);
}
public Map<String, Object> executeFunction(String name) throws Exception {
Map<String, Object> data = new HashMap<>();
data.put("name", name);
return sendRequest("execute_function", data);
}
public Map<String, Object> getTables(String user) throws Exception {
Map<String, Object> data = new HashMap<>();
data.put("user", user);
return sendRequest("get_tables", data);
}
public Map<String, Object> getTableData(String table) throws Exception {
Map<String, Object> data = new HashMap<>();
data.put("table", table);
return sendRequest("get_table_data", data);
}
public Map<String, Object> deleteTable(String table) throws Exception {
Map<String, Object> data = new HashMap<>();
Map<String, String> tableData = new HashMap<>();
tableData.put("name", table);
data.put("table", tableData);
return sendRequest("delete_table", data);
}
public Map<String, Object> createTable(String table) throws Exception {
Map<String, Object> data = new HashMap<>();
Map<String, String> tableData = new HashMap<>();
tableData.put("name", table);
data.put("table", tableData);
return sendRequest("create_table", data);
}
public Map<String, Object> set(String table, String name, String value) throws Exception {
Map<String, Object> data = new HashMap<>();
Map<String, String> tableData = new HashMap<>();
tableData.put("name", table);
data.put("table", tableData);
Map<String, String> variable = new HashMap<>();
variable.put("name", name);
variable.put("value", value);
data.put("variable", variable);
return sendRequest("set_variable", data);
}
public Map<String, Object> delete(String table, String name) throws Exception {
Map<String, Object> data = new HashMap<>();
Map<String, String> tableData = new HashMap<>();
tableData.put("name", table);
data.put("table", tableData);
Map<String, String> variable = new HashMap<>();
variable.put("name", name);
data.put("variable", variable);
return sendRequest("remove_variable", data);
}
public Map<String, Object> get(String table, String name) throws Exception {
Map<String, Object> data = new HashMap<>();
Map<String, String> tableData = new HashMap<>();
tableData.put("name", table);
data.put("table", tableData);
Map<String, String> variable = new HashMap<>();
variable.put("name", name);
data.put("variable", variable);
return sendRequest("get_variable", data);
}
public Map<String, Object> createUser(String name, String pass) throws Exception {
Map<String, Object> data = new HashMap<>();
Map<String, String> user = new HashMap<>();
user.put("name", name);
user.put("password", pass);
data.put("user", user);
return sendRequest("create_user", data);
}
public Map<String, Object> deleteUser(String name) throws Exception {
Map<String, Object> data = new HashMap<>();
Map<String, String> user = new HashMap<>();
user.put("name", name);
data.put("user", user);
return sendRequest("delete_user", data);
}
public Map<String, Object> checkPassword(String name, String pass) throws Exception {
Map<String, Object> data = new HashMap<>();
Map<String, String> checkPass = new HashMap<>();
checkPass.put("name", name);
checkPass.put("pass", pass);
data.put("checkPass", checkPass);
return sendRequest("check_password", data);
}
public Map<String, Object> getUsers() throws Exception {
Map<String, Object> data = new HashMap<>();
return sendRequest("get_users", data);
}
public Map<String, Object> addPermission(String name, String permission) throws Exception {
Map<String, Object> data = new HashMap<>();
Map<String, String> permissionData = new HashMap<>();
permissionData.put("user", name);
permissionData.put("name", permission);
data.put("permission", permissionData);
return sendRequest("add_permission", data);
}
public Map<String, Object> removePermission(String name, String permission) throws Exception {
Map<String, Object> data = new HashMap<>();
Map<String, String> permissionData = new HashMap<>();
permissionData.put("user", name);
permissionData.put("name", permission);
data.put("permission", permissionData);
return sendRequest("remove_permission", data);
}
public Map<String, Object> checkPermission(String name, String permission) throws Exception {
Map<String, Object> data = new HashMap<>();
Map<String, String> permissionData = new HashMap<>();
permissionData.put("user", name);
permissionData.put("name", permission);
data.put("permission", permissionData);
return sendRequest("check_permission", data);
}
public Map<String, Object> getPermissionsRaw(String name) throws Exception {
Map<String, Object> data = new HashMap<>();
data.put("user", name);
return sendRequest("get_permissions_raw", data);
}
public Map<String, Object> eval(String func) throws Exception {
Map<String, Object> data = new HashMap<>();
data.put("function", func);
return sendRequest("eval", data);
}
}

View File

@ -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);
}
}