mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-04 16:37:46 +08:00
fix(merge): align security contracts with latest main
This commit is contained in:
@@ -426,11 +426,11 @@ mod tests {
|
|||||||
assert!(candidate.finished_at_unix_ms.is_some());
|
assert!(candidate.finished_at_unix_ms.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The guard holds no request body, so its settlement write must describe the
|
/// The guard holds no request body, and the persistence boundary intentionally
|
||||||
/// capture rather than deny it: a typed `none` capture state would clear the
|
/// rejects request/response capture material. A dropped-attempt settlement
|
||||||
/// stored request body instead of leaving it alone.
|
/// must not re-introduce an inline body or a caller-controlled body reference.
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn settling_a_dropped_attempt_leaves_the_captured_request_body_alone() {
|
async fn settling_a_dropped_attempt_does_not_reintroduce_request_body_capture() {
|
||||||
let usage_repository = Arc::new(InMemoryUsageReadRepository::default());
|
let usage_repository = Arc::new(InMemoryUsageReadRepository::default());
|
||||||
let request_candidate_repository = Arc::new(InMemoryRequestCandidateRepository::default());
|
let request_candidate_repository = Arc::new(InMemoryRequestCandidateRepository::default());
|
||||||
let state = test_state(&usage_repository, &request_candidate_repository);
|
let state = test_state(&usage_repository, &request_candidate_repository);
|
||||||
@@ -444,7 +444,8 @@ mod tests {
|
|||||||
candidate_started_unix_ms,
|
candidate_started_unix_ms,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
// Stand in for a write that already captured this request's body.
|
// This deliberately supplies capture material to prove that the usage
|
||||||
|
// persistence boundary strips it before either lifecycle write stores it.
|
||||||
let captured_body = json!({"stream": true, "service_tier": "priority"});
|
let captured_body = json!({"stream": true, "service_tier": "priority"});
|
||||||
let mut capture = build_pending_usage_record(
|
let mut capture = build_pending_usage_record(
|
||||||
&plan,
|
&plan,
|
||||||
@@ -478,11 +479,9 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.expect("cancelled usage should be recorded");
|
.expect("cancelled usage should be recorded");
|
||||||
assert_eq!(usage.provider_request_body, Some(captured_body));
|
assert_eq!(usage.provider_request_body, None);
|
||||||
assert_ne!(
|
assert_eq!(usage.provider_request_body_ref, None);
|
||||||
usage.provider_request_body_state,
|
assert_eq!(usage.provider_request_body_state, None);
|
||||||
Some(UsageBodyCaptureState::None)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ use aether_contracts::ProxySnapshot;
|
|||||||
use aether_data_contracts::repository::provider_catalog::{
|
use aether_data_contracts::repository::provider_catalog::{
|
||||||
StoredProviderCatalogEndpoint, StoredProviderCatalogKey, StoredProviderCatalogProvider,
|
StoredProviderCatalogEndpoint, StoredProviderCatalogKey, StoredProviderCatalogProvider,
|
||||||
};
|
};
|
||||||
use aether_provider_pool::build_antigravity_pool_quota_request;
|
use aether_provider_pool::{
|
||||||
use aether_provider_pool::build_antigravity_pool_quota_summary_request;
|
build_antigravity_pool_quota_request, build_antigravity_pool_quota_summary_request,
|
||||||
|
};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|||||||
@@ -46,6 +46,11 @@ fn provider_oauth_service_for_template(
|
|||||||
let adapter = AntigravityProviderOAuthAdapter::default()
|
let adapter = AntigravityProviderOAuthAdapter::default()
|
||||||
.with_token_url_override(token_url)
|
.with_token_url_override(token_url)
|
||||||
.with_user_info_url_override(antigravity_user_info_url);
|
.with_user_info_url_override(antigravity_user_info_url);
|
||||||
|
#[cfg(test)]
|
||||||
|
let adapter = adapter.with_oauth_credentials_for_tests(
|
||||||
|
"gateway-test-antigravity-client-id",
|
||||||
|
"gateway-test-antigravity-client-secret",
|
||||||
|
);
|
||||||
return Ok(ProviderOAuthService::new().with_adapter(Arc::new(adapter)));
|
return Ok(ProviderOAuthService::new().with_adapter(Arc::new(adapter)));
|
||||||
}
|
}
|
||||||
GenericProviderOAuthAdapter::for_provider_type(template.provider_type)
|
GenericProviderOAuthAdapter::for_provider_type(template.provider_type)
|
||||||
|
|||||||
@@ -4000,13 +4000,16 @@ async fn gateway_names_new_antigravity_oauth_account_from_google_userinfo_email_
|
|||||||
.with_encryption_key_for_tests(DEVELOPMENT_ENCRYPTION_KEY),
|
.with_encryption_key_for_tests(DEVELOPMENT_ENCRYPTION_KEY),
|
||||||
)
|
)
|
||||||
.with_provider_oauth_state_entry_for_tests(
|
.with_provider_oauth_state_entry_for_tests(
|
||||||
"nonce-antigravity-123",
|
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||||||
json!({
|
json!({
|
||||||
"nonce": "nonce-antigravity-123",
|
"nonce": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||||||
"key_id": "",
|
"key_id": "",
|
||||||
"provider_id": "provider-antigravity",
|
"provider_id": "provider-antigravity",
|
||||||
"provider_type": "antigravity",
|
"provider_type": "antigravity",
|
||||||
"pkce_verifier": "verifier-antigravity-123",
|
"pkce_verifier": "verifier-antigravity-123",
|
||||||
|
"initiated_by_user_id": "admin-user-123",
|
||||||
|
"initiated_by_session_id": "session-123",
|
||||||
|
"created_at": aether_admin::provider::state::current_unix_secs(),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.with_provider_oauth_token_url_for_tests(
|
.with_provider_oauth_token_url_for_tests(
|
||||||
@@ -4029,7 +4032,7 @@ async fn gateway_names_new_antigravity_oauth_account_from_google_userinfo_email_
|
|||||||
.header(TRUSTED_ADMIN_USER_ROLE_HEADER, "admin")
|
.header(TRUSTED_ADMIN_USER_ROLE_HEADER, "admin")
|
||||||
.header(TRUSTED_ADMIN_SESSION_ID_HEADER, "session-123")
|
.header(TRUSTED_ADMIN_SESSION_ID_HEADER, "session-123")
|
||||||
.json(&json!({
|
.json(&json!({
|
||||||
"callback_url": "http://localhost:51121/oauth2callback?code=antigravity-code-123&state=nonce-antigravity-123"
|
"callback_url": "http://localhost:51121/oauth2callback?code=antigravity-code-123&state=cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
|
||||||
}))
|
}))
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
@@ -4062,14 +4065,7 @@ async fn gateway_names_new_antigravity_oauth_account_from_google_userinfo_email_
|
|||||||
.expect("created key should load");
|
.expect("created key should load");
|
||||||
let persisted = persisted_keys.first().expect("created key should exist");
|
let persisted = persisted_keys.first().expect("created key should exist");
|
||||||
assert_eq!(persisted.name, "[email protected]");
|
assert_eq!(persisted.name, "[email protected]");
|
||||||
let decrypted_auth_config = decrypt_python_fernet_ciphertext(
|
let decrypted_auth_config = decrypt_persisted_provider_auth_config(persisted);
|
||||||
DEVELOPMENT_ENCRYPTION_KEY,
|
|
||||||
persisted
|
|
||||||
.encrypted_auth_config
|
|
||||||
.as_deref()
|
|
||||||
.expect("auth config should be stored"),
|
|
||||||
)
|
|
||||||
.expect("auth config should decrypt");
|
|
||||||
let auth_config: Value =
|
let auth_config: Value =
|
||||||
serde_json::from_str(&decrypted_auth_config).expect("auth config json should parse");
|
serde_json::from_str(&decrypted_auth_config).expect("auth config json should parse");
|
||||||
assert_eq!(auth_config["email"], "[email protected]");
|
assert_eq!(auth_config["email"], "[email protected]");
|
||||||
|
|||||||
@@ -47,8 +47,6 @@ use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
|||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
use wreq::ws::message::Message as WreqWsMessage;
|
use wreq::ws::message::Message as WreqWsMessage;
|
||||||
|
|
||||||
use crate::data::GatewayDataState;
|
|
||||||
|
|
||||||
fn codex_models_snapshot(
|
fn codex_models_snapshot(
|
||||||
api_key_id: &str,
|
api_key_id: &str,
|
||||||
user_id: &str,
|
user_id: &str,
|
||||||
|
|||||||
@@ -289,18 +289,6 @@ fn tunnel_attachment_key(node_id: &str) -> String {
|
|||||||
format!("tunnel.attachments.{node_id}")
|
format!("tunnel.attachments.{node_id}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn system_default_affinity_cache_key(api_key_id: &str, api_format: &str, model: &str) -> String {
|
|
||||||
let scope = aether_scheduler_core::SchedulerAffinityScope::new("system-default", Some(1));
|
|
||||||
aether_scheduler_core::build_scheduler_affinity_cache_key_for_api_key_id_with_client_session_and_scope(
|
|
||||||
api_key_id,
|
|
||||||
api_format,
|
|
||||||
model,
|
|
||||||
None,
|
|
||||||
Some(&scope),
|
|
||||||
)
|
|
||||||
.expect("system-default affinity cache key should build")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sample_tunnel_proxy_node(node_id: &str, tunnel_generation: &str) -> StoredProxyNode {
|
fn sample_tunnel_proxy_node(node_id: &str, tunnel_generation: &str) -> StoredProxyNode {
|
||||||
StoredProxyNode::new(
|
StoredProxyNode::new(
|
||||||
node_id.to_string(),
|
node_id.to_string(),
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ define_candidate_diagnostic_categories!(
|
|||||||
"invalid_request_error",
|
"invalid_request_error",
|
||||||
"kiro_web_search_mcp_unavailable",
|
"kiro_web_search_mcp_unavailable",
|
||||||
"local_stream_candidate_watchdog_timeout",
|
"local_stream_candidate_watchdog_timeout",
|
||||||
|
"local_stream_attempt_cancelled",
|
||||||
"local_sync_attempt_aborted",
|
"local_sync_attempt_aborted",
|
||||||
"local_sync_attempt_cancelled",
|
"local_sync_attempt_cancelled",
|
||||||
"not_found_error",
|
"not_found_error",
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ impl AntigravityProviderOAuthAdapter {
|
|||||||
/// Supply deterministic OAuth client credentials for tests without
|
/// Supply deterministic OAuth client credentials for tests without
|
||||||
/// requiring a process-wide environment variable. Production callers
|
/// requiring a process-wide environment variable. Production callers
|
||||||
/// continue to resolve the secret from the configured environment.
|
/// continue to resolve the secret from the configured environment.
|
||||||
#[cfg(test)]
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn with_oauth_credentials_for_tests(
|
pub fn with_oauth_credentials_for_tests(
|
||||||
mut self,
|
mut self,
|
||||||
|
|||||||
Reference in New Issue
Block a user