orion_accessor/addr/access_ctrl/
rule.rs1use crate::prelude::*;
2use serde_derive::{Deserialize, Serialize};
3use wildmatch::WildMatch;
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Getters)]
6#[getset(get = "pub")]
7pub struct Rule {
8 #[serde(skip)]
9 matchs: WildMatch,
10 pattern: String,
11 target: String,
12}
13
14impl Rule {
15 pub fn new<S: AsRef<str>, S2: Into<String>>(matchs: S, target: S2) -> Self {
16 let pattern = matchs.as_ref().to_string();
17 Self {
18 matchs: WildMatch::new(&pattern),
19 pattern,
20 target: target.into(),
21 }
22 }
23 pub fn replace(&self, input: &str) -> Option<String> {
24 if self.matchs.matches(input) {
25 if let Some(star_idx) = self.pattern.find('*') {
27 let prefix = &self.pattern[..star_idx];
28 if let Some(suffix) = input.strip_prefix(prefix) {
29 return Some(format!("{}{suffix}", self.target));
30 }
31 }
32 None
34 } else {
35 None
36 }
37 }
38}
39impl EnvEvalable<Rule> for Rule {
40 fn env_eval(self, dict: &EnvDict) -> Rule {
41 Rule::new(self.pattern.env_eval(dict), self.target.env_eval(dict))
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn test_rule2() {
51 let rule = Rule::new(
52 "https://github.com/galaxy-sec/galaxy-flow*",
53 "https://gflow.com",
54 );
55 let url = rule.replace("https://github.com/galaxy-sec/galaxy-flow/releases/download/v0.8.5/galaxy-flow-v0.8.5-aarch64-apple-darwin.tar.gz");
56 assert_eq!(url, Some("https://gflow.com/releases/download/v0.8.5/galaxy-flow-v0.8.5-aarch64-apple-darwin.tar.gz".to_string()));
57 }
58
59 #[test]
60 fn test_rule_env_eval() {
61 let mut env_dict = EnvDict::new();
62 env_dict.insert(
63 "DOMAIN".to_string(),
64 ValueType::String("example.com".to_string()),
65 );
66 env_dict.insert(
67 "TARGET".to_string(),
68 ValueType::String("redirect.com".to_string()),
69 );
70
71 let rule = Rule::new("https://${DOMAIN}/*", "https://${TARGET}");
72 let evaluated = rule.env_eval(&env_dict);
73
74 assert_eq!(evaluated.pattern(), "https://example.com/*");
75 assert_eq!(evaluated.target(), "https://redirect.com");
76 }
77
78 #[test]
79 fn test_rule_env_eval_with_defaults() {
80 let env_dict = EnvDict::new();
81
82 let rule = Rule::new(
83 "https://${MISSING_DOMAIN:default.com}/*",
84 "https://${MISSING_TARGET:target.com}",
85 );
86 let evaluated = rule.env_eval(&env_dict);
87
88 assert_eq!(evaluated.pattern(), "https://default.com/*");
89 assert_eq!(evaluated.target(), "https://target.com");
90 }
91}