Skip to content

Commit 58bf40e

Browse files
committed
Redact passwords in Client's Debug implementation
1 parent f7141a3 commit 58bf40e

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

influxdb/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@ wasm-client = ["surf", "surf/wasm-client"]
4141

4242
[dev-dependencies]
4343
async-std = { version = "1.6.5", features = ["attributes", "tokio02", "tokio1"] }
44+
indoc = "1.0"
4445
tokio = { version = "1.7", features = ["macros", "rt-multi-thread"] }

influxdb/src/client/mod.rs

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,49 @@ use futures_util::TryFutureExt;
1919
use http::StatusCode;
2020
#[cfg(feature = "reqwest")]
2121
use reqwest::{Client as HttpClient, Response as HttpResponse};
22+
use std::collections::{BTreeMap, HashMap};
23+
use std::fmt::{self, Debug, Formatter};
24+
use std::sync::Arc;
2225
#[cfg(feature = "surf")]
2326
use surf::{Client as HttpClient, Response as HttpResponse};
2427

2528
use crate::query::QueryType;
2629
use crate::Error;
2730
use crate::Query;
28-
use std::collections::HashMap;
29-
use std::sync::Arc;
3031

31-
#[derive(Clone, Debug)]
32+
#[derive(Clone)]
3233
/// Internal Representation of a Client
3334
pub struct Client {
3435
pub(crate) url: Arc<String>,
3536
pub(crate) parameters: Arc<HashMap<&'static str, String>>,
3637
pub(crate) client: HttpClient,
3738
}
3839

40+
struct RedactPassword<'a>(&'a HashMap<&'static str, String>);
41+
42+
impl<'a> Debug for RedactPassword<'a> {
43+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
44+
let entries = self
45+
.0
46+
.iter()
47+
.map(|(k, v)| match *k {
48+
"p" => (*k, "<redacted>"),
49+
_ => (*k, v.as_str()),
50+
})
51+
.collect::<BTreeMap<&'static str, &str>>();
52+
f.debug_map().entries(entries.into_iter()).finish()
53+
}
54+
}
55+
56+
impl Debug for Client {
57+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
58+
f.debug_struct("Client")
59+
.field("url", &self.url)
60+
.field("parameters", &RedactPassword(&self.parameters))
61+
.finish_non_exhaustive()
62+
}
63+
}
64+
3965
impl Client {
4066
/// Instantiates a new [`Client`](crate::Client)
4167
///
@@ -260,6 +286,25 @@ pub(crate) fn check_status(res: &HttpResponse) -> Result<(), Error> {
260286
#[cfg(test)]
261287
mod tests {
262288
use super::Client;
289+
use indoc::indoc;
290+
291+
#[test]
292+
fn test_client_debug_redacted_password() {
293+
let client = Client::new("https://localhost:8086", "db").with_auth("user", "pass");
294+
let actual = format!("{:#?}", client);
295+
let expected = indoc! { r#"
296+
Client {
297+
url: "https://localhost:8086",
298+
parameters: {
299+
"db": "db",
300+
"p": "<redacted>",
301+
"u": "user",
302+
},
303+
..
304+
}
305+
"# };
306+
assert_eq!(actual.trim(), expected.trim());
307+
}
263308

264309
#[test]
265310
fn test_fn_database() {

0 commit comments

Comments
 (0)