sol_cerberus/utils/
rules.rs

1use crate::Errors;
2use anchor_lang::prelude::*;
3
4pub fn valid_rule(text: &String, allow_wildcard: bool) -> bool {
5    if text.is_empty() || text.as_bytes().len() > 16 {
6        return false;
7    }
8    for char in text.chars() {
9        if !char.is_ascii_alphanumeric() {
10            // Allow wildcard character "*" on all fields but Role.
11            if allow_wildcard && char == '*' && text.as_bytes().len() == 1 {
12                continue;
13            }
14            return false;
15        }
16    }
17
18    true
19}
20pub fn valid_rules(role: &String, resource: &String, permission: &String) -> bool {
21    for (index, item) in vec![role, resource, permission].iter().enumerate() {
22        if !valid_rule(item, index > 0) {
23            return false;
24        }
25    }
26    true
27}
28
29pub fn allowed_perm(rule1: &String, rule2: &String) -> bool {
30    if rule1 == rule2 || rule2 == "*" {
31        return true;
32    }
33
34    false
35}
36
37pub fn validate_ns_permission(namespace: &String) -> Result<()> {
38    if namespace != &"*" {
39        if let Err(_) = namespace.parse::<u8>() {
40            return err!(Errors::InvalidNamespace);
41        }
42    }
43    Ok(())
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49
50    #[test]
51    fn test_valid_rules() {
52        assert_eq!(
53            valid_rules(&"a".to_string(), &"b".to_string(), &"c".to_string()),
54            true
55        );
56        // Empty Role, Resource or Permission are not allowed.
57        assert_eq!(
58            valid_rules(&"".to_string(), &"b".to_string(), &"c".to_string()),
59            false
60        );
61        // 16 Characters max per Role, Resource or Permission.
62        assert_eq!(
63            valid_rules(
64                &"12345678901234567".to_string(),
65                &"b".to_string(),
66                &"c".to_string()
67            ),
68            false
69        );
70        // Only Alphanumeric chars allowed.
71        assert_eq!(
72            valid_rules(&"-".to_string(), &"b".to_string(), &"C".to_string()),
73            false
74        );
75        // Allow "*" on all fields but Role.
76        assert_eq!(
77            valid_rules(&"A".to_string(), &"*".to_string(), &"*".to_string()),
78            true
79        );
80        assert_eq!(
81            valid_rules(&"*".to_string(), &"B".to_string(), &"C".to_string()),
82            false
83        );
84    }
85
86    #[test]
87    fn test_valid_permission() {
88        assert_eq!(allowed_perm(&"add".to_string(), &"add".to_string()), true);
89        assert_eq!(allowed_perm(&"add".to_string(), &"edit".to_string()), false);
90        assert_eq!(allowed_perm(&"add".to_string(), &"*".to_string()), true);
91    }
92
93    #[test]
94    fn test_validate_ns_permission() {
95        assert_eq!(validate_ns_permission(&"*".to_string()), Ok(()));
96        assert_eq!(validate_ns_permission(&"0".to_string()), Ok(()));
97        assert_eq!(validate_ns_permission(&"1".to_string()), Ok(()));
98        assert_eq!(validate_ns_permission(&"255".to_string()), Ok(()));
99        assert_eq!(
100            validate_ns_permission(&"256".to_string()),
101            err!(Errors::InvalidNamespace)
102        );
103        assert_eq!(
104            validate_ns_permission(&"-1".to_string()),
105            err!(Errors::InvalidNamespace)
106        );
107        assert_eq!(
108            validate_ns_permission(&"a".to_string()),
109            err!(Errors::InvalidNamespace)
110        );
111    }
112}