SHA256
04 12 25
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
package Test;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.WebSocket;
|
||||
import java.net.http.WebSocket.Listener;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
package Test;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import utils.crypto.Ed25519Util;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.WebSocket;
|
||||
import java.net.http.WebSocket.Listener;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class Test_AddUser_FirstAuth {
|
||||
|
||||
// Адрес сервера
|
||||
private static final String WS_URI = "ws://localhost:7070/ws";
|
||||
|
||||
private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
|
||||
|
||||
// Тестовые данные пользователя
|
||||
private static final String TEST_LOGIN = "anya2";
|
||||
private static final long TEST_LOGIN_ID = 100212L;
|
||||
private static final long TEST_BCH_ID = 4222L;
|
||||
private static final int TEST_BCH_LIMIT = 1_000_000;
|
||||
|
||||
// Тестовая пара ключей Ed25519 (стабильная, чтобы поведение не прыгало)
|
||||
private static final byte[] TEST_PRIV_KEY;
|
||||
private static final String TEST_PUBKEY_B64;
|
||||
|
||||
static {
|
||||
// Можно сделать детерминированно от логина, чтобы всегда были одинаковые ключи
|
||||
TEST_PRIV_KEY = Ed25519Util.generatePrivateKeyFromString("test-ed25519-" + TEST_LOGIN);
|
||||
byte[] pub = Ed25519Util.derivePublicKey(TEST_PRIV_KEY);
|
||||
TEST_PUBKEY_B64 = Ed25519Util.keyToBase64(pub);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Подключаемся к " + WS_URI);
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
HttpClient client = HttpClient.newHttpClient();
|
||||
|
||||
ClientListener listener = new ClientListener(latch);
|
||||
|
||||
client.newWebSocketBuilder()
|
||||
.buildAsync(URI.create(WS_URI), listener)
|
||||
.join();
|
||||
|
||||
// Ждём, пока всё не завершится (успех/ошибка/закрытие)
|
||||
latch.await();
|
||||
System.out.println("Тест завершён, выходим.");
|
||||
}
|
||||
|
||||
// --- вспомогательные билдера JSON-запросов ---
|
||||
|
||||
// 1) Добавление пользователя
|
||||
private static String buildAddUserJson() {
|
||||
return """
|
||||
{
|
||||
"op": "AddUser",
|
||||
"requestId": "test-add-1",
|
||||
"login": "%s",
|
||||
"loginId": %d,
|
||||
"bchId": %d,
|
||||
"pubkey0": "%s",
|
||||
"pubkey1": "%s",
|
||||
"bchLimit": %d
|
||||
}
|
||||
""".formatted(
|
||||
TEST_LOGIN,
|
||||
TEST_LOGIN_ID,
|
||||
TEST_BCH_ID,
|
||||
TEST_PUBKEY_B64, // pubkey0
|
||||
TEST_PUBKEY_B64, // pubkey1 (для теста можно тот же)
|
||||
TEST_BCH_LIMIT
|
||||
);
|
||||
}
|
||||
|
||||
// 2) Шаг 1 авторизации: запрос sessionPwd
|
||||
private static String buildAuthStep1Json() {
|
||||
return """
|
||||
{
|
||||
"op": "AuthSessionNewStep1",
|
||||
"requestId": "test-auth-1",
|
||||
"login": "%s"
|
||||
}
|
||||
""".formatted(TEST_LOGIN);
|
||||
}
|
||||
|
||||
// 3) Шаг 2 авторизации: подтверждение подписью
|
||||
private static String buildAuthStep2Json(String sessionPwd) {
|
||||
if (sessionPwd == null) {
|
||||
sessionPwd = "";
|
||||
}
|
||||
|
||||
long timeMs = System.currentTimeMillis();
|
||||
|
||||
// preimage = loginId + timeMs + sessionPwd
|
||||
String preimageStr = String.valueOf(TEST_LOGIN_ID) + timeMs + sessionPwd;
|
||||
byte[] preimage = preimageStr.getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
// Подписываем приватным ключом
|
||||
byte[] sig = Ed25519Util.sign(preimage, TEST_PRIV_KEY);
|
||||
String sigB64 = Base64.getEncoder().encodeToString(sig);
|
||||
|
||||
return """
|
||||
{
|
||||
"op": "AuthSessionNewStep2",
|
||||
"requestId": "test-auth-2",
|
||||
"loginId": %d,
|
||||
"sigNum": 0,
|
||||
"timeMs": %d,
|
||||
"signatureB64": "%s"
|
||||
}
|
||||
""".formatted(
|
||||
TEST_LOGIN_ID,
|
||||
timeMs,
|
||||
sigB64
|
||||
);
|
||||
}
|
||||
|
||||
// ================== LISTENER ==================
|
||||
|
||||
// Внутренний Listener, который сам по шагам шлёт запросы и печатает ответы
|
||||
private static class ClientListener implements Listener {
|
||||
|
||||
private final CountDownLatch latch;
|
||||
private int step = 0; // 0 - AddUser, 1 - AuthStep1, 2 - AuthStep2
|
||||
private String sessionPwdFromStep1;
|
||||
|
||||
ClientListener(CountDownLatch latch) {
|
||||
this.latch = latch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(WebSocket webSocket) {
|
||||
System.out.println("✅ WebSocket подключен");
|
||||
|
||||
// Разрешаем приём первого сообщения
|
||||
webSocket.request(1);
|
||||
|
||||
sendNextRequest(webSocket);
|
||||
Listener.super.onOpen(webSocket);
|
||||
}
|
||||
|
||||
// Отправка следующего запроса в зависимости от шага
|
||||
private void sendNextRequest(WebSocket webSocket) {
|
||||
switch (step) {
|
||||
case 0 -> {
|
||||
String json = buildAddUserJson();
|
||||
System.out.println();
|
||||
System.out.println("📤 [Шаг 1] Отправляем AddUser:");
|
||||
System.out.println(json);
|
||||
webSocket.sendText(json, true);
|
||||
}
|
||||
case 1 -> {
|
||||
String json = buildAuthStep1Json();
|
||||
System.out.println();
|
||||
System.out.println("📤 [Шаг 2] Отправляем AuthSessionNewStep1:");
|
||||
System.out.println(json);
|
||||
webSocket.sendText(json, true);
|
||||
}
|
||||
case 2 -> {
|
||||
String json = buildAuthStep2Json(sessionPwdFromStep1);
|
||||
System.out.println();
|
||||
System.out.println("📤 [Шаг 3] Отправляем AuthSessionNewStep2 (подпись):");
|
||||
System.out.println(json);
|
||||
webSocket.sendText(json, true);
|
||||
}
|
||||
default -> {
|
||||
System.out.println("✅ Все шаги выполнены, закрываем соединение");
|
||||
webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "all tests done");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionStage<?> onText(WebSocket webSocket,
|
||||
CharSequence data,
|
||||
boolean last) {
|
||||
String message = data.toString();
|
||||
System.out.println("📥 Ответ на шаг " + (step + 1) + ":");
|
||||
System.out.println(message);
|
||||
System.out.println("-----------------------------------------------------");
|
||||
|
||||
// Если это ответ на шаг 2 (AuthSessionNewStep1) — достаем sessionPwd из payload
|
||||
if (step == 1) {
|
||||
sessionPwdFromStep1 = extractSessionPwd(message);
|
||||
System.out.println("🔑 Извлечён sessionPwd: " + sessionPwdFromStep1);
|
||||
}
|
||||
|
||||
// Переходим к следующему шагу
|
||||
step++;
|
||||
sendNextRequest(webSocket);
|
||||
|
||||
// Запрашиваем следующее входящее сообщение
|
||||
webSocket.request(1);
|
||||
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(WebSocket webSocket, Throwable error) {
|
||||
System.out.println("❌ Ошибка WebSocket-клиента: " + error.getMessage());
|
||||
error.printStackTrace(System.out);
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionStage<?> onClose(WebSocket webSocket,
|
||||
int statusCode,
|
||||
String reason) {
|
||||
System.out.println("🔚 Соединение закрыто. Код=" + statusCode + ", причина=" + reason);
|
||||
latch.countDown();
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
private String extractSessionPwd(String json) {
|
||||
try {
|
||||
JsonNode root = JSON_MAPPER.readTree(json);
|
||||
JsonNode payload = root.get("payload");
|
||||
if (payload != null && payload.has("sessionPwd")) {
|
||||
return payload.get("sessionPwd").asText();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("⚠️ Не удалось распарсить sessionPwd из ответа: " + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package Test;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.WebSocket;
|
||||
import java.net.http.WebSocket.Listener;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class Test_SessionRefreshClient {
|
||||
|
||||
// Адрес сервера
|
||||
private static final String WS_URI = "ws://localhost:7070/ws";
|
||||
|
||||
// ==== ЗДЕСЬ ПОДСТАВИШЬ СВОИ ДАННЫЕ СЕССИИ ====
|
||||
private static final long SESSION_ID = 7599553208996461137L; // TODO: подставь реальный sessionId
|
||||
private static final String SESSION_PWD = "11b3508f37ae7b41816f42031b90"; // TODO: подставь реальный sessionPwd
|
||||
// =============================================
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Подключаемся к " + WS_URI);
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
HttpClient client = HttpClient.newHttpClient();
|
||||
|
||||
ClientListener listener = new ClientListener(latch);
|
||||
|
||||
client.newWebSocketBuilder()
|
||||
.buildAsync(URI.create(WS_URI), listener)
|
||||
.join();
|
||||
|
||||
latch.await();
|
||||
System.out.println("Тест SessionRefresh завершён, выходим.");
|
||||
}
|
||||
|
||||
private static String buildSessionRefreshJson() {
|
||||
return """
|
||||
{
|
||||
"op": "SessionRefresh",
|
||||
"requestId": "test-session-refresh-1",
|
||||
"sessionId": %d,
|
||||
"sessionPwd": "%s"
|
||||
}
|
||||
""".formatted(SESSION_ID, SESSION_PWD);
|
||||
}
|
||||
|
||||
private static class ClientListener implements Listener {
|
||||
|
||||
private final CountDownLatch latch;
|
||||
private boolean sent = false;
|
||||
|
||||
ClientListener(CountDownLatch latch) {
|
||||
this.latch = latch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(WebSocket webSocket) {
|
||||
System.out.println("✅ WebSocket подключен");
|
||||
|
||||
webSocket.request(1); // разрешаем принимать одно сообщение
|
||||
|
||||
// сразу отправляем запрос SessionRefresh
|
||||
String json = buildSessionRefreshJson();
|
||||
System.out.println();
|
||||
System.out.println("📤 Отправляем SessionRefresh:");
|
||||
System.out.println(json);
|
||||
webSocket.sendText(json, true);
|
||||
sent = true;
|
||||
|
||||
Listener.super.onOpen(webSocket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionStage<?> onText(WebSocket webSocket,
|
||||
CharSequence data,
|
||||
boolean last) {
|
||||
System.out.println("📥 Ответ от сервера:");
|
||||
System.out.println(data.toString());
|
||||
System.out.println("-----------------------------------------------------");
|
||||
|
||||
// После одного ответа просто закрываем соединение
|
||||
System.out.println("✅ Получен ответ на SessionRefresh, закрываем соединение");
|
||||
webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "session refresh test done");
|
||||
|
||||
// запрашиваем следующее сообщение на всякий случай (хотя уже закрываемся)
|
||||
webSocket.request(1);
|
||||
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(WebSocket webSocket, Throwable error) {
|
||||
System.out.println("❌ Ошибка WebSocket-клиента: " + error.getMessage());
|
||||
error.printStackTrace(System.out);
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionStage<?> onClose(WebSocket webSocket,
|
||||
int statusCode,
|
||||
String reason) {
|
||||
System.out.println("🔚 Соединение закрыто. Код=" + statusCode + ", причина=" + reason);
|
||||
latch.countDown();
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.WebSocket;
|
||||
import java.net.http.WebSocket.Listener;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class TestJsonWsClient {
|
||||
|
||||
// Адрес сервера
|
||||
private static final String WS_URI = "ws://localhost:7070/ws";
|
||||
|
||||
// Отдельные запросы
|
||||
private static final String JSON_REQUEST_SESSION_REFRESH = """
|
||||
{
|
||||
"op": "SessionRefresh",
|
||||
"requestId": "test-1",
|
||||
"sessionId": 123,
|
||||
"sessionPwd": "test-password"
|
||||
}
|
||||
""";
|
||||
|
||||
private static final String JSON_REQUEST_ADD_USER = """
|
||||
{
|
||||
"op": "AddUser",
|
||||
"requestId": "test-add-1",
|
||||
"login": "anya1111",
|
||||
"loginId": 100211,
|
||||
"bchId": 4222,
|
||||
"pubkey0": "PUB0",
|
||||
"pubkey1": "PUB1",
|
||||
"bchLimit": 1000000
|
||||
}
|
||||
""";
|
||||
|
||||
private static final String JSON_REQUEST_AUTH_SESSION_NEW_STEP1 = """
|
||||
{
|
||||
"op": "AuthSessionNewStep1",
|
||||
"requestId": "test-auth-1",
|
||||
"login": "anya1111"
|
||||
}
|
||||
""";
|
||||
|
||||
// МАССИВ КОНСТАНТА с запросами — добавляешь сюда любые свои JSON
|
||||
private static final String[] JSON_REQUESTS = {
|
||||
JSON_REQUEST_SESSION_REFRESH,
|
||||
JSON_REQUEST_ADD_USER,
|
||||
JSON_REQUEST_AUTH_SESSION_NEW_STEP1
|
||||
};
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Подключаемся к " + WS_URI);
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
HttpClient client = HttpClient.newHttpClient();
|
||||
|
||||
ClientListener listener = new ClientListener(JSON_REQUESTS, latch);
|
||||
|
||||
client.newWebSocketBuilder()
|
||||
.buildAsync(URI.create(WS_URI), listener)
|
||||
.join();
|
||||
|
||||
// Ждём, пока всё не завершится (успех/ошибка/закрытие)
|
||||
latch.await();
|
||||
System.out.println("Тест завершён, выходим.");
|
||||
}
|
||||
|
||||
// Внутренний Listener, который сам по очереди шлёт запросы и печатает ответы
|
||||
private static class ClientListener implements Listener {
|
||||
|
||||
private final String[] requests;
|
||||
private final CountDownLatch latch;
|
||||
private int index = 0; // какой запрос сейчас отправляем/ждём ответ
|
||||
|
||||
ClientListener(String[] requests, CountDownLatch latch) {
|
||||
this.requests = requests;
|
||||
this.latch = latch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(WebSocket webSocket) {
|
||||
System.out.println("✅ WebSocket подключен");
|
||||
sendNextRequest(webSocket);
|
||||
Listener.super.onOpen(webSocket);
|
||||
}
|
||||
|
||||
// Отправка следующего запроса из массива
|
||||
private void sendNextRequest(WebSocket webSocket) {
|
||||
if (index < requests.length) {
|
||||
String json = requests[index];
|
||||
System.out.println();
|
||||
System.out.println("📤 Отправляем запрос " + (index + 1) + " из " + requests.length + ":");
|
||||
System.out.println(json);
|
||||
webSocket.sendText(json, true);
|
||||
} else {
|
||||
System.out.println("✅ Все запросы отправлены, закрываем соединение");
|
||||
webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "all tests done");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionStage<?> onText(WebSocket webSocket,
|
||||
CharSequence data,
|
||||
boolean last) {
|
||||
// Ответ на текущий запрос (с индексом index)
|
||||
System.out.println("📥 Ответ на запрос " + (index + 1) + ":");
|
||||
System.out.println(data.toString());
|
||||
System.out.println("-----------------------------------------------------");
|
||||
|
||||
// Переходим к следующему запросу
|
||||
index++;
|
||||
sendNextRequest(webSocket);
|
||||
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(WebSocket webSocket, Throwable error) {
|
||||
System.out.println("❌ Ошибка WebSocket-клиента: " + error.getMessage());
|
||||
error.printStackTrace(System.out);
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionStage<?> onClose(WebSocket webSocket,
|
||||
int statusCode,
|
||||
String reason) {
|
||||
System.out.println("🔚 Соединение закрыто. Код=" + statusCode + ", причина=" + reason);
|
||||
latch.countDown();
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user