mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
feat: refactor CodexAuth so invalid state cannot be represented (#10208)
Previously, `CodexAuth` was defined as follows: https://github.com/openai/codex/blob/d550fbf41afc09d7d7b5ac813aea38de07b2a73f/codex-rs/core/src/auth.rs#L39-L46 But if you looked at its constructors, we had creation for `AuthMode::ApiKey` where `storage` was built using a nonsensical path (`PathBuf::new()`) and `auth_dot_json` was `None`: https://github.com/openai/codex/blob/d550fbf41afc09d7d7b5ac813aea38de07b2a73f/codex-rs/core/src/auth.rs#L212-L220 By comparison, when `AuthMode::ChatGPT` was used, `api_key` was always `None`: https://github.com/openai/codex/blob/d550fbf41afc09d7d7b5ac813aea38de07b2a73f/codex-rs/core/src/auth.rs#L665-L671 https://github.com/openai/codex/pull/10012 took things further because it introduced a new `ChatgptAuthTokens` variant to `AuthMode`, which is important in when invoking `account/login/start` via the app server, but most logic _internal_ to the app server should just reason about two `AuthMode` variants: `ApiKey` and `ChatGPT`. This PR tries to clean things up as follows: - `LoginAccountParams` and `AuthMode` in `codex-rs/app-server-protocol/` both continue to have the `ChatgptAuthTokens` variant, though it is used exclusively for the on-the-wire messaging. - `codex-rs/core/src/auth.rs` now has its own `AuthMode` enum, which only has two variants: `ApiKey` and `ChatGPT`. - `CodexAuth` has been changed from a struct to an enum. It is a disjoint union where each variant (`ApiKey`, `ChatGpt`, and `ChatGptAuthTokens`) have only the associated fields that make sense for that variant. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/10208). * #10224 * __->__ #10208
This commit is contained in:
committed by
GitHub
Unverified
parent
0212f4010e
commit
377ab0c77c
@@ -984,7 +984,7 @@ impl App {
|
||||
model.as_str(),
|
||||
auth_ref.and_then(CodexAuth::get_account_id),
|
||||
auth_ref.and_then(CodexAuth::get_account_email),
|
||||
auth_ref.map(|auth| auth.mode),
|
||||
auth_ref.map(CodexAuth::api_auth_mode),
|
||||
config.otel.log_user_prompt,
|
||||
codex_core::terminal::user_agent(),
|
||||
SessionSource::Cli,
|
||||
|
||||
@@ -30,7 +30,6 @@ use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
|
||||
use crate::version::CODEX_CLI_VERSION;
|
||||
use codex_app_server_protocol::AuthMode;
|
||||
use codex_backend_client::Client as BackendClient;
|
||||
use codex_chatgpt::connectors;
|
||||
use codex_core::config::Config;
|
||||
@@ -3584,10 +3583,12 @@ impl ChatWidget {
|
||||
fn prefetch_rate_limits(&mut self) {
|
||||
self.stop_rate_limit_poller();
|
||||
|
||||
if !matches!(
|
||||
self.auth_manager.auth_cached().map(|auth| auth.mode),
|
||||
Some(AuthMode::ChatGPT | AuthMode::ChatgptAuthTokens)
|
||||
) {
|
||||
if !self
|
||||
.auth_manager
|
||||
.auth_cached()
|
||||
.as_ref()
|
||||
.is_some_and(CodexAuth::is_chatgpt_auth)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3600,7 +3601,7 @@ impl ChatWidget {
|
||||
|
||||
loop {
|
||||
if let Some(auth) = auth_manager.auth().await
|
||||
&& matches!(auth.mode, AuthMode::ChatGPT | AuthMode::ChatgptAuthTokens)
|
||||
&& auth.is_chatgpt_auth()
|
||||
&& let Some(snapshot) = fetch_rate_limits(base_url.clone(), auth).await
|
||||
{
|
||||
app_event_tx.send(AppEvent::RateLimitSnapshotFetched(snapshot));
|
||||
|
||||
@@ -833,7 +833,7 @@ fn get_login_status(config: &Config) -> LoginStatus {
|
||||
// to refresh the token. Block on it.
|
||||
let codex_home = config.codex_home.clone();
|
||||
match CodexAuth::from_auth_storage(&codex_home, config.cli_auth_credentials_store_mode) {
|
||||
Ok(Some(auth)) => LoginStatus::AuthMode(auth.mode),
|
||||
Ok(Some(auth)) => LoginStatus::AuthMode(auth.api_auth_mode()),
|
||||
Ok(None) => LoginStatus::NotAuthenticated,
|
||||
Err(err) => {
|
||||
error!("Failed to read auth.json: {err}");
|
||||
|
||||
@@ -2,8 +2,8 @@ use crate::exec_command::relativize_to_home;
|
||||
use crate::text_formatting;
|
||||
use chrono::DateTime;
|
||||
use chrono::Local;
|
||||
use codex_app_server_protocol::AuthMode;
|
||||
use codex_core::AuthManager;
|
||||
use codex_core::CodexAuth;
|
||||
use codex_core::config::Config;
|
||||
use codex_core::project_doc::discover_project_doc_paths;
|
||||
use codex_protocol::account::PlanType;
|
||||
@@ -90,15 +90,15 @@ pub(crate) fn compose_account_display(
|
||||
) -> Option<StatusAccountDisplay> {
|
||||
let auth = auth_manager.auth_cached()?;
|
||||
|
||||
match auth.mode {
|
||||
AuthMode::ChatGPT | AuthMode::ChatgptAuthTokens => {
|
||||
match auth {
|
||||
CodexAuth::ChatGpt(_) | CodexAuth::ChatGptAuthTokens(_) => {
|
||||
let email = auth.get_account_email();
|
||||
let plan = plan
|
||||
.map(|plan_type| title_case(format!("{plan_type:?}").as_str()))
|
||||
.or_else(|| Some("Unknown".to_string()));
|
||||
Some(StatusAccountDisplay::ChatGpt { email, plan })
|
||||
}
|
||||
AuthMode::ApiKey => Some(StatusAccountDisplay::ApiKey),
|
||||
CodexAuth::ApiKey(_) => Some(StatusAccountDisplay::ApiKey),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user