sandbox_runtime/manager/
filesystem.rs

1//! Filesystem configuration processing.
2
3use std::path::{Path, PathBuf};
4
5use crate::config::FilesystemConfig;
6use crate::utils::{contains_glob_chars, normalize_path_for_sandbox};
7
8/// Processed filesystem read restriction configuration.
9#[derive(Debug, Clone, Default)]
10pub struct FsReadRestrictionConfig {
11    /// Paths denied for reading.
12    pub deny_paths: Vec<PathBuf>,
13    /// Glob patterns denied for reading.
14    pub deny_patterns: Vec<String>,
15}
16
17/// Processed filesystem write restriction configuration.
18#[derive(Debug, Clone, Default)]
19pub struct FsWriteRestrictionConfig {
20    /// Paths allowed for writing.
21    pub allow_paths: Vec<PathBuf>,
22    /// Glob patterns allowed for writing.
23    pub allow_patterns: Vec<String>,
24    /// Paths denied for writing (overrides allow).
25    pub deny_paths: Vec<PathBuf>,
26    /// Glob patterns denied for writing.
27    pub deny_patterns: Vec<String>,
28}
29
30/// Process filesystem configuration into normalized paths.
31pub fn process_fs_config(config: &FilesystemConfig) -> (FsReadRestrictionConfig, FsWriteRestrictionConfig) {
32    let mut read_config = FsReadRestrictionConfig::default();
33    let mut write_config = FsWriteRestrictionConfig::default();
34
35    // Process deny_read
36    for path in &config.deny_read {
37        let normalized = normalize_path_for_sandbox(path);
38        if contains_glob_chars(&normalized) {
39            read_config.deny_patterns.push(normalized);
40        } else {
41            read_config.deny_paths.push(PathBuf::from(normalized));
42        }
43    }
44
45    // Process allow_write
46    for path in &config.allow_write {
47        let normalized = normalize_path_for_sandbox(path);
48        if contains_glob_chars(&normalized) {
49            write_config.allow_patterns.push(normalized);
50        } else {
51            write_config.allow_paths.push(PathBuf::from(normalized));
52        }
53    }
54
55    // Process deny_write
56    for path in &config.deny_write {
57        let normalized = normalize_path_for_sandbox(path);
58        if contains_glob_chars(&normalized) {
59            write_config.deny_patterns.push(normalized);
60        } else {
61            write_config.deny_paths.push(PathBuf::from(normalized));
62        }
63    }
64
65    (read_config, write_config)
66}
67
68/// Check if a path is within any of the allowed paths.
69pub fn is_path_allowed(path: &Path, allowed_paths: &[PathBuf]) -> bool {
70    for allowed in allowed_paths {
71        if path.starts_with(allowed) {
72            return true;
73        }
74    }
75    false
76}
77
78/// Check if a path is denied.
79pub fn is_path_denied(path: &Path, denied_paths: &[PathBuf]) -> bool {
80    for denied in denied_paths {
81        if path.starts_with(denied) || path == denied.as_path() {
82            return true;
83        }
84    }
85    false
86}