Files
codex/codex-rs/config/src/overrides.rs
T
Winston Howes c3d5e4418f Add credential brokering to network proxy feature config (#40466)
## What changed

- Add `features.network_proxy.credential_broker` and preserve structured network proxy settings when toggling the feature through config APIs.
- Protect broker enablement and provider context variables from project config, while carrying trusted context into filtered shell environments.
- Propagate brokered credentials through shell snapshots and restore real credentials for unsandboxed escalated commands.
- Normalize broker context environment keys case-insensitively on Windows and avoid conflicting remote managed-network enforcement when no proxy launch configuration is available.

## Testing

- Cover config layering, editing, project sanitization, Windows environment handling, shell snapshots, escalated execution, and end-to-end GitHub credential brokering in the zsh-fork runtime.

GitOrigin-RevId: 500e51e804e1988022052ccfe00b8fac5e495f4f
2026-08-24 19:52:27 +00:00

100 lines
3.9 KiB
Rust

use crate::merge::is_structured_feature_path;
use crate::merge::merge_toml_values;
use toml::Value as TomlValue;
pub(crate) fn default_empty_table() -> TomlValue {
TomlValue::Table(Default::default())
}
pub fn build_cli_overrides_layer(cli_overrides: &[(String, TomlValue)]) -> TomlValue {
let mut root = default_empty_table();
for (path, value) in cli_overrides {
apply_toml_override(&mut root, path, value.clone());
}
root
}
/// Apply a single dotted-path override onto a TOML value.
fn apply_toml_override(root: &mut TomlValue, path: &str, value: TomlValue) {
use toml::value::Table;
let mut current = root;
let mut segments_iter = path.split('.').peekable();
let mut traversed_segments = Vec::new();
while let Some(segment) = segments_iter.next() {
traversed_segments.push(segment);
let is_last = segments_iter.peek().is_none();
if is_last {
match current {
TomlValue::Table(table) => {
if is_structured_feature_path(&traversed_segments)
&& let Some(existing) = table.get_mut(segment)
{
match (&mut *existing, &value) {
(TomlValue::Table(feature), TomlValue::Boolean(enabled)) => {
feature.insert("enabled".to_string(), TomlValue::Boolean(*enabled));
return;
}
(TomlValue::Boolean(enabled), TomlValue::Table(_)) => {
*existing = TomlValue::Table(Table::from_iter([(
"enabled".to_string(),
TomlValue::Boolean(*enabled),
)]));
merge_toml_values(existing, &value);
return;
}
(TomlValue::Table(_), TomlValue::Table(_)) => {
merge_toml_values(existing, &value);
return;
}
(
TomlValue::String(_)
| TomlValue::Integer(_)
| TomlValue::Float(_)
| TomlValue::Boolean(_)
| TomlValue::Datetime(_)
| TomlValue::Array(_)
| TomlValue::Table(_),
_,
) => {}
}
}
table.insert(segment.to_string(), value);
}
_ => {
let mut table = Table::new();
table.insert(segment.to_string(), value);
*current = TomlValue::Table(table);
}
}
return;
}
match current {
TomlValue::Table(table) => {
current = table
.entry(segment.to_string())
.or_insert_with(|| TomlValue::Table(Table::new()));
if is_structured_feature_path(&traversed_segments)
&& let TomlValue::Boolean(enabled) = current
{
*current = TomlValue::Table(Table::from_iter([(
"enabled".to_string(),
TomlValue::Boolean(*enabled),
)]));
}
}
_ => {
*current = TomlValue::Table(Table::new());
if let TomlValue::Table(tbl) = current {
current = tbl
.entry(segment.to_string())
.or_insert_with(|| TomlValue::Table(Table::new()));
}
}
}
}
}