motorx_core/config/
authentication.rs

1use regex::Regex;
2
3#[cfg_attr(feature = "serde-config", derive(serde::Deserialize))]
4#[derive(Debug)]
5pub struct Authentication {
6    #[cfg_attr(feature = "serde-config", serde(default))]
7    pub exclude: Vec<PathWithWildCard>,
8    pub source: AuthenticationSource,
9}
10
11#[cfg_attr(feature = "serde-config", derive(serde::Deserialize))]
12#[cfg_attr(feature = "serde-config", serde(rename_all = "snake_case"))]
13#[derive(Debug)]
14pub enum AuthenticationSource {
15    /// Authenticate with another registered upstream
16    Upstream {
17        name: String,
18        path: String,
19        #[cfg_attr(feature = "serde-config", serde(default))]
20        key: usize,
21    },
22    Path(String),
23}
24
25#[derive(Debug)]
26pub enum PathWithWildCard {
27    Path(String),
28    WithWildCard(Regex),
29}
30
31impl PathWithWildCard {
32    pub fn matches(&self, subject_path: &str) -> bool {
33        match self {
34            PathWithWildCard::Path(path) => path == subject_path,
35            PathWithWildCard::WithWildCard(re) => re.is_match(subject_path),
36        }
37    }
38}
39
40#[cfg(feature = "serde-config")]
41mod de_path_with_wild_card {
42    use regex::Regex;
43    use serde::de::{Deserialize, Visitor};
44
45    use super::PathWithWildCard;
46
47    struct PathWithWildCardVisitor;
48
49    impl<'de> Visitor<'de> for PathWithWildCardVisitor {
50        type Value = PathWithWildCard;
51
52        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
53            write!(
54                formatter,
55                "A valid path, optionally with wildcards (ex. /path/here or /path/with/*/wildcards"
56            )
57        }
58
59        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
60        where
61            E: serde::de::Error,
62        {
63            if !v.contains("*") {
64                Ok(PathWithWildCard::Path(v.to_owned()))
65            } else {
66                let re_string = v.replace("*", ".+");
67                let regex =
68                    Regex::new(&format!(r"^{re_string}$")).map_err(|e| E::custom(e.to_string()))?;
69                Ok(PathWithWildCard::WithWildCard(regex))
70            }
71        }
72    }
73
74    impl<'de> Deserialize<'de> for PathWithWildCard {
75        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
76        where
77            D: serde::Deserializer<'de>,
78        {
79            deserializer.deserialize_str(PathWithWildCardVisitor)
80        }
81    }
82}