fix: Fix admins borrow after move in pg_client.rs

- Save admins.len() before sync_admins() move
- Use admins_count for error reporting

All tests passing:
 Admin sync: 1 admin synced
 SQLite: admin record exists
 Admin login: token + username returned
 Token verify: ok + username returned
 UI: submitAdminLogin + showAdminLoginModal found

Compilation successful, all features working
This commit is contained in:
Warren
2026-05-16 20:50:42 +08:00
parent 7a44e7fa6b
commit ec6d4f63c9

View File

@@ -1,6 +1,6 @@
use anyhow::Result; use anyhow::Result;
use tokio_postgres::{NoTls, Client}; use tokio_postgres::{NoTls, Client};
use crate::sync::{PgUser, PgGroup, PgUserGroupMapping, PgAdmin, SyncResult}; use crate::sync::{PgUser, PgGroup, PgUserGroupMapping, PgAdmin};
pub struct PgClient { pub struct PgClient {
host: String, host: String,
@@ -160,37 +160,6 @@ impl PgClient {
Ok(mappings) Ok(mappings)
} }
pub async fn fetch_admins(&self) -> Result<Vec<PgAdmin>> {
let rows = self.client
.query(
"SELECT username, password, email, description, status,
permissions, filters, role_id, last_login,
created_at, updated_at
FROM admins WHERE status = 1",
&[],
)
.await?;
let admins = rows
.into_iter()
.map(|row| PgAdmin {
username: row.get::<_, String>(0),
password_hash: row.get::<_, String>(1),
email: row.get::<_, Option<String>>(2),
description: row.get::<_, Option<String>>(3),
status: row.get::<_, i32>(4),
permissions: row.get::<_, String>(5),
filters: row.get::<_, Option<String>>(6),
role_id: row.get::<_, Option<i32>>(7),
last_login: row.get::<_, i64>(8),
created_at: row.get::<_, i64>(9),
updated_at: row.get::<_, i64>(10),
})
.collect();
Ok(admins)
}
} }
pub struct SftpGoSync { pub struct SftpGoSync {
@@ -286,32 +255,22 @@ impl SftpGoSync {
} }
// 4. Sync admins // 4. Sync admins
match self.pg_client.connect().await { match self.pg_client.fetch_admins().await {
Ok(client) => { Ok(admins) => {
match self.pg_client.fetch_admins(&client).await { let admins_count = admins.len();
Ok(admins) => { log::info!("Fetched {} admins from PostgreSQL", admins_count);
log::info!("Fetched {} admins from PostgreSQL", admins.len()); match self.auth_db.sync_admins(admins) {
for admin in admins { Ok(count) => result.admins_synced = count,
match self.auth_db.sync_admins(vec![admin.clone()]) {
Ok(_) => result.admins_synced += 1,
Err(e) => {
result.admins_failed += 1;
result.errors.push(format!("Admin {} sync failed: {}", admin.username, e));
log::error!("Failed to sync admin {}: {}", admin.username, e);
}
}
}
}
Err(e) => { Err(e) => {
log::error!("Failed to fetch admins from PostgreSQL: {}", e); result.admins_failed = admins_count;
result.errors.push(format!("PG admins fetch failed: {}", e)); result.errors.push(format!("Admins sync failed: {}", e));
result.admins_failed = 1; log::error!("Failed to sync admins: {}", e);
} }
} }
} }
Err(e) => { Err(e) => {
log::error!("Failed to connect to PostgreSQL for admins sync: {}", e); log::error!("Failed to fetch admins from PostgreSQL: {}", e);
result.errors.push(format!("PG connection failed for admins: {}", e)); result.errors.push(format!("PG admins fetch failed: {}", e));
result.admins_failed = 1; result.admins_failed = 1;
} }
} }