Skip to content

Commit daca788

Browse files
committed
Add api_token field to client configuration for reading API tokens from env vars
Signed-off-by: Rob Geada <[email protected]>
1 parent 999b24c commit daca788

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

src/clients.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,11 @@ pub async fn create_http_client(
254254
.layer(http_trace_layer())
255255
.layer(TimeoutLayer::new(request_timeout))
256256
.service(client);
257-
Ok(HttpClient::new(base_url, client))
257+
Ok(HttpClient::new(
258+
base_url,
259+
service_config.api_token.clone(),
260+
client,
261+
))
258262
}
259263

260264
pub async fn create_grpc_client<C: Debug + Clone>(

src/clients/http.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,15 +119,17 @@ pub trait HttpClientExt: Client {
119119
pub struct HttpClient {
120120
base_url: Url,
121121
health_url: Url,
122+
api_token: Option<String>,
122123
inner: HttpClientInner,
123124
}
124125

125126
impl HttpClient {
126-
pub fn new(base_url: Url, inner: HttpClientInner) -> Self {
127+
pub fn new(base_url: Url, api_token: Option<String>, inner: HttpClientInner) -> Self {
127128
let health_url = base_url.join("health").unwrap();
128129
Self {
129130
base_url,
130131
health_url,
132+
api_token,
131133
inner,
132134
}
133135
}
@@ -140,6 +142,21 @@ impl HttpClient {
140142
self.base_url.join(path).unwrap()
141143
}
142144

145+
/// Injects the API token as a Bearer token in the Authorization header if configured and present in the environment.
146+
fn inject_api_token(&self, headers: &mut HeaderMap) -> Result<(), Error> {
147+
if let Some(env_var) = &self.api_token
148+
&& let Ok(token) = std::env::var(env_var)
149+
{
150+
headers.insert(
151+
http::header::AUTHORIZATION,
152+
HeaderValue::from_str(&format!("Bearer {}", token)).map_err(|e| Error::Http {
153+
code: StatusCode::INTERNAL_SERVER_ERROR,
154+
message: format!("invalid authorization header: {e}"),
155+
})?,
156+
);
157+
}
158+
Ok(())
159+
}
143160
pub async fn get(
144161
&self,
145162
url: Url,
@@ -162,11 +179,14 @@ impl HttpClient {
162179
&self,
163180
url: Url,
164181
method: Method,
165-
headers: HeaderMap,
182+
mut headers: HeaderMap,
166183
body: impl RequestBody,
167184
) -> Result<Response, Error> {
168185
let ctx = Span::current().context();
186+
187+
self.inject_api_token(&mut headers)?;
169188
let headers = trace::with_traceparent_header(&ctx, headers);
189+
170190
let mut builder = hyper::http::request::Builder::new()
171191
.method(method)
172192
.uri(url.as_uri());

src/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ pub struct ServiceConfig {
8686
pub http2_keep_alive_interval: Option<u64>,
8787
/// Keep-alive timeout in seconds for client calls [currently only for grpc generation]
8888
pub keep_alive_timeout: Option<u64>,
89+
/// Name of environment variable that contains the API key to use for this service [currently only for http generation]
90+
pub api_token: Option<String>,
8991
}
9092

9193
impl ServiceConfig {
@@ -101,6 +103,7 @@ impl ServiceConfig {
101103
max_retries: None,
102104
http2_keep_alive_interval: None,
103105
keep_alive_timeout: None,
106+
api_token: None,
104107
}
105108
}
106109
}

0 commit comments

Comments
 (0)