feat(wave-1): 适配器框架与安全基座(schema校验/dry-run/exec沙箱/密钥库/日志脱敏/字段拆分)
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
//! 生产密钥库后端:keyring → Windows Credential Manager(优先)/ Linux Secret Service
|
||||
//! (架构 §4.1)
|
||||
//!
|
||||
//! 错误映射时只保留中文说明,绝不把后端原始错误或密钥明文带入错误信息。
|
||||
|
||||
use crate::error::SecretStoreError;
|
||||
use crate::store::SecretStore;
|
||||
|
||||
/// keyring 后端封装。
|
||||
#[derive(Default)]
|
||||
pub struct KeyringSecretStore;
|
||||
|
||||
impl KeyringSecretStore {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
mod platform {
|
||||
use keyring::Entry;
|
||||
|
||||
use crate::error::SecretStoreError;
|
||||
|
||||
pub fn set(service: &str, account: &str, secret: &str) -> Result<(), SecretStoreError> {
|
||||
let entry = Entry::new(service, account).map_err(map_err)?;
|
||||
entry.set_password(secret).map_err(map_err)
|
||||
}
|
||||
|
||||
pub fn get(service: &str, account: &str) -> Result<String, SecretStoreError> {
|
||||
let entry = Entry::new(service, account).map_err(map_err)?;
|
||||
entry.get_password().map_err(map_err)
|
||||
}
|
||||
|
||||
pub fn has(service: &str, account: &str) -> bool {
|
||||
Entry::new(service, account)
|
||||
.and_then(|e| e.get_password())
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub fn delete(service: &str, account: &str) -> Result<(), SecretStoreError> {
|
||||
let entry = Entry::new(service, account).map_err(map_err)?;
|
||||
entry.delete_credential().map_err(map_err)
|
||||
}
|
||||
|
||||
fn map_err(e: keyring::Error) -> SecretStoreError {
|
||||
// NoEntry 表示无此条目;其余错误统一映射为后端失败,绝不回显原始错误文本。
|
||||
if matches!(e, keyring::Error::NoEntry) {
|
||||
SecretStoreError::NotFound
|
||||
} else {
|
||||
SecretStoreError::Backend("系统密钥库操作失败(Windows Credential Manager)".into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
mod platform {
|
||||
use crate::error::SecretStoreError;
|
||||
|
||||
pub fn set(_service: &str, _account: &str, _secret: &str) -> Result<(), SecretStoreError> {
|
||||
Err(SecretStoreError::Backend("Linux 密钥库后端自 Wave 2 起接入(Secret Service)".into()))
|
||||
}
|
||||
|
||||
pub fn get(_service: &str, _account: &str) -> Result<String, SecretStoreError> {
|
||||
Err(SecretStoreError::Backend("Linux 密钥库后端自 Wave 2 起接入(Secret Service)".into()))
|
||||
}
|
||||
|
||||
pub fn has(_service: &str, _account: &str) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn delete(_service: &str, _account: &str) -> Result<(), SecretStoreError> {
|
||||
Err(SecretStoreError::Backend("Linux 密钥库后端自 Wave 2 起接入(Secret Service)".into()))
|
||||
}
|
||||
}
|
||||
|
||||
impl SecretStore for KeyringSecretStore {
|
||||
fn set(&self, service: &str, account: &str, secret: &str) -> Result<(), SecretStoreError> {
|
||||
platform::set(service, account, secret)
|
||||
}
|
||||
|
||||
fn get(&self, service: &str, account: &str) -> Result<String, SecretStoreError> {
|
||||
platform::get(service, account)
|
||||
}
|
||||
|
||||
fn has(&self, service: &str, account: &str) -> bool {
|
||||
platform::has(service, account)
|
||||
}
|
||||
|
||||
fn delete(&self, service: &str, account: &str) -> Result<(), SecretStoreError> {
|
||||
platform::delete(service, account)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user