Skip to main content

secexit_common/
lib.rs

1use serde::{Deserialize, Serialize};
2use std::fs::File;
3
4#[derive(Serialize, Deserialize, Debug, Clone)]
5pub struct SecurityPolicy {
6    pub revision: u64,
7    pub blocked_domains: Vec<String>,
8    pub blocked_ips: Vec<String>,
9    // Panic button
10    pub lockdown_mode: bool,
11}
12
13impl SecurityPolicy {
14    pub fn default_allow() -> Self {
15        Self {
16            revision: 0,
17            blocked_domains: vec![],
18            blocked_ips: vec![],
19            lockdown_mode: false,
20        }
21    }
22}
23
24pub fn expand_path(path: &str) -> String {
25    if path.starts_with("~/")
26        && let Some(home) = dirs::home_dir()
27            // Convert PathBuf to string and replace the first "~"
28            && let Some(home_str) = home.to_str()
29    {
30        return path.replacen("~", home_str, 1);
31    }
32
33    path.to_string()
34}
35
36pub async fn load_policy(raw_path: &str) -> SecurityPolicy {
37    let path_string = expand_path(raw_path);
38    let path = path_string.as_str();
39
40    if path.starts_with("http://") || path.starts_with("https://") {
41        match reqwest::get(path).await {
42            Ok(resp) => match resp.json::<SecurityPolicy>().await {
43                Ok(p) => {
44                    log::info!("secexit policy (v{}) loaded from URL: {}", p.revision, path);
45                    return p;
46                }
47                Err(e) => log::warn!("Failed to parse policy from URL {}: {}", path, e),
48            },
49            Err(e) => log::warn!("Failed to fetch policy from URL {}: {}", path, e),
50        }
51    } else {
52        if let Ok(file) = File::open(path)
53            && let Ok(p) = serde_json::from_reader::<_, SecurityPolicy>(file)
54        {
55            log::info!("secexit policy (v{}) loaded from: {}", p.revision, path);
56            return p;
57        }
58
59        log::warn!("No policy found at {}.", path);
60    }
61
62    log::warn!("Defaulting to empty policy.");
63    SecurityPolicy::default_allow()
64}