Redesign sensitive info protection settings

This commit is contained in:
fawney19
2026-05-14 11:14:20 +08:00
parent 91955ad1e0
commit 509bd30252
71 changed files with 3254 additions and 884 deletions

View File

@@ -34,7 +34,8 @@ pub(crate) use self::email_templates::{
};
pub(crate) use self::external_models::OFFICIAL_EXTERNAL_MODEL_PROVIDERS;
pub(crate) use self::normalize::{
normalize_json_array, normalize_json_object, normalize_string_list,
deserialize_optional_json_patch, normalize_feature_settings, normalize_json_array,
normalize_json_object, normalize_string_list,
};
pub(crate) use self::payloads::{
InternalGatewayAuthContextRequest, InternalGatewayExecuteRequest,

View File

@@ -1,5 +1,7 @@
use std::collections::BTreeSet;
use serde_json::{Map, Value};
pub(crate) fn normalize_string_list(values: Option<Vec<String>>) -> Option<Vec<String>> {
let mut out = Vec::new();
let mut seen = BTreeSet::new();
@@ -42,3 +44,65 @@ pub(crate) fn normalize_json_array(
_ => Err(format!("{field_name} 必须是 JSON 数组")),
}
}
pub(crate) fn normalize_feature_settings(value: Option<Value>) -> Result<Option<Value>, String> {
let Some(mut value) = value else {
return Ok(None);
};
match value {
Value::Null => Ok(None),
Value::Object(ref mut settings) => {
normalize_chat_pii_redaction_feature_settings(settings)?;
if settings.is_empty() {
Ok(None)
} else {
Ok(Some(value))
}
}
_ => Err("feature_settings 必须是对象".to_string()),
}
}
pub(crate) fn deserialize_optional_json_patch<'de, D>(
deserializer: D,
) -> Result<Option<Option<Value>>, D::Error>
where
D: serde::Deserializer<'de>,
{
<Option<Value> as serde::Deserialize>::deserialize(deserializer).map(Some)
}
fn normalize_chat_pii_redaction_feature_settings(
settings: &mut Map<String, Value>,
) -> Result<(), String> {
let Some(value) = settings.get_mut("chat_pii_redaction") else {
return Ok(());
};
match value {
Value::Null => {
settings.remove("chat_pii_redaction");
Ok(())
}
Value::Object(feature) => {
normalize_chat_pii_redaction_feature_object(feature)?;
if feature.is_empty() {
settings.remove("chat_pii_redaction");
}
Ok(())
}
_ => Err("chat_pii_redaction 必须是对象".to_string()),
}
}
fn normalize_chat_pii_redaction_feature_object(
feature: &mut Map<String, Value>,
) -> Result<(), String> {
for key in ["enabled", "inject_model_instruction"] {
if let Some(value) = feature.get(key) {
if !value.is_boolean() {
return Err(format!("chat_pii_redaction.{key} 必须是布尔值"));
}
}
}
Ok(())
}