XNSim/Login/login.cpp

802 lines
24 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Login_global.h"
#include <string>
#include <memory>
#include <chrono>
#include <filesystem>
#include <sqlite3.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <nlohmann/json.hpp>
#include <cstring>
#include <stdexcept>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <vector>
#include <algorithm>
#include <openssl/rand.h>
using json = nlohmann::json;
namespace fs = std::filesystem;
std::string generateSalt(const std::string &username)
{
// 使用用户名生成盐值
return username + "XNSim_Salt_Key";
}
std::string encryptPassword(const std::string &password, const std::string &salt)
{
// 将密码和盐值组合
std::string saltedPassword = password;
if (!salt.empty()) {
saltedPassword += salt;
}
// 使用SHA-256算法对加盐密码进行加密
unsigned char hash[SHA256_DIGEST_LENGTH];
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
EVP_DigestUpdate(ctx, saltedPassword.c_str(), saltedPassword.length());
EVP_DigestFinal_ex(ctx, hash, NULL);
EVP_MD_CTX_free(ctx);
// 转换为十六进制字符串
std::stringstream ss;
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(hash[i]);
}
return ss.str();
}
// Base64编码函数
std::string base64_encode(const unsigned char *data, size_t length)
{
const char *base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string ret;
ret.reserve(((length + 2) / 3) * 4);
for (size_t i = 0; i < length; i += 3) {
unsigned char octet_a = i < length ? data[i] : 0;
unsigned char octet_b = i + 1 < length ? data[i + 1] : 0;
unsigned char octet_c = i + 2 < length ? data[i + 2] : 0;
unsigned char triple = (octet_a << 16) + (octet_b << 8) + octet_c;
ret.push_back(base64_chars[(triple >> 18) & 0x3F]);
ret.push_back(base64_chars[(triple >> 12) & 0x3F]);
ret.push_back(base64_chars[(triple >> 6) & 0x3F]);
ret.push_back(base64_chars[triple & 0x3F]);
}
// 添加填充
switch (length % 3) {
case 1:
ret[ret.size() - 2] = '=';
ret[ret.size() - 1] = '=';
break;
case 2:
ret[ret.size() - 1] = '=';
break;
}
return ret;
}
// 利用用户名和固定密钥派生32字节AES密钥
std::vector<unsigned char> derive_aes_key(const std::string &username, const std::string &fixed_key)
{
unsigned char hash[SHA256_DIGEST_LENGTH];
std::string key_material = username + fixed_key;
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
EVP_DigestUpdate(ctx, key_material.c_str(), key_material.length());
EVP_DigestFinal_ex(ctx, hash, NULL);
EVP_MD_CTX_free(ctx);
return std::vector<unsigned char>(hash, hash + SHA256_DIGEST_LENGTH);
}
// AES-256-CBC加密
std::vector<unsigned char> aes_encrypt(const std::string &plaintext,
const std::vector<unsigned char> &key,
std::vector<unsigned char> &iv_out)
{
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if (!ctx)
throw std::runtime_error("EVP_CIPHER_CTX_new failed");
iv_out.resize(16);
if (!RAND_bytes(iv_out.data(), iv_out.size())) {
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("RAND_bytes failed");
}
if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key.data(), iv_out.data()))
throw std::runtime_error("EVP_EncryptInit_ex failed");
std::vector<unsigned char> ciphertext(plaintext.size() + 16);
int len = 0, ciphertext_len = 0;
if (1
!= EVP_EncryptUpdate(ctx, ciphertext.data(), &len,
reinterpret_cast<const unsigned char *>(plaintext.c_str()),
plaintext.size()))
throw std::runtime_error("EVP_EncryptUpdate failed");
ciphertext_len = len;
if (1 != EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len))
throw std::runtime_error("EVP_EncryptFinal_ex failed");
ciphertext_len += len;
ciphertext.resize(ciphertext_len);
EVP_CIPHER_CTX_free(ctx);
return ciphertext;
}
// AES-256-CBC解密
std::string aes_decrypt(const std::vector<unsigned char> &ciphertext,
const std::vector<unsigned char> &key, const std::vector<unsigned char> &iv)
{
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if (!ctx)
throw std::runtime_error("EVP_CIPHER_CTX_new failed");
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key.data(), iv.data()))
throw std::runtime_error("EVP_DecryptInit_ex failed");
std::vector<unsigned char> plaintext(ciphertext.size());
int len = 0, plaintext_len = 0;
if (1 != EVP_DecryptUpdate(ctx, plaintext.data(), &len, ciphertext.data(), ciphertext.size()))
throw std::runtime_error("EVP_DecryptUpdate failed");
plaintext_len = len;
if (1 != EVP_DecryptFinal_ex(ctx, plaintext.data() + len, &len))
throw std::runtime_error("EVP_DecryptFinal_ex failed");
plaintext_len += len;
plaintext.resize(plaintext_len);
EVP_CIPHER_CTX_free(ctx);
return std::string(plaintext.begin(), plaintext.end());
}
// 二进制转16进制字符串
std::string bin2hex(const std::vector<unsigned char> &data)
{
std::ostringstream oss;
for (auto c : data) {
oss << std::hex << std::setw(2) << std::setfill('0') << (int)c;
}
return oss.str();
}
// 16进制字符串转二进制
std::vector<unsigned char> hex2bin(const std::string &hex)
{
std::vector<unsigned char> out;
for (size_t i = 0; i + 1 < hex.length(); i += 2) {
std::string byteString = hex.substr(i, 2);
unsigned char byte = (unsigned char)strtol(byteString.c_str(), nullptr, 16);
out.push_back(byte);
}
return out;
}
extern "C" LOGIN_EXPORT int validateUser(const char *username_buffer, size_t username_length,
const char *password_buffer, size_t password_length)
{
try {
std::string username_str(username_buffer, username_length);
std::string password_str(password_buffer, password_length);
if (username_str.empty() || password_str.empty()) {
return -1;
}
std::string salt = generateSalt(username_str);
std::string encryptedPassword = encryptPassword(password_str, salt);
// 获取环境变量
const char *xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
return -1;
}
fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db";
sqlite3 *db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
return -1;
}
int userId = -1;
sqlite3_stmt *stmt;
const char *queryStr = "SELECT * FROM users WHERE username = ? AND password = ?";
if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, username_str.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, encryptedPassword.c_str(), -1, SQLITE_STATIC);
if (sqlite3_step(stmt) == SQLITE_ROW) {
userId = sqlite3_column_int(stmt, 0);
}
sqlite3_finalize(stmt);
}
sqlite3_close(db);
return userId;
} catch (const std::exception &) {
return -1;
}
}
extern "C" LOGIN_EXPORT int getUserInfo(int user_id, char *result, int result_length)
{
try {
const char *xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
std::cout << "xnCorePath is null" << std::endl;
return -1;
}
fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db";
sqlite3 *db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
std::cout << "sqlite3_open failed" << std::endl;
return -1;
}
sqlite3_stmt *stmt;
const char *queryStr = "SELECT * FROM users WHERE id = ?";
if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_int(stmt, 1, user_id);
if (sqlite3_step(stmt) == SQLITE_ROW) {
json userInfo;
userInfo["id"] = sqlite3_column_int(stmt, 0);
userInfo["username"] = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
// access_level 解密
std::string accessLevelEnc =
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 3));
std::vector<unsigned char> iv_and_ciphertext = hex2bin(accessLevelEnc);
if (iv_and_ciphertext.size() < 16) {
userInfo["access_level"] = nullptr;
} else {
std::vector<unsigned char> iv(iv_and_ciphertext.begin(),
iv_and_ciphertext.begin() + 16);
std::vector<unsigned char> ciphertext(iv_and_ciphertext.begin() + 16,
iv_and_ciphertext.end());
std::string fixed_key = "XNSim_Access_Key";
std::string username = userInfo["username"].get<std::string>();
std::vector<unsigned char> key = derive_aes_key(username, fixed_key);
try {
std::string accessLevelStr = aes_decrypt(ciphertext, key, iv);
userInfo["access_level"] = std::stoi(accessLevelStr);
} catch (...) {
userInfo["access_level"] = nullptr;
}
}
userInfo["full_name"] =
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 4));
userInfo["phone"] = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 5));
userInfo["email"] = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 6));
userInfo["department"] =
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 7));
userInfo["position"] = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 8));
// 处理二进制数据
const void *blob_data = sqlite3_column_blob(stmt, 9);
int blob_size = sqlite3_column_bytes(stmt, 9);
if (blob_data && blob_size > 0) {
userInfo["icon"] =
base64_encode(static_cast<const unsigned char *>(blob_data), blob_size);
} else {
userInfo["icon"] = nullptr; // 使用null值代替空字符串
}
std::string jsonData = userInfo.dump();
if (result_length >= jsonData.size() + 1) {
std::strcpy(result, jsonData.c_str());
return 0;
} else {
std::cout << "result_length: " << result_length << std::endl;
return -1;
}
}
sqlite3_finalize(stmt);
}
sqlite3_close(db);
return 0;
} catch (const std::exception &) {
std::cout << "getUserInfo failed" << std::endl;
return -1;
}
}
extern "C" LOGIN_EXPORT void freeUserInfo(const char *ptr)
{
if (ptr) {
delete[] ptr;
}
}
extern "C" LOGIN_EXPORT void cleanup()
{
}
// 检查用户名是否已存在
int checkUsernameExists(const void *username_buffer, size_t username_length)
{
try {
const char *username_data = static_cast<const char *>(username_buffer);
std::string username_str(username_data, username_length);
if (username_str.empty()) {
return -1;
}
const char *xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
return -1;
}
fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db";
std::string connectionName =
"usercheck_"
+ std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count());
int result = -1;
{
sqlite3 *db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
return -1;
}
sqlite3_stmt *stmt;
const char *queryStr = "SELECT COUNT(*) FROM users WHERE username = ?";
if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, username_str.c_str(), -1, SQLITE_STATIC);
if (sqlite3_step(stmt) == SQLITE_ROW) {
result = sqlite3_column_int(stmt, 0) > 0 ? 1 : 0;
}
sqlite3_finalize(stmt);
}
sqlite3_close(db);
}
return result;
} catch (const std::exception &) {
return -1;
}
}
// 注册新用户
extern "C" LOGIN_EXPORT int registerUser(const char *username_buffer, int username_length,
const char *password_buffer, int password_length,
const char *userinfo_buffer, int userinfo_length)
{
try {
// 转换输入参数
std::string username_str(username_buffer, username_length);
std::string password_str(password_buffer, password_length);
std::string userinfo_str(userinfo_buffer, userinfo_length);
// 验证用户名和密码非空
if (username_str.empty()) {
return -4; // 用户名为空
}
if (password_str.empty()) {
return -5; // 密码为空
}
// 检查用户名是否已存在
if (checkUsernameExists(username_buffer, username_length) != 0) {
return -2; // 用户名已存在
}
// 解析用户信息JSON
json userInfo;
try {
userInfo = json::parse(userinfo_str);
} catch (const json::parse_error &) {
return -3; // Invalid user info format
}
// 验证权限级别
int accessLevel = 0;
if (userInfo.contains("access_level")) {
accessLevel = userInfo["access_level"].get<int>();
}
// access_level 加密
std::string fixed_key = "XNSim_Access_Key";
std::vector<unsigned char> key = derive_aes_key(username_str, fixed_key);
std::vector<unsigned char> iv;
std::vector<unsigned char> ciphertext = aes_encrypt(std::to_string(accessLevel), key, iv);
std::vector<unsigned char> iv_and_ciphertext = iv;
iv_and_ciphertext.insert(iv_and_ciphertext.end(), ciphertext.begin(), ciphertext.end());
std::string accessLevelEnc = bin2hex(iv_and_ciphertext);
// 生成加密密码
std::string salt = generateSalt(username_str);
std::string encryptedPassword = encryptPassword(password_str, salt);
// 连接数据库
const char *xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
return -1;
}
fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db";
std::string connectionName =
"userreg_"
+ std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count());
int newUserId = -1;
{
sqlite3 *db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
return -1;
}
sqlite3_stmt *stmt;
const char *queryStr =
"INSERT INTO users (username, password, access_level, full_name, phone, "
"email, department, position) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, username_str.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, encryptedPassword.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 3, accessLevelEnc.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 4, userInfo["full_name"].get<std::string>().c_str(), -1,
SQLITE_STATIC);
sqlite3_bind_text(stmt, 5, userInfo["phone"].get<std::string>().c_str(), -1,
SQLITE_STATIC);
sqlite3_bind_text(stmt, 6, userInfo["email"].get<std::string>().c_str(), -1,
SQLITE_STATIC);
sqlite3_bind_text(stmt, 7, userInfo["department"].get<std::string>().c_str(), -1,
SQLITE_STATIC);
sqlite3_bind_text(stmt, 8, userInfo["position"].get<std::string>().c_str(), -1,
SQLITE_STATIC);
if (sqlite3_step(stmt) == SQLITE_DONE) {
newUserId = sqlite3_last_insert_rowid(db);
}
sqlite3_finalize(stmt);
}
sqlite3_close(db);
}
return newUserId;
} catch (const std::exception &) {
return -1;
}
}
// 修改密码
extern "C" LOGIN_EXPORT int changePassword(int user_id, const char *old_password_buffer,
int old_password_length, const char *new_password_buffer,
int new_password_length)
{
try {
std::string old_password_str(old_password_buffer, old_password_length);
std::string new_password_str(new_password_buffer, new_password_length);
if (old_password_str.empty() || new_password_str.empty()) {
return -1;
}
const char *xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
return -1;
}
fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db";
std::string connectionName =
"changepwd_"
+ std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count());
{
sqlite3 *db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
return -1;
}
// 首先验证旧密码
sqlite3_stmt *stmt;
const char *queryStr = "SELECT username, password FROM users WHERE id = ?";
if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_int(stmt, 1, user_id);
if (sqlite3_step(stmt) == SQLITE_ROW) {
std::string username =
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
std::string storedPassword =
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
// 验证旧密码
std::string salt = generateSalt(username);
std::string encryptedOldPassword = encryptPassword(old_password_str, salt);
if (encryptedOldPassword != storedPassword) {
sqlite3_finalize(stmt);
sqlite3_close(db);
return -3; // 旧密码错误
}
// 生成新的加密密码
std::string encryptedNewPassword = encryptPassword(new_password_str, salt);
// 更新密码
sqlite3_finalize(stmt);
stmt = nullptr;
queryStr = "UPDATE users SET password = ? WHERE id = ?";
if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, encryptedNewPassword.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_int(stmt, 2, user_id);
if (sqlite3_step(stmt) == SQLITE_DONE) {
sqlite3_finalize(stmt);
sqlite3_close(db);
return 1; // 密码修改成功
}
sqlite3_finalize(stmt);
}
}
}
sqlite3_close(db);
}
return -1; // Default error return
} catch (const std::exception &) {
return -1;
}
}
// 更新用户信息
extern "C" LOGIN_EXPORT int updateUserInfo(int user_id, const char *userinfo_buffer,
int userinfo_length)
{
try {
std::string userinfo_str(userinfo_buffer, userinfo_length);
// 解析用户信息JSON
json userInfo;
try {
userInfo = json::parse(userinfo_str);
} catch (const json::parse_error &) {
return -1; // Invalid user info format
}
// 连接数据库
const char *xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
return -1;
}
fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db";
std::string connectionName =
"userupdate_"
+ std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count());
int result = -1;
{
sqlite3 *db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
return -1;
}
// 首先检查用户是否存在
sqlite3_stmt *stmt;
const char *checkQueryStr = "SELECT id FROM users WHERE id = ?";
if (sqlite3_prepare_v2(db, checkQueryStr, -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_int(stmt, 1, user_id);
if (sqlite3_step(stmt) == SQLITE_ROW) {
sqlite3_finalize(stmt);
sqlite3_close(db);
return -2; // 用户不存在
}
sqlite3_finalize(stmt);
}
stmt = nullptr;
const char *queryStr =
"UPDATE users SET full_name = ?, phone = ?, email = ?, department = ?, "
"position = ? "
"WHERE id = ?";
if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, userInfo["full_name"].get<std::string>().c_str(), -1,
SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, userInfo["phone"].get<std::string>().c_str(), -1,
SQLITE_STATIC);
sqlite3_bind_text(stmt, 3, userInfo["email"].get<std::string>().c_str(), -1,
SQLITE_STATIC);
sqlite3_bind_text(stmt, 4, userInfo["department"].get<std::string>().c_str(), -1,
SQLITE_STATIC);
sqlite3_bind_text(stmt, 5, userInfo["position"].get<std::string>().c_str(), -1,
SQLITE_STATIC);
sqlite3_bind_int(stmt, 6, user_id);
if (sqlite3_step(stmt) == SQLITE_DONE) {
result = 1; // 更新成功
}
sqlite3_finalize(stmt);
}
sqlite3_close(db);
}
return result;
} catch (const std::exception &) {
return -1;
}
}
// 更新用户权限级别
extern "C" LOGIN_EXPORT int updateUserAccessLevel(int user_id, int access_level)
{
try {
// 验证权限级别
if (access_level < 0 || access_level >= 3) {
return -3; // 无效的权限级别
}
// 连接数据库
const char *xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
return -1;
}
fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db";
std::string connectionName =
"useraccess_"
+ std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count());
int result = -1;
{
sqlite3 *db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
return -1;
}
// 首先检查用户是否存在
sqlite3_stmt *stmt;
const char *checkQueryStr = "SELECT id FROM users WHERE id = ?";
if (sqlite3_prepare_v2(db, checkQueryStr, -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_int(stmt, 1, user_id);
if (sqlite3_step(stmt) == SQLITE_ROW) {
sqlite3_finalize(stmt);
sqlite3_close(db);
return -2; // 用户不存在
}
sqlite3_finalize(stmt);
}
stmt = nullptr;
const char *queryStr = "UPDATE users SET access_level = ? WHERE id = ?";
if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) {
// 需要查用户名
std::string username;
{
sqlite3_stmt *stmt2;
const char *q2 = "SELECT username FROM users WHERE id = ?";
if (sqlite3_prepare_v2(db, q2, -1, &stmt2, nullptr) == SQLITE_OK) {
sqlite3_bind_int(stmt2, 1, user_id);
if (sqlite3_step(stmt2) == SQLITE_ROW) {
username =
reinterpret_cast<const char *>(sqlite3_column_text(stmt2, 0));
}
sqlite3_finalize(stmt2);
}
}
std::string fixed_key = "XNSim_Access_Key";
std::vector<unsigned char> key = derive_aes_key(username, fixed_key);
std::vector<unsigned char> iv;
std::vector<unsigned char> ciphertext =
aes_encrypt(std::to_string(access_level), key, iv);
std::vector<unsigned char> iv_and_ciphertext = iv;
iv_and_ciphertext.insert(iv_and_ciphertext.end(), ciphertext.begin(),
ciphertext.end());
std::string accessLevelEnc = bin2hex(iv_and_ciphertext);
sqlite3_bind_text(stmt, 1, accessLevelEnc.c_str(), -1, SQLITE_STATIC);
sqlite3_bind_int(stmt, 2, user_id);
if (sqlite3_step(stmt) == SQLITE_DONE) {
result = 1; // 更新成功
}
sqlite3_finalize(stmt);
}
sqlite3_close(db);
}
return result;
} catch (const std::exception &) {
return -1;
}
}
// 获取所有用户的username、full_name和access_level返回JSON数组字符串
extern "C" LOGIN_EXPORT int getAllUsersSimpleInfo(char *result, int result_length)
{
try {
const char *xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
return -1;
}
fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db";
sqlite3 *db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
return -1;
}
const char *queryStr = "SELECT username, full_name, access_level FROM users";
sqlite3_stmt *stmt;
json arr = json::array();
if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) {
while (sqlite3_step(stmt) == SQLITE_ROW) {
json userInfo;
std::string username = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0));
userInfo["username"] = username;
userInfo["full_name"] =
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
// access_level 解密
std::string accessLevelEnc =
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 2));
std::vector<unsigned char> iv_and_ciphertext = hex2bin(accessLevelEnc);
if (iv_and_ciphertext.size() < 16) {
userInfo["access_level"] = nullptr;
} else {
std::vector<unsigned char> iv(iv_and_ciphertext.begin(),
iv_and_ciphertext.begin() + 16);
std::vector<unsigned char> ciphertext(iv_and_ciphertext.begin() + 16,
iv_and_ciphertext.end());
std::string fixed_key = "XNSim_Access_Key";
std::vector<unsigned char> key = derive_aes_key(username, fixed_key);
try {
std::string accessLevelStr = aes_decrypt(ciphertext, key, iv);
userInfo["access_level"] = std::stoi(accessLevelStr);
} catch (...) {
userInfo["access_level"] = nullptr;
}
}
arr.push_back(userInfo);
}
sqlite3_finalize(stmt);
}
sqlite3_close(db);
std::string jsonStr = arr.dump();
if (result_length >= jsonStr.size() + 1) {
std::strcpy(result, jsonStr.c_str());
return 0;
} else {
return -1;
}
} catch (const std::exception &) {
return -1;
}
}