mirror of
https://github.com/openai/codex.git
synced 2026-10-24 18:18:41 +00:00
tui: sync session permission profiles
This commit is contained in:
@@ -72,13 +72,15 @@ impl App {
|
||||
"Failed to carry forward approval policy override: {err}"
|
||||
));
|
||||
}
|
||||
if let Some(policy) = self.runtime_sandbox_policy_override.as_ref()
|
||||
&& let Err(err) = config.permissions.sandbox_policy.set(policy.clone())
|
||||
{
|
||||
tracing::warn!(%err, "failed to carry forward sandbox policy override");
|
||||
self.chat_widget.add_error_message(format!(
|
||||
"Failed to carry forward sandbox policy override: {err}"
|
||||
));
|
||||
if let Some(policy) = self.runtime_sandbox_policy_override.as_ref() {
|
||||
if let Err(err) = config.permissions.sandbox_policy.set(policy.clone()) {
|
||||
tracing::warn!(%err, "failed to carry forward sandbox policy override");
|
||||
self.chat_widget.add_error_message(format!(
|
||||
"Failed to carry forward sandbox policy override: {err}"
|
||||
));
|
||||
} else {
|
||||
sync_runtime_permissions_from_legacy_sandbox_policy(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +119,7 @@ impl App {
|
||||
.add_error_message(format!("{user_message_prefix}: {err}"));
|
||||
return false;
|
||||
}
|
||||
sync_runtime_permissions_from_legacy_sandbox_policy(config);
|
||||
|
||||
true
|
||||
}
|
||||
@@ -534,6 +537,17 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
fn sync_runtime_permissions_from_legacy_sandbox_policy(config: &mut Config) {
|
||||
let sandbox_policy = config.permissions.sandbox_policy.get();
|
||||
config.permissions.file_system_sandbox_policy =
|
||||
codex_protocol::permissions::FileSystemSandboxPolicy::from_legacy_sandbox_policy(
|
||||
sandbox_policy,
|
||||
&config.cwd,
|
||||
);
|
||||
config.permissions.network_sandbox_policy =
|
||||
codex_protocol::permissions::NetworkSandboxPolicy::from(sandbox_policy);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -139,6 +139,7 @@ use codex_protocol::items::AgentMessageContent;
|
||||
use codex_protocol::items::AgentMessageItem;
|
||||
use codex_protocol::items::UserMessageItem;
|
||||
use codex_protocol::models::MessagePhase;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::models::local_image_label_text;
|
||||
use codex_protocol::parse_command::ParsedCommand;
|
||||
use codex_protocol::plan_tool::PlanItemArg as UpdatePlanItemArg;
|
||||
@@ -2119,6 +2120,12 @@ impl ChatWidget {
|
||||
display: SessionConfiguredDisplay,
|
||||
fork_parent_title: Option<String>,
|
||||
) {
|
||||
let permission_profile = event.permission_profile.clone().unwrap_or_else(|| {
|
||||
PermissionProfile::from_legacy_sandbox_policy(&event.sandbox_policy, &event.cwd)
|
||||
});
|
||||
let (file_system_sandbox_policy, network_sandbox_policy) =
|
||||
permission_profile.to_runtime_permissions();
|
||||
|
||||
self.last_agent_markdown = None;
|
||||
self.agent_turn_markdowns.clear();
|
||||
self.visible_user_turn_count = 0;
|
||||
@@ -2156,6 +2163,8 @@ impl ChatWidget {
|
||||
self.config.permissions.sandbox_policy =
|
||||
Constrained::allow_only(event.sandbox_policy.clone());
|
||||
}
|
||||
self.config.permissions.file_system_sandbox_policy = file_system_sandbox_policy;
|
||||
self.config.permissions.network_sandbox_policy = network_sandbox_policy;
|
||||
self.config.approvals_reviewer = event.approvals_reviewer;
|
||||
self.status_line_project_root_name_cache = None;
|
||||
let forked_from_id = event.forked_from_id;
|
||||
@@ -9764,6 +9773,14 @@ impl ChatWidget {
|
||||
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
|
||||
pub(crate) fn set_sandbox_policy(&mut self, policy: SandboxPolicy) -> ConstraintResult<()> {
|
||||
self.config.permissions.sandbox_policy.set(policy)?;
|
||||
let sandbox_policy = self.config.permissions.sandbox_policy.get();
|
||||
self.config.permissions.file_system_sandbox_policy =
|
||||
codex_protocol::permissions::FileSystemSandboxPolicy::from_legacy_sandbox_policy(
|
||||
sandbox_policy,
|
||||
&self.config.cwd,
|
||||
);
|
||||
self.config.permissions.network_sandbox_policy =
|
||||
codex_protocol::permissions::NetworkSandboxPolicy::from(sandbox_policy);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
use super::*;
|
||||
use codex_protocol::protocol::FileSystemAccessMode;
|
||||
use codex_protocol::protocol::FileSystemPath;
|
||||
use codex_protocol::protocol::FileSystemSandboxEntry;
|
||||
use codex_protocol::protocol::FileSystemSandboxPolicy;
|
||||
use codex_protocol::protocol::FileSystemSpecialPath;
|
||||
use codex_protocol::protocol::NetworkSandboxPolicy;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[tokio::test]
|
||||
@@ -252,6 +258,25 @@ async fn session_configured_syncs_widget_config_permissions_and_cwd() {
|
||||
|
||||
let expected_sandbox = SandboxPolicy::new_read_only_policy();
|
||||
let expected_cwd = test_path_buf("/home/user/sub-agent").abs();
|
||||
let expected_file_system_policy = FileSystemSandboxPolicy::restricted(vec![
|
||||
FileSystemSandboxEntry {
|
||||
path: FileSystemPath::Special {
|
||||
value: FileSystemSpecialPath::Root,
|
||||
},
|
||||
access: FileSystemAccessMode::Read,
|
||||
},
|
||||
FileSystemSandboxEntry {
|
||||
path: FileSystemPath::GlobPattern {
|
||||
pattern: "**/.secret".to_string(),
|
||||
},
|
||||
access: FileSystemAccessMode::None,
|
||||
},
|
||||
]);
|
||||
let expected_permission_profile =
|
||||
codex_protocol::models::PermissionProfile::from_runtime_permissions(
|
||||
&expected_file_system_policy,
|
||||
NetworkSandboxPolicy::Restricted,
|
||||
);
|
||||
let configured = codex_protocol::protocol::SessionConfiguredEvent {
|
||||
session_id: ThreadId::new(),
|
||||
forked_from_id: None,
|
||||
@@ -262,7 +287,7 @@ async fn session_configured_syncs_widget_config_permissions_and_cwd() {
|
||||
approval_policy: AskForApproval::Never,
|
||||
approvals_reviewer: ApprovalsReviewer::User,
|
||||
sandbox_policy: expected_sandbox.clone(),
|
||||
permission_profile: None,
|
||||
permission_profile: Some(expected_permission_profile.clone()),
|
||||
cwd: expected_cwd.clone(),
|
||||
reasoning_effort: Some(ReasoningEffortConfig::default()),
|
||||
history_log_id: 0,
|
||||
@@ -285,7 +310,23 @@ async fn session_configured_syncs_widget_config_permissions_and_cwd() {
|
||||
chat.config_ref().permissions.sandbox_policy.get(),
|
||||
&expected_sandbox
|
||||
);
|
||||
assert_eq!(
|
||||
chat.config_ref().permissions.permission_profile(),
|
||||
expected_permission_profile
|
||||
);
|
||||
assert_eq!(&chat.config_ref().cwd, &expected_cwd);
|
||||
|
||||
let updated_sandbox = SandboxPolicy::new_workspace_write_policy();
|
||||
chat.set_sandbox_policy(updated_sandbox.clone())
|
||||
.expect("set sandbox policy");
|
||||
assert_eq!(
|
||||
chat.config_ref().permissions.permission_profile(),
|
||||
codex_protocol::models::PermissionProfile::from_legacy_sandbox_policy(
|
||||
&updated_sandbox,
|
||||
&expected_cwd
|
||||
),
|
||||
"local sandbox changes should replace SessionConfigured profile-derived runtime permissions"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user