XNSim/Login/login.cpp

1023 lines
30 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>
#include <openssl/bio.h>
#include <openssl/buffer.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)
{
BIO *bio, *b64;
BUF_MEM *bufferPtr;
b64 = BIO_new(BIO_f_base64());
bio = BIO_new(BIO_s_mem());
bio = BIO_push(b64, bio);
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); // 不添加换行符
BIO_write(bio, data, length);
BIO_flush(bio);
BIO_get_mem_ptr(bio, &bufferPtr);
std::string result(bufferPtr->data, bufferPtr->length);
BIO_free_all(bio);
return result;
}
// Base64解码函数
std::vector<unsigned char> base64_decode(const std::string &encoded_string)
{
BIO *bio, *b64;
std::vector<unsigned char> result;
b64 = BIO_new(BIO_f_base64());
bio = BIO_new_mem_buf(encoded_string.c_str(), encoded_string.length());
bio = BIO_push(b64, bio);
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); // 不添加换行符
// 计算解码后的长度
size_t decoded_length = (encoded_string.length() * 3) / 4;
result.resize(decoded_length);
int actual_length = BIO_read(bio, result.data(), decoded_length);
if (actual_length > 0) {
result.resize(actual_length);
} else {
result.clear();
}
BIO_free_all(bio);
return result;
}
// 利用用户名和固定密钥派生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" / "UserInfo.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" / "UserInfo.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());
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
} else {
std::cout << "result_length: " << result_length << std::endl;
sqlite3_finalize(stmt);
sqlite3_close(db);
return -1;
}
} else {
// 用户不存在
sqlite3_finalize(stmt);
sqlite3_close(db);
return -2; // 用户不存在
}
}
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" / "UserInfo.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" / "UserInfo.db";
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;
}
if (old_password_str == new_password_str) {
return -2;
}
const char *xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
return -3;
}
fs::path dbPath = fs::path(xnCorePath) / "database" / "UserInfo.db";
{
sqlite3 *db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
return -3;
}
// 首先验证旧密码
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 -4; // 旧密码错误
}
// 生成新的加密密码
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 0; // 密码修改成功
}
sqlite3_finalize(stmt);
}
} else {
// 用户不存在
sqlite3_finalize(stmt);
sqlite3_close(db);
return -5; // 用户不存在
}
}
sqlite3_close(db);
}
return -6; // Default error return
} catch (const std::exception &) {
return -3;
}
}
extern "C" LOGIN_EXPORT int resetPassword(int user_id)
{
try {
const char *xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
return -1;
}
fs::path dbPath = fs::path(xnCorePath) / "database" / "UserInfo.db";
{
sqlite3 *db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
return -2;
}
// 首先查询用户名
sqlite3_stmt *stmt;
const char *queryStr = "SELECT username FROM users WHERE id = ?";
if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) != SQLITE_OK) {
sqlite3_close(db);
return -3; // SELECT 语句准备失败
}
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 salt = generateSalt(username);
std::string new_password_str = "123456";
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_close(db);
return -4; // UPDATE 语句准备失败
}
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 0; // 密码重置成功
} else {
// 获取具体的错误信息
int error_code = sqlite3_errcode(db);
const char *error_msg = sqlite3_errmsg(db);
std::cout << "UPDATE failed with error code: " << error_code
<< ", message: " << (error_msg ? error_msg : "unknown") << std::endl;
sqlite3_finalize(stmt);
sqlite3_close(db);
return -5; // UPDATE 语句执行失败
}
} else {
// 用户不存在
sqlite3_finalize(stmt);
sqlite3_close(db);
return -6; // 用户不存在
}
}
return -7; // 其他错误
} catch (const std::exception &) {
return -8;
}
}
// 更新用户信息
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" / "UserInfo.db";
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) {
// 安全地获取字符串值处理null情况
std::string full_name =
userInfo.contains("full_name") && !userInfo["full_name"].is_null()
? userInfo["full_name"].get<std::string>()
: "";
std::string phone = userInfo.contains("phone") && !userInfo["phone"].is_null()
? userInfo["phone"].get<std::string>()
: "";
std::string email = userInfo.contains("email") && !userInfo["email"].is_null()
? userInfo["email"].get<std::string>()
: "";
std::string department =
userInfo.contains("department") && !userInfo["department"].is_null()
? userInfo["department"].get<std::string>()
: "";
std::string position =
userInfo.contains("position") && !userInfo["position"].is_null()
? userInfo["position"].get<std::string>()
: "";
sqlite3_bind_text(stmt, 1, full_name.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, phone.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 3, email.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 4, department.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 5, position.c_str(), -1, SQLITE_TRANSIENT);
sqlite3_bind_int(stmt, 6, user_id);
if (sqlite3_step(stmt) == SQLITE_DONE) {
result = 0; // 更新成功
}
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" / "UserInfo.db";
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 = 0; // 更新成功
}
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" / "UserInfo.db";
sqlite3 *db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
return -1;
}
const char *queryStr = "SELECT id, 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;
userInfo["id"] = sqlite3_column_int(stmt, 0);
std::string username = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
userInfo["username"] = username;
userInfo["full_name"] =
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 2));
// 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::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;
}
}
extern "C" LOGIN_EXPORT int deleteUser(int user_id)
{
try {
const char *xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
return -1;
}
fs::path dbPath = fs::path(xnCorePath) / "database" / "UserInfo.db";
sqlite3 *db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
return -1;
}
const char *queryStr = "DELETE FROM users WHERE id = ?";
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_int(stmt, 1, user_id);
if (sqlite3_step(stmt) == SQLITE_DONE) {
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
}
sqlite3_close(db);
return -1;
} catch (const std::exception &) {
return -1;
}
}
// 更新用户头像
extern "C" LOGIN_EXPORT int updateUserIcon(int user_id, const char *icon_base64_buffer,
int icon_base64_length)
{
try {
if (!icon_base64_buffer || icon_base64_length <= 0) {
return -1; // 无效的输入参数
}
std::string icon_base64(icon_base64_buffer, icon_base64_length);
if (icon_base64.empty()) {
return -1; // 空的Base64数据
}
const char *xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
return -2; // 环境变量未设置
}
fs::path dbPath = fs::path(xnCorePath) / "database" / "UserInfo.db";
{
sqlite3 *db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
return -3; // 数据库连接失败
}
// 首先检查用户是否存在
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 -4; // 用户不存在
}
sqlite3_finalize(stmt);
}
// 将Base64字符串转换为二进制数据
std::vector<unsigned char> icon_data;
try {
icon_data = base64_decode(icon_base64);
} catch (...) {
sqlite3_close(db);
return -5; // Base64解码失败
}
if (icon_data.empty()) {
sqlite3_close(db);
return -6; // 解码后数据为空
}
// 更新用户头像
stmt = nullptr;
const char *queryStr = "UPDATE users SET icon = ? WHERE id = ?";
if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_blob(stmt, 1, icon_data.data(), icon_data.size(), SQLITE_TRANSIENT);
sqlite3_bind_int(stmt, 2, user_id);
if (sqlite3_step(stmt) == SQLITE_DONE) {
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0; // 更新成功
} else {
// 获取具体的错误信息
int error_code = sqlite3_errcode(db);
const char *error_msg = sqlite3_errmsg(db);
std::cout << "UPDATE icon failed with error code: " << error_code
<< ", message: " << (error_msg ? error_msg : "unknown") << std::endl;
sqlite3_finalize(stmt);
sqlite3_close(db);
return -7; // UPDATE语句执行失败
}
} else {
sqlite3_close(db);
return -8; // UPDATE语句准备失败
}
}
return -9; // 其他错误
} catch (const std::exception &) {
return -10; // 异常错误
}
}