Tighten local auth allow-list matching

This commit is contained in:
fawney19
2026-04-30 00:26:33 +08:00
parent 37392d8774
commit 9e2faa7e5b
10 changed files with 758 additions and 53 deletions

View File

@@ -47,7 +47,16 @@ pub fn auth_constraints_allow_api_format(
allowed
.iter()
.any(|value| crate::normalize_api_format(value) == api_format)
.any(|value| api_format_matches_allowed_value(value, api_format))
}
pub fn api_format_matches_allowed_value(allowed_value: &str, api_format: &str) -> bool {
let allowed_value = allowed_value.trim();
let api_format = api_format.trim();
if allowed_value.is_empty() || api_format.is_empty() {
return false;
}
crate::normalize_api_format(allowed_value) == crate::normalize_api_format(api_format)
}
pub fn auth_constraints_allow_model(
@@ -68,8 +77,9 @@ pub fn auth_constraints_allow_model(
#[cfg(test)]
mod tests {
use super::{
auth_constraints_allow_api_format, auth_constraints_allow_model,
auth_constraints_allow_provider, provider_matches_allowed_value, SchedulerAuthConstraints,
api_format_matches_allowed_value, auth_constraints_allow_api_format,
auth_constraints_allow_model, auth_constraints_allow_provider,
provider_matches_allowed_value, SchedulerAuthConstraints,
};
fn sample_constraints() -> SchedulerAuthConstraints {
@@ -125,6 +135,52 @@ mod tests {
));
}
#[test]
fn provider_allowed_value_matches_exact_identifiers_only() {
assert!(provider_matches_allowed_value(
"claude",
"provider-1",
"Claude",
"custom",
));
assert!(provider_matches_allowed_value(
"CLAUDE",
"provider-1",
"Claude",
"custom",
));
assert!(provider_matches_allowed_value(
"provider-1",
"provider-1",
"Other",
"claude",
));
assert!(!provider_matches_allowed_value(
"anthropic",
"provider-1",
"Other",
"claude",
));
assert!(!provider_matches_allowed_value(
"claude",
"provider-1",
"Anthropic",
"custom",
));
assert!(!provider_matches_allowed_value(
"anthropic:messages",
"provider-1",
"Other",
"claude",
));
assert!(!provider_matches_allowed_value(
"openai:responses",
"provider-1",
"Other",
"claude",
));
}
#[test]
fn constraints_normalize_api_formats_and_models() {
let constraints = sample_constraints();
@@ -143,4 +199,40 @@ mod tests {
"gpt-4.1"
));
}
#[test]
fn api_format_allowed_value_rejects_retired_aliases() {
assert!(!api_format_matches_allowed_value(
"anthropic:messages",
"claude:messages"
));
assert!(!api_format_matches_allowed_value(
"claude:chat",
"claude:messages"
));
assert!(!api_format_matches_allowed_value(
"claude:cli",
"claude:messages"
));
assert!(!api_format_matches_allowed_value(
"openai:cli",
"openai:responses"
));
assert!(!api_format_matches_allowed_value(
"openai:compact",
"openai:responses:compact"
));
assert!(!api_format_matches_allowed_value(
"gemini:chat",
"gemini:generate_content"
));
assert!(api_format_matches_allowed_value(
"CLAUDE:MESSAGES",
"claude:messages"
));
assert!(!api_format_matches_allowed_value(
"openai:responses",
"claude:messages"
));
}
}