vtcode_core/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 pub fn requires_approval(&self) -> bool {
31 matches!(
32 self,
33 Self::RequireEscalated | Self::WithAdditionalPermissions | Self::BypassSandbox
34 )
35 }
36
37 pub fn requires_escalated_permissions(&self) -> bool {
39 matches!(self, Self::RequireEscalated | Self::BypassSandbox)
40 }
41
42 pub fn requires_additional_permissions(&self) -> bool {
44 !matches!(self, Self::UseDefault)
45 }
46
47 pub fn uses_additional_permissions(&self) -> bool {
49 matches!(self, Self::WithAdditionalPermissions)
50 }
51
52 pub fn bypasses_sandbox(&self) -> bool {
54 matches!(self, Self::BypassSandbox)
55 }
56
57 pub fn merge(&self, other: &Self) -> Self {
59 use SandboxPermissions::*;
60 match (self, other) {
61 (BypassSandbox, _) | (_, BypassSandbox) => BypassSandbox,
62 (RequireEscalated, _) | (_, RequireEscalated) => RequireEscalated,
63 (WithAdditionalPermissions, _) | (_, WithAdditionalPermissions) => {
64 WithAdditionalPermissions
65 }
66 (UseDefault, UseDefault) => UseDefault,
67 }
68 }
69}
70
71#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
73pub struct AdditionalPermissions {
74 #[serde(default, skip_serializing_if = "Vec::is_empty")]
76 pub fs_read: Vec<PathBuf>,
77 #[serde(default, skip_serializing_if = "Vec::is_empty")]
79 pub fs_write: Vec<PathBuf>,
80}
81
82impl AdditionalPermissions {
83 pub fn is_empty(&self) -> bool {
84 self.fs_read.is_empty() && self.fs_write.is_empty()
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91
92 #[test]
93 fn test_default_permissions() {
94 let perm = SandboxPermissions::default();
95 assert!(!perm.requires_approval());
96 assert!(!perm.bypasses_sandbox());
97 }
98
99 #[test]
100 fn test_escalated_permissions() {
101 let perm = SandboxPermissions::RequireEscalated;
102 assert!(perm.requires_approval());
103 assert!(!perm.bypasses_sandbox());
104 assert!(perm.requires_escalated_permissions());
105 }
106
107 #[test]
108 fn test_bypass_permissions() {
109 let perm = SandboxPermissions::BypassSandbox;
110 assert!(perm.requires_approval());
111 assert!(perm.bypasses_sandbox());
112 assert!(perm.requires_escalated_permissions());
113 }
114
115 #[test]
116 fn test_with_additional_permissions() {
117 let perm = SandboxPermissions::WithAdditionalPermissions;
118 assert!(perm.requires_approval());
119 assert!(perm.requires_additional_permissions());
120 assert!(perm.uses_additional_permissions());
121 assert!(!perm.requires_escalated_permissions());
122 assert!(!perm.bypasses_sandbox());
123 }
124
125 #[test]
126 fn test_merge_permissions() {
127 use SandboxPermissions::*;
128
129 assert_eq!(UseDefault.merge(&UseDefault), UseDefault);
130 assert_eq!(
131 UseDefault.merge(&WithAdditionalPermissions),
132 WithAdditionalPermissions
133 );
134 assert_eq!(UseDefault.merge(&RequireEscalated), RequireEscalated);
135 assert_eq!(RequireEscalated.merge(&BypassSandbox), BypassSandbox);
136 }
137}