api_testing_core/
redact.rs1use crate::Result;
2
3pub const REDACTED: &str = "<REDACTED>";
4
5fn should_redact_key(key: &str) -> bool {
6 let k = key.trim().to_ascii_lowercase();
7 matches!(
8 k.as_str(),
9 "accesstoken"
10 | "access_token"
11 | "refreshtoken"
12 | "refresh_token"
13 | "password"
14 | "token"
15 | "apikey"
16 | "api_key"
17 | "authorization"
18 | "cookie"
19 | "set-cookie"
20 )
21}
22
23fn redact_value(value: &mut serde_json::Value) {
24 *value = serde_json::Value::String(REDACTED.to_string());
25}
26
27fn redact_in_json(value: &mut serde_json::Value) {
28 match value {
29 serde_json::Value::Object(map) => {
30 for (k, v) in map.iter_mut() {
31 if should_redact_key(k) {
32 redact_value(v);
33 } else {
34 redact_in_json(v);
35 }
36 }
37 }
38 serde_json::Value::Array(values) => {
39 for v in values {
40 redact_in_json(v);
41 }
42 }
43 _ => {}
44 }
45}
46
47pub fn redact_json(value: &mut serde_json::Value) -> Result<()> {
51 redact_in_json(value);
52 Ok(())
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use pretty_assertions::assert_eq;
59
60 #[test]
61 fn redact_replaces_common_secret_fields_recursively() {
62 let mut v = serde_json::json!({
63 "accessToken": "a",
64 "access_token": "a2",
65 "refreshToken": "b",
66 "refresh_token": "b2",
67 "password": "c",
68 "token": "d",
69 "apiKey": "e",
70 "api_key": "e2",
71 "authorization": "Bearer x",
72 "cookie": "a=b",
73 "set-cookie": "c=d",
74 "nested": {
75 "Authorization": "Bearer y",
76 "ok": "keep"
77 },
78 "arr": [
79 {"token": "t"},
80 {"ok": 1}
81 ]
82 });
83
84 redact_json(&mut v).unwrap();
85
86 assert_eq!(v["accessToken"], REDACTED);
87 assert_eq!(v["access_token"], REDACTED);
88 assert_eq!(v["refreshToken"], REDACTED);
89 assert_eq!(v["refresh_token"], REDACTED);
90 assert_eq!(v["password"], REDACTED);
91 assert_eq!(v["token"], REDACTED);
92 assert_eq!(v["apiKey"], REDACTED);
93 assert_eq!(v["api_key"], REDACTED);
94 assert_eq!(v["authorization"], REDACTED);
95 assert_eq!(v["cookie"], REDACTED);
96 assert_eq!(v["set-cookie"], REDACTED);
97 assert_eq!(v["nested"]["Authorization"], REDACTED);
98 assert_eq!(v["nested"]["ok"], "keep");
99 assert_eq!(v["arr"][0]["token"], REDACTED);
100 assert_eq!(v["arr"][1]["ok"], 1);
101 }
102}