allow_me/
validator.rs

1use thiserror::Error;
2
3use crate::{PolicyDefinition, Statement};
4
5/// Trait to extend [`PolicyBuilder`](`crate::PolicyBuilder`) validation for policy definition.
6pub trait PolicyValidator {
7    /// The type of the validation error.
8    type Error;
9
10    /// This method is being called by [`PolicyBuilder`](`crate::PolicyBuilder`) for policy definition
11    /// while [`Policy`](`crate::Policy`) is being constructed.
12    ///
13    /// If a policy definitions fails the validation, the error is returned.
14    fn validate(&self, definition: &PolicyDefinition) -> Result<(), Self::Error>;
15}
16
17/// Provides basic validation that policy definition elements are not empty.
18#[derive(Debug)]
19pub struct DefaultValidator;
20
21impl PolicyValidator for DefaultValidator {
22    type Error = ValidatorError;
23
24    fn validate(&self, definition: &PolicyDefinition) -> Result<(), Self::Error> {
25        let errors = definition
26            .statements()
27            .iter()
28            .flat_map(|statement| visit_statement(statement))
29            .collect::<Vec<_>>();
30
31        if !errors.is_empty() {
32            return Err(ValidatorError::ValidationSummary(errors));
33        }
34        Ok(())
35    }
36}
37
38fn visit_statement(statement: &Statement) -> Vec<String> {
39    let mut result = vec![];
40    if statement.identities().is_empty() {
41        result.push("Identities list must not be empty".into());
42    }
43    if statement.operations().is_empty() {
44        result.push("Operations list must not be empty".into());
45    }
46    result
47}
48
49#[derive(Debug, Error)]
50pub enum ValidatorError {
51    #[error("An error occurred validating policy definition: {0:?}.")]
52    ValidationSummary(Vec<String>),
53}