mirror of
https://github.com/SECTL/SecScore.git
synced 2026-07-19 19:04:23 +08:00
修复设置未持久化导致重启后重复进入OOBE
This commit is contained in:
@@ -40,7 +40,10 @@ pub async fn auth_get_status(
|
||||
state: State<'_, Arc<RwLock<AppState>>>,
|
||||
) -> Result<IpcResponse<AuthStatusResponse>, String> {
|
||||
let state_guard = state.read();
|
||||
let settings = state_guard.settings.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await?;
|
||||
let mut permissions = state_guard.permissions.write();
|
||||
|
||||
let status = AuthService::get_status(&settings, sender_id, &mut permissions);
|
||||
@@ -67,7 +70,10 @@ pub async fn auth_login(
|
||||
|
||||
let result = {
|
||||
let state_guard = state.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await?;
|
||||
let security = state_guard.security.read();
|
||||
let mut permissions = state_guard.permissions.write();
|
||||
|
||||
@@ -133,7 +139,10 @@ pub async fn auth_set_passwords(
|
||||
|
||||
let result = {
|
||||
let state_guard = state.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await?;
|
||||
let security = state_guard.security.read();
|
||||
let mut permissions = state_guard.permissions.write();
|
||||
|
||||
@@ -172,7 +181,10 @@ pub async fn auth_generate_recovery(
|
||||
|
||||
let result = {
|
||||
let state_guard = state.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await?;
|
||||
let security = state_guard.security.read();
|
||||
let mut permissions = state_guard.permissions.write();
|
||||
|
||||
@@ -205,7 +217,10 @@ pub async fn auth_reset_by_recovery(
|
||||
|
||||
let result = {
|
||||
let state_guard = state.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await?;
|
||||
let security = state_guard.security.read();
|
||||
let mut permissions = state_guard.permissions.write();
|
||||
|
||||
@@ -242,7 +257,10 @@ pub async fn auth_clear_all(
|
||||
|
||||
let result = {
|
||||
let state_guard = state.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await?;
|
||||
let mut permissions = state_guard.permissions.write();
|
||||
|
||||
AuthService::clear_all(&mut settings, &mut permissions, sender).await
|
||||
|
||||
@@ -87,8 +87,11 @@ pub async fn auto_score_add_rule(
|
||||
|
||||
let new_id = {
|
||||
let state_guard = state.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut auto_score_service = state_guard.auto_score.write();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await?;
|
||||
|
||||
let new_rule = AutoScoreRule {
|
||||
id: 0,
|
||||
@@ -136,8 +139,11 @@ pub async fn auto_score_update_rule(
|
||||
|
||||
let success = {
|
||||
let state_guard = state.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut auto_score_service = state_guard.auto_score.write();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await?;
|
||||
|
||||
let existing = auto_score_service.get_rule_by_id(rule.id);
|
||||
let last_executed = existing.and_then(|r| r.last_executed.clone());
|
||||
@@ -191,8 +197,11 @@ pub async fn auto_score_delete_rule(
|
||||
|
||||
let success = {
|
||||
let state_guard = state.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut auto_score_service = state_guard.auto_score.write();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await?;
|
||||
|
||||
let success = auto_score_service.delete_rule(rule_id);
|
||||
|
||||
@@ -233,8 +242,11 @@ pub async fn auto_score_toggle_rule(
|
||||
|
||||
let success = {
|
||||
let state_guard = state.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut auto_score_service = state_guard.auto_score.write();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await?;
|
||||
|
||||
let success = auto_score_service.toggle_rule(params.rule_id, params.enabled);
|
||||
|
||||
@@ -294,8 +306,11 @@ pub async fn auto_score_sort_rules(
|
||||
|
||||
{
|
||||
let state_guard = state.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut auto_score_service = state_guard.auto_score.write();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await?;
|
||||
|
||||
auto_score_service.sort_rules(&rule_ids);
|
||||
|
||||
|
||||
@@ -74,7 +74,10 @@ pub async fn settings_get_all(
|
||||
state: State<'_, Arc<RwLock<AppState>>>,
|
||||
) -> Result<IpcResponse<SettingsSpec>, String> {
|
||||
let state_guard = state.read();
|
||||
let settings = state_guard.settings.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await.map_err(|e| e.to_string())?;
|
||||
let all = settings.get_all();
|
||||
Ok(IpcResponse::success(all))
|
||||
}
|
||||
@@ -88,7 +91,10 @@ pub async fn settings_get(
|
||||
SettingsKey::from_str(&key).ok_or_else(|| format!("Unknown setting key: {}", key))?;
|
||||
|
||||
let state_guard = state.read();
|
||||
let settings = state_guard.settings.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await.map_err(|e| e.to_string())?;
|
||||
let value = settings.get_value(settings_key);
|
||||
let json_value = settings_value_to_json(value);
|
||||
|
||||
@@ -126,7 +132,10 @@ pub async fn settings_set(
|
||||
|
||||
{
|
||||
let state_guard = state.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await.map_err(|e| e.to_string())?;
|
||||
settings
|
||||
.set_value(settings_key, settings_value)
|
||||
.await
|
||||
|
||||
@@ -54,8 +54,11 @@ pub async fn theme_set(
|
||||
|
||||
let current_theme = {
|
||||
let state_guard = state.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut theme_service = state_guard.theme.write();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await?;
|
||||
|
||||
if theme_service.set_current_theme(&theme_id) {
|
||||
let _ = settings
|
||||
@@ -94,8 +97,11 @@ pub async fn theme_save(
|
||||
|
||||
let current_theme = {
|
||||
let state_guard = state.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut theme_service = state_guard.theme.write();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await?;
|
||||
|
||||
match theme_service.save_theme(theme) {
|
||||
Ok(()) => {
|
||||
@@ -136,8 +142,11 @@ pub async fn theme_delete(
|
||||
|
||||
let current_theme = {
|
||||
let state_guard = state.read();
|
||||
let db_conn = state_guard.db.read().clone();
|
||||
let mut theme_service = state_guard.theme.write();
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(db_conn);
|
||||
settings.initialize().await?;
|
||||
|
||||
match theme_service.delete_theme(&theme_id) {
|
||||
Ok(()) => {
|
||||
|
||||
+26
-17
@@ -50,25 +50,34 @@ fn setup_database(app: &mut App) -> Result<(), Box<dyn std::error::Error>> {
|
||||
.ok_or("Invalid database path")?
|
||||
.to_string();
|
||||
|
||||
tauri::async_runtime::spawn(async move {
|
||||
match create_sqlite_connection(&db_path_str).await {
|
||||
Ok(conn) => {
|
||||
if let Err(e) = run_migration(&conn, DatabaseType::SQLite).await {
|
||||
eprintln!("Failed to run sqlite migration: {}", e);
|
||||
return;
|
||||
}
|
||||
let state = handle.state::<crate::state::SafeAppState>();
|
||||
let state_guard = state.write();
|
||||
let mut db_guard = state_guard.db.write();
|
||||
*db_guard = Some(conn);
|
||||
eprintln!("Database connected to: {}", db_path_str);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Failed to connect to database: {}", e);
|
||||
}
|
||||
}
|
||||
let db_result = tauri::async_runtime::block_on(async {
|
||||
let conn = create_sqlite_connection(&db_path_str).await?;
|
||||
run_migration(&conn, DatabaseType::SQLite).await?;
|
||||
Ok::<_, Box<dyn std::error::Error>>(conn)
|
||||
});
|
||||
|
||||
match db_result {
|
||||
Ok(conn) => {
|
||||
let state = handle.state::<crate::state::SafeAppState>();
|
||||
let state_guard = state.write();
|
||||
{
|
||||
let mut db_guard = state_guard.db.write();
|
||||
*db_guard = Some(conn.clone());
|
||||
}
|
||||
{
|
||||
let mut settings = state_guard.settings.write();
|
||||
settings.attach_db(Some(conn));
|
||||
if let Err(e) = tauri::async_runtime::block_on(settings.initialize()) {
|
||||
eprintln!("Failed to initialize settings from database: {}", e);
|
||||
}
|
||||
}
|
||||
eprintln!("Database connected to: {}", db_path_str);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Failed to connect to database: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value as JsonValue;
|
||||
use sea_orm::{ConnectionTrait, DatabaseConnection, Statement};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@@ -133,6 +134,8 @@ pub enum PermissionRequirement {
|
||||
pub struct SettingsService {
|
||||
cache: HashMap<String, String>,
|
||||
initialized: bool,
|
||||
db_loaded: bool,
|
||||
db_conn: Option<DatabaseConnection>,
|
||||
}
|
||||
|
||||
impl Default for SettingsService {
|
||||
@@ -146,19 +149,88 @@ impl SettingsService {
|
||||
Self {
|
||||
cache: HashMap::new(),
|
||||
initialized: false,
|
||||
db_loaded: false,
|
||||
db_conn: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn attach_db(&mut self, conn: Option<DatabaseConnection>) {
|
||||
if conn.is_some() {
|
||||
self.db_conn = conn;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn initialize(&mut self) -> Result<(), String> {
|
||||
if self.initialized {
|
||||
if self.initialized && (self.db_loaded || self.db_conn.is_none()) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.ensure_defaults();
|
||||
if let Some(conn) = self.db_conn.clone() {
|
||||
if !self.db_loaded {
|
||||
self.load_cache_from_db(&conn).await?;
|
||||
self.ensure_defaults_in_db(&conn).await?;
|
||||
self.db_loaded = true;
|
||||
}
|
||||
} else {
|
||||
self.ensure_defaults();
|
||||
}
|
||||
self.initialized = true;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn escape_sql(value: &str) -> String {
|
||||
value.replace('\'', "''")
|
||||
}
|
||||
|
||||
async fn load_cache_from_db(&mut self, conn: &DatabaseConnection) -> Result<(), String> {
|
||||
let sql = "SELECT key, value FROM settings".to_string();
|
||||
let rows = conn
|
||||
.query_all(Statement::from_string(conn.get_database_backend(), sql))
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
self.cache.clear();
|
||||
for row in rows {
|
||||
let key: String = row.try_get("", "key").map_err(|e| e.to_string())?;
|
||||
let value: String = row.try_get("", "value").map_err(|e| e.to_string())?;
|
||||
self.cache.insert(key, value);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn upsert_raw_db(
|
||||
&self,
|
||||
conn: &DatabaseConnection,
|
||||
key: &str,
|
||||
value: &str,
|
||||
) -> Result<(), String> {
|
||||
let key_escaped = Self::escape_sql(key);
|
||||
let value_escaped = Self::escape_sql(value);
|
||||
let sql = format!(
|
||||
"INSERT INTO settings (key, value) VALUES ('{}', '{}') ON CONFLICT(key) DO UPDATE SET value = EXCLUDED.value",
|
||||
key_escaped, value_escaped
|
||||
);
|
||||
|
||||
conn.execute(Statement::from_string(conn.get_database_backend(), sql))
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn ensure_defaults_in_db(&mut self, conn: &DatabaseConnection) -> Result<(), String> {
|
||||
let definitions = Self::get_definitions();
|
||||
for (key, def) in definitions.iter() {
|
||||
let key_str = key.as_str();
|
||||
if !self.cache.contains_key(key_str) {
|
||||
let raw = def.default_value.to_raw();
|
||||
self.upsert_raw_db(conn, key_str, &raw).await?;
|
||||
self.cache.insert(key_str.to_string(), raw);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_definitions() -> HashMap<SettingsKey, SettingDefinition> {
|
||||
let mut defs = HashMap::new();
|
||||
|
||||
@@ -279,6 +351,8 @@ impl SettingsService {
|
||||
}
|
||||
|
||||
pub async fn set_raw(&mut self, key: &str, value: &str) -> Result<(), String> {
|
||||
self.initialize().await?;
|
||||
|
||||
if let Some(settings_key) = SettingsKey::from_str(key) {
|
||||
let definitions = Self::get_definitions();
|
||||
if let Some(def) = definitions.get(&settings_key) {
|
||||
@@ -292,11 +366,17 @@ impl SettingsService {
|
||||
} else {
|
||||
parsed.to_raw()
|
||||
};
|
||||
self.cache.insert(key.to_string(), validated);
|
||||
self.cache.insert(key.to_string(), validated.clone());
|
||||
if let Some(conn) = self.db_conn.clone() {
|
||||
self.upsert_raw_db(&conn, key, &validated).await?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
self.cache.insert(key.to_string(), value.to_string());
|
||||
if let Some(conn) = self.db_conn.clone() {
|
||||
self.upsert_raw_db(&conn, key, value).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -322,6 +402,8 @@ impl SettingsService {
|
||||
key: SettingsKey,
|
||||
value: SettingsValue,
|
||||
) -> Result<(), String> {
|
||||
self.initialize().await?;
|
||||
|
||||
let definitions = Self::get_definitions();
|
||||
if let Some(def) = definitions.get(&key) {
|
||||
if let Some(validate_fn) = def.validate {
|
||||
@@ -329,7 +411,11 @@ impl SettingsService {
|
||||
return Err(format!("Invalid value for setting: {:?}", key));
|
||||
}
|
||||
}
|
||||
self.cache.insert(key.as_str().to_string(), value.to_raw());
|
||||
let raw = value.to_raw();
|
||||
self.cache.insert(key.as_str().to_string(), raw.clone());
|
||||
if let Some(conn) = self.db_conn.clone() {
|
||||
self.upsert_raw_db(&conn, key.as_str(), &raw).await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user