mirror of
https://github.com/openai/codex.git
synced 2026-11-03 16:23:51 +00:00
Use ApiPathString in app-server filesystem permission paths (#28367)
## Why Clients running an app-server on one OS and an exec-server on another OS need to be able to pass sandbox config to app-server that refers to resources on the executor's foreign OS. ## What `AbsolutePathBuf` can't represent these paths and we don't want users to be exposed to `PathUri` yet, so this moves the public app-server API to be expressed in terms of `ApiPathString`. Stacked on #28165. - change app-server v2 filesystem permission paths, including legacy read/write roots, to `ApiPathString` - localize API paths through `PathUri` when converting into the current native core permission types - make path-bearing permission conversions fallible and surface localization failures instead of silently treating malformed grants as ordinary denials - propagate conversion failures through app-server and TUI approval handling - regenerate the app-server JSON and TypeScript schemas - leave migration TODOs on native-path conversions so they can be removed once core permission paths use `PathUri`
This commit is contained in:
1 parent
d959664420
commit
ecfe174d5f
34 files changed
+546
-233
No files matched your search
@@ -210,9 +210,9 @@ impl App {
|
||||
&self,
|
||||
thread_id: ThreadId,
|
||||
request: &ServerRequest,
|
||||
) -> Option<ThreadInteractiveRequest> {
|
||||
) -> std::io::Result<Option<ThreadInteractiveRequest>> {
|
||||
let thread_label = Some(self.thread_label(thread_id));
|
||||
match request {
|
||||
Ok(match request {
|
||||
ServerRequest::CommandExecutionRequestApproval { params, .. } => {
|
||||
let network_approval_context = params.network_approval_context.clone();
|
||||
let additional_permissions = params.additional_permissions.clone();
|
||||
@@ -305,18 +305,28 @@ impl App {
|
||||
}
|
||||
}
|
||||
}
|
||||
ServerRequest::PermissionsRequestApproval { params, .. } => Some(
|
||||
ThreadInteractiveRequest::Approval(ApprovalRequest::Permissions {
|
||||
thread_id,
|
||||
thread_label,
|
||||
call_id: params.item_id.clone(),
|
||||
environment_id: params.environment_id.clone(),
|
||||
reason: params.reason.clone(),
|
||||
permissions: params.permissions.clone().into(),
|
||||
}),
|
||||
),
|
||||
ServerRequest::PermissionsRequestApproval { params, .. } => {
|
||||
// TODO(anp): Remove this native-path localization error path once core permission
|
||||
// paths remain PathUri after crossing the app-server boundary.
|
||||
let permissions = params.permissions.clone().try_into().map_err(|err| {
|
||||
std::io::Error::new(
|
||||
std::io::ErrorKind::InvalidInput,
|
||||
format!("failed to localize requested filesystem paths: {err}"),
|
||||
)
|
||||
})?;
|
||||
Some(ThreadInteractiveRequest::Approval(
|
||||
ApprovalRequest::Permissions {
|
||||
thread_id,
|
||||
thread_label,
|
||||
call_id: params.item_id.clone(),
|
||||
environment_id: params.environment_id.clone(),
|
||||
reason: params.reason.clone(),
|
||||
permissions,
|
||||
},
|
||||
))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn push_thread_interactive_request(&mut self, request: ThreadInteractiveRequest) {
|
||||
@@ -376,20 +386,23 @@ impl App {
|
||||
requests
|
||||
}
|
||||
|
||||
pub(super) async fn surface_pending_inactive_thread_interactive_requests(&mut self) {
|
||||
pub(super) async fn surface_pending_inactive_thread_interactive_requests(
|
||||
&mut self,
|
||||
) -> Result<()> {
|
||||
if self.active_side_parent_thread_id().is_some() {
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let requests = self.pending_inactive_thread_requests().await;
|
||||
for (thread_id, request) in requests {
|
||||
if let Some(request) = self
|
||||
.interactive_request_for_thread_request(thread_id, &request)
|
||||
.await
|
||||
.await?
|
||||
{
|
||||
self.push_thread_interactive_request(request);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) async fn submit_active_thread_op(
|
||||
@@ -991,7 +1004,7 @@ impl App {
|
||||
) -> Result<()> {
|
||||
let inactive_interactive_request = if self.active_thread_id != Some(thread_id) {
|
||||
self.interactive_request_for_thread_request(thread_id, &request)
|
||||
.await
|
||||
.await?
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user