use crate::SecondaryValidator::{
ChineseIdChecksum, GithubTokenChecksum, IbanChecker, JwtExpirationChecker, NhsCheckDigit,
NonHexChecker,
};
use crate::scanner::RootRuleConfig;
use crate::{MatchAction, RegexRuleConfig, ScannerBuilder, SecondaryValidator};
use chrono::Utc;
#[test]
fn test_luhn_checksum() {
let match_action = MatchAction::Redact {
replacement: "[credit card]".to_string(),
};
let rule = RegexRuleConfig::new("(\\d{16})|((\\d{4} ){3}\\d{4})");
let rule_with_checksum = RootRuleConfig::new(
rule.with_validator(Some(SecondaryValidator::LuhnChecksum))
.build(),
)
.match_action(match_action.clone());
let scanner =
ScannerBuilder::new(&[RootRuleConfig::new(rule.build()).match_action(match_action)])
.build()
.unwrap();
let mut content = "4556997807150071 4111 1111 1111 1111".to_string();
let matches = scanner.scan(&mut content).unwrap();
assert_eq!(matches.len(), 2);
assert_eq!(content, "[credit card] [credit card]");
let scanner = ScannerBuilder::new(&[rule_with_checksum]).build().unwrap();
let mut content = "4556997807150071 4111 1111 1111 1111".to_string();
let matches = scanner.scan(&mut content).unwrap();
assert_eq!(matches.len(), 1);
assert_eq!(content, "4556997807150071 [credit card]");
}
#[test]
fn test_chinese_id_checksum() {
let match_action = MatchAction::Redact {
replacement: "[IDCARD]".to_string(),
};
let rule = RegexRuleConfig::new("\\d+");
let rule_with_checksum =
RootRuleConfig::new(rule.with_validator(Some(ChineseIdChecksum)).build())
.match_action(match_action.clone());
let scanner =
ScannerBuilder::new(&[RootRuleConfig::new(rule.build()).match_action(match_action)])
.build()
.unwrap();
let mut content = "513231200012121657 513231200012121651".to_string();
let matches = scanner.scan(&mut content).unwrap();
assert_eq!(matches.len(), 2);
assert_eq!(content, "[IDCARD] [IDCARD]");
let scanner = ScannerBuilder::new(&[rule_with_checksum]).build().unwrap();
let mut content = "513231200012121657 513231200012121651".to_string();
let matches = scanner.scan(&mut content).unwrap();
assert_eq!(matches.len(), 1);
assert_eq!(content, "[IDCARD] 513231200012121651");
}
#[test]
fn test_iban_checksum() {
let rule_with_checksum = RootRuleConfig::new(
RegexRuleConfig::new("DE[0-9]+")
.with_validator(Some(IbanChecker))
.build(),
)
.match_action(MatchAction::Redact {
replacement: "[IBAN]".to_string(),
});
let mut content = "number=DE44500105175407324931".to_string();
let scanner = ScannerBuilder::new(&[rule_with_checksum.clone()])
.build()
.unwrap();
let matches = scanner.scan(&mut content).unwrap();
assert_eq!(matches.len(), 1);
assert_eq!(content, "number=[IBAN]");
let mut content = "number=DE34500105175407324931".to_string();
let scanner = ScannerBuilder::new(&[rule_with_checksum.clone()])
.build()
.unwrap();
let matches = scanner.scan(&mut content).unwrap();
assert_eq!(matches.len(), 0);
assert_eq!(content, "number=DE34500105175407324931");
}
#[test]
fn test_github_token_checksum() {
let rule = RegexRuleConfig::new("[^ ]+");
let match_action = MatchAction::Redact {
replacement: "[GITHUB]".to_string(),
};
let rule_with_checksum =
RootRuleConfig::new(rule.with_validator(Some(GithubTokenChecksum)).build())
.match_action(match_action.clone());
let scanner =
ScannerBuilder::new(&[RootRuleConfig::new(rule.build()).match_action(match_action)])
.build()
.unwrap();
let mut content =
"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 ghp_M7H4jxUDDWHP4kZ6A4dxlQYsQIWJuq11T4V5"
.to_string();
let matches = scanner.scan(&mut content).unwrap();
assert_eq!(matches.len(), 2);
assert_eq!(content, "[GITHUB] [GITHUB]");
let scanner = ScannerBuilder::new(&[rule_with_checksum]).build().unwrap();
let mut content =
"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 ghp_M7H4jxUDDWHP4kZ6A4dxlQYsQIWJuq11T4V5"
.to_string();
let matches = scanner.scan(&mut content).unwrap();
assert_eq!(matches.len(), 1);
assert_eq!(content, "[GITHUB] ghp_M7H4jxUDDWHP4kZ6A4dxlQYsQIWJuq11T4V5");
}
#[test]
fn test_jwt_expiration_checker() {
use crate::secondary_validation::generate_jwt;
let rule = RootRuleConfig::new(
RegexRuleConfig::new("[A-Za-z0-9._-]+")
.with_validator(Some(JwtExpirationChecker))
.build(),
)
.match_action(MatchAction::Redact {
replacement: "[JWT]".to_string(),
});
let scanner = ScannerBuilder::new(&[rule]).build().unwrap();
let future_time_as_string = (Utc::now().timestamp() + 1000000).to_string();
let mut content = generate_jwt(future_time_as_string).to_string();
let matches = scanner.scan(&mut content).unwrap();
assert_eq!(matches.len(), 1);
assert_eq!(content, "[JWT]");
let past_time_as_string = (Utc::now().timestamp() - 1000000).to_string();
let mut content = generate_jwt(past_time_as_string).to_string();
let matches = scanner.scan(&mut content).unwrap();
assert_eq!(matches.len(), 0);
}
#[test]
fn test_nhs_checksum() {
let rule_with_checksum = RootRuleConfig::new(
RegexRuleConfig::new(".+")
.with_validator(Some(NhsCheckDigit))
.build(),
)
.match_action(MatchAction::Redact {
replacement: "[NHS]".to_string(),
});
let mut content = "1234567881".to_string();
let scanner = ScannerBuilder::new(&[rule_with_checksum.clone()])
.build()
.unwrap();
let matches = scanner.scan(&mut content).unwrap();
assert_eq!(matches.len(), 1);
assert_eq!(content, "[NHS]");
}
#[test]
fn test_non_hex_checker_filters_pure_hex() {
let rule = RegexRuleConfig::new("[a-zA-Z0-9_]{16,}");
let match_action = MatchAction::Redact {
replacement: "[token]".to_string(),
};
let rule_with_validator =
RootRuleConfig::new(rule.clone().with_validator(Some(NonHexChecker)).build())
.match_action(match_action.clone());
let scanner_without =
ScannerBuilder::new(&[RootRuleConfig::new(rule.build()).match_action(match_action)])
.build()
.unwrap();
let mut pure_hex = "0123456789abcdef".to_string();
assert_eq!(scanner_without.scan(&mut pure_hex).unwrap().len(), 1);
let scanner_with = ScannerBuilder::new(&[rule_with_validator]).build().unwrap();
let mut pure_hex_again = "0123456789abcdef".to_string();
assert_eq!(scanner_with.scan(&mut pure_hex_again).unwrap().len(), 0);
assert_eq!(pure_hex_again, "0123456789abcdef");
let mut with_prefix = "sk_live_0123456789abcd".to_string();
assert_eq!(scanner_with.scan(&mut with_prefix).unwrap().len(), 1);
assert_eq!(with_prefix, "[token]");
}