use crate::role_expr::RoleExpr;
use std::collections::HashSet;
pub struct RoleValidator {}
impl RoleValidator {
pub fn is_valid(roles: &HashSet<String>, role_expr: &RoleExpr) -> bool {
match role_expr {
RoleExpr::Invalid => false,
RoleExpr::And(a, b) => {
Self::is_valid(roles, a.as_ref()) && Self::is_valid(roles, b.as_ref())
}
RoleExpr::Or(a, b) => {
Self::is_valid(roles, a.as_ref()) || Self::is_valid(roles, b.as_ref())
}
RoleExpr::Not(a) => !Self::is_valid(roles, a.as_ref()),
RoleExpr::Role(role) => roles.contains(role),
}
}
}
#[cfg(test)]
mod test {
use super::RoleValidator;
use crate::role_expr::RoleExpr;
use std::collections::HashSet;
#[test]
fn validate_expressions() {
let mut roles = HashSet::new();
roles.insert("role1".to_string());
roles.insert("role2".to_string());
let e = RoleExpr::role("role1".to_string());
assert_eq!(RoleValidator::is_valid(&roles, &e), true);
let e = RoleExpr::role("role1".to_string()).and(RoleExpr::role("role2".to_string()));
assert_eq!(RoleValidator::is_valid(&roles, &e), true);
let e = RoleExpr::role("role1".to_string()).and(RoleExpr::role("role3".to_string()));
assert_eq!(RoleValidator::is_valid(&roles, &e), false);
let e = RoleExpr::role("role1".to_string()).or(RoleExpr::role("role3".to_string()));
assert_eq!(RoleValidator::is_valid(&roles, &e), true);
let e = RoleExpr::role("role3".to_string()).or(RoleExpr::role("role4".to_string()));
assert_eq!(RoleValidator::is_valid(&roles, &e), false);
let e = RoleExpr::role("role3".to_string()).not();
assert_eq!(RoleValidator::is_valid(&roles, &e), true);
let e = RoleExpr::role("role1".to_string()).not();
assert_eq!(RoleValidator::is_valid(&roles, &e), false);
let e = RoleExpr::invalid();
assert_eq!(RoleValidator::is_valid(&roles, &e), false);
}
}