File size: 2,585 Bytes
afa0cbf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | //! CLI-only glue between Codex authentication and generic AWS signing.
//!
//! Keeping this adapter here leaves `codex-api` and `codex-aws-auth` independent.
use std::sync::Arc;
use codex_api::AuthError;
use codex_api::AuthProvider;
use codex_api::SharedAuthProvider;
use codex_aws_auth::AwsAuthConfig;
use codex_aws_auth::AwsAuthContext;
use codex_aws_auth::AwsAuthError;
use codex_aws_auth::AwsRequestToSign;
use codex_http_client::Request;
use codex_http_client::RequestBody;
use codex_http_client::RequestCompression;
use http::HeaderMap;
/// Creates a SigV4 provider, preferring an explicit profile over the default credential chain.
pub(super) async fn aws_sigv4_auth_provider(
mut config: AwsAuthConfig,
) -> Result<SharedAuthProvider, AwsAuthError> {
config.profile = config
.profile
.map(|profile| profile.trim().to_string())
.filter(|profile| !profile.is_empty());
config.region = config
.region
.map(|region| region.trim().to_string())
.filter(|region| !region.is_empty());
let context = if config.profile.is_some() {
AwsAuthContext::load_profile(config).await
} else {
AwsAuthContext::load(config).await
}?;
Ok(Arc::new(AwsSigV4AuthProvider { context }))
}
#[derive(Debug)]
struct AwsSigV4AuthProvider {
context: AwsAuthContext,
}
impl AuthProvider for AwsSigV4AuthProvider {
fn add_auth_headers(&self, _headers: &mut HeaderMap) {}
fn apply_auth(&self, mut request: Request) -> codex_api::AuthProviderFuture<'_> {
Box::pin(async move {
let prepared = request.prepare_body_for_send().map_err(AuthError::Build)?;
let signed = self
.context
.sign(AwsRequestToSign {
method: request.method.clone(),
url: request.url.clone(),
headers: prepared.headers.clone(),
body: prepared.body_bytes(),
})
.await
.map_err(|error| {
if error.is_retryable() {
AuthError::Transient(error.to_string())
} else {
AuthError::Build(error.to_string())
}
})?;
request.url = signed.url;
request.headers = signed.headers;
request.body = prepared.body.map(RequestBody::Raw);
request.compression = RequestCompression::None;
Ok(request)
})
}
}
#[cfg(test)]
#[path = "exec_server_auth_tests.rs"]
mod tests;
|