pub mod aws;
pub mod github;
pub mod http;
pub mod slack;
pub mod stripe;
pub use aws::AwsValidator;
pub use github::GitHubValidator;
pub use http::HttpValidator;
pub use slack::SlackValidator;
pub use stripe::StripeValidator;
use crate::models::{Secret, SecretType};
use anyhow::Result;
#[async_trait::async_trait]
pub trait Validator {
async fn validate(&self, secret: &Secret) -> Result<bool>;
fn supports(&self, secret_type: &SecretType) -> bool;
}
pub async fn validate_secret(secret: &mut Secret) -> Result<()> {
let validators: Vec<Box<dyn Validator + Send + Sync>> = vec![
Box::new(AwsValidator::new()),
Box::new(GitHubValidator::new()),
Box::new(SlackValidator::new()),
Box::new(StripeValidator::new()),
];
for validator in validators {
if validator.supports(&secret.secret_type) {
match validator.validate(secret).await {
Ok(is_valid) => {
secret.validated = Some(is_valid);
return Ok(());
}
Err(_) => {
secret.validated = None;
}
}
}
}
Ok(())
}
pub async fn validate_secrets_parallel(secrets: &mut [Secret]) -> Result<()> {
use tokio::task::JoinSet;
let validators: Vec<Box<dyn Validator + Send + Sync>> = vec![
Box::new(AwsValidator::new()),
Box::new(GitHubValidator::new()),
Box::new(SlackValidator::new()),
Box::new(StripeValidator::new()),
];
let mut tasks: JoinSet<(usize, Option<bool>)> = JoinSet::new();
for (idx, secret) in secrets.iter().enumerate() {
let mut found_validator = false;
for v in &validators {
if v.supports(&secret.secret_type) {
found_validator = true;
break;
}
}
if !found_validator {
continue;
}
let secret_clone = secret.clone();
tasks.spawn(async move {
let validators: Vec<Box<dyn Validator + Send + Sync>> = vec![
Box::new(AwsValidator::new()),
Box::new(GitHubValidator::new()),
Box::new(SlackValidator::new()),
Box::new(StripeValidator::new()),
];
for validator in &validators {
if validator.supports(&secret_clone.secret_type) {
match validator.validate(&secret_clone).await {
Ok(is_valid) => return (idx, Some(is_valid)),
Err(_) => return (idx, None),
}
}
}
(idx, None)
});
}
while let Some(result) = tasks.join_next().await {
if let Ok((idx, validated)) = result {
secrets[idx].validated = validated;
}
}
Ok(())
}