protocol: canonicalize file system permissions

This commit is contained in:
Michael Bolin
2026-04-17 10:47:50 -07:00
parent fad3d0f1d0
commit 18fc17aeab
24 changed files with 1529 additions and 278 deletions
@@ -2041,6 +2041,7 @@ mod tests {
file_system: Some(v2::AdditionalFileSystemPermissions {
read: Some(vec![absolute_path("/tmp/allowed")]),
write: None,
entries: None,
}),
}),
proposed_execpolicy_amendment: None,
+87 -14
View File
@@ -1155,22 +1155,46 @@ impl From<CoreNetworkApprovalContext> for NetworkApprovalContext {
pub struct AdditionalFileSystemPermissions {
pub read: Option<Vec<AbsolutePathBuf>>,
pub write: Option<Vec<AbsolutePathBuf>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
pub entries: Option<Vec<FileSystemSandboxEntry>>,
}
impl From<CoreFileSystemPermissions> for AdditionalFileSystemPermissions {
fn from(value: CoreFileSystemPermissions) -> Self {
Self {
read: value.read,
write: value.write,
if let Some((read, write)) = value.legacy_read_write_roots() {
Self {
read,
write,
entries: None,
}
} else {
Self {
read: None,
write: None,
entries: Some(
value
.entries
.into_iter()
.map(FileSystemSandboxEntry::from)
.collect(),
),
}
}
}
}
impl From<AdditionalFileSystemPermissions> for CoreFileSystemPermissions {
fn from(value: AdditionalFileSystemPermissions) -> Self {
Self {
read: value.read,
write: value.write,
if let Some(entries) = value.entries {
Self {
entries: entries
.into_iter()
.map(CoreFileSystemSandboxEntry::from)
.collect(),
}
} else {
CoreFileSystemPermissions::from_read_write_roots(value.read, value.write)
}
}
}
@@ -6756,6 +6780,7 @@ mod tests {
AbsolutePathBuf::try_from(PathBuf::from(read_write_path))
.expect("path must be absolute"),
]),
entries: None,
}),
}
);
@@ -6766,16 +6791,16 @@ mod tests {
network: Some(CoreNetworkPermissions {
enabled: Some(true),
}),
file_system: Some(CoreFileSystemPermissions {
read: Some(vec![
file_system: Some(CoreFileSystemPermissions::from_read_write_roots(
Some(vec![
AbsolutePathBuf::try_from(PathBuf::from(read_only_path))
.expect("path must be absolute"),
]),
write: Some(vec![
Some(vec![
AbsolutePathBuf::try_from(PathBuf::from(read_write_path))
.expect("path must be absolute"),
]),
}),
)),
}
);
}
@@ -6809,6 +6834,53 @@ mod tests {
);
}
#[test]
fn additional_file_system_permissions_preserves_canonical_entries() {
let core_permissions = CoreFileSystemPermissions {
entries: vec![
CoreFileSystemSandboxEntry {
path: CoreFileSystemPath::Special {
value: CoreFileSystemSpecialPath::Root,
},
access: CoreFileSystemAccessMode::Write,
},
CoreFileSystemSandboxEntry {
path: CoreFileSystemPath::GlobPattern {
pattern: "**/*.env".to_string(),
},
access: CoreFileSystemAccessMode::None,
},
],
};
let permissions = AdditionalFileSystemPermissions::from(core_permissions.clone());
assert_eq!(
permissions,
AdditionalFileSystemPermissions {
read: None,
write: None,
entries: Some(vec![
FileSystemSandboxEntry {
path: FileSystemPath::Special {
value: FileSystemSpecialPath::Root,
},
access: FileSystemAccessMode::Write,
},
FileSystemSandboxEntry {
path: FileSystemPath::GlobPattern {
pattern: "**/*.env".to_string(),
},
access: FileSystemAccessMode::None,
},
]),
}
);
assert_eq!(
CoreFileSystemPermissions::from(permissions),
core_permissions
);
}
#[test]
fn permissions_request_approval_response_uses_granted_permission_profile_without_macos() {
let read_only_path = if cfg!(windows) {
@@ -6849,6 +6921,7 @@ mod tests {
AbsolutePathBuf::try_from(PathBuf::from(read_write_path))
.expect("path must be absolute"),
]),
entries: None,
}),
}
);
@@ -6859,16 +6932,16 @@ mod tests {
network: Some(CoreNetworkPermissions {
enabled: Some(true),
}),
file_system: Some(CoreFileSystemPermissions {
read: Some(vec![
file_system: Some(CoreFileSystemPermissions::from_read_write_roots(
Some(vec![
AbsolutePathBuf::try_from(PathBuf::from(read_only_path))
.expect("path must be absolute"),
]),
write: Some(vec![
Some(vec![
AbsolutePathBuf::try_from(PathBuf::from(read_write_path))
.expect("path must be absolute"),
]),
}),
)),
}
);
}