use std::sync::LazyLock;
use regex::Regex;
use super::placeholder::Placeholders;
use super::{Detection, Detector, LeafContext};
static CREDENTIALED_URI: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(
r#"(?i)(?-u:\b)[a-z][a-z0-9+.-]{1,31}://[^\s/?#@"'`<>:]*:([^\s/?#@"'`<>]+)@[^\s"'`<>]+"#,
)
.unwrap()
});
#[derive(Debug, Clone, Default)]
pub struct CredentialedUriDetector {
placeholders: Placeholders,
}
impl CredentialedUriDetector {
pub fn new(placeholders: &Placeholders) -> Self {
Self {
placeholders: placeholders.clone(),
}
}
}
impl Detector for CredentialedUriDetector {
fn name(&self) -> &str {
"credentialed_uri"
}
fn detect(&self, value: &str, _ctx: &LeafContext<'_>, out: &mut Vec<Detection>) {
for caps in CREDENTIALED_URI.captures_iter(value) {
let (uri, [password]) = caps.extract();
if self.placeholders.has_real_value(password) {
let start = caps.get(0).expect("group 0 always participates").start();
out.push(Detection::new(start..start + uri.len(), self.name()));
}
}
}
}