This commit is contained in:
Anton Panasenko
2026-03-16 16:41:26 -07:00
parent c8e2b46acd
commit 6853ce9136
3 changed files with 1190 additions and 28 deletions
+9
View File
@@ -532,10 +532,19 @@ pub async fn run_main_with_transport(
let shutdown_when_no_connections = single_client_mode;
let graceful_signal_restart_enabled = !single_client_mode;
let auth_manager = AuthManager::shared(
config.codex_home.clone(),
false,
config.cli_auth_credentials_store_mode,
);
auth_manager.set_forced_chatgpt_workspace_id(config.forced_chatgpt_workspace_id.clone());
let remote_control_url = config.experimental_app_server_remote_control_url.clone();
if let Some(remote_control_url) = remote_control_url {
let accept_handle = start_remote_control(
remote_control_url,
config.codex_home.clone(),
auth_manager.clone(),
transport_event_tx.clone(),
transport_shutdown_token.clone(),
)
File diff suppressed because it is too large Load Diff
+52
View File
@@ -328,6 +328,7 @@ impl CloudRequirementsService {
return Ok(None);
};
if !auth.is_chatgpt_auth()
|| auth.is_external_chatgpt_tokens()
|| !matches!(
auth.account_plan_type(),
Some(PlanType::Business | PlanType::Enterprise)
@@ -967,6 +968,42 @@ mod tests {
auth_manager_with_plan_and_identity(plan_type, Some("user-12345"), Some("account-12345"))
}
fn auth_manager_with_external_chatgpt_tokens(plan_type: &str) -> Arc<AuthManager> {
let tmp = tempdir().expect("tempdir");
let header = json!({ "alg": "none", "typ": "JWT" });
let auth_payload = json!({
"chatgpt_plan_type": plan_type,
"chatgpt_user_id": "user-12345",
"user_id": "user-12345",
});
let payload = json!({
"email": "user@example.com",
"https://api.openai.com/auth": auth_payload,
});
let header_b64 = URL_SAFE_NO_PAD.encode(serde_json::to_vec(&header).expect("header"));
let payload_b64 = URL_SAFE_NO_PAD.encode(serde_json::to_vec(&payload).expect("payload"));
let signature_b64 = URL_SAFE_NO_PAD.encode(b"sig");
let fake_jwt = format!("{header_b64}.{payload_b64}.{signature_b64}");
let auth_json = json!({
"auth_mode": "chatgptAuthTokens",
"OPENAI_API_KEY": null,
"tokens": {
"id_token": fake_jwt,
"access_token": "test-access-token",
"refresh_token": "",
"account_id": "account-12345",
},
"last_refresh": "2025-01-01T00:00:00Z",
});
write_auth_json(tmp.path(), auth_json).expect("write auth");
Arc::new(AuthManager::new(
tmp.path().to_path_buf(),
false,
AuthCredentialsStoreMode::File,
))
}
fn parse_for_fetch(contents: Option<&str>) -> Option<ConfigRequirementsToml> {
contents.and_then(|contents| parse_cloud_requirements(contents).ok().flatten())
}
@@ -1088,6 +1125,21 @@ mod tests {
assert_eq!(result, Ok(None));
}
#[tokio::test]
async fn fetch_cloud_requirements_skips_external_chatgpt_tokens_auth() {
let codex_home = tempdir().expect("tempdir");
let service = CloudRequirementsService::new(
auth_manager_with_external_chatgpt_tokens("enterprise"),
Arc::new(StaticFetcher {
contents: Some("allowed_approval_policies = [\"never\"]".to_string()),
}),
codex_home.path().to_path_buf(),
CLOUD_REQUIREMENTS_TIMEOUT,
);
let result = service.fetch().await;
assert_eq!(result, Ok(None));
}
#[tokio::test]
async fn fetch_cloud_requirements_skips_non_business_or_enterprise_plan() {
let codex_home = tempdir().expect("tempdir");