Skip to main content

opendev_models/config/
permissions.rs

1//! Permission-related configuration models.
2
3use regex::Regex;
4use serde::{Deserialize, Serialize};
5
6pub(super) fn default_true() -> bool {
7    true
8}
9
10/// Permission settings for a specific tool.
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct ToolPermission {
13    #[serde(default = "default_true")]
14    pub enabled: bool,
15    #[serde(default)]
16    pub always_allow: bool,
17    #[serde(default)]
18    pub deny_patterns: Vec<String>,
19}
20
21impl Default for ToolPermission {
22    fn default() -> Self {
23        Self {
24            enabled: true,
25            always_allow: false,
26            deny_patterns: Vec::new(),
27        }
28    }
29}
30
31impl ToolPermission {
32    /// Check if a target (file path, command, etc.) is allowed.
33    pub fn is_allowed(&self, target: &str) -> bool {
34        if !self.enabled {
35            return false;
36        }
37        if self.always_allow {
38            return true;
39        }
40        !self.deny_patterns.iter().any(|pattern| {
41            Regex::new(pattern)
42                .map(|re| re.is_match(target))
43                .unwrap_or(false)
44        })
45    }
46}
47
48/// Global permission configuration.
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct PermissionConfig {
51    #[serde(default)]
52    pub file_write: ToolPermission,
53    #[serde(default)]
54    pub file_read: ToolPermission,
55    #[serde(default = "default_bash_permission")]
56    pub bash: ToolPermission,
57    #[serde(default)]
58    pub git: ToolPermission,
59    #[serde(default)]
60    pub web_fetch: ToolPermission,
61}
62
63fn default_bash_permission() -> ToolPermission {
64    ToolPermission {
65        enabled: true,
66        always_allow: false,
67        deny_patterns: vec![
68            "rm -rf /".to_string(),
69            "sudo rm -rf /*".to_string(),
70            "chmod -R 777 /*".to_string(),
71        ],
72    }
73}
74
75impl Default for PermissionConfig {
76    fn default() -> Self {
77        Self {
78            file_write: ToolPermission::default(),
79            file_read: ToolPermission::default(),
80            bash: default_bash_permission(),
81            git: ToolPermission::default(),
82            web_fetch: ToolPermission::default(),
83        }
84    }
85}
86
87#[cfg(test)]
88#[path = "permissions_tests.rs"]
89mod tests;