mirror of
https://github.com/openai/codex.git
synced 2026-09-20 12:47:38 +00:00
fix(config): merge nested permissions requirements
Co-authored-by: Codex noreply@openai.com
This commit is contained in:
@@ -991,11 +991,21 @@ impl ConfigRequirementsWithSources {
|
||||
rules,
|
||||
enforce_residency,
|
||||
network,
|
||||
permissions,
|
||||
guardian_policy_config,
|
||||
}
|
||||
);
|
||||
|
||||
if let Some(incoming_permissions) = other.permissions.take() {
|
||||
if let Some(existing_permissions) = self.permissions.as_mut() {
|
||||
merge_permissions_requirements_descending(
|
||||
&mut existing_permissions.value,
|
||||
incoming_permissions,
|
||||
);
|
||||
} else {
|
||||
self.permissions = Some(Sourced::new(incoming_permissions, source.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(incoming_apps) = other.apps.take() {
|
||||
if let Some(existing_apps) = self.apps.as_mut() {
|
||||
merge_app_requirements_descending(&mut existing_apps.value, incoming_apps);
|
||||
@@ -1054,6 +1064,21 @@ impl ConfigRequirementsWithSources {
|
||||
}
|
||||
}
|
||||
|
||||
fn merge_permissions_requirements_descending(
|
||||
existing: &mut PermissionsRequirementsToml,
|
||||
mut incoming: PermissionsRequirementsToml,
|
||||
) {
|
||||
if existing.filesystem.is_none() {
|
||||
existing.filesystem = incoming.filesystem.take();
|
||||
}
|
||||
if existing.network.is_none() {
|
||||
existing.network = incoming.network.take();
|
||||
}
|
||||
for (profile_id, profile) in incoming.profiles {
|
||||
existing.profiles.entry(profile_id).or_insert(profile);
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_hostname(hostname: &str) -> Option<String> {
|
||||
let hostname = hostname.trim().trim_end_matches('.');
|
||||
(!hostname.is_empty()).then(|| hostname.to_ascii_lowercase())
|
||||
@@ -1965,6 +1990,62 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merge_unset_fields_merges_nested_permissions_requirements() -> Result<()> {
|
||||
let deny_read = if cfg!(windows) {
|
||||
r"C:\Users\alice\.ssh"
|
||||
} else {
|
||||
"/home/alice/.ssh"
|
||||
};
|
||||
let high_precedence: ConfigRequirementsToml = from_str(&format!(
|
||||
r#"
|
||||
[permissions.filesystem]
|
||||
deny_read = [{deny_read:?}]
|
||||
"#
|
||||
))?;
|
||||
let low_precedence: ConfigRequirementsToml = from_str(
|
||||
r#"
|
||||
[permissions.network]
|
||||
enabled = true
|
||||
|
||||
[permissions.managed]
|
||||
sandbox_mode = "workspace-write"
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let mut target = ConfigRequirementsWithSources::default();
|
||||
target.merge_unset_fields(RequirementSource::CloudRequirements, high_precedence);
|
||||
target.merge_unset_fields(RequirementSource::Unknown, low_precedence);
|
||||
let merged_toml = target.clone().into_toml();
|
||||
let requirements = ConfigRequirements::try_from(target)?;
|
||||
|
||||
assert!(
|
||||
merged_toml
|
||||
.permissions
|
||||
.as_ref()
|
||||
.is_some_and(|permissions| permissions.profiles.contains_key("managed"))
|
||||
);
|
||||
assert_eq!(
|
||||
requirements.filesystem,
|
||||
Some(Sourced::new(
|
||||
FilesystemConstraints {
|
||||
deny_read: vec![AbsolutePathBuf::from_absolute_path(deny_read)?.into()],
|
||||
},
|
||||
RequirementSource::CloudRequirements,
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
requirements
|
||||
.network
|
||||
.expect("network requirements should merge")
|
||||
.value
|
||||
.enabled,
|
||||
Some(true)
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merge_unset_fields_ignores_blank_guardian_override() {
|
||||
let mut target = ConfigRequirementsWithSources::default();
|
||||
|
||||
Reference in New Issue
Block a user