workerlib/
redact.rs

1//!
2//! Helper utility that can redact sensitive strings common in Lorry
3//!
4
5use fancy_regex::Regex;
6use std::fmt::Display;
7use std::sync::OnceLock;
8
9fn get_expressions() -> &'static Vec<Regex> {
10    static EXPRESSIONS: OnceLock<Vec<Regex>> = OnceLock::new();
11    EXPRESSIONS.get_or_init(|| vec![Regex::new(r##"glpat-[0-9a-zA-Z\-_]*"##).unwrap()])
12}
13
14/// Removes any known sensitive strings from the input and replaces them
15/// with LORRY_REDACTED
16pub fn redact(input: &impl Display) -> String {
17    let mut copy = input.to_string();
18    for expr in get_expressions() {
19        copy = expr.replace_all(&copy, "LORRY_REDACTED").to_string();
20    }
21    copy
22}
23
24#[cfg(test)]
25mod tests {
26    use super::*;
27
28    struct TestCase<'a> {
29        pub input: &'a str,
30        pub expected: &'a str,
31    }
32
33    impl TestCase<'_> {
34        pub fn check(&self) {
35            let result = redact(&self.input.to_string());
36            assert!(result == self.expected);
37        }
38    }
39
40    #[test]
41    fn test_redact() {
42        TestCase {
43            input: "glpat-Y38-kU_3pviux6H1D9ec",
44            expected: "LORRY_REDACTED",
45        }
46        .check();
47        TestCase {
48            input: "glpat-AdmAbJdT-FMYPa_2bQyy",
49            expected: "LORRY_REDACTED",
50        }
51        .check();
52        TestCase {
53            input: "glpat-MjW2FqijnvVBs7yPEoDG",
54            expected: "LORRY_REDACTED",
55        }
56        .check();
57        TestCase {
58            input: "Using git binary to push remote: http://oauth2:glpat-25HjHgcpRJsY_JQweJYa@localhost:9999/lorry-mirrors/test/lorry.git",
59            expected: "Using git binary to push remote: http://oauth2:LORRY_REDACTED@localhost:9999/lorry-mirrors/test/lorry.git",
60        }.check();
61    }
62}