mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-01 17:00:21 +08:00
fix: allow empty provider secrets to attempt requests
This commit is contained in:
@@ -95,8 +95,12 @@ pub async fn build_standard_models_fetch_execution_plan(
|
||||
.ok_or_else(|| {
|
||||
"Rust models fetch auth resolution is not supported for this key".to_string()
|
||||
})?;
|
||||
protected_headers.push(auth_header_name.clone());
|
||||
headers.insert(auth_header_name.clone(), auth_header_value.clone());
|
||||
insert_non_empty_auth_header(
|
||||
&mut headers,
|
||||
&mut protected_headers,
|
||||
&auth_header_name,
|
||||
&auth_header_value,
|
||||
);
|
||||
headers = apply_fetch_header_rules(transport, headers, &protected_headers)?;
|
||||
ensure_upstream_auth_header(&mut headers, &auth_header_name, &auth_header_value);
|
||||
} else {
|
||||
@@ -181,6 +185,7 @@ pub async fn build_gemini_cli_load_code_assist_plan(
|
||||
) -> Result<ExecutionPlan, String> {
|
||||
let authorization = resolve_bearer_or_oauth_header_auth(runtime, transport)
|
||||
.await?
|
||||
.filter(|(_, value)| !value.trim().is_empty())
|
||||
.ok_or_else(|| "GeminiCLI loadCodeAssist requires bearer or OAuth auth".to_string())?;
|
||||
|
||||
let mut headers = BTreeMap::from([
|
||||
@@ -188,8 +193,13 @@ pub async fn build_gemini_cli_load_code_assist_plan(
|
||||
("accept-encoding".to_string(), "identity".to_string()),
|
||||
("content-type".to_string(), "application/json".to_string()),
|
||||
]);
|
||||
headers.insert(authorization.0.clone(), authorization.1.clone());
|
||||
let protected_headers = vec![authorization.0];
|
||||
let mut protected_headers = Vec::new();
|
||||
insert_non_empty_auth_header(
|
||||
&mut headers,
|
||||
&mut protected_headers,
|
||||
&authorization.0,
|
||||
&authorization.1,
|
||||
);
|
||||
headers = apply_fetch_header_rules(transport, headers, &protected_headers)?;
|
||||
|
||||
build_execution_plan(
|
||||
@@ -225,8 +235,7 @@ pub async fn build_vertex_models_fetch_execution_plan(
|
||||
let mut headers = standard_models_fetch_headers(api_format, &transport.provider.provider_type);
|
||||
let mut protected_headers = Vec::<String>::new();
|
||||
if let Some((name, value)) = auth_header {
|
||||
protected_headers.push(name.clone());
|
||||
headers.insert(name.clone(), value.clone());
|
||||
insert_non_empty_auth_header(&mut headers, &mut protected_headers, &name, &value);
|
||||
headers = apply_fetch_header_rules(transport, headers, &protected_headers)?;
|
||||
ensure_upstream_auth_header(&mut headers, &name, &value);
|
||||
} else {
|
||||
@@ -472,6 +481,22 @@ fn append_query_param(mut url: String, key: &str, value: &str) -> String {
|
||||
url
|
||||
}
|
||||
|
||||
fn insert_non_empty_auth_header(
|
||||
headers: &mut BTreeMap<String, String>,
|
||||
protected_headers: &mut Vec<String>,
|
||||
name: &str,
|
||||
value: &str,
|
||||
) {
|
||||
let name = name.trim();
|
||||
let value = value.trim();
|
||||
if name.is_empty() || value.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
protected_headers.push(name.to_string());
|
||||
headers.insert(name.to_string(), value.to_string());
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use aether_contracts::{ExecutionPlan, ExecutionResult, ProxySnapshot};
|
||||
|
||||
@@ -236,7 +236,7 @@ pub fn resolve_local_openai_bearer_auth(
|
||||
}
|
||||
let secret = resolved_local_secret(transport)?;
|
||||
|
||||
Some(("authorization".to_string(), format!("Bearer {secret}")))
|
||||
Some(("authorization".to_string(), bearer_auth_value(secret)))
|
||||
}
|
||||
|
||||
pub fn resolve_local_standard_auth(
|
||||
@@ -247,7 +247,7 @@ pub fn resolve_local_standard_auth(
|
||||
|
||||
match auth_type.as_str() {
|
||||
"api_key" => Some(("x-api-key".to_string(), secret.to_string())),
|
||||
"bearer" => Some(("authorization".to_string(), format!("Bearer {secret}"))),
|
||||
"bearer" => Some(("authorization".to_string(), bearer_auth_value(secret))),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -260,7 +260,7 @@ pub fn resolve_local_gemini_auth(
|
||||
|
||||
match auth_type.as_str() {
|
||||
"api_key" => Some(("x-goog-api-key".to_string(), secret.to_string())),
|
||||
"bearer" => Some(("authorization".to_string(), format!("Bearer {secret}"))),
|
||||
"bearer" => Some(("authorization".to_string(), bearer_auth_value(secret))),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -291,7 +291,21 @@ pub(crate) fn resolve_local_auth_type_for_transport_format(
|
||||
|
||||
fn resolved_local_secret(transport: &GatewayProviderTransportSnapshot) -> Option<&str> {
|
||||
let secret = transport.key.decrypted_api_key.trim();
|
||||
(!secret.is_empty() && secret != PLACEHOLDER_API_KEY).then_some(secret)
|
||||
if !secret.is_empty() && secret != PLACEHOLDER_API_KEY {
|
||||
Some(secret)
|
||||
} else if transport.key.decrypted_auth_config.is_some() {
|
||||
None
|
||||
} else {
|
||||
Some("")
|
||||
}
|
||||
}
|
||||
|
||||
fn bearer_auth_value(secret: &str) -> String {
|
||||
if secret.is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
format!("Bearer {secret}")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -465,16 +479,31 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn local_standard_auth_rejects_placeholder_secret() {
|
||||
assert!(resolve_local_standard_auth(&sample_transport()).is_none());
|
||||
fn local_standard_auth_keeps_header_shape_for_placeholder_secret() {
|
||||
assert_eq!(
|
||||
resolve_local_standard_auth(&sample_transport()),
|
||||
Some(("authorization".to_string(), String::new()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn local_standard_auth_rejects_empty_secret() {
|
||||
fn local_standard_auth_keeps_header_shape_for_empty_secret() {
|
||||
let mut transport = sample_transport();
|
||||
transport.key.auth_type = "api_key".to_string();
|
||||
transport.key.decrypted_api_key = String::new();
|
||||
|
||||
assert_eq!(
|
||||
resolve_local_standard_auth(&transport),
|
||||
Some(("x-api-key".to_string(), String::new()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn local_standard_auth_defers_to_auth_config_when_raw_secret_is_empty() {
|
||||
let mut transport = sample_transport();
|
||||
transport.key.decrypted_auth_config =
|
||||
Some(r#"{"access_token":"cached-token"}"#.to_string());
|
||||
|
||||
assert!(resolve_local_standard_auth(&transport).is_none());
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@ use super::super::snapshot::GatewayProviderTransportSnapshot;
|
||||
use super::super::supports_local_oauth_request_auth_resolution;
|
||||
|
||||
pub fn supports_local_claude_code_auth(transport: &GatewayProviderTransportSnapshot) -> bool {
|
||||
resolve_local_standard_auth(transport).is_some()
|
||||
resolve_local_standard_auth(transport).is_some_and(|(_, value)| !value.trim().is_empty())
|
||||
|| supports_local_oauth_request_auth_resolution(transport)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user