diff --git a/api_generator/src/generator/code_gen/url/enum_builder.rs b/api_generator/src/generator/code_gen/url/enum_builder.rs index 237cbbe1..aa37779e 100644 --- a/api_generator/src/generator/code_gen/url/enum_builder.rs +++ b/api_generator/src/generator/code_gen/url/enum_builder.rs @@ -357,7 +357,7 @@ mod tests { methods: vec![HttpMethod::Get, HttpMethod::Post], parts: { let mut map = BTreeMap::new(); - map.insert("index".to_string(), Type {i + map.insert("index".to_string(), Type { ty: TypeKind::List, description: Some("A comma-separated list of index names to search".to_string()), options: vec![], diff --git a/elasticsearch/src/auth.rs b/elasticsearch/src/auth.rs index b8eeff05..11657f83 100644 --- a/elasticsearch/src/auth.rs +++ b/elasticsearch/src/auth.rs @@ -31,8 +31,10 @@ pub enum Credentials { /// This requires the `native-tls` or `rustls-tls` feature to be enabled. #[cfg(any(feature = "native-tls", feature = "rustls-tls"))] Certificate(ClientCertificate), - /// An id and api_key to use for API key authentication + /// An API key id and secret to use for API key authentication ApiKey(String, String), + /// An API key as a base64-encoded id and secret + EncodedApiKey(String), } #[cfg(any(feature = "native-tls", feature = "rustls-tls"))] diff --git a/elasticsearch/src/http/transport.rs b/elasticsearch/src/http/transport.rs index 22100fe9..44b01358 100644 --- a/elasticsearch/src/http/transport.rs +++ b/elasticsearch/src/http/transport.rs @@ -41,6 +41,7 @@ use lazy_static::lazy_static; use serde::Serialize; use serde_json::Value; use std::{ + convert::TryFrom, error, fmt, fmt::Debug, io::{self, Write}, @@ -492,10 +493,14 @@ impl Transport { write!(encoder, "{}:", i).unwrap(); write!(encoder, "{}", k).unwrap(); } - request_builder.header( - AUTHORIZATION, - HeaderValue::from_bytes(&header_value).unwrap(), - ) + let mut header_value = HeaderValue::from_bytes(&header_value).unwrap(); + header_value.set_sensitive(true); + request_builder.header(AUTHORIZATION, header_value) + } + Credentials::EncodedApiKey(k) => { + let mut header_value = HeaderValue::try_from(format!("ApiKey {}", k)).unwrap(); + header_value.set_sensitive(true); + request_builder.header(AUTHORIZATION, header_value) } } } diff --git a/elasticsearch/tests/auth.rs b/elasticsearch/tests/auth.rs index 17d3f1b1..75935d99 100644 --- a/elasticsearch/tests/auth.rs +++ b/elasticsearch/tests/auth.rs @@ -74,6 +74,32 @@ async fn api_key_header() -> Result<(), failure::Error> { Ok(()) } +#[tokio::test] +async fn encoded_api_key_header() -> Result<(), failure::Error> { + let server = server::http(move |req| async move { + let mut header_value = b"ApiKey ".to_vec(); + { + let mut encoder = EncoderWriter::new(&mut header_value, &BASE64_STANDARD); + write!(encoder, "id:api_key").unwrap(); + } + + assert_eq!( + req.headers()["authorization"], + String::from_utf8(header_value).unwrap() + ); + http::Response::default() + }); + + let builder = client::create_builder(format!("http://{}", server.addr()).as_ref()) + // result of `echo -n "id:api_key" | base64` + .auth(Credentials::EncodedApiKey("aWQ6YXBpX2tleQ==".into())); + + let client = client::create(builder); + let _response = client.ping().send().await?; + + Ok(()) +} + #[tokio::test] async fn bearer_header() -> Result<(), failure::Error> { let server = server::http(move |req| async move {