mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
feat: configure auth channel mismatch formats
This commit is contained in:
@@ -856,6 +856,10 @@ pub(super) fn build_admin_pool_key_payload(
|
||||
"auth_type_by_format".to_string(),
|
||||
json!(key.auth_type_by_format),
|
||||
);
|
||||
payload.insert(
|
||||
"allow_auth_channel_mismatch_formats".to_string(),
|
||||
json!(key.allow_auth_channel_mismatch_formats),
|
||||
);
|
||||
payload.insert(
|
||||
"credential_kind".to_string(),
|
||||
json!(auth_semantics.credential_kind().as_str()),
|
||||
|
||||
@@ -14,6 +14,8 @@ pub(crate) struct AdminProviderKeyCreateRequest {
|
||||
#[serde(default)]
|
||||
pub(crate) auth_type_by_format: Option<serde_json::Value>,
|
||||
#[serde(default)]
|
||||
pub(crate) allow_auth_channel_mismatch_formats: Option<Option<Vec<String>>>,
|
||||
#[serde(default)]
|
||||
pub(crate) auth_config: Option<serde_json::Value>,
|
||||
pub(crate) name: String,
|
||||
#[serde(default)]
|
||||
@@ -53,6 +55,8 @@ pub(crate) struct AdminProviderKeyUpdateRequest {
|
||||
#[serde(default)]
|
||||
pub(crate) auth_type_by_format: Option<serde_json::Value>,
|
||||
#[serde(default)]
|
||||
pub(crate) allow_auth_channel_mismatch_formats: Option<Vec<String>>,
|
||||
#[serde(default)]
|
||||
pub(crate) auth_config: Option<serde_json::Value>,
|
||||
#[serde(default)]
|
||||
pub(crate) name: Option<String>,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use crate::handlers::admin::provider::shared::payloads::AdminProviderKeyCreateRequest;
|
||||
use crate::handlers::admin::provider::write::normalize::{
|
||||
normalize_api_format_json_object_keys, normalize_api_format_list, normalize_auth_type,
|
||||
normalize_auth_type_by_format, validate_vertex_api_formats,
|
||||
normalize_allow_auth_channel_mismatch_formats, normalize_api_format_json_object_keys,
|
||||
normalize_api_format_list, normalize_auth_type, normalize_auth_type_by_format,
|
||||
validate_vertex_api_formats,
|
||||
};
|
||||
use crate::handlers::admin::request::AdminAppState;
|
||||
use crate::handlers::admin::shared::{
|
||||
@@ -192,6 +193,14 @@ pub(crate) async fn build_admin_create_provider_key_record(
|
||||
key.health_by_format = Some(json!({}));
|
||||
key.circuit_breaker_by_format = Some(json!({}));
|
||||
key.auth_type_by_format = auth_type_by_format;
|
||||
let allow_auth_channel_mismatch_formats = payload
|
||||
.allow_auth_channel_mismatch_formats
|
||||
.unwrap_or_else(|| Some(api_formats.clone()));
|
||||
key.allow_auth_channel_mismatch_formats = normalize_allow_auth_channel_mismatch_formats(
|
||||
allow_auth_channel_mismatch_formats,
|
||||
"allow_auth_channel_mismatch_formats",
|
||||
&api_formats,
|
||||
)?;
|
||||
key.created_at_unix_ms = Some(now_unix_secs);
|
||||
key.updated_at_unix_secs = Some(now_unix_secs);
|
||||
Ok(key)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use crate::handlers::admin::provider::shared::payloads::AdminProviderKeyUpdatePatch;
|
||||
use crate::handlers::admin::provider::write::normalize::{
|
||||
normalize_api_format_json_object_keys, normalize_api_format_list, normalize_auth_type,
|
||||
normalize_auth_type_by_format, validate_vertex_api_formats,
|
||||
normalize_allow_auth_channel_mismatch_formats, normalize_api_format_json_object_keys,
|
||||
normalize_api_format_list, normalize_auth_type, normalize_auth_type_by_format,
|
||||
validate_vertex_api_formats,
|
||||
};
|
||||
use crate::handlers::admin::request::AdminAppState;
|
||||
use crate::handlers::admin::shared::{
|
||||
@@ -221,6 +222,32 @@ pub(crate) async fn build_admin_update_provider_key_record(
|
||||
} else {
|
||||
updated.auth_type_by_format = None;
|
||||
}
|
||||
if fields.contains("allow_auth_channel_mismatch_formats") {
|
||||
updated.allow_auth_channel_mismatch_formats =
|
||||
normalize_allow_auth_channel_mismatch_formats(
|
||||
payload.allow_auth_channel_mismatch_formats,
|
||||
"allow_auth_channel_mismatch_formats",
|
||||
&effective_api_formats,
|
||||
)?;
|
||||
} else if fields.contains("api_formats") {
|
||||
let existing = updated
|
||||
.allow_auth_channel_mismatch_formats
|
||||
.as_ref()
|
||||
.and_then(serde_json::Value::as_array)
|
||||
.map(|items| {
|
||||
items
|
||||
.iter()
|
||||
.filter_map(serde_json::Value::as_str)
|
||||
.map(ToOwned::to_owned)
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
updated.allow_auth_channel_mismatch_formats =
|
||||
normalize_allow_auth_channel_mismatch_formats(
|
||||
existing,
|
||||
"allow_auth_channel_mismatch_formats",
|
||||
&effective_api_formats,
|
||||
)?;
|
||||
}
|
||||
|
||||
updated.auth_type = target_auth_type;
|
||||
|
||||
|
||||
@@ -81,6 +81,36 @@ pub(crate) fn normalize_auth_type_by_format(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn normalize_allow_auth_channel_mismatch_formats(
|
||||
values: Option<Vec<String>>,
|
||||
field_name: &str,
|
||||
api_formats: &[String],
|
||||
) -> Result<Option<serde_json::Value>, String> {
|
||||
let Some(values) = values else {
|
||||
return Ok(None);
|
||||
};
|
||||
let allowed = api_formats.iter().cloned().collect::<BTreeSet<_>>();
|
||||
let mut seen = BTreeSet::new();
|
||||
let mut normalized = Vec::new();
|
||||
for value in values {
|
||||
let canonical = crate::ai_serving::normalize_api_format_alias(&value);
|
||||
if canonical.is_empty() {
|
||||
continue;
|
||||
}
|
||||
if !allowed.is_empty() && !allowed.contains(&canonical) {
|
||||
return Err(format!("{field_name} 包含未选择的 API 格式: {canonical}"));
|
||||
}
|
||||
if seen.insert(canonical.clone()) {
|
||||
normalized.push(serde_json::Value::String(canonical));
|
||||
}
|
||||
}
|
||||
if normalized.is_empty() {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(serde_json::Value::Array(normalized)))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn normalize_auth_type(value: Option<&str>) -> Result<String, String> {
|
||||
let auth_type = value.unwrap_or("api_key").trim().to_ascii_lowercase();
|
||||
match auth_type.as_str() {
|
||||
|
||||
@@ -120,6 +120,17 @@ pub(crate) async fn build_admin_system_export_providers_payload(
|
||||
internal_priority: Some(key.internal_priority),
|
||||
global_priority_by_format: key.global_priority_by_format.clone(),
|
||||
auth_type_by_format: key.auth_type_by_format.clone(),
|
||||
allow_auth_channel_mismatch_formats: key
|
||||
.allow_auth_channel_mismatch_formats
|
||||
.as_ref()
|
||||
.and_then(serde_json::Value::as_array)
|
||||
.map(|items| {
|
||||
items
|
||||
.iter()
|
||||
.filter_map(serde_json::Value::as_str)
|
||||
.map(ToOwned::to_owned)
|
||||
.collect::<Vec<_>>()
|
||||
}),
|
||||
rpm_limit: key.rpm_limit,
|
||||
allowed_models: key.allowed_models.as_ref().and_then(|value| {
|
||||
value.as_array().map(|items| {
|
||||
|
||||
@@ -1312,6 +1312,10 @@ pub(crate) fn build_admin_provider_key_response(
|
||||
"auth_type_by_format".to_string(),
|
||||
json!(key.auth_type_by_format),
|
||||
);
|
||||
payload.insert(
|
||||
"allow_auth_channel_mismatch_formats".to_string(),
|
||||
json!(key.allow_auth_channel_mismatch_formats),
|
||||
);
|
||||
payload.insert(
|
||||
"credential_kind".to_string(),
|
||||
json!(auth_semantics.credential_kind().as_str()),
|
||||
|
||||
Reference in New Issue
Block a user