08 01 25
Сделал что бы при создании пользователя передавались три ключа пользователя. И имя блокчейна сделал через "-"
This commit is contained in:
parent
1ea5390771
commit
7a167b470a
@ -1,2 +1,2 @@
|
|||||||
Сделать возможность убрать свой лайк. (пока не надо а сложность что надо больше проверок) - хотя можно и без проверки, просто за двойной лайк или за снятие двойное лайка. Будет двойное проникновение :)) тому кто изменил код клиента и убрал проверку на клиенте - и блокчейн заблокируется и всё.
|
Сделать возможность убрать свой лайк. (пока не надо а сложность что надо больше проверок) - хотя можно и без проверки, просто за двойной лайк или за снятие двойное лайка. Будет двойное проникновение :)) тому кто изменил код клиента и убрал проверку на клиенте - и блокчейн заблокируется и всё.
|
||||||
поэтому просто на каждую реакцию добавиться убрать эту ракцию .
|
поэтому просто на каждую реакцию добавиться убрать эту ракцию .
|
||||||
|
|||||||
@ -1,21 +1,71 @@
|
|||||||
package utils.blockchain;
|
package utils.blockchain;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public final class BlockchainNameUtil {
|
public final class BlockchainNameUtil {
|
||||||
|
|
||||||
/** Сколько символов отрезаем с конца blockchainName, чтобы получить login. */
|
/**
|
||||||
/** Теперь новое правило везде использовать только 3 символа номера блокчена в конце его имени */
|
* Теперь новое правило:
|
||||||
public static final int BLOCKCHAIN_NAME_LOGIN_SUFFIX_LEN = 3;
|
* blockchainName = login + "-"+ 3 цифры
|
||||||
|
* Пример: "Dima-001" -> "Dima"
|
||||||
|
*
|
||||||
|
* Сколько символов отрезаем с конца blockchainName, чтобы получить login: "-001" = 4
|
||||||
|
*/
|
||||||
|
public static final int BLOCKCHAIN_NAME_LOGIN_SUFFIX_LEN = 4;
|
||||||
|
|
||||||
private BlockchainNameUtil() {}
|
private BlockchainNameUtil() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Извлечь login из blockchainName: отрезаем последние 3 символа.
|
* Извлечь login из blockchainName: отрезаем последние 4 символа ("-NNN").
|
||||||
* Пример: "Dima001" -> "Dima"
|
* Пример: "Dima-001" -> "Dima"
|
||||||
*/
|
*/
|
||||||
public static String loginFromBlockchainName(String blockchainName) {
|
public static String loginFromBlockchainName(String blockchainName) {
|
||||||
if (blockchainName == null) return null;
|
if (blockchainName == null) return null;
|
||||||
|
|
||||||
String s = blockchainName.trim();
|
String s = blockchainName.trim();
|
||||||
if (s.length() <= BLOCKCHAIN_NAME_LOGIN_SUFFIX_LEN) return null;
|
if (!hasDashAnd3DigitsSuffix(s)) return null;
|
||||||
|
|
||||||
return s.substring(0, s.length() - BLOCKCHAIN_NAME_LOGIN_SUFFIX_LEN);
|
return s.substring(0, s.length() - BLOCKCHAIN_NAME_LOGIN_SUFFIX_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Проверка правила:
|
||||||
|
* - blockchainName должен оканчиваться на "-"+3 цифры
|
||||||
|
* - blockchainName без суффикса "-NNN" должен равняться login
|
||||||
|
*
|
||||||
|
* ВАЖНО:
|
||||||
|
* - сравнение строгое (case-sensitive)
|
||||||
|
* - null/blank считаем невалидным
|
||||||
|
*/
|
||||||
|
public static boolean isBlockchainNameMatchesLogin(String blockchainName, String login) {
|
||||||
|
if (blockchainName == null || login == null) return false;
|
||||||
|
|
||||||
|
String bn = blockchainName.trim();
|
||||||
|
String lg = login.trim();
|
||||||
|
|
||||||
|
if (bn.isEmpty() || lg.isEmpty()) return false;
|
||||||
|
if (!hasDashAnd3DigitsSuffix(bn)) return false;
|
||||||
|
|
||||||
|
String extracted = bn.substring(0, bn.length() - BLOCKCHAIN_NAME_LOGIN_SUFFIX_LEN);
|
||||||
|
return Objects.equals(extracted, lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasDashAnd3DigitsSuffix(String s) {
|
||||||
|
if (s == null) return false;
|
||||||
|
int len = s.length();
|
||||||
|
if (len <= BLOCKCHAIN_NAME_LOGIN_SUFFIX_LEN) return false;
|
||||||
|
|
||||||
|
int dashPos = len - 4;
|
||||||
|
if (s.charAt(dashPos) != '-') return false;
|
||||||
|
|
||||||
|
char c1 = s.charAt(len - 3);
|
||||||
|
char c2 = s.charAt(len - 2);
|
||||||
|
char c3 = s.charAt(len - 1);
|
||||||
|
|
||||||
|
return isDigit(c1) && isDigit(c2) && isDigit(c3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isDigit(char c) {
|
||||||
|
return c >= '0' && c <= '9';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -5,9 +5,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
import server.logic.ws_protocol.JSON.ConnectionContext;
|
import server.logic.ws_protocol.JSON.ConnectionContext;
|
||||||
import server.logic.ws_protocol.JSON.entyties.Net_Request;
|
import server.logic.ws_protocol.JSON.entyties.Net_Request;
|
||||||
import server.logic.ws_protocol.JSON.entyties.Net_Response;
|
import server.logic.ws_protocol.JSON.entyties.Net_Response;
|
||||||
|
import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler;
|
||||||
import server.logic.ws_protocol.JSON.handlers.tempToTest.entyties.Net_AddUser_Request;
|
import server.logic.ws_protocol.JSON.handlers.tempToTest.entyties.Net_AddUser_Request;
|
||||||
import server.logic.ws_protocol.JSON.handlers.tempToTest.entyties.Net_AddUser_Response;
|
import server.logic.ws_protocol.JSON.handlers.tempToTest.entyties.Net_AddUser_Response;
|
||||||
import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler;
|
|
||||||
import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory;
|
import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory;
|
||||||
import server.logic.ws_protocol.WireCodes;
|
import server.logic.ws_protocol.WireCodes;
|
||||||
import shine.db.SqliteDbController;
|
import shine.db.SqliteDbController;
|
||||||
@ -15,6 +15,7 @@ import shine.db.dao.BlockchainStateDAO;
|
|||||||
import shine.db.dao.SolanaUsersDAO;
|
import shine.db.dao.SolanaUsersDAO;
|
||||||
import shine.db.entities.BlockchainStateEntry;
|
import shine.db.entities.BlockchainStateEntry;
|
||||||
import shine.db.entities.SolanaUserEntry;
|
import shine.db.entities.SolanaUserEntry;
|
||||||
|
import utils.blockchain.BlockchainNameUtil;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@ -34,13 +35,24 @@ public class Net_AddUser_Handler implements JsonMessageHandler {
|
|||||||
if (req.getLogin() == null || req.getLogin().isBlank()
|
if (req.getLogin() == null || req.getLogin().isBlank()
|
||||||
|| req.getBlockchainName() == null || req.getBlockchainName().isBlank()
|
|| req.getBlockchainName() == null || req.getBlockchainName().isBlank()
|
||||||
|| req.getSolanaKey() == null || req.getSolanaKey().isBlank()
|
|| req.getSolanaKey() == null || req.getSolanaKey().isBlank()
|
||||||
|
|| req.getBlockchainKey() == null || req.getBlockchainKey().isBlank()
|
||||||
|| req.getDeviceKey() == null || req.getDeviceKey().isBlank()) {
|
|| req.getDeviceKey() == null || req.getDeviceKey().isBlank()) {
|
||||||
|
|
||||||
return NetExceptionResponseFactory.error(
|
return NetExceptionResponseFactory.error(
|
||||||
req,
|
req,
|
||||||
WireCodes.Status.BAD_REQUEST,
|
WireCodes.Status.BAD_REQUEST,
|
||||||
"BAD_FIELDS",
|
"BAD_FIELDS",
|
||||||
"Некорректные поля: login/blockchainName/solanaKey/deviceKey"
|
"Некорректные поля: login/blockchainName/solanaKey/blockchainKey/deviceKey"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// blockchainName должен быть вида: <login>-NNN
|
||||||
|
if (!BlockchainNameUtil.isBlockchainNameMatchesLogin(req.getBlockchainName(), req.getLogin())) {
|
||||||
|
return NetExceptionResponseFactory.error(
|
||||||
|
req,
|
||||||
|
WireCodes.Status.BAD_REQUEST,
|
||||||
|
"BAD_BLOCKCHAIN_NAME",
|
||||||
|
"blockchainName должен быть вида <login>-NNN (пример: anya-001)"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,13 +61,13 @@ public class Net_AddUser_Handler implements JsonMessageHandler {
|
|||||||
: req.getBchLimit();
|
: req.getBchLimit();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
byte[] blockchainKey32 = Base64.getDecoder().decode(req.getSolanaKey());
|
byte[] blockchainKey32 = Base64.getDecoder().decode(req.getBlockchainKey());
|
||||||
if (blockchainKey32.length != 32) {
|
if (blockchainKey32.length != 32) {
|
||||||
return NetExceptionResponseFactory.error(
|
return NetExceptionResponseFactory.error(
|
||||||
req,
|
req,
|
||||||
WireCodes.Status.BAD_REQUEST,
|
WireCodes.Status.BAD_REQUEST,
|
||||||
"BAD_BLOCKCHAIN_KEY",
|
"BAD_BLOCKCHAIN_KEY",
|
||||||
"solanaKey должен быть Base64(32 bytes)"
|
"blockchainKey должен быть Base64(32 bytes)"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,20 +99,20 @@ public class Net_AddUser_Handler implements JsonMessageHandler {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Создаём пользователя
|
// 3. Создаём пользователя (solanaKey + deviceKey)
|
||||||
SolanaUserEntry user = new SolanaUserEntry(
|
SolanaUserEntry user = new SolanaUserEntry(
|
||||||
req.getLogin(),
|
req.getLogin(),
|
||||||
req.getDeviceKey(),
|
req.getSolanaKey(),
|
||||||
req.getDeviceKey()
|
req.getDeviceKey()
|
||||||
);
|
);
|
||||||
|
|
||||||
usersDAO.insert(c, user);
|
usersDAO.insert(c, user);
|
||||||
|
|
||||||
// 4. Создаём INITIAL blockchain_state
|
// 4. Создаём INITIAL blockchain_state (blockchainKey)
|
||||||
BlockchainStateEntry st = new BlockchainStateEntry();
|
BlockchainStateEntry st = new BlockchainStateEntry();
|
||||||
st.setBlockchainName(req.getBlockchainName());
|
st.setBlockchainName(req.getBlockchainName());
|
||||||
st.setLogin(req.getLogin());
|
st.setLogin(req.getLogin());
|
||||||
st.setBlockchainKey(req.getSolanaKey()); // Base64(32)
|
st.setBlockchainKey(req.getBlockchainKey()); // Base64(32)
|
||||||
st.setLastGlobalNumber(-1);
|
st.setLastGlobalNumber(-1);
|
||||||
st.setLastGlobalHash(new byte[32]);
|
st.setLastGlobalHash(new byte[32]);
|
||||||
st.setFileSizeBytes(0);
|
st.setFileSizeBytes(0);
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import server.logic.ws_protocol.JSON.entyties.Net_Request;
|
|||||||
* "login": "anya",
|
* "login": "anya",
|
||||||
* "blockchainName": "anya0001",
|
* "blockchainName": "anya0001",
|
||||||
* "solanaKey": "base64-ed25519-public-key-login",
|
* "solanaKey": "base64-ed25519-public-key-login",
|
||||||
|
* "blockchainKey": "base64-ed25519-public-key-blockchain",
|
||||||
* "deviceKey": "base64-ed25519-public-key-device",
|
* "deviceKey": "base64-ed25519-public-key-device",
|
||||||
* "bchLimit": 1000000
|
* "bchLimit": 1000000
|
||||||
* }
|
* }
|
||||||
@ -25,8 +26,16 @@ public class Net_AddUser_Request extends Net_Request {
|
|||||||
|
|
||||||
private String login;
|
private String login;
|
||||||
private String blockchainName;
|
private String blockchainName;
|
||||||
|
|
||||||
|
/** Ключ пользователя Solana (публичный ключ логина) */
|
||||||
private String solanaKey;
|
private String solanaKey;
|
||||||
|
|
||||||
|
/** Ключ блокчейна (публичный ключ блокчейна) */
|
||||||
|
private String blockchainKey;
|
||||||
|
|
||||||
|
/** Ключ устройства (публичный ключ устройства) */
|
||||||
private String deviceKey;
|
private String deviceKey;
|
||||||
|
|
||||||
private Integer bchLimit;
|
private Integer bchLimit;
|
||||||
|
|
||||||
public String getLogin() { return login; }
|
public String getLogin() { return login; }
|
||||||
@ -38,6 +47,9 @@ public class Net_AddUser_Request extends Net_Request {
|
|||||||
public String getSolanaKey() { return solanaKey; }
|
public String getSolanaKey() { return solanaKey; }
|
||||||
public void setSolanaKey(String solanaKey) { this.solanaKey = solanaKey; }
|
public void setSolanaKey(String solanaKey) { this.solanaKey = solanaKey; }
|
||||||
|
|
||||||
|
public String getBlockchainKey() { return blockchainKey; }
|
||||||
|
public void setBlockchainKey(String blockchainKey) { this.blockchainKey = blockchainKey; }
|
||||||
|
|
||||||
public String getDeviceKey() { return deviceKey; }
|
public String getDeviceKey() { return deviceKey; }
|
||||||
public void setDeviceKey(String deviceKey) { this.deviceKey = deviceKey; }
|
public void setDeviceKey(String deviceKey) { this.deviceKey = deviceKey; }
|
||||||
|
|
||||||
|
|||||||
@ -17,4 +17,4 @@ import server.logic.ws_protocol.JSON.entyties.Net_Response;
|
|||||||
*/
|
*/
|
||||||
public class Net_AddUser_Response extends Net_Response {
|
public class Net_AddUser_Response extends Net_Response {
|
||||||
// При необходимости сюда можно добавить, например, флаг created/updated и т.п.
|
// При необходимости сюда можно добавить, например, флаг created/updated и т.п.
|
||||||
}
|
}
|
||||||
@ -10,7 +10,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
* TestConfig — конфиг IT тестов:
|
* TestConfig — конфиг IT тестов:
|
||||||
* - 3 пользователя (TestUser1/2/3)
|
* - 3 пользователя (TestUser1/2/3)
|
||||||
* - ключи по login через map (device/solana/blockchain)
|
* - ключи по login через map (device/solana/blockchain)
|
||||||
* - blockchainName = login + "001"
|
* - blockchainName = login + "-" + "001"
|
||||||
*
|
*
|
||||||
* Важно:
|
* Важно:
|
||||||
* - privateKey = Ed25519Util.generatePrivateKeyFromString(login) (sha256, 32 bytes)
|
* - privateKey = Ed25519Util.generatePrivateKeyFromString(login) (sha256, 32 bytes)
|
||||||
@ -45,7 +45,7 @@ public final class TestConfig {
|
|||||||
|
|
||||||
public static String getBlockchainName(String login) {
|
public static String getBlockchainName(String login) {
|
||||||
if (login == null) throw new IllegalArgumentException("login is null");
|
if (login == null) throw new IllegalArgumentException("login is null");
|
||||||
return login + BCH_SUFFIX_3();
|
return login + "-" + BCH_SUFFIX_3();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============ key maps ============
|
// ============ key maps ============
|
||||||
@ -92,6 +92,7 @@ public final class TestConfig {
|
|||||||
|
|
||||||
// ============ base64 helpers ============
|
// ============ base64 helpers ============
|
||||||
public static String devicePublicKeyB64(String login) { return Base64.getEncoder().encodeToString(getDevicePublicKey(login)); }
|
public static String devicePublicKeyB64(String login) { return Base64.getEncoder().encodeToString(getDevicePublicKey(login)); }
|
||||||
|
public static String solanaPublicKeyB64(String login) { return Base64.getEncoder().encodeToString(getSolanaPublicKey(login)); }
|
||||||
public static String blockchainPublicKeyB64(String login) { return Base64.getEncoder().encodeToString(getBlockchainPublicKey(login)); }
|
public static String blockchainPublicKeyB64(String login) { return Base64.getEncoder().encodeToString(getBlockchainPublicKey(login)); }
|
||||||
|
|
||||||
// ============ backward-compatible helpers for "user1" ============
|
// ============ backward-compatible helpers for "user1" ============
|
||||||
@ -99,10 +100,15 @@ public final class TestConfig {
|
|||||||
public static String BCH_NAME2() { return getBlockchainName(LOGIN2()); }
|
public static String BCH_NAME2() { return getBlockchainName(LOGIN2()); }
|
||||||
public static String BCH_NAME3() { return getBlockchainName(LOGIN3()); }
|
public static String BCH_NAME3() { return getBlockchainName(LOGIN3()); }
|
||||||
|
|
||||||
/** solanaKey для AddUser: по твоему решению = blockchain pubkey. */
|
/** solanaKey для AddUser: публичный ключ Solana-пользователя */
|
||||||
public static String LOGIN_PUBKEY_B64() { return blockchainPublicKeyB64(LOGIN()); }
|
public static String SOLANA_PUBKEY_B64() { return solanaPublicKeyB64(LOGIN()); }
|
||||||
public static String LOGIN2_PUBKEY_B64() { return blockchainPublicKeyB64(LOGIN2()); }
|
public static String SOLANA2_PUBKEY_B64() { return solanaPublicKeyB64(LOGIN2()); }
|
||||||
public static String LOGIN3_PUBKEY_B64() { return blockchainPublicKeyB64(LOGIN3()); }
|
public static String SOLANA3_PUBKEY_B64() { return solanaPublicKeyB64(LOGIN3()); }
|
||||||
|
|
||||||
|
/** blockchainKey для AddUser: публичный ключ блокчейна */
|
||||||
|
public static String BLOCKCHAIN_PUBKEY_B64() { return blockchainPublicKeyB64(LOGIN()); }
|
||||||
|
public static String BLOCKCHAIN2_PUBKEY_B64() { return blockchainPublicKeyB64(LOGIN2()); }
|
||||||
|
public static String BLOCKCHAIN3_PUBKEY_B64() { return blockchainPublicKeyB64(LOGIN3()); }
|
||||||
|
|
||||||
public static String DEVICE_PUBKEY_B64() { return devicePublicKeyB64(LOGIN()); }
|
public static String DEVICE_PUBKEY_B64() { return devicePublicKeyB64(LOGIN()); }
|
||||||
public static String DEVICE2_PUBKEY_B64() { return devicePublicKeyB64(LOGIN2()); }
|
public static String DEVICE2_PUBKEY_B64() { return devicePublicKeyB64(LOGIN2()); }
|
||||||
|
|||||||
@ -16,8 +16,11 @@ public final class JsonBuilders {
|
|||||||
public static String addUser(String login) {
|
public static String addUser(String login) {
|
||||||
String requestId = TestIds.next("adduser");
|
String requestId = TestIds.next("adduser");
|
||||||
String blockchainName = TestConfig.getBlockchainName(login);
|
String blockchainName = TestConfig.getBlockchainName(login);
|
||||||
String solanaKeyB64 = TestConfig.blockchainPublicKeyB64(login); // solanaKey = blockchain pub
|
|
||||||
|
String solanaKeyB64 = TestConfig.solanaPublicKeyB64(login);
|
||||||
|
String blockchainKeyB64 = TestConfig.blockchainPublicKeyB64(login);
|
||||||
String deviceKeyB64 = TestConfig.devicePublicKeyB64(login);
|
String deviceKeyB64 = TestConfig.devicePublicKeyB64(login);
|
||||||
|
|
||||||
return """
|
return """
|
||||||
{
|
{
|
||||||
"op": "AddUser",
|
"op": "AddUser",
|
||||||
@ -26,11 +29,20 @@ public final class JsonBuilders {
|
|||||||
"login": "%s",
|
"login": "%s",
|
||||||
"blockchainName": "%s",
|
"blockchainName": "%s",
|
||||||
"solanaKey": "%s",
|
"solanaKey": "%s",
|
||||||
|
"blockchainKey": "%s",
|
||||||
"deviceKey": "%s",
|
"deviceKey": "%s",
|
||||||
"bchLimit": %d
|
"bchLimit": %d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""".formatted(requestId, login, blockchainName, solanaKeyB64, deviceKeyB64, TestConfig.TEST_BCH_LIMIT);
|
""".formatted(
|
||||||
|
requestId,
|
||||||
|
login,
|
||||||
|
blockchainName,
|
||||||
|
solanaKeyB64,
|
||||||
|
blockchainKeyB64,
|
||||||
|
deviceKeyB64,
|
||||||
|
TestConfig.TEST_BCH_LIMIT
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------- AuthChallenge ----------------
|
// ---------------- AuthChallenge ----------------
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user