XNSim/Login/login.cpp

517 lines
15 KiB
C++
Raw Normal View History

2025-04-28 12:25:20 +08:00
#include "Login_global.h"
#include <string>
#include <memory>
2025-05-18 09:54:59 +08:00
#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>
using json = nlohmann::json;
namespace fs = std::filesystem;
std::string generateSalt(const std::string& username)
2025-04-28 12:25:20 +08:00
{
// 使用用户名生成盐值
return username + "XNSim_Salt_Key";
}
2025-05-18 09:54:59 +08:00
std::string encryptPassword(const std::string& password, const std::string& salt)
2025-04-28 12:25:20 +08:00
{
// 将密码和盐值组合
2025-05-18 09:54:59 +08:00
std::string saltedPassword = password;
if (!salt.empty()) {
saltedPassword += salt;
2025-04-28 12:25:20 +08:00
}
// 使用SHA-256算法对加盐密码进行加密
2025-05-18 09:54:59 +08:00
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();
2025-04-28 12:25:20 +08:00
}
2025-05-18 09:54:59 +08:00
extern "C" LOGIN_EXPORT int validateUser(const void* username_buffer, size_t username_length,
const void* password_buffer, size_t password_length)
2025-04-28 12:25:20 +08:00
{
try {
2025-05-18 09:54:59 +08:00
std::string username_str(static_cast<const char*>(username_buffer), username_length);
std::string password_str(static_cast<const char*>(password_buffer), password_length);
2025-04-28 12:25:20 +08:00
2025-05-18 09:54:59 +08:00
if (username_str.empty() || password_str.empty()) {
return -1;
}
2025-04-28 12:25:20 +08:00
2025-05-18 09:54:59 +08:00
std::string salt = generateSalt(username_str);
std::string encryptedPassword = encryptPassword(password_str, salt);
2025-04-28 12:25:20 +08:00
2025-05-18 09:54:59 +08:00
// 获取环境变量
const char* xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
2025-04-28 12:25:20 +08:00
return -1;
}
2025-05-18 09:54:59 +08:00
fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db";
2025-04-28 12:25:20 +08:00
2025-05-18 09:54:59 +08:00
sqlite3* db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
2025-04-28 12:25:20 +08:00
return -1;
}
int userId = -1;
2025-05-18 09:54:59 +08:00
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);
2025-04-28 12:25:20 +08:00
}
2025-05-18 09:54:59 +08:00
sqlite3_finalize(stmt);
2025-04-28 12:25:20 +08:00
}
2025-05-18 09:54:59 +08:00
sqlite3_close(db);
2025-04-28 12:25:20 +08:00
return userId;
2025-05-18 09:54:59 +08:00
} catch (const std::exception&) {
2025-04-28 12:25:20 +08:00
return -1;
}
}
2025-05-18 09:54:59 +08:00
extern "C" LOGIN_EXPORT const char* getUserInfo(int user_id)
2025-04-28 12:25:20 +08:00
{
try {
2025-05-18 09:54:59 +08:00
const char* xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
2025-04-28 12:25:20 +08:00
return nullptr;
}
2025-05-18 09:54:59 +08:00
fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db";
2025-04-28 12:25:20 +08:00
2025-05-18 09:54:59 +08:00
sqlite3* db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
return nullptr;
}
2025-04-28 12:25:20 +08:00
2025-05-18 09:54:59 +08:00
char* result = nullptr;
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));
userInfo["access_level"] = sqlite3_column_int(stmt, 3);
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));
std::string jsonData = userInfo.dump();
result = new char[jsonData.size() + 1];
std::strcpy(result, jsonData.c_str());
2025-04-28 12:25:20 +08:00
}
2025-05-18 09:54:59 +08:00
sqlite3_finalize(stmt);
2025-04-28 12:25:20 +08:00
}
2025-05-18 09:54:59 +08:00
sqlite3_close(db);
2025-04-28 12:25:20 +08:00
return result;
2025-05-18 09:54:59 +08:00
} catch (const std::exception&) {
2025-04-28 12:25:20 +08:00
return nullptr;
}
}
2025-05-18 09:54:59 +08:00
extern "C" LOGIN_EXPORT void freeUserInfo(const char* ptr)
2025-04-28 12:25:20 +08:00
{
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);
2025-05-18 09:54:59 +08:00
std::string username_str(username_data, username_length);
2025-04-28 12:25:20 +08:00
2025-05-18 09:54:59 +08:00
if (username_str.empty()) {
2025-04-28 12:25:20 +08:00
return -1;
}
2025-05-18 09:54:59 +08:00
const char* xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
2025-04-28 12:25:20 +08:00
return -1;
}
2025-05-18 09:54:59 +08:00
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());
2025-04-28 12:25:20 +08:00
int result = -1;
{
2025-05-18 09:54:59 +08:00
sqlite3* db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
2025-04-28 12:25:20 +08:00
return -1;
}
2025-05-18 09:54:59 +08:00
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);
2025-04-28 12:25:20 +08:00
2025-05-18 09:54:59 +08:00
if (sqlite3_step(stmt) == SQLITE_ROW) {
result = sqlite3_column_int(stmt, 0) > 0 ? 1 : 0;
}
sqlite3_finalize(stmt);
2025-04-28 12:25:20 +08:00
}
2025-05-18 09:54:59 +08:00
sqlite3_close(db);
2025-04-28 12:25:20 +08:00
}
return result;
} catch (const std::exception &) {
return -1;
}
}
// 注册新用户
extern "C" LOGIN_EXPORT int registerUser(const void *username_buffer, size_t username_length,
const void *password_buffer, size_t password_length,
const void *userinfo_buffer, size_t userinfo_length)
{
try {
// 转换输入参数
const char *username_data = static_cast<const char *>(username_buffer);
const char *password_data = static_cast<const char *>(password_buffer);
const char *userinfo_data = static_cast<const char *>(userinfo_buffer);
2025-05-18 09:54:59 +08:00
std::string username_str(username_data, username_length);
std::string password_str(password_data, password_length);
2025-04-28 12:25:20 +08:00
// 验证用户名和密码非空
2025-05-18 09:54:59 +08:00
if (username_str.empty()) {
2025-04-28 12:25:20 +08:00
return -4; // 用户名为空
}
2025-05-18 09:54:59 +08:00
if (password_str.empty()) {
2025-04-28 12:25:20 +08:00
return -5; // 密码为空
}
// 检查用户名是否已存在
if (checkUsernameExists(username_buffer, username_length) != 0) {
return -2; // 用户名已存在
}
// 解析用户信息JSON
2025-05-18 09:54:59 +08:00
json userInfo;
try {
userInfo = json::parse(std::string(userinfo_data, userinfo_length));
} catch (const json::parse_error&) {
return -3; // Invalid user info format
2025-04-28 12:25:20 +08:00
}
// 验证权限级别
int accessLevel = 0;
// 生成加密密码
2025-05-18 09:54:59 +08:00
std::string salt = generateSalt(username_str);
std::string encryptedPassword = encryptPassword(password_str, salt);
2025-04-28 12:25:20 +08:00
// 连接数据库
2025-05-18 09:54:59 +08:00
const char* xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
2025-04-28 12:25:20 +08:00
return -1;
}
2025-05-18 09:54:59 +08:00
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());
2025-04-28 12:25:20 +08:00
int newUserId = -1;
{
2025-05-18 09:54:59 +08:00
sqlite3* db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
2025-04-28 12:25:20 +08:00
return -1;
}
2025-05-18 09:54:59 +08:00
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_int(stmt, 3, accessLevel);
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);
2025-04-28 12:25:20 +08:00
}
2025-05-18 09:54:59 +08:00
sqlite3_close(db);
2025-04-28 12:25:20 +08:00
}
return newUserId;
} catch (const std::exception &) {
return -1;
}
}
// 修改密码
extern "C" LOGIN_EXPORT int changePassword(int user_id, const void *old_password_buffer,
size_t old_password_length,
const void *new_password_buffer,
size_t new_password_length)
{
try {
const char *old_password_data = static_cast<const char *>(old_password_buffer);
const char *new_password_data = static_cast<const char *>(new_password_buffer);
2025-05-18 09:54:59 +08:00
std::string old_password_str(old_password_data, old_password_length);
std::string new_password_str(new_password_data, new_password_length);
2025-04-28 12:25:20 +08:00
2025-05-18 09:54:59 +08:00
if (old_password_str.empty() || new_password_str.empty()) {
2025-04-28 12:25:20 +08:00
return -1;
}
2025-05-18 09:54:59 +08:00
const char* xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
2025-04-28 12:25:20 +08:00
return -1;
}
2025-05-18 09:54:59 +08:00
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());
2025-04-28 12:25:20 +08:00
{
2025-05-18 09:54:59 +08:00
sqlite3* db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
2025-04-28 12:25:20 +08:00
return -1;
}
// 首先验证旧密码
2025-05-18 09:54:59 +08:00
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);
}
}
2025-04-28 12:25:20 +08:00
}
2025-05-18 09:54:59 +08:00
sqlite3_close(db);
2025-04-28 12:25:20 +08:00
}
2025-05-18 09:54:59 +08:00
return -1; // Default error return
} catch (const std::exception&) {
2025-04-28 12:25:20 +08:00
return -1;
}
}
// 更新用户信息
extern "C" LOGIN_EXPORT int updateUserInfo(int user_id, const void *userinfo_buffer,
size_t userinfo_length)
{
try {
const char *userinfo_data = static_cast<const char *>(userinfo_buffer);
2025-05-18 09:54:59 +08:00
std::string userinfo_str(userinfo_data, userinfo_length);
2025-04-28 12:25:20 +08:00
// 解析用户信息JSON
2025-05-18 09:54:59 +08:00
json userInfo;
try {
userInfo = json::parse(userinfo_str);
} catch (const json::parse_error&) {
return -1; // Invalid user info format
2025-04-28 12:25:20 +08:00
}
// 连接数据库
2025-05-18 09:54:59 +08:00
const char* xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
2025-04-28 12:25:20 +08:00
return -1;
}
2025-05-18 09:54:59 +08:00
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());
2025-04-28 12:25:20 +08:00
int result = -1;
{
2025-05-18 09:54:59 +08:00
sqlite3* db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
2025-04-28 12:25:20 +08:00
return -1;
}
// 首先检查用户是否存在
2025-05-18 09:54:59 +08:00
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);
2025-04-28 12:25:20 +08:00
}
2025-05-18 09:54:59 +08:00
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);
2025-04-28 12:25:20 +08:00
}
2025-05-18 09:54:59 +08:00
sqlite3_close(db);
2025-04-28 12:25:20 +08:00
}
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; // 无效的权限级别
}
// 连接数据库
2025-05-18 09:54:59 +08:00
const char* xnCorePath = std::getenv("XNCore");
if (!xnCorePath) {
2025-04-28 12:25:20 +08:00
return -1;
}
2025-05-18 09:54:59 +08:00
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());
2025-04-28 12:25:20 +08:00
int result = -1;
{
2025-05-18 09:54:59 +08:00
sqlite3* db;
if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) {
2025-04-28 12:25:20 +08:00
return -1;
}
// 首先检查用户是否存在
2025-05-18 09:54:59 +08:00
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);
2025-04-28 12:25:20 +08:00
}
2025-05-18 09:54:59 +08:00
stmt = nullptr;
const char* queryStr = "UPDATE users SET access_level = ? WHERE id = ?";
2025-04-28 12:25:20 +08:00
2025-05-18 09:54:59 +08:00
if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) {
sqlite3_bind_int(stmt, 1, access_level);
sqlite3_bind_int(stmt, 2, user_id);
if (sqlite3_step(stmt) == SQLITE_DONE) {
result = 1; // 更新成功
}
2025-04-28 12:25:20 +08:00
2025-05-18 09:54:59 +08:00
sqlite3_finalize(stmt);
2025-04-28 12:25:20 +08:00
}
2025-05-18 09:54:59 +08:00
sqlite3_close(db);
2025-04-28 12:25:20 +08:00
}
return result;
} catch (const std::exception &) {
return -1;
}
}