589 lines
16 KiB
C++
589 lines
16 KiB
C++
#include "Login_global.h"
|
|
#include <QString>
|
|
#include <QCryptographicHash>
|
|
#include <QProcessEnvironment>
|
|
#include <QDir>
|
|
#include <QSqlDatabase>
|
|
#include <QSqlQuery>
|
|
#include <QSqlError>
|
|
#include <QSqlRecord>
|
|
#include <QJsonObject>
|
|
#include <QJsonDocument>
|
|
#include <QCoreApplication>
|
|
#include <string>
|
|
#include <memory>
|
|
#include <QDateTime>
|
|
|
|
// 全局变量用于跟踪是否已初始化
|
|
static bool g_isInitialized = false;
|
|
static QCoreApplication *g_app = nullptr;
|
|
|
|
// 初始化Qt环境
|
|
void initializeQt()
|
|
{
|
|
if (!g_isInitialized) {
|
|
static int argc = 1;
|
|
static char *argv[] = {const_cast<char *>("Login")};
|
|
g_app = new QCoreApplication(argc, argv);
|
|
g_isInitialized = true;
|
|
}
|
|
}
|
|
|
|
// 清理Qt环境
|
|
void cleanupQt()
|
|
{
|
|
if (g_isInitialized && g_app) {
|
|
delete g_app;
|
|
g_app = nullptr;
|
|
g_isInitialized = false;
|
|
}
|
|
}
|
|
|
|
QString generateSalt(const QString &username)
|
|
{
|
|
// 使用用户名生成盐值
|
|
// 可以根据需要添加额外的静态字符串来增加复杂度
|
|
return username + "XNSim_Salt_Key";
|
|
}
|
|
|
|
QString encryptPassword(const QString &password, const QString &salt)
|
|
{
|
|
// 将密码和盐值组合
|
|
QByteArray saltedPassword = password.toUtf8();
|
|
|
|
// 如果提供了盐值,则添加到密码中
|
|
if (!salt.isEmpty()) {
|
|
saltedPassword.append(salt.toUtf8());
|
|
}
|
|
|
|
// 使用SHA-256算法对加盐密码进行加密
|
|
QByteArray hashedPassword =
|
|
QCryptographicHash::hash(saltedPassword, QCryptographicHash::Sha256);
|
|
return hashedPassword.toHex();
|
|
}
|
|
|
|
extern "C" LOGIN_EXPORT int validateUser(const void *username_buffer, size_t username_length,
|
|
const void *password_buffer, size_t password_length)
|
|
{
|
|
try {
|
|
initializeQt();
|
|
|
|
const char *username_data = static_cast<const char *>(username_buffer);
|
|
const char *password_data = static_cast<const char *>(password_buffer);
|
|
|
|
QByteArray username_bytes(username_data, username_length);
|
|
QByteArray password_bytes(password_data, password_length);
|
|
|
|
QString username_str = QString::fromUtf8(username_bytes);
|
|
QString password_str = QString::fromUtf8(password_bytes);
|
|
|
|
if (username_str.isEmpty() || password_str.isEmpty()) {
|
|
return -1;
|
|
}
|
|
|
|
QString salt = generateSalt(username_str);
|
|
QString encryptedPassword = encryptPassword(password_str, salt);
|
|
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
QString xnCorePath = env.value("XNCore", "");
|
|
|
|
if (xnCorePath.isEmpty()) {
|
|
return -1;
|
|
}
|
|
|
|
QString dbPath = QDir(xnCorePath).filePath("database/XNSim.db");
|
|
|
|
int userId = -1;
|
|
{
|
|
// 创建一个独立的作用域来管理数据库连接
|
|
QString connectionName =
|
|
QString("userauth_%1").arg(QDateTime::currentMSecsSinceEpoch());
|
|
{
|
|
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", connectionName);
|
|
db.setDatabaseName(dbPath);
|
|
|
|
if (!db.open()) {
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return -1;
|
|
}
|
|
|
|
QSqlQuery query(db);
|
|
QString queryStr = "SELECT * FROM users WHERE username = ? AND password = ?";
|
|
query.prepare(queryStr);
|
|
query.addBindValue(username_str);
|
|
query.addBindValue(encryptedPassword);
|
|
|
|
if (query.exec() && query.next()) {
|
|
userId = query.value(0).toInt();
|
|
}
|
|
|
|
query.finish();
|
|
db.close();
|
|
}
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
}
|
|
|
|
return userId;
|
|
|
|
} catch (const std::exception &) {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
extern "C" LOGIN_EXPORT const char *getUserInfo(int user_id)
|
|
{
|
|
try {
|
|
initializeQt();
|
|
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
QString xnCorePath = env.value("XNCore", "");
|
|
|
|
if (xnCorePath.isEmpty()) {
|
|
return nullptr;
|
|
}
|
|
|
|
QString dbPath = QDir(xnCorePath).filePath("database/XNSim.db");
|
|
|
|
char *result = nullptr;
|
|
{
|
|
// 创建一个独立的作用域来管理数据库连接
|
|
QString connectionName =
|
|
QString("userinfo_%1").arg(QDateTime::currentMSecsSinceEpoch());
|
|
{
|
|
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", connectionName);
|
|
db.setDatabaseName(dbPath);
|
|
|
|
if (!db.open()) {
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return nullptr;
|
|
}
|
|
|
|
QSqlQuery query(db);
|
|
query.prepare("SELECT * FROM users WHERE id = ?");
|
|
query.addBindValue(user_id);
|
|
|
|
if (query.exec() && query.next()) {
|
|
QJsonObject userInfo;
|
|
userInfo["id"] = query.value(0).toInt();
|
|
userInfo["username"] = query.value(1).toString();
|
|
userInfo["access_level"] = query.value(3).toInt();
|
|
userInfo["full_name"] = query.value(4).toString();
|
|
userInfo["phone"] = query.value(5).toString();
|
|
userInfo["email"] = query.value(6).toString();
|
|
userInfo["department"] = query.value(7).toString();
|
|
userInfo["position"] = query.value(8).toString();
|
|
|
|
QJsonDocument doc(userInfo);
|
|
QByteArray jsonData = doc.toJson(QJsonDocument::Compact);
|
|
|
|
result = new char[jsonData.size() + 1];
|
|
std::strcpy(result, jsonData.constData());
|
|
}
|
|
|
|
query.finish();
|
|
db.close();
|
|
}
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
}
|
|
|
|
return result;
|
|
|
|
} catch (const std::exception &) {
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
extern "C" LOGIN_EXPORT void freeUserInfo(const char *ptr)
|
|
{
|
|
if (ptr) {
|
|
delete[] ptr;
|
|
}
|
|
}
|
|
|
|
// 导出清理函数
|
|
extern "C" LOGIN_EXPORT void cleanup()
|
|
{
|
|
cleanupQt();
|
|
}
|
|
|
|
// 检查用户名是否已存在
|
|
int checkUsernameExists(const void *username_buffer, size_t username_length)
|
|
{
|
|
try {
|
|
initializeQt();
|
|
|
|
const char *username_data = static_cast<const char *>(username_buffer);
|
|
QByteArray username_bytes(username_data, username_length);
|
|
QString username_str = QString::fromUtf8(username_bytes);
|
|
|
|
if (username_str.isEmpty()) {
|
|
return -1;
|
|
}
|
|
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
QString xnCorePath = env.value("XNCore", "");
|
|
|
|
if (xnCorePath.isEmpty()) {
|
|
return -1;
|
|
}
|
|
|
|
QString dbPath = QDir(xnCorePath).filePath("database/XNSim.db");
|
|
QString connectionName = QString("usercheck_%1").arg(QDateTime::currentMSecsSinceEpoch());
|
|
|
|
int result = -1;
|
|
{
|
|
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", connectionName);
|
|
db.setDatabaseName(dbPath);
|
|
|
|
if (!db.open()) {
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return -1;
|
|
}
|
|
|
|
QSqlQuery query(db);
|
|
query.prepare("SELECT COUNT(*) FROM users WHERE username = ?");
|
|
query.addBindValue(username_str);
|
|
|
|
if (query.exec() && query.next()) {
|
|
result = query.value(0).toInt() > 0 ? 1 : 0;
|
|
}
|
|
|
|
query.finish();
|
|
db.close();
|
|
}
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
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 {
|
|
initializeQt();
|
|
|
|
// 转换输入参数
|
|
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);
|
|
|
|
QByteArray username_bytes(username_data, username_length);
|
|
QByteArray password_bytes(password_data, password_length);
|
|
QByteArray userinfo_bytes(userinfo_data, userinfo_length);
|
|
|
|
QString username_str = QString::fromUtf8(username_bytes);
|
|
QString password_str = QString::fromUtf8(password_bytes);
|
|
|
|
// 验证用户名和密码非空
|
|
if (username_str.isEmpty()) {
|
|
return -4; // 用户名为空
|
|
}
|
|
if (password_str.isEmpty()) {
|
|
return -5; // 密码为空
|
|
}
|
|
|
|
// 检查用户名是否已存在
|
|
if (checkUsernameExists(username_buffer, username_length) != 0) {
|
|
return -2; // 用户名已存在
|
|
}
|
|
|
|
// 解析用户信息JSON
|
|
QJsonDocument userInfoDoc = QJsonDocument::fromJson(userinfo_bytes);
|
|
if (!userInfoDoc.isObject()) {
|
|
return -3; // 无效的用户信息格式
|
|
}
|
|
QJsonObject userInfo = userInfoDoc.object();
|
|
|
|
// 验证权限级别
|
|
int accessLevel = 0;
|
|
|
|
// 生成加密密码
|
|
QString salt = generateSalt(username_str);
|
|
QString encryptedPassword = encryptPassword(password_str, salt);
|
|
|
|
// 连接数据库
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
QString xnCorePath = env.value("XNCore", "");
|
|
if (xnCorePath.isEmpty()) {
|
|
return -1;
|
|
}
|
|
|
|
QString dbPath = QDir(xnCorePath).filePath("database/XNSim.db");
|
|
QString connectionName = QString("userreg_%1").arg(QDateTime::currentMSecsSinceEpoch());
|
|
|
|
int newUserId = -1;
|
|
{
|
|
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", connectionName);
|
|
db.setDatabaseName(dbPath);
|
|
|
|
if (!db.open()) {
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return -1;
|
|
}
|
|
|
|
QSqlQuery query(db);
|
|
query.prepare("INSERT INTO users (username, password, access_level, full_name, phone, "
|
|
"email, department, position) "
|
|
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
|
|
|
query.addBindValue(username_str);
|
|
query.addBindValue(encryptedPassword);
|
|
query.addBindValue(accessLevel);
|
|
query.addBindValue(userInfo["full_name"].toString());
|
|
query.addBindValue(userInfo["phone"].toString());
|
|
query.addBindValue(userInfo["email"].toString());
|
|
query.addBindValue(userInfo["department"].toString());
|
|
query.addBindValue(userInfo["position"].toString());
|
|
|
|
if (query.exec()) {
|
|
newUserId = query.lastInsertId().toInt();
|
|
}
|
|
|
|
query.finish();
|
|
db.close();
|
|
}
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
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 {
|
|
initializeQt();
|
|
|
|
const char *old_password_data = static_cast<const char *>(old_password_buffer);
|
|
const char *new_password_data = static_cast<const char *>(new_password_buffer);
|
|
|
|
QByteArray old_password_bytes(old_password_data, old_password_length);
|
|
QByteArray new_password_bytes(new_password_data, new_password_length);
|
|
|
|
QString old_password_str = QString::fromUtf8(old_password_bytes);
|
|
QString new_password_str = QString::fromUtf8(new_password_bytes);
|
|
|
|
if (old_password_str.isEmpty() || new_password_str.isEmpty()) {
|
|
return -1;
|
|
}
|
|
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
QString xnCorePath = env.value("XNCore", "");
|
|
|
|
if (xnCorePath.isEmpty()) {
|
|
return -1;
|
|
}
|
|
|
|
QString dbPath = QDir(xnCorePath).filePath("database/XNSim.db");
|
|
QString connectionName = QString("changepwd_%1").arg(QDateTime::currentMSecsSinceEpoch());
|
|
|
|
{
|
|
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", connectionName);
|
|
db.setDatabaseName(dbPath);
|
|
|
|
if (!db.open()) {
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return -1;
|
|
}
|
|
|
|
// 首先验证旧密码
|
|
QSqlQuery query(db);
|
|
query.prepare("SELECT username, password FROM users WHERE id = ?");
|
|
query.addBindValue(user_id);
|
|
|
|
if (!query.exec() || !query.next()) {
|
|
db.close();
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return -2; // 用户不存在
|
|
}
|
|
|
|
QString username = query.value(0).toString();
|
|
QString storedPassword = query.value(1).toString();
|
|
|
|
// 验证旧密码
|
|
QString salt = generateSalt(username);
|
|
QString encryptedOldPassword = encryptPassword(old_password_str, salt);
|
|
|
|
if (encryptedOldPassword != storedPassword) {
|
|
db.close();
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return -3; // 旧密码错误
|
|
}
|
|
|
|
// 生成新的加密密码
|
|
QString encryptedNewPassword = encryptPassword(new_password_str, salt);
|
|
|
|
// 更新密码
|
|
QSqlQuery updateQuery(db);
|
|
updateQuery.prepare("UPDATE users SET password = ? WHERE id = ?");
|
|
updateQuery.addBindValue(encryptedNewPassword);
|
|
updateQuery.addBindValue(user_id);
|
|
|
|
if (!updateQuery.exec()) {
|
|
db.close();
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return -1;
|
|
}
|
|
|
|
db.close();
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return 1; // 密码修改成功
|
|
}
|
|
|
|
} catch (const std::exception &) {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// 更新用户信息
|
|
extern "C" LOGIN_EXPORT int updateUserInfo(int user_id, const void *userinfo_buffer,
|
|
size_t userinfo_length)
|
|
{
|
|
try {
|
|
initializeQt();
|
|
|
|
const char *userinfo_data = static_cast<const char *>(userinfo_buffer);
|
|
QByteArray userinfo_bytes(userinfo_data, userinfo_length);
|
|
|
|
// 解析用户信息JSON
|
|
QJsonDocument userInfoDoc = QJsonDocument::fromJson(userinfo_bytes);
|
|
if (!userInfoDoc.isObject()) {
|
|
return -1; // 无效的用户信息格式
|
|
}
|
|
QJsonObject userInfo = userInfoDoc.object();
|
|
|
|
// 连接数据库
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
QString xnCorePath = env.value("XNCore", "");
|
|
if (xnCorePath.isEmpty()) {
|
|
return -1;
|
|
}
|
|
|
|
QString dbPath = QDir(xnCorePath).filePath("database/XNSim.db");
|
|
QString connectionName = QString("userupdate_%1").arg(QDateTime::currentMSecsSinceEpoch());
|
|
|
|
int result = -1;
|
|
{
|
|
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", connectionName);
|
|
db.setDatabaseName(dbPath);
|
|
|
|
if (!db.open()) {
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return -1;
|
|
}
|
|
|
|
// 首先检查用户是否存在
|
|
QSqlQuery checkQuery(db);
|
|
checkQuery.prepare("SELECT id FROM users WHERE id = ?");
|
|
checkQuery.addBindValue(user_id);
|
|
|
|
if (!checkQuery.exec() || !checkQuery.next()) {
|
|
checkQuery.finish();
|
|
db.close();
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return -2; // 用户不存在
|
|
}
|
|
checkQuery.finish();
|
|
|
|
QSqlQuery query(db);
|
|
query.prepare("UPDATE users SET full_name = ?, phone = ?, email = ?, department = ?, "
|
|
"position = ? "
|
|
"WHERE id = ?");
|
|
|
|
query.addBindValue(userInfo["full_name"].toString());
|
|
query.addBindValue(userInfo["phone"].toString());
|
|
query.addBindValue(userInfo["email"].toString());
|
|
query.addBindValue(userInfo["department"].toString());
|
|
query.addBindValue(userInfo["position"].toString());
|
|
query.addBindValue(user_id);
|
|
|
|
if (query.exec()) {
|
|
result = 1; // 更新成功
|
|
}
|
|
|
|
query.finish();
|
|
db.close();
|
|
}
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return result;
|
|
|
|
} catch (const std::exception &) {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// 更新用户权限级别
|
|
extern "C" LOGIN_EXPORT int updateUserAccessLevel(int user_id, int access_level)
|
|
{
|
|
try {
|
|
initializeQt();
|
|
|
|
// 验证权限级别
|
|
if (access_level < 0 || access_level >= 3) {
|
|
return -3; // 无效的权限级别
|
|
}
|
|
|
|
// 连接数据库
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
QString xnCorePath = env.value("XNCore", "");
|
|
if (xnCorePath.isEmpty()) {
|
|
return -1;
|
|
}
|
|
|
|
QString dbPath = QDir(xnCorePath).filePath("database/XNSim.db");
|
|
QString connectionName = QString("useraccess_%1").arg(QDateTime::currentMSecsSinceEpoch());
|
|
|
|
int result = -1;
|
|
{
|
|
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", connectionName);
|
|
db.setDatabaseName(dbPath);
|
|
|
|
if (!db.open()) {
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return -1;
|
|
}
|
|
|
|
// 首先检查用户是否存在
|
|
QSqlQuery checkQuery(db);
|
|
checkQuery.prepare("SELECT id FROM users WHERE id = ?");
|
|
checkQuery.addBindValue(user_id);
|
|
|
|
if (!checkQuery.exec() || !checkQuery.next()) {
|
|
checkQuery.finish();
|
|
db.close();
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return -2; // 用户不存在
|
|
}
|
|
checkQuery.finish();
|
|
|
|
QSqlQuery query(db);
|
|
query.prepare("UPDATE users SET access_level = ? WHERE id = ?");
|
|
|
|
query.addBindValue(access_level);
|
|
query.addBindValue(user_id);
|
|
|
|
if (query.exec()) {
|
|
result = 1; // 更新成功
|
|
}
|
|
|
|
query.finish();
|
|
db.close();
|
|
}
|
|
QSqlDatabase::removeDatabase(connectionName);
|
|
return result;
|
|
|
|
} catch (const std::exception &) {
|
|
return -1;
|
|
}
|
|
}
|