From e53e6bc48f9b0de5c2b350dad05da923a5cbd37d Mon Sep 17 00:00:00 2001 From: jif-oai Date: Mon, 20 Apr 2026 15:35:28 +0100 Subject: [PATCH] fix: auth.json leak in tests (#18657) Before this some tests were leaking an auth.json file into `codex-rs/core`. This just fixes it --- codex-rs/login/src/auth/auth_tests.rs | 27 +++++++++++++++++++++++++++ codex-rs/login/src/auth/manager.rs | 9 ++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/codex-rs/login/src/auth/auth_tests.rs b/codex-rs/login/src/auth/auth_tests.rs index c28b77a617..50dcc90e19 100644 --- a/codex-rs/login/src/auth/auth_tests.rs +++ b/codex-rs/login/src/auth/auth_tests.rs @@ -230,6 +230,33 @@ fn chatgpt_auth_persists_agent_identity_for_workspace() { assert_eq!(auth.get_agent_identity("account-123"), None); } +#[test] +fn dummy_chatgpt_auth_does_not_create_cwd_auth_json_when_identity_is_set() { + let cwd_auth = std::env::current_dir() + .expect("current dir") + .join("auth.json"); + let had_auth_json_before_test = cwd_auth.exists(); + let auth = CodexAuth::create_dummy_chatgpt_auth_for_testing(); + let record = AgentIdentityAuthRecord { + workspace_id: "account_id".to_string(), + chatgpt_user_id: None, + agent_runtime_id: "agent_123".to_string(), + agent_private_key: "pkcs8-base64".to_string(), + registered_at: "2026-04-13T12:00:00Z".to_string(), + }; + + auth.set_agent_identity(record.clone()) + .expect("set agent identity"); + + assert_eq!(auth.get_agent_identity("account_id"), Some(record)); + if !had_auth_json_before_test { + assert!( + !cwd_auth.exists(), + "dummy ChatGPT auth must not write auth.json in the test process cwd" + ); + } +} + #[test] fn unauthorized_recovery_reports_mode_and_step_names() { let dir = tempdir().unwrap(); diff --git a/codex-rs/login/src/auth/manager.rs b/codex-rs/login/src/auth/manager.rs index 8a5e2fa663..0731bf97db 100644 --- a/codex-rs/login/src/auth/manager.rs +++ b/codex-rs/login/src/auth/manager.rs @@ -13,6 +13,8 @@ use std::path::PathBuf; use std::sync::Arc; use std::sync::Mutex; use std::sync::RwLock; +use std::sync::atomic::AtomicU64; +use std::sync::atomic::Ordering; use tokio::sync::Mutex as AsyncMutex; use tokio::sync::watch; @@ -96,6 +98,7 @@ const REFRESH_TOKEN_URL: &str = "https://auth.openai.com/oauth/token"; pub(super) const REVOKE_TOKEN_URL: &str = "https://auth.openai.com/oauth/revoke"; pub const REFRESH_TOKEN_URL_OVERRIDE_ENV_VAR: &str = "CODEX_REFRESH_TOKEN_URL_OVERRIDE"; pub const REVOKE_TOKEN_URL_OVERRIDE_ENV_VAR: &str = "CODEX_REVOKE_TOKEN_URL_OVERRIDE"; +static NEXT_DUMMY_AUTH_ID: AtomicU64 = AtomicU64::new(1); #[derive(Debug, Error)] pub enum RefreshTokenError { @@ -442,7 +445,11 @@ impl CodexAuth { auth_dot_json: Arc::new(Mutex::new(Some(auth_dot_json))), client, }; - let storage = create_auth_storage(PathBuf::new(), AuthCredentialsStoreMode::File); + let dummy_auth_id = NEXT_DUMMY_AUTH_ID.fetch_add(1, Ordering::Relaxed); + let storage = create_auth_storage( + PathBuf::from(format!("dummy-chatgpt-auth-{dummy_auth_id}")), + AuthCredentialsStoreMode::Ephemeral, + ); Self::Chatgpt(ChatgptAuth { state, storage }) }