vtcode_safety/sandboxing/
permissions.rs1use std::path::PathBuf;
4
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
12#[serde(rename_all = "snake_case")]
13pub enum SandboxPermissions {
14 #[default]
16 UseDefault,
17
18 RequireEscalated,
20
21 WithAdditionalPermissions,
23
24 BypassSandbox,
26}
27
28impl SandboxPermissions {
29 fn requires_approval(&self) -> bool {
31 matches!(self, Self::RequireEscalated | Self::WithAdditionalPermissions | Self::BypassSandbox)
32 }
33
34 pub fn requires_escalated_permissions(&self) -> bool {
36 matches!(self, Self::RequireEscalated | Self::BypassSandbox)
37 }
38
39 fn requires_additional_permissions(&self) -> bool {
41 !matches!(self, Self::UseDefault)
42 }
43
44 pub fn uses_additional_permissions(&self) -> bool {
46 matches!(self, Self::WithAdditionalPermissions)
47 }
48
49 fn bypasses_sandbox(&self) -> bool {
51 matches!(self, Self::BypassSandbox)
52 }
53
54 fn merge(&self, other: &Self) -> Self {
56 use SandboxPermissions::*;
57 match (self, other) {
58 (BypassSandbox, _) | (_, BypassSandbox) => BypassSandbox,
59 (RequireEscalated, _) | (_, RequireEscalated) => RequireEscalated,
60 (WithAdditionalPermissions, _) | (_, WithAdditionalPermissions) => WithAdditionalPermissions,
61 (UseDefault, UseDefault) => UseDefault,
62 }
63 }
64}
65
66#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
68pub struct AdditionalPermissions {
69 #[serde(default, skip_serializing_if = "Vec::is_empty")]
71 pub fs_read: Vec<PathBuf>,
72 #[serde(default, skip_serializing_if = "Vec::is_empty")]
74 pub fs_write: Vec<PathBuf>,
75}
76
77impl AdditionalPermissions {
78 pub fn is_empty(&self) -> bool {
79 self.fs_read.is_empty() && self.fs_write.is_empty()
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn test_default_permissions() {
89 let perm = SandboxPermissions::default();
90 assert!(!perm.requires_approval());
91 assert!(!perm.bypasses_sandbox());
92 }
93
94 #[test]
95 fn test_escalated_permissions() {
96 let perm = SandboxPermissions::RequireEscalated;
97 assert!(perm.requires_approval());
98 assert!(!perm.bypasses_sandbox());
99 assert!(perm.requires_escalated_permissions());
100 }
101
102 #[test]
103 fn test_bypass_permissions() {
104 let perm = SandboxPermissions::BypassSandbox;
105 assert!(perm.requires_approval());
106 assert!(perm.bypasses_sandbox());
107 assert!(perm.requires_escalated_permissions());
108 }
109
110 #[test]
111 fn test_with_additional_permissions() {
112 let perm = SandboxPermissions::WithAdditionalPermissions;
113 assert!(perm.requires_approval());
114 assert!(perm.requires_additional_permissions());
115 assert!(perm.uses_additional_permissions());
116 assert!(!perm.requires_escalated_permissions());
117 assert!(!perm.bypasses_sandbox());
118 }
119
120 #[test]
121 fn test_merge_permissions() {
122 use SandboxPermissions::*;
123
124 assert_eq!(UseDefault.merge(&UseDefault), UseDefault);
125 assert_eq!(UseDefault.merge(&WithAdditionalPermissions), WithAdditionalPermissions);
126 assert_eq!(UseDefault.merge(&RequireEscalated), RequireEscalated);
127 assert_eq!(RequireEscalated.merge(&BypassSandbox), BypassSandbox);
128 }
129}