10 12 25
Попереименовывал классы и запросы для авторификации. Вроде хоршо и наверное всё работает :) пока не тестил
This commit is contained in:
parent
888bb1595f
commit
47c53c1a14
@ -1,15 +1,15 @@
|
||||
package server.logic.ws_protocol.JSON;
|
||||
|
||||
import server.logic.ws_protocol.JSON.entyties.*;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.NetAuthSessionNewStep1Request;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.NetAuthSessionNewStep2Request;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.NetSessionRefreshRequest;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.Net_AuthChallenge_Request;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.Net_CreateAuthSession_Request;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.Net_RefreshSession_Request;
|
||||
import server.logic.ws_protocol.JSON.handlers.*;
|
||||
import server.logic.ws_protocol.JSON.entyties.tempToTest.NetAddUserRequest;
|
||||
import server.logic.ws_protocol.JSON.handlers.auth.NetAuthSessionNewStep2Handler;
|
||||
import server.logic.ws_protocol.JSON.handlers.auth.Net_CreateAuthSession__Handler;
|
||||
import server.logic.ws_protocol.JSON.handlers.auth.Net_RefreshSession_Handler;
|
||||
import server.logic.ws_protocol.JSON.handlers.tempToTest.NetAddUserHandler;
|
||||
import server.logic.ws_protocol.JSON.handlers.auth.NetAuthSessionNewStep1Handler;
|
||||
import server.logic.ws_protocol.JSON.handlers.auth.NetSessionRefreshHandler;
|
||||
import server.logic.ws_protocol.JSON.handlers.auth.Net_AuthChallenge_Handler;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -25,18 +25,18 @@ import java.util.Map;
|
||||
public final class JsonHandlerRegistry {
|
||||
|
||||
private static final Map<String, JsonMessageHandler> HANDLERS = Map.of(
|
||||
"SessionRefresh", new NetSessionRefreshHandler(),
|
||||
"RefreshSession", new Net_RefreshSession_Handler(),
|
||||
"AddUser", new NetAddUserHandler(),
|
||||
"AuthSessionNewStep1", new NetAuthSessionNewStep1Handler(),
|
||||
"AuthSessionNewStep2", new NetAuthSessionNewStep2Handler()
|
||||
"AuthChallenge", new Net_AuthChallenge_Handler(),
|
||||
"CreateAuthSession", new Net_CreateAuthSession__Handler()
|
||||
// сюда потом добавишь другие операции
|
||||
);
|
||||
|
||||
private static final Map<String, Class<? extends NetRequest>> REQUEST_TYPES = Map.of(
|
||||
"SessionRefresh", NetSessionRefreshRequest.class,
|
||||
"RefreshSession", Net_RefreshSession_Request.class,
|
||||
"AddUser", NetAddUserRequest.class,
|
||||
"AuthSessionNewStep1", NetAuthSessionNewStep1Request.class,
|
||||
"AuthSessionNewStep2", NetAuthSessionNewStep2Request.class
|
||||
"AuthChallenge", Net_AuthChallenge_Request.class,
|
||||
"CreateAuthSession", Net_CreateAuthSession_Request.class
|
||||
);
|
||||
|
||||
private JsonHandlerRegistry() {
|
||||
|
||||
@ -0,0 +1,176 @@
|
||||
Протокол создания новой сессии
|
||||
📌 Общие правила JSON-протокола
|
||||
|
||||
Любой запрос от клиента имеет формат:
|
||||
|
||||
{
|
||||
"op": "OperationName",
|
||||
"requestId": "some-id",
|
||||
"payload": { ... }
|
||||
}
|
||||
|
||||
|
||||
Ответ от сервера:
|
||||
|
||||
{
|
||||
"op": "OperationName",
|
||||
"requestId": "some-id",
|
||||
"status": 200,
|
||||
"payload": { "ok": true, ... }
|
||||
}
|
||||
|
||||
|
||||
Ошибка:
|
||||
|
||||
{
|
||||
"op": "OperationName",
|
||||
"requestId": "some-id",
|
||||
"status": 4xx/5xx,
|
||||
"payload": {
|
||||
"ok": false,
|
||||
"code": "ERROR_CODE",
|
||||
"message": "Описание ошибки"
|
||||
}
|
||||
}
|
||||
|
||||
1. Добавление пользователя (AddUser)
|
||||
|
||||
Назначение: создать локальную запись пользователя с двумя ключами — loginKey и deviceKey.
|
||||
|
||||
📤 Запрос клиента
|
||||
{
|
||||
"op": "AddUser",
|
||||
"requestId": "req-1",
|
||||
"payload": {
|
||||
"login": "anya4",
|
||||
"loginId": 100212,
|
||||
"bchId": 4222,
|
||||
"loginKey": "BASE64_LOGIN_KEY",
|
||||
"deviceKey": "BASE64_DEVICE_KEY",
|
||||
"bchLimit": 1000000
|
||||
}
|
||||
}
|
||||
|
||||
🖥 Действия сервера
|
||||
|
||||
Проверяет корректность данных.
|
||||
|
||||
Вставляет запись в таблицу:
|
||||
|
||||
CREATE TABLE solana_users (
|
||||
login TEXT NOT NULL,
|
||||
loginId INTEGER PRIMARY KEY,
|
||||
bchId INTEGER NOT NULL,
|
||||
loginKey TEXT,
|
||||
deviceKey TEXT,
|
||||
bchLimit INTEGER
|
||||
);
|
||||
|
||||
📥 Ответ
|
||||
{
|
||||
"op": "AddUser",
|
||||
"requestId": "req-1",
|
||||
"status": 200,
|
||||
"payload": { "ok": true }
|
||||
}
|
||||
|
||||
2. Шаг 1 — запрос временного пароля сессии
|
||||
AuthChallenge
|
||||
|
||||
Назначение: сервер выдаёт клиенту временный sessionPwd.
|
||||
Он потом будет включён в подписываемую строку.
|
||||
|
||||
📤 Запрос клиента
|
||||
{
|
||||
"op": "AuthChallenge",
|
||||
"requestId": "req-2",
|
||||
"payload": {
|
||||
"login": "anya4"
|
||||
}
|
||||
}
|
||||
|
||||
🖥 Действия сервера
|
||||
|
||||
Находит пользователя по login.
|
||||
|
||||
Генерирует sessionPwd — случайный 32-байтовый base64.
|
||||
|
||||
Сохраняет sessionPwd во временный in-memory storage, привязанный к loginId.
|
||||
|
||||
📥 Ответ
|
||||
{
|
||||
"op": "AuthChallenge",
|
||||
"requestId": "req-2",
|
||||
"status": 200,
|
||||
"payload": {
|
||||
"ok": true,
|
||||
"sessionPwd": "BASE64_SESSION_PWD"
|
||||
}
|
||||
}
|
||||
|
||||
3. Шаг 2 — подтверждение подписью и создание сессии
|
||||
CreateAuthSession
|
||||
📌 Клиент подписывает строку:
|
||||
preimage = "AUTHORIFICATED:" + timeMs + sessionPwd
|
||||
|
||||
|
||||
timeMs — timestamp клиента (UTC).
|
||||
|
||||
sessionPwd — строка с шага 1.
|
||||
|
||||
signatureB64 — Ed25519‐подпись preimage приватным ключом deviceKey.
|
||||
|
||||
📤 Запрос клиента
|
||||
{
|
||||
"op": "CreateAuthSession",
|
||||
"requestId": "req-3",
|
||||
"payload": {
|
||||
"storagePwd": "BASE64_32_BYTES",
|
||||
"timeMs": 1765298068436,
|
||||
"signatureB64": "BASE64_SIGNATURE"
|
||||
}
|
||||
}
|
||||
|
||||
🔍 Валидация сервера
|
||||
|
||||
Проверяет timeMs:
|
||||
|
||||
не старше 30 секунд (now - timeMs <= 30s);
|
||||
|
||||
не в сильном будущем (опционально).
|
||||
|
||||
Восстанавливает preimage.
|
||||
|
||||
Находит deviceKey пользователя.
|
||||
|
||||
Проверяет Ed25519-подпись.
|
||||
|
||||
Создаёт sessionId — base64 от 32 байт.
|
||||
|
||||
Создаёт запись ActiveSession:
|
||||
|
||||
CREATE TABLE active_sessions (
|
||||
sessionId TEXT PRIMARY KEY,
|
||||
loginId INTEGER NOT NULL,
|
||||
sessionPwd TEXT NOT NULL,
|
||||
storagePwd TEXT NOT NULL,
|
||||
sessionCreatedAtMs INTEGER NOT NULL,
|
||||
lastAuthirificatedAtMs INTEGER NOT NULL,
|
||||
pushEndpoint TEXT,
|
||||
pushP256dhKey TEXT,
|
||||
pushAuthKey TEXT
|
||||
);
|
||||
|
||||
📥 Ответ сервера (успех)
|
||||
{
|
||||
"op": "CreateAuthSession",
|
||||
"requestId": "req-3",
|
||||
"status": 200,
|
||||
"payload": {
|
||||
"ok": true,
|
||||
"sessionId": "BASE64_SESSION_ID"
|
||||
}
|
||||
}
|
||||
|
||||
📘 Итоговая схема создания сессии
|
||||
AddUser → AuthChallenge → CreateAuthSession → Session Created
|
||||
@ -10,7 +10,7 @@ import server.logic.ws_protocol.JSON.entyties.NetRequest;
|
||||
*
|
||||
* Формат входящего JSON:
|
||||
* {
|
||||
* "op": "AuthSessionNewStep1",
|
||||
* "op": "AuthChallenge",
|
||||
* "requestId": "...",
|
||||
* "payload": {
|
||||
* "login": "someLogin"
|
||||
@ -19,7 +19,7 @@ import server.logic.ws_protocol.JSON.entyties.NetRequest;
|
||||
*
|
||||
* Формат успешного ответа:
|
||||
* {
|
||||
* "op": "AuthSessionNewStep1",
|
||||
* "op": "AuthChallenge",
|
||||
* "requestId": "...",
|
||||
* "status": 200,
|
||||
* "payload": {
|
||||
@ -27,7 +27,7 @@ import server.logic.ws_protocol.JSON.entyties.NetRequest;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public class NetAuthSessionNewStep1Request extends NetRequest {
|
||||
public class Net_AuthChallenge_Request extends NetRequest {
|
||||
|
||||
/**
|
||||
* Логин пользователя, для которого запускается авторизация.
|
||||
@ -3,14 +3,14 @@ package server.logic.ws_protocol.JSON.entyties.Auth;
|
||||
import server.logic.ws_protocol.JSON.entyties.NetResponse;
|
||||
|
||||
/**
|
||||
* Ответ на AuthSessionNewStep1.
|
||||
* Ответ на AuthChallenge.
|
||||
*
|
||||
* При успехе сервер возвращает временный секрет sessionPwd,
|
||||
* который клиент обязан использовать на втором шаге при формировании подписи.
|
||||
*
|
||||
* JSON:
|
||||
* {
|
||||
* "op": "AuthSessionNewStep1",
|
||||
* "op": "AuthChallenge",
|
||||
* "requestId": "...",
|
||||
* "status": 200,
|
||||
* "payload": {
|
||||
@ -18,7 +18,7 @@ import server.logic.ws_protocol.JSON.entyties.NetResponse;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public class NetAuthSessionNewStep1Response extends NetResponse {
|
||||
public class Net_AuthChallenge_Response extends NetResponse {
|
||||
|
||||
/**
|
||||
* Временный секрет, сгенерированный сервером.
|
||||
@ -15,7 +15,7 @@ import server.logic.ws_protocol.JSON.entyties.NetRequest;
|
||||
*
|
||||
* Формат входящего JSON:
|
||||
* {
|
||||
* "op": "AuthSessionNewStep2",
|
||||
* "op": "CreateAuthSession",
|
||||
* "requestId": "...",
|
||||
* "payload": {
|
||||
* "storagePwd": "base64-строка-от-32-байт",
|
||||
@ -27,7 +27,7 @@ import server.logic.ws_protocol.JSON.entyties.NetRequest;
|
||||
* При успешной проверке подписи сервер создаёт запись в active_sessions
|
||||
* и возвращает sessionId (base64-строка от 32 байт).
|
||||
*/
|
||||
public class NetAuthSessionNewStep2Request extends NetRequest {
|
||||
public class Net_CreateAuthSession_Request extends NetRequest {
|
||||
|
||||
/** Клиентский пароль для хранения данных (base64 от 32 байт). */
|
||||
private String storagePwd;
|
||||
@ -3,14 +3,14 @@ package server.logic.ws_protocol.JSON.entyties.Auth;
|
||||
import server.logic.ws_protocol.JSON.entyties.NetResponse;
|
||||
|
||||
/**
|
||||
* Ответ на AuthSessionNewStep2.
|
||||
* Ответ на CreateAuthSession.
|
||||
*
|
||||
* При успехе сервер создаёт запись в active_sessions
|
||||
* и возвращает идентификатор сессии sessionId.
|
||||
*
|
||||
* JSON:
|
||||
* {
|
||||
* "op": "AuthSessionNewStep2",
|
||||
* "op": "CreateAuthSession",
|
||||
* "requestId": "...",
|
||||
* "status": 200,
|
||||
* "payload": {
|
||||
@ -18,7 +18,7 @@ import server.logic.ws_protocol.JSON.entyties.NetResponse;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public class NetAuthSessionNewStep2Response extends NetResponse {
|
||||
public class Net_CreateAuthSession_Response extends NetResponse {
|
||||
|
||||
/** Идентификатор сессии, base64 от 32 байт. */
|
||||
private String sessionId;
|
||||
@ -3,7 +3,7 @@ package server.logic.ws_protocol.JSON.entyties.Auth;
|
||||
import server.logic.ws_protocol.JSON.entyties.NetRequest;
|
||||
|
||||
/**
|
||||
* Запрос SessionRefresh.
|
||||
* Запрос RefreshSession.
|
||||
*
|
||||
* Используется для повторного входа без повторной подписи:
|
||||
* клиент хранит sessionId и sessionPwd, которые получил на шаге 2.
|
||||
@ -14,7 +14,7 @@ import server.logic.ws_protocol.JSON.entyties.NetRequest;
|
||||
* "sessionPwd": "base64-sessionPwd"
|
||||
* }
|
||||
*/
|
||||
public class NetSessionRefreshRequest extends NetRequest {
|
||||
public class Net_RefreshSession_Request extends NetRequest {
|
||||
|
||||
private String sessionId;
|
||||
private String sessionPwd;
|
||||
@ -3,14 +3,14 @@ package server.logic.ws_protocol.JSON.entyties.Auth;
|
||||
import server.logic.ws_protocol.JSON.entyties.NetResponse;
|
||||
|
||||
/**
|
||||
* Успешный ответ на SessionRefresh.
|
||||
* Успешный ответ на RefreshSession.
|
||||
*
|
||||
* Дополнительно к статусу 200 сервер возвращает storagePwd,
|
||||
* чтобы клиент мог восстановить/синхронизировать локальное хранилище.
|
||||
*
|
||||
* JSON:
|
||||
* {
|
||||
* "op": "SessionRefresh",
|
||||
* "op": "RefreshSession",
|
||||
* "requestId": "...",
|
||||
* "status": 200,
|
||||
* "payload": {
|
||||
@ -18,7 +18,7 @@ import server.logic.ws_protocol.JSON.entyties.NetResponse;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public class NetSessionRefreshResponse extends NetResponse {
|
||||
public class Net_RefreshSession_Response extends NetResponse {
|
||||
|
||||
/** Пароль хранилища, сохранённый в сессии (storagePwd). */
|
||||
private String storagePwd;
|
||||
@ -0,0 +1,74 @@
|
||||
Протокол обновления существующей сессии
|
||||
1. Назначение
|
||||
|
||||
RefreshSession используется для:
|
||||
|
||||
проверки, что клиент всё ещё владеет правильным sessionPwd;
|
||||
|
||||
продления “живучести” сессии;
|
||||
|
||||
возврата клиенту его storagePwd.
|
||||
|
||||
2. Формат запроса RefreshSession
|
||||
{
|
||||
"op": "RefreshSession",
|
||||
"requestId": "abc-1",
|
||||
"payload": {
|
||||
"sessionId": "BASE64_SESSION_ID",
|
||||
"sessionPwd": "BASE64_SESSION_PWD"
|
||||
}
|
||||
}
|
||||
|
||||
3. Действия сервера при RefreshSession
|
||||
1) Поиск записи в active_sessions
|
||||
SELECT * FROM active_sessions WHERE sessionId = ?
|
||||
|
||||
|
||||
Если нет — ошибка:
|
||||
|
||||
{
|
||||
"op": "RefreshSession",
|
||||
"status": 404,
|
||||
"payload": {
|
||||
"ok": false,
|
||||
"code": "SESSION_NOT_FOUND",
|
||||
"message": "Сессия не найдена"
|
||||
}
|
||||
}
|
||||
|
||||
2) Проверка поля sessionPwd
|
||||
|
||||
Сравнивается payload.sessionPwd с полем active_sessions.sessionPwd.
|
||||
|
||||
Если неверно:
|
||||
|
||||
{
|
||||
"op": "RefreshSession",
|
||||
"status": 401,
|
||||
"payload": {
|
||||
"ok": false,
|
||||
"code": "SESSION_PWD_MISMATCH",
|
||||
"message": "Неверный пароль сессии"
|
||||
}
|
||||
}
|
||||
|
||||
3) Обновление времени последней авторизации
|
||||
UPDATE active_sessions
|
||||
SET lastAuthirificatedAtMs = ?
|
||||
WHERE sessionId = ?
|
||||
|
||||
4) Возвращение клиенту актуального storagePwd
|
||||
{
|
||||
"op": "RefreshSession",
|
||||
"requestId": "abc-1",
|
||||
"status": 200,
|
||||
"payload": {
|
||||
"ok": true,
|
||||
"storagePwd": "BASE64_STORAGE_PWD"
|
||||
}
|
||||
}
|
||||
|
||||
4. Итоговая схема RefreshSession
|
||||
Client → RefreshSession(sessionId, sessionPwd)
|
||||
→ Server validates → updates lastAuth
|
||||
→ returns storagePwd
|
||||
@ -0,0 +1,40 @@
|
||||
Net_AuthChallenge_Request — запрос вызова авторизации
|
||||
Net_CreateAuthSession_Request — создание авторизационной сессии
|
||||
Net_CloseAuthSession_Request — закрытие (завершение) сессии
|
||||
Net_ListSessions_Request — получение списка активных сессий
|
||||
Net_RefreshSession_Request — обновление / продление сессии
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Net_AuthChallenge_Request — запрос вызова авторизации
|
||||
Net_CreateAuthSession_Request — создание авторизационной сессии
|
||||
|
||||
|
||||
закрытие сессии
|
||||
Net_CloseAuthSession_Request — закрытие (завершение) сессии
|
||||
елси уже авторифицирован то:
|
||||
Net_CloseAuthSession_Request с параметром номер сесии или без параметра если прям эту сесиию
|
||||
если не авторифицирован то:
|
||||
Net_AuthChallenge_Request — запрос вызова авторизации
|
||||
Net_CloseAuthSession_Request с параметром номер сесии для закрытия и время и цп для подтвержедния
|
||||
|
||||
|
||||
получение списка сессий
|
||||
|
||||
Net_AuthChallenge_Request — запрос вызова авторизации
|
||||
Net_ListSessions_Request — получение списка активных сессий
|
||||
|
||||
|
||||
Net_RefreshSession_Request — обновление / продление сессии
|
||||
|
||||
|
||||
|
||||
план что сделать
|
||||
|
||||
Додумать названия что бы было общее новое приветствие ( и поле назвать число для проверки а не пароль )
|
||||
или от него или новая сессия (и плюс в ней новый пароль передавать)
|
||||
или получить список сесссий
|
||||
или удалить сессию
|
||||
И добавить хранимую инфу по сессии
|
||||
@ -2,8 +2,8 @@ package server.logic.ws_protocol.JSON.handlers.auth;
|
||||
|
||||
import server.logic.ws_protocol.JSON.ConnectionContext;
|
||||
import server.logic.ws_protocol.JSON.entyties.*;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.NetAuthSessionNewStep1Request;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.NetAuthSessionNewStep1Response;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.Net_AuthChallenge_Request;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.Net_AuthChallenge_Response;
|
||||
import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler;
|
||||
import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory;
|
||||
import server.logic.ws_protocol.WireCodes;
|
||||
@ -13,14 +13,14 @@ import shine.db.entities.SolanaUser;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
|
||||
public class NetAuthSessionNewStep1Handler implements JsonMessageHandler {
|
||||
public class Net_AuthChallenge_Handler implements JsonMessageHandler {
|
||||
|
||||
private static final SecureRandom RANDOM = new SecureRandom();
|
||||
|
||||
@Override
|
||||
public NetResponse handle(NetRequest baseReq, ConnectionContext ctx) throws Exception {
|
||||
|
||||
NetAuthSessionNewStep1Request req = (NetAuthSessionNewStep1Request) baseReq;
|
||||
Net_AuthChallenge_Request req = (Net_AuthChallenge_Request) baseReq;
|
||||
|
||||
String login = req.getLogin();
|
||||
if (login == null || login.isBlank()) {
|
||||
@ -66,7 +66,7 @@ public class NetAuthSessionNewStep1Handler implements JsonMessageHandler {
|
||||
ctx.setSessionPwd(sessionPwd);
|
||||
|
||||
// 5) Формируем ответ
|
||||
NetAuthSessionNewStep1Response resp = new NetAuthSessionNewStep1Response();
|
||||
Net_AuthChallenge_Response resp = new Net_AuthChallenge_Response();
|
||||
resp.setOp(req.getOp());
|
||||
resp.setRequestId(req.getRequestId());
|
||||
resp.setStatus(WireCodes.Status.OK);
|
||||
@ -4,10 +4,10 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import server.logic.ws_protocol.JSON.ActiveConnectionsRegistry;
|
||||
import server.logic.ws_protocol.JSON.ConnectionContext;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.Net_CreateAuthSession_Response;
|
||||
import server.logic.ws_protocol.JSON.entyties.NetRequest;
|
||||
import server.logic.ws_protocol.JSON.entyties.NetResponse;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.NetAuthSessionNewStep2Request;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.NetAuthSessionNewStep2Response;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.Net_CreateAuthSession_Request;
|
||||
import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler;
|
||||
import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory;
|
||||
import server.logic.ws_protocol.WireCodes;
|
||||
@ -43,16 +43,16 @@ import java.util.Base64;
|
||||
* - pushEndpoint / pushP256dhKey / pushAuthKey остаются пустыми;
|
||||
* - возвращается sessionId в ответе.
|
||||
*/
|
||||
public class NetAuthSessionNewStep2Handler implements JsonMessageHandler {
|
||||
public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(NetAuthSessionNewStep2Handler.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(Net_CreateAuthSession__Handler.class);
|
||||
|
||||
private static final SecureRandom RANDOM = new SecureRandom();
|
||||
private static final long ALLOWED_SKEW_MS = 30_000L;
|
||||
|
||||
@Override
|
||||
public NetResponse handle(NetRequest baseReq, ConnectionContext ctx) throws Exception {
|
||||
NetAuthSessionNewStep2Request req = (NetAuthSessionNewStep2Request) baseReq;
|
||||
Net_CreateAuthSession_Request req = (Net_CreateAuthSession_Request) baseReq;
|
||||
|
||||
// --- базовые проверки контекста ---
|
||||
if (ctx == null || ctx.getSolanaUser() == null || ctx.getSessionPwd() == null) {
|
||||
@ -198,7 +198,7 @@ public class NetAuthSessionNewStep2Handler implements JsonMessageHandler {
|
||||
ActiveConnectionsRegistry.getInstance().register(ctx);
|
||||
|
||||
// --- формируем ответ ---
|
||||
NetAuthSessionNewStep2Response resp = new NetAuthSessionNewStep2Response();
|
||||
Net_CreateAuthSession_Response resp = new Net_CreateAuthSession_Response();
|
||||
resp.setOp(req.getOp());
|
||||
resp.setRequestId(req.getRequestId());
|
||||
resp.setStatus(WireCodes.Status.OK);
|
||||
@ -4,10 +4,10 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import server.logic.ws_protocol.JSON.ActiveConnectionsRegistry;
|
||||
import server.logic.ws_protocol.JSON.ConnectionContext;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.Net_RefreshSession_Request;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.Net_RefreshSession_Response;
|
||||
import server.logic.ws_protocol.JSON.entyties.NetRequest;
|
||||
import server.logic.ws_protocol.JSON.entyties.NetResponse;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.NetSessionRefreshRequest;
|
||||
import server.logic.ws_protocol.JSON.entyties.Auth.NetSessionRefreshResponse;
|
||||
import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler;
|
||||
import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory;
|
||||
import server.logic.ws_protocol.WireCodes;
|
||||
@ -19,7 +19,7 @@ import shine.db.entities.SolanaUser;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Хэндлер SessionRefresh.
|
||||
* Хэндлер RefreshSession.
|
||||
*
|
||||
* При успешной проверке sessionId + sessionPwd:
|
||||
* - подтягивает пользователя по loginId из сессии;
|
||||
@ -27,13 +27,13 @@ import java.sql.SQLException;
|
||||
* - обновляет lastAuthirificatedAtMs в БД на текущее время;
|
||||
* - возвращает storagePwd в payload.
|
||||
*/
|
||||
public class NetSessionRefreshHandler implements JsonMessageHandler {
|
||||
public class Net_RefreshSession_Handler implements JsonMessageHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(NetSessionRefreshHandler.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(Net_RefreshSession_Handler.class);
|
||||
|
||||
@Override
|
||||
public NetResponse handle(NetRequest request, ConnectionContext ctx) throws Exception {
|
||||
NetSessionRefreshRequest req = (NetSessionRefreshRequest) request;
|
||||
Net_RefreshSession_Request req = (Net_RefreshSession_Request) request;
|
||||
|
||||
String sessionId = req.getSessionId();
|
||||
String sessionPwd = req.getSessionPwd();
|
||||
@ -135,7 +135,7 @@ public class NetSessionRefreshHandler implements JsonMessageHandler {
|
||||
}
|
||||
|
||||
// Возвращаем OK + storagePwd
|
||||
NetSessionRefreshResponse resp = new NetSessionRefreshResponse();
|
||||
Net_RefreshSession_Response resp = new Net_RefreshSession_Response();
|
||||
resp.setOp(req.getOp());
|
||||
resp.setRequestId(req.getRequestId());
|
||||
resp.setStatus(WireCodes.Status.OK);
|
||||
@ -12,9 +12,9 @@ public class TestJsonWsClient2 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
String uri = "ws://localhost:7070/ws";
|
||||
|
||||
String jsonRequestSessionRefresh = """
|
||||
String jsonRequestRefreshSession = """
|
||||
{
|
||||
"op": "SessionRefresh",
|
||||
"op": "RefreshSession",
|
||||
"requestId": "test-1",
|
||||
"payload": {
|
||||
"sessionId": 123,
|
||||
@ -38,9 +38,9 @@ public class TestJsonWsClient2 {
|
||||
}
|
||||
""";
|
||||
|
||||
String jsonRequestAuthSessionNewStep1 = """
|
||||
String jsonRequestAuthChallenge = """
|
||||
{
|
||||
"op": "AuthSessionNewStep1",
|
||||
"op": "AuthChallenge",
|
||||
"requestId": "test-auth-1",
|
||||
"payload": {
|
||||
"login": "anya1111"
|
||||
@ -49,8 +49,8 @@ public class TestJsonWsClient2 {
|
||||
""";
|
||||
|
||||
// Что тестируем сейчас:
|
||||
String jsonRequest = jsonRequestAuthSessionNewStep1;
|
||||
// String jsonRequest = jsonRequestSessionRefresh;
|
||||
String jsonRequest = jsonRequestAuthChallenge;
|
||||
// String jsonRequest = jsonRequestRefreshSession;
|
||||
// String jsonRequest = jsonRequestAddUser;
|
||||
|
||||
System.out.println("Подключаемся к " + uri);
|
||||
|
||||
@ -20,18 +20,18 @@ import java.util.concurrent.CountDownLatch;
|
||||
* 1) AddUser — добавляем пользователя в локальную БД
|
||||
* (loginKey и deviceKey разные).
|
||||
*
|
||||
* 2) AuthSessionNewStep1 — запрашиваем sessionPwd.
|
||||
* 2) AuthChallenge — запрашиваем sessionPwd.
|
||||
*
|
||||
* 3) AuthSessionNewStep2 — подтверждаем владение deviceKey,
|
||||
* 3) CreateAuthSession — подтверждаем владение deviceKey,
|
||||
* создаётся сессия, сервер возвращает sessionId (строка).
|
||||
*
|
||||
* 4) Новое подключение:
|
||||
* - отправляем SessionRefresh с тем же sessionId,
|
||||
* - отправляем RefreshSession с тем же sessionId,
|
||||
* но заведомо неверным sessionPwd
|
||||
* (в консоль пишем: ожидаем ОТРИЦАТЕЛЬНЫЙ ответ).
|
||||
*
|
||||
* 5) Ещё одно новое подключение:
|
||||
* - отправляем SessionRefresh с sessionId
|
||||
* - отправляем RefreshSession с sessionId
|
||||
* и корректным sessionPwd
|
||||
* (в консоль пишем: ожидаем УСПЕШНЫЙ ответ).
|
||||
*/
|
||||
@ -72,13 +72,13 @@ public class Test_AddUser_and_Authorification {
|
||||
|
||||
// --- Глобальные переменные между сценариями ---
|
||||
|
||||
/** sessionPwd, выданный на шаге AuthSessionNewStep1. */
|
||||
/** sessionPwd, выданный на шаге AuthChallenge. */
|
||||
private static String GLOBAL_SESSION_PWD;
|
||||
|
||||
/** sessionId (строка, base64-32 байта), выданный на шаге AuthSessionNewStep2. */
|
||||
/** sessionId (строка, base64-32 байта), выданный на шаге CreateAuthSession. */
|
||||
private static String GLOBAL_SESSION_ID;
|
||||
|
||||
/** storagePwd, который мы отправили при AuthSessionNewStep2 (для информации). */
|
||||
/** storagePwd, который мы отправили при CreateAuthSession (для информации). */
|
||||
private static String GLOBAL_STORAGE_PWD_SENT;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -87,11 +87,11 @@ public class Test_AddUser_and_Authorification {
|
||||
// Сценарий 1: регистрация + первичная авторизация
|
||||
runScenario_AddUser_And_FirstAuth();
|
||||
|
||||
// Сценарий 2: новое подключение, SessionRefresh с неверным sessionPwd
|
||||
runScenario_SessionRefresh_WrongPwd();
|
||||
// Сценарий 2: новое подключение, RefreshSession с неверным sessionPwd
|
||||
runScenario_RefreshSession_WrongPwd();
|
||||
|
||||
// Сценарий 3: новое подключение, SessionRefresh с корректным sessionPwd
|
||||
runScenario_SessionRefresh_CorrectPwd();
|
||||
// Сценарий 3: новое подключение, RefreshSession с корректным sessionPwd
|
||||
runScenario_RefreshSession_CorrectPwd();
|
||||
|
||||
System.out.println("Все тесты завершены, выходим.");
|
||||
}
|
||||
@ -102,7 +102,7 @@ public class Test_AddUser_and_Authorification {
|
||||
|
||||
private static void runScenario_AddUser_And_FirstAuth() throws Exception {
|
||||
System.out.println();
|
||||
System.out.println("=== СЦЕНАРИЙ 1: AddUser + AuthSessionNewStep1 + AuthSessionNewStep2 ===");
|
||||
System.out.println("=== СЦЕНАРИЙ 1: AddUser + AuthChallenge + CreateAuthSession ===");
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
HttpClient client = HttpClient.newHttpClient();
|
||||
@ -132,7 +132,7 @@ public class Test_AddUser_and_Authorification {
|
||||
case 1 -> {
|
||||
String json = buildAuthStep1Json();
|
||||
System.out.println();
|
||||
System.out.println("📤 [S1 / Шаг 2] Отправляем AuthSessionNewStep1:");
|
||||
System.out.println("📤 [S1 / Шаг 2] Отправляем AuthChallenge:");
|
||||
System.out.println(json);
|
||||
webSocket.sendText(json, true);
|
||||
}
|
||||
@ -140,7 +140,7 @@ public class Test_AddUser_and_Authorification {
|
||||
GLOBAL_STORAGE_PWD_SENT = generateFakeStoragePwd();
|
||||
String json = buildAuthStep2Json(GLOBAL_SESSION_PWD, GLOBAL_STORAGE_PWD_SENT);
|
||||
System.out.println();
|
||||
System.out.println("📤 [S1 / Шаг 3] Отправляем AuthSessionNewStep2 (подпись deviceKey):");
|
||||
System.out.println("📤 [S1 / Шаг 3] Отправляем CreateAuthSession (подпись deviceKey):");
|
||||
System.out.println(json);
|
||||
webSocket.sendText(json, true);
|
||||
}
|
||||
@ -202,12 +202,12 @@ public class Test_AddUser_and_Authorification {
|
||||
}
|
||||
|
||||
// ==========================================================
|
||||
// SCENARIO 2: SessionRefresh с неправильным паролем
|
||||
// SCENARIO 2: RefreshSession с неправильным паролем
|
||||
// ==========================================================
|
||||
|
||||
private static void runScenario_SessionRefresh_WrongPwd() throws Exception {
|
||||
private static void runScenario_RefreshSession_WrongPwd() throws Exception {
|
||||
System.out.println();
|
||||
System.out.println("=== СЦЕНАРИЙ 2: SessionRefresh с НЕВЕРНЫМ sessionPwd ===");
|
||||
System.out.println("=== СЦЕНАРИЙ 2: RefreshSession с НЕВЕРНЫМ sessionPwd ===");
|
||||
System.out.println("Ожидаем ОТРИЦАТЕЛЬНЫЙ ответ сервера (UNVERIFIED / SESSION_PWD_MISMATCH и т.п.)");
|
||||
|
||||
if (GLOBAL_SESSION_ID == null || GLOBAL_SESSION_PWD == null) {
|
||||
@ -229,9 +229,9 @@ public class Test_AddUser_and_Authorification {
|
||||
System.out.println("✅ [S2] WebSocket подключен");
|
||||
webSocket.request(1);
|
||||
|
||||
String json = buildSessionRefreshJson(GLOBAL_SESSION_ID, wrongPwd, "test-refresh-wrong-1");
|
||||
String json = buildRefreshSessionJson(GLOBAL_SESSION_ID, wrongPwd, "test-refresh-wrong-1");
|
||||
System.out.println();
|
||||
System.out.println("📤 [S2] Отправляем SessionRefresh с НЕВЕРНЫМ sessionPwd:");
|
||||
System.out.println("📤 [S2] Отправляем RefreshSession с НЕВЕРНЫМ sessionPwd:");
|
||||
System.out.println(json);
|
||||
webSocket.sendText(json, true);
|
||||
Listener.super.onOpen(webSocket);
|
||||
@ -274,12 +274,12 @@ public class Test_AddUser_and_Authorification {
|
||||
}
|
||||
|
||||
// ==========================================================
|
||||
// SCENARIO 3: SessionRefresh с правильными данными
|
||||
// SCENARIO 3: RefreshSession с правильными данными
|
||||
// ==========================================================
|
||||
|
||||
private static void runScenario_SessionRefresh_CorrectPwd() throws Exception {
|
||||
private static void runScenario_RefreshSession_CorrectPwd() throws Exception {
|
||||
System.out.println();
|
||||
System.out.println("=== СЦЕНАРИЙ 3: SessionRefresh с КОРРЕКТНЫМ sessionPwd ===");
|
||||
System.out.println("=== СЦЕНАРИЙ 3: RefreshSession с КОРРЕКТНЫМ sessionPwd ===");
|
||||
System.out.println("Ожидаем УСПЕШНЫЙ ответ сервера (status=200),");
|
||||
System.out.println(" а в payload должен вернуться актуальный storagePwd (по твоей схеме).");
|
||||
|
||||
@ -299,9 +299,9 @@ public class Test_AddUser_and_Authorification {
|
||||
System.out.println("✅ [S3] WebSocket подключен");
|
||||
webSocket.request(1);
|
||||
|
||||
String json = buildSessionRefreshJson(GLOBAL_SESSION_ID, GLOBAL_SESSION_PWD, "test-refresh-ok-1");
|
||||
String json = buildRefreshSessionJson(GLOBAL_SESSION_ID, GLOBAL_SESSION_PWD, "test-refresh-ok-1");
|
||||
System.out.println();
|
||||
System.out.println("📤 [S3] Отправляем SessionRefresh с КОРРЕКТНЫМ sessionPwd:");
|
||||
System.out.println("📤 [S3] Отправляем RefreshSession с КОРРЕКТНЫМ sessionPwd:");
|
||||
System.out.println(json);
|
||||
webSocket.sendText(json, true);
|
||||
Listener.super.onOpen(webSocket);
|
||||
@ -379,7 +379,7 @@ public class Test_AddUser_and_Authorification {
|
||||
private static String buildAuthStep1Json() {
|
||||
return """
|
||||
{
|
||||
"op": "AuthSessionNewStep1",
|
||||
"op": "AuthChallenge",
|
||||
"requestId": "test-auth-1",
|
||||
"payload": {
|
||||
"login": "%s"
|
||||
@ -410,7 +410,7 @@ public class Test_AddUser_and_Authorification {
|
||||
|
||||
return """
|
||||
{
|
||||
"op": "AuthSessionNewStep2",
|
||||
"op": "CreateAuthSession",
|
||||
"requestId": "test-auth-2",
|
||||
"payload": {
|
||||
"storagePwd": "%s",
|
||||
@ -425,11 +425,11 @@ public class Test_AddUser_and_Authorification {
|
||||
);
|
||||
}
|
||||
|
||||
// 4) SessionRefresh: всё в payload
|
||||
private static String buildSessionRefreshJson(String sessionId, String sessionPwd, String requestId) {
|
||||
// 4) RefreshSession: всё в payload
|
||||
private static String buildRefreshSessionJson(String sessionId, String sessionPwd, String requestId) {
|
||||
return """
|
||||
{
|
||||
"op": "SessionRefresh",
|
||||
"op": "RefreshSession",
|
||||
"requestId": "%s",
|
||||
"payload": {
|
||||
"sessionId": "%s",
|
||||
|
||||
@ -32,13 +32,13 @@ public class Test_SessionRefreshClient {
|
||||
.join();
|
||||
|
||||
latch.await();
|
||||
System.out.println("Тест SessionRefresh завершён, выходим.");
|
||||
System.out.println("Тест RefreshSession завершён, выходим.");
|
||||
}
|
||||
|
||||
private static String buildSessionRefreshJson() {
|
||||
private static String buildRefreshSessionJson() {
|
||||
return """
|
||||
{
|
||||
"op": "SessionRefresh",
|
||||
"op": "RefreshSession",
|
||||
"requestId": "test-session-refresh-1",
|
||||
"payload": {
|
||||
"sessionId": %d,
|
||||
@ -62,10 +62,10 @@ public class Test_SessionRefreshClient {
|
||||
|
||||
webSocket.request(1); // разрешаем принимать одно сообщение
|
||||
|
||||
// сразу отправляем запрос SessionRefresh
|
||||
String json = buildSessionRefreshJson();
|
||||
// сразу отправляем запрос RefreshSession
|
||||
String json = buildRefreshSessionJson();
|
||||
System.out.println();
|
||||
System.out.println("📤 Отправляем SessionRefresh:");
|
||||
System.out.println("📤 Отправляем RefreshSession:");
|
||||
System.out.println(json);
|
||||
webSocket.sendText(json, true);
|
||||
|
||||
@ -81,7 +81,7 @@ public class Test_SessionRefreshClient {
|
||||
System.out.println("-----------------------------------------------------");
|
||||
|
||||
// После одного ответа просто закрываем соединение
|
||||
System.out.println("✅ Получен ответ на SessionRefresh, закрываем соединение");
|
||||
System.out.println("✅ Получен ответ на RefreshSession, закрываем соединение");
|
||||
webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "session refresh test done");
|
||||
|
||||
// запрашиваем следующее сообщение на всякий случай (хотя уже закрываемся)
|
||||
|
||||
5
src/main/java/Test/test1.java
Normal file
5
src/main/java/Test/test1.java
Normal file
@ -0,0 +1,5 @@
|
||||
package Test;
|
||||
|
||||
public class test1 {
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user