VFS/DataProvider/Config refactoring + SSH public key authentication
Phase 1-6 of refactoring plan: - VFS abstraction (VfsBackend trait + LocalFs + OpenFlags builder) - DataProvider trait (SqliteProvider + PgProvider, SFTPGo-compatible) - Config refactoring (AppConfig unified sections, env overrides) - SSH handlers (sftp/scp/rsync) migrated to VFS + DataProvider - SSH public key authentication (Ed25519 signature verification) - SSH stderr → CHANNEL_EXTENDED_DATA support - Web auth uses DataProvider instead of direct SQL - User home directory from provider (per-user isolation) - PostgreSQL auth provider for SFTPGo compatibility
This commit is contained in:
65
markbase-core/src/provider/mod.rs
Normal file
65
markbase-core/src/provider/mod.rs
Normal file
@@ -0,0 +1,65 @@
|
||||
pub mod sqlite;
|
||||
pub mod pg;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// 用户信息
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct User {
|
||||
pub username: String,
|
||||
pub password_hash: String,
|
||||
pub home_dir: PathBuf,
|
||||
pub uid: u32,
|
||||
pub gid: u32,
|
||||
pub permissions: String,
|
||||
pub status: i32,
|
||||
}
|
||||
|
||||
/// Provider 错误类型
|
||||
#[derive(Debug)]
|
||||
pub enum ProviderError {
|
||||
NotFound(String),
|
||||
AuthFailed(String),
|
||||
Internal(String),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ProviderError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ProviderError::NotFound(msg) => write!(f, "Not found: {}", msg),
|
||||
ProviderError::AuthFailed(msg) => write!(f, "Authentication failed: {}", msg),
|
||||
ProviderError::Internal(msg) => write!(f, "Internal error: {}", msg),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for ProviderError {}
|
||||
|
||||
/// 数据提供者 trait(用户认证和配置)
|
||||
pub trait DataProvider: Send + Sync {
|
||||
/// 获取用户信息
|
||||
fn get_user(&self, username: &str) -> Result<Option<User>, ProviderError>;
|
||||
|
||||
/// 验证用户密码
|
||||
fn check_password(&self, username: &str, password: &str) -> Result<bool, ProviderError>;
|
||||
|
||||
/// 获取用户主目录
|
||||
fn get_home_dir(&self, username: &str) -> Result<Option<String>, ProviderError>;
|
||||
|
||||
/// 获取用户组列表
|
||||
fn get_user_groups(&self, username: &str) -> Result<Vec<String>, ProviderError> {
|
||||
let _ = username;
|
||||
Ok(Vec::new())
|
||||
}
|
||||
|
||||
/// 检查用户是否存在且启用
|
||||
fn user_exists(&self, username: &str) -> Result<bool, ProviderError> {
|
||||
Ok(self.get_user(username)?.map(|u| u.status == 1).unwrap_or(false))
|
||||
}
|
||||
|
||||
/// 获取用户的公开密钥列表(OpenSSH authorized_keys格式)
|
||||
fn get_public_keys(&self, username: &str) -> Result<Vec<String>, ProviderError> {
|
||||
let _ = username;
|
||||
Ok(Vec::new())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user