[Auth] Choose which auth storage to use based on config (#5792)

This PR is a follow-up to #5591. It allows users to choose which auth
storage mode they want by using the new
`cli_auth_credentials_store_mode` config.
This commit is contained in:
Celia Chen
2025-10-27 19:41:49 -07:00
committed by GitHub
parent 66a4b89822
commit 4a42c4e142
30 changed files with 361 additions and 80 deletions

View File

@@ -1219,7 +1219,10 @@ impl ChatWidget {
self.app_event_tx.send(AppEvent::ExitRequest);
}
SlashCommand::Logout => {
if let Err(e) = codex_core::auth::logout(&self.config.codex_home) {
if let Err(e) = codex_core::auth::logout(
&self.config.codex_home,
self.config.cli_auth_credentials_store_mode,
) {
tracing::error!("failed to logout: {e}");
}
self.app_event_tx.send(AppEvent::ExitRequest);

View File

@@ -315,7 +315,11 @@ async fn run_ratatui_app(
// Initialize high-fidelity session event logging if enabled.
session_log::maybe_init(&initial_config);
let auth_manager = AuthManager::shared(initial_config.codex_home.clone(), false);
let auth_manager = AuthManager::shared(
initial_config.codex_home.clone(),
false,
initial_config.cli_auth_credentials_store_mode,
);
let login_status = get_login_status(&initial_config);
let should_show_trust_screen = should_show_trust_screen(&initial_config);
let should_show_windows_wsl_screen =
@@ -476,7 +480,7 @@ fn get_login_status(config: &Config) -> LoginStatus {
// Reading the OpenAI API key is an async operation because it may need
// to refresh the token. Block on it.
let codex_home = config.codex_home.clone();
match CodexAuth::from_auth_storage(&codex_home) {
match CodexAuth::from_auth_storage(&codex_home, config.cli_auth_credentials_store_mode) {
Ok(Some(auth)) => LoginStatus::AuthMode(auth.mode),
Ok(None) => LoginStatus::NotAuthenticated,
Err(err) => {

View File

@@ -1,6 +1,7 @@
#![allow(clippy::unwrap_used)]
use codex_core::AuthManager;
use codex_core::auth::AuthCredentialsStoreMode;
use codex_core::auth::CLIENT_ID;
use codex_core::auth::login_with_api_key;
use codex_core::auth::read_openai_api_key_from_env;
@@ -148,6 +149,7 @@ pub(crate) struct AuthModeWidget {
pub error: Option<String>,
pub sign_in_state: Arc<RwLock<SignInState>>,
pub codex_home: PathBuf,
pub cli_auth_credentials_store_mode: AuthCredentialsStoreMode,
pub login_status: LoginStatus,
pub auth_manager: Arc<AuthManager>,
pub forced_chatgpt_workspace_id: Option<String>,
@@ -512,7 +514,11 @@ impl AuthModeWidget {
self.disallow_api_login();
return;
}
match login_with_api_key(&self.codex_home, &api_key) {
match login_with_api_key(
&self.codex_home,
&api_key,
self.cli_auth_credentials_store_mode,
) {
Ok(()) => {
self.error = None;
self.login_status = LoginStatus::AuthMode(AuthMode::ApiKey);
@@ -553,6 +559,7 @@ impl AuthModeWidget {
self.codex_home.clone(),
CLIENT_ID.to_string(),
self.forced_chatgpt_workspace_id.clone(),
self.cli_auth_credentials_store_mode,
);
match run_login_server(opts) {
Ok(child) => {
@@ -640,6 +647,8 @@ mod tests {
use pretty_assertions::assert_eq;
use tempfile::TempDir;
use codex_core::auth::AuthCredentialsStoreMode;
fn widget_forced_chatgpt() -> (AuthModeWidget, TempDir) {
let codex_home = TempDir::new().unwrap();
let codex_home_path = codex_home.path().to_path_buf();
@@ -649,8 +658,13 @@ mod tests {
error: None,
sign_in_state: Arc::new(RwLock::new(SignInState::PickMode)),
codex_home: codex_home_path.clone(),
cli_auth_credentials_store_mode: AuthCredentialsStoreMode::File,
login_status: LoginStatus::NotAuthenticated,
auth_manager: AuthManager::shared(codex_home_path, false),
auth_manager: AuthManager::shared(
codex_home_path,
false,
AuthCredentialsStoreMode::File,
),
forced_chatgpt_workspace_id: None,
forced_login_method: Some(ForcedLoginMethod::Chatgpt),
};

View File

@@ -87,6 +87,7 @@ impl OnboardingScreen {
let forced_chatgpt_workspace_id = config.forced_chatgpt_workspace_id.clone();
let forced_login_method = config.forced_login_method;
let codex_home = config.codex_home;
let cli_auth_credentials_store_mode = config.cli_auth_credentials_store_mode;
let mut steps: Vec<Step> = Vec::new();
if show_windows_wsl_screen {
steps.push(Step::Windows(WindowsSetupWidget::new(codex_home.clone())));
@@ -106,6 +107,7 @@ impl OnboardingScreen {
error: None,
sign_in_state: Arc::new(RwLock::new(SignInState::PickMode)),
codex_home: codex_home.clone(),
cli_auth_credentials_store_mode,
login_status,
auth_manager,
forced_chatgpt_workspace_id,

View File

@@ -83,7 +83,8 @@ pub(crate) fn compose_agents_summary(config: &Config) -> String {
}
pub(crate) fn compose_account_display(config: &Config) -> Option<StatusAccountDisplay> {
let auth = load_auth_dot_json(&config.codex_home).ok()??;
let auth =
load_auth_dot_json(&config.codex_home, config.cli_auth_credentials_store_mode).ok()??;
if let Some(tokens) = auth.tokens.as_ref() {
let info = &tokens.id_token;