mirror of
https://github.com/openai/codex.git
synced 2026-11-13 06:45:07 +00:00
auth: move domain mode below app wire types (#29721)
## Why Authentication mode is a domain concept used by login, model selection, telemetry, and transports. Keeping the canonical type in app-server protocol forces those lower-level crates to depend on an unrelated wire API. ## What changed - Added canonical `codex_protocol::auth::AuthMode` domain values. - Kept the app-server wire DTO unchanged and added an explicit app-side conversion. - Removed production app-server-protocol dependencies from login, model-provider-info, models-manager, and otel call paths. ## Stack This is PR 2 of 6, stacked on [PR #29714](https://github.com/openai/codex/pull/29714). Review only the delta from `codex/split-json-rpc-protocols`. Next: [PR #29722](https://github.com/openai/codex/pull/29722). ## Validation - Auth and login coverage passed in the focused protocol/domain test run. - App-server account and auth conversion coverage passed.
This commit is contained in:
1 parent
806a4b66c9
commit
31372078d1
47 files changed
+224
-146
No files matched your search
Generated
+1
-4
@@ -2163,6 +2163,7 @@ dependencies = [
|
|||||||
"codex-core",
|
"codex-core",
|
||||||
"codex-login",
|
"codex-login",
|
||||||
"codex-model-provider",
|
"codex-model-provider",
|
||||||
|
"codex-protocol",
|
||||||
"codex-state",
|
"codex-state",
|
||||||
"codex-uds",
|
"codex-uds",
|
||||||
"codex-utils-absolute-path",
|
"codex-utils-absolute-path",
|
||||||
@@ -3263,7 +3264,6 @@ dependencies = [
|
|||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"chrono",
|
"chrono",
|
||||||
"codex-agent-identity",
|
"codex-agent-identity",
|
||||||
"codex-app-server-protocol",
|
|
||||||
"codex-client",
|
"codex-client",
|
||||||
"codex-config",
|
"codex-config",
|
||||||
"codex-keyring-store",
|
"codex-keyring-store",
|
||||||
@@ -3498,7 +3498,6 @@ name = "codex-model-provider-info"
|
|||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"codex-api",
|
"codex-api",
|
||||||
"codex-app-server-protocol",
|
|
||||||
"codex-protocol",
|
"codex-protocol",
|
||||||
"codex-utils-absolute-path",
|
"codex-utils-absolute-path",
|
||||||
"http 1.4.0",
|
"http 1.4.0",
|
||||||
@@ -3515,7 +3514,6 @@ name = "codex-models-manager"
|
|||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"codex-app-server-protocol",
|
|
||||||
"codex-collaboration-mode-templates",
|
"codex-collaboration-mode-templates",
|
||||||
"codex-login",
|
"codex-login",
|
||||||
"codex-otel",
|
"codex-otel",
|
||||||
@@ -3591,7 +3589,6 @@ version = "0.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"codex-api",
|
"codex-api",
|
||||||
"codex-app-server-protocol",
|
|
||||||
"codex-protocol",
|
"codex-protocol",
|
||||||
"codex-utils-absolute-path",
|
"codex-utils-absolute-path",
|
||||||
"codex-utils-string",
|
"codex-utils-string",
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ uuid = { workspace = true, features = ["serde", "v7"] }
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
chrono = { workspace = true }
|
chrono = { workspace = true }
|
||||||
codex-config = { workspace = true }
|
codex-config = { workspace = true }
|
||||||
|
codex-protocol = { workspace = true }
|
||||||
pretty_assertions = { workspace = true }
|
pretty_assertions = { workspace = true }
|
||||||
tempfile = { workspace = true }
|
tempfile = { workspace = true }
|
||||||
tokio = { workspace = true, features = ["test-util"] }
|
tokio = { workspace = true, features = ["test-util"] }
|
||||||
@@ -18,7 +18,6 @@ use crate::transport::CHANNEL_CAPACITY;
|
|||||||
use crate::transport::ConnectionOrigin;
|
use crate::transport::ConnectionOrigin;
|
||||||
use crate::transport::TransportEvent;
|
use crate::transport::TransportEvent;
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_app_server_protocol::ConfigWarningNotification;
|
use codex_app_server_protocol::ConfigWarningNotification;
|
||||||
use codex_app_server_protocol::JSONRPCMessage;
|
use codex_app_server_protocol::JSONRPCMessage;
|
||||||
use codex_app_server_protocol::RemoteControlConnectionStatus;
|
use codex_app_server_protocol::RemoteControlConnectionStatus;
|
||||||
@@ -36,6 +35,7 @@ use codex_login::CodexAuth;
|
|||||||
use codex_login::save_auth;
|
use codex_login::save_auth;
|
||||||
use codex_login::token_data::TokenData;
|
use codex_login::token_data::TokenData;
|
||||||
use codex_login::token_data::parse_chatgpt_jwt_claims;
|
use codex_login::token_data::parse_chatgpt_jwt_claims;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_state::RemoteControlEnrollmentRecord;
|
use codex_state::RemoteControlEnrollmentRecord;
|
||||||
use codex_state::StateRuntime;
|
use codex_state::StateRuntime;
|
||||||
use futures::SinkExt;
|
use futures::SinkExt;
|
||||||
|
|||||||
@@ -1813,7 +1813,6 @@ mod tests {
|
|||||||
use crate::transport::remote_control::protocol::StreamId;
|
use crate::transport::remote_control::protocol::StreamId;
|
||||||
use crate::transport::remote_control::protocol::normalize_remote_control_url;
|
use crate::transport::remote_control::protocol::normalize_remote_control_url;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_app_server_protocol::ConfigWarningNotification;
|
use codex_app_server_protocol::ConfigWarningNotification;
|
||||||
use codex_app_server_protocol::JSONRPCMessage;
|
use codex_app_server_protocol::JSONRPCMessage;
|
||||||
use codex_app_server_protocol::JSONRPCNotification;
|
use codex_app_server_protocol::JSONRPCNotification;
|
||||||
@@ -1826,6 +1825,7 @@ mod tests {
|
|||||||
use codex_login::save_auth;
|
use codex_login::save_auth;
|
||||||
use codex_login::token_data::TokenData;
|
use codex_login::token_data::TokenData;
|
||||||
use codex_login::token_data::parse_chatgpt_jwt_claims;
|
use codex_login::token_data::parse_chatgpt_jwt_claims;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_state::StateRuntime;
|
use codex_state::StateRuntime;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
use codex_app_server_protocol::AuthMode as ApiAuthMode;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
|
|
||||||
|
/// Converts the domain auth mode owned by `codex-protocol` into the app-server wire type owned by
|
||||||
|
/// `codex-app-server-protocol`.
|
||||||
|
///
|
||||||
|
/// The types stay separate so app-server protocol ownership does not leak into domain crates.
|
||||||
|
/// Because this crate owns neither type, Rust's orphan rules require an explicit conversion
|
||||||
|
/// function instead of a `From` implementation.
|
||||||
|
pub(crate) fn auth_mode_to_api(auth_mode: AuthMode) -> ApiAuthMode {
|
||||||
|
match auth_mode {
|
||||||
|
AuthMode::ApiKey => ApiAuthMode::ApiKey,
|
||||||
|
AuthMode::Chatgpt => ApiAuthMode::Chatgpt,
|
||||||
|
AuthMode::ChatgptAuthTokens => ApiAuthMode::ChatgptAuthTokens,
|
||||||
|
AuthMode::AgentIdentity => ApiAuthMode::AgentIdentity,
|
||||||
|
AuthMode::PersonalAccessToken => ApiAuthMode::PersonalAccessToken,
|
||||||
|
AuthMode::BedrockApiKey => ApiAuthMode::BedrockApiKey,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -82,6 +82,7 @@ const SQLITE_RECOVERY_CONFIG_WARNING_SUMMARY: &str = "Codex rebuilt its local da
|
|||||||
mod analytics_utils;
|
mod analytics_utils;
|
||||||
mod app_server_tracing;
|
mod app_server_tracing;
|
||||||
mod attestation;
|
mod attestation;
|
||||||
|
mod auth_mode;
|
||||||
mod bespoke_event_handling;
|
mod bespoke_event_handling;
|
||||||
mod command_exec;
|
mod command_exec;
|
||||||
mod config;
|
mod config;
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ use crate::transport::AppServerTransport;
|
|||||||
use crate::transport::RemoteControlHandle;
|
use crate::transport::RemoteControlHandle;
|
||||||
use codex_analytics::AnalyticsEventsClient;
|
use codex_analytics::AnalyticsEventsClient;
|
||||||
use codex_analytics::AppServerRpcTransport;
|
use codex_analytics::AppServerRpcTransport;
|
||||||
use codex_app_server_protocol::AuthMode as LoginAuthMode;
|
|
||||||
use codex_app_server_protocol::ChatgptAuthTokensRefreshParams;
|
use codex_app_server_protocol::ChatgptAuthTokensRefreshParams;
|
||||||
use codex_app_server_protocol::ChatgptAuthTokensRefreshReason;
|
use codex_app_server_protocol::ChatgptAuthTokensRefreshReason;
|
||||||
use codex_app_server_protocol::ChatgptAuthTokensRefreshResponse;
|
use codex_app_server_protocol::ChatgptAuthTokensRefreshResponse;
|
||||||
@@ -80,6 +79,7 @@ use codex_login::auth::ExternalAuthRefreshContext;
|
|||||||
use codex_login::auth::ExternalAuthRefreshReason;
|
use codex_login::auth::ExternalAuthRefreshReason;
|
||||||
use codex_login::auth::ExternalAuthTokens;
|
use codex_login::auth::ExternalAuthTokens;
|
||||||
use codex_protocol::ThreadId;
|
use codex_protocol::ThreadId;
|
||||||
|
use codex_protocol::auth::AuthMode as LoginAuthMode;
|
||||||
use codex_protocol::protocol::SessionSource;
|
use codex_protocol::protocol::SessionSource;
|
||||||
use codex_protocol::protocol::W3cTraceContext;
|
use codex_protocol::protocol::W3cTraceContext;
|
||||||
use codex_rollout::StateDbHandle;
|
use codex_rollout::StateDbHandle;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::auth_mode::auth_mode_to_api;
|
||||||
use chrono::DateTime;
|
use chrono::DateTime;
|
||||||
|
|
||||||
mod rate_limit_resets;
|
mod rate_limit_resets;
|
||||||
@@ -179,7 +180,10 @@ impl AccountRequestProcessor {
|
|||||||
fn current_account_updated_notification(&self) -> AccountUpdatedNotification {
|
fn current_account_updated_notification(&self) -> AccountUpdatedNotification {
|
||||||
let auth = self.auth_manager.auth_cached();
|
let auth = self.auth_manager.auth_cached();
|
||||||
AccountUpdatedNotification {
|
AccountUpdatedNotification {
|
||||||
auth_mode: auth.as_ref().map(CodexAuth::api_auth_mode),
|
auth_mode: auth
|
||||||
|
.as_ref()
|
||||||
|
.map(CodexAuth::api_auth_mode)
|
||||||
|
.map(auth_mode_to_api),
|
||||||
plan_type: auth.as_ref().and_then(CodexAuth::account_plan_type),
|
plan_type: auth.as_ref().and_then(CodexAuth::account_plan_type),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -693,7 +697,10 @@ impl AccountRequestProcessor {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
let payload_v2 = AccountUpdatedNotification {
|
let payload_v2 = AccountUpdatedNotification {
|
||||||
auth_mode: auth.as_ref().map(CodexAuth::api_auth_mode),
|
auth_mode: auth
|
||||||
|
.as_ref()
|
||||||
|
.map(CodexAuth::api_auth_mode)
|
||||||
|
.map(auth_mode_to_api),
|
||||||
plan_type: auth.as_ref().and_then(CodexAuth::account_plan_type),
|
plan_type: auth.as_ref().and_then(CodexAuth::account_plan_type),
|
||||||
};
|
};
|
||||||
outgoing
|
outgoing
|
||||||
@@ -730,7 +737,8 @@ impl AccountRequestProcessor {
|
|||||||
.auth_manager
|
.auth_manager
|
||||||
.auth_cached()
|
.auth_cached()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(CodexAuth::api_auth_mode))
|
.map(CodexAuth::api_auth_mode)
|
||||||
|
.map(auth_mode_to_api))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn logout_v2(&self, request_id: ConnectionRequestId) -> Result<(), JSONRPCErrorError> {
|
async fn logout_v2(&self, request_id: ConnectionRequestId) -> Result<(), JSONRPCErrorError> {
|
||||||
@@ -801,7 +809,7 @@ impl AccountRequestProcessor {
|
|||||||
Some(auth) => {
|
Some(auth) => {
|
||||||
let permanent_refresh_failure =
|
let permanent_refresh_failure =
|
||||||
self.auth_manager.refresh_failure_for_auth(&auth).is_some();
|
self.auth_manager.refresh_failure_for_auth(&auth).is_some();
|
||||||
let auth_mode = auth.api_auth_mode();
|
let auth_mode = auth_mode_to_api(auth.api_auth_mode());
|
||||||
let (reported_auth_method, token_opt) = if matches!(
|
let (reported_auth_method, token_opt) = if matches!(
|
||||||
auth,
|
auth,
|
||||||
CodexAuth::AgentIdentity(_) | CodexAuth::PersonalAccessToken(_)
|
CodexAuth::AgentIdentity(_) | CodexAuth::PersonalAccessToken(_)
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ use codex_mcp::oauth_login_support;
|
|||||||
use codex_mcp::should_retry_without_scopes;
|
use codex_mcp::should_retry_without_scopes;
|
||||||
use codex_plugin::PluginId;
|
use codex_plugin::PluginId;
|
||||||
use codex_plugin::PluginTelemetryMetadata;
|
use codex_plugin::PluginTelemetryMetadata;
|
||||||
|
use codex_protocol::auth::AuthMode as DomainAuthMode;
|
||||||
use codex_rmcp_client::perform_oauth_login_silent;
|
use codex_rmcp_client::perform_oauth_login_silent;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -567,7 +568,7 @@ impl PluginRequestProcessor {
|
|||||||
let include_global_remote =
|
let include_global_remote =
|
||||||
!explicit_marketplace_kinds && config.features.enabled(Feature::RemotePlugin);
|
!explicit_marketplace_kinds && config.features.enabled(Feature::RemotePlugin);
|
||||||
let use_remote_global_catalog =
|
let use_remote_global_catalog =
|
||||||
include_global_remote && auth_mode.is_some_and(AuthMode::uses_codex_backend);
|
include_global_remote && auth_mode.is_some_and(DomainAuthMode::uses_codex_backend);
|
||||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ use base64::Engine;
|
|||||||
use base64::engine::general_purpose::URL_SAFE_NO_PAD;
|
use base64::engine::general_purpose::URL_SAFE_NO_PAD;
|
||||||
use chrono::DateTime;
|
use chrono::DateTime;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_config::types::AuthCredentialsStoreMode;
|
use codex_config::types::AuthCredentialsStoreMode;
|
||||||
use codex_login::AuthDotJson;
|
use codex_login::AuthDotJson;
|
||||||
use codex_login::AuthKeyringBackendKind;
|
use codex_login::AuthKeyringBackendKind;
|
||||||
use codex_login::save_auth;
|
use codex_login::save_auth;
|
||||||
use codex_login::token_data::TokenData;
|
use codex_login::token_data::TokenData;
|
||||||
use codex_login::token_data::parse_chatgpt_jwt_claims;
|
use codex_login::token_data::parse_chatgpt_jwt_claims;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
/// Builder for writing a fake ChatGPT auth.json in tests.
|
/// Builder for writing a fake ChatGPT auth.json in tests.
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ use codex_app_server_protocol::AppReview;
|
|||||||
use codex_app_server_protocol::AppScreenshot;
|
use codex_app_server_protocol::AppScreenshot;
|
||||||
use codex_app_server_protocol::AppsListParams;
|
use codex_app_server_protocol::AppsListParams;
|
||||||
use codex_app_server_protocol::AppsListResponse;
|
use codex_app_server_protocol::AppsListResponse;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_app_server_protocol::JSONRPCError;
|
use codex_app_server_protocol::JSONRPCError;
|
||||||
use codex_app_server_protocol::JSONRPCResponse;
|
use codex_app_server_protocol::JSONRPCResponse;
|
||||||
use codex_app_server_protocol::RequestId;
|
use codex_app_server_protocol::RequestId;
|
||||||
@@ -38,6 +37,7 @@ use codex_config::types::AuthCredentialsStoreMode;
|
|||||||
use codex_login::AuthDotJson;
|
use codex_login::AuthDotJson;
|
||||||
use codex_login::AuthKeyringBackendKind;
|
use codex_login::AuthKeyringBackendKind;
|
||||||
use codex_login::save_auth;
|
use codex_login::save_auth;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use rmcp::handler::server::ServerHandler;
|
use rmcp::handler::server::ServerHandler;
|
||||||
use rmcp::model::JsonObject;
|
use rmcp::model::JsonObject;
|
||||||
|
|||||||
+32
-34
@@ -53,6 +53,7 @@ use codex_login::default_client::build_reqwest_client;
|
|||||||
use codex_login::default_client::default_headers;
|
use codex_login::default_client::default_headers;
|
||||||
use codex_login::load_auth_dot_json;
|
use codex_login::load_auth_dot_json;
|
||||||
use codex_model_provider::create_model_provider;
|
use codex_model_provider::create_model_provider;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::protocol::AskForApproval;
|
use codex_protocol::protocol::AskForApproval;
|
||||||
use codex_terminal_detection::Multiplexer;
|
use codex_terminal_detection::Multiplexer;
|
||||||
use codex_terminal_detection::TerminalInfo;
|
use codex_terminal_detection::TerminalInfo;
|
||||||
@@ -1323,27 +1324,27 @@ fn provider_specific_auth_check(
|
|||||||
|
|
||||||
fn stored_auth_mode(auth: &codex_login::AuthDotJson) -> &'static str {
|
fn stored_auth_mode(auth: &codex_login::AuthDotJson) -> &'static str {
|
||||||
match stored_auth_mode_value(auth) {
|
match stored_auth_mode_value(auth) {
|
||||||
codex_app_server_protocol::AuthMode::ApiKey => "api_key",
|
AuthMode::ApiKey => "api_key",
|
||||||
codex_app_server_protocol::AuthMode::Chatgpt => "chatgpt",
|
AuthMode::Chatgpt => "chatgpt",
|
||||||
codex_app_server_protocol::AuthMode::ChatgptAuthTokens => "chatgpt_auth_tokens",
|
AuthMode::ChatgptAuthTokens => "chatgpt_auth_tokens",
|
||||||
codex_app_server_protocol::AuthMode::AgentIdentity => "agent_identity",
|
AuthMode::AgentIdentity => "agent_identity",
|
||||||
codex_app_server_protocol::AuthMode::PersonalAccessToken => "personal_access_token",
|
AuthMode::PersonalAccessToken => "personal_access_token",
|
||||||
codex_app_server_protocol::AuthMode::BedrockApiKey => "bedrock_api_key",
|
AuthMode::BedrockApiKey => "bedrock_api_key",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stored_auth_mode_value(auth: &AuthDotJson) -> codex_app_server_protocol::AuthMode {
|
fn stored_auth_mode_value(auth: &AuthDotJson) -> AuthMode {
|
||||||
if let Some(mode) = auth.auth_mode {
|
if let Some(mode) = auth.auth_mode {
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
if auth.personal_access_token.is_some() {
|
if auth.personal_access_token.is_some() {
|
||||||
codex_app_server_protocol::AuthMode::PersonalAccessToken
|
AuthMode::PersonalAccessToken
|
||||||
} else if auth.bedrock_api_key.is_some() {
|
} else if auth.bedrock_api_key.is_some() {
|
||||||
codex_app_server_protocol::AuthMode::BedrockApiKey
|
AuthMode::BedrockApiKey
|
||||||
} else if auth.openai_api_key.is_some() {
|
} else if auth.openai_api_key.is_some() {
|
||||||
codex_app_server_protocol::AuthMode::ApiKey
|
AuthMode::ApiKey
|
||||||
} else {
|
} else {
|
||||||
codex_app_server_protocol::AuthMode::Chatgpt
|
AuthMode::Chatgpt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1353,7 +1354,7 @@ fn stored_auth_issues(
|
|||||||
) -> Vec<&'static str> {
|
) -> Vec<&'static str> {
|
||||||
let mut issues = Vec::new();
|
let mut issues = Vec::new();
|
||||||
match stored_auth_mode_value(auth) {
|
match stored_auth_mode_value(auth) {
|
||||||
codex_app_server_protocol::AuthMode::ApiKey => {
|
AuthMode::ApiKey => {
|
||||||
let stored_key_present = auth
|
let stored_key_present = auth
|
||||||
.openai_api_key
|
.openai_api_key
|
||||||
.as_deref()
|
.as_deref()
|
||||||
@@ -1364,7 +1365,7 @@ fn stored_auth_issues(
|
|||||||
issues.push("API key auth is missing an API key");
|
issues.push("API key auth is missing an API key");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
codex_app_server_protocol::AuthMode::Chatgpt => {
|
AuthMode::Chatgpt => {
|
||||||
match auth.tokens.as_ref() {
|
match auth.tokens.as_ref() {
|
||||||
Some(tokens) => {
|
Some(tokens) => {
|
||||||
if tokens.access_token.trim().is_empty() {
|
if tokens.access_token.trim().is_empty() {
|
||||||
@@ -1380,7 +1381,7 @@ fn stored_auth_issues(
|
|||||||
issues.push("ChatGPT auth is missing refresh metadata");
|
issues.push("ChatGPT auth is missing refresh metadata");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
codex_app_server_protocol::AuthMode::ChatgptAuthTokens => {
|
AuthMode::ChatgptAuthTokens => {
|
||||||
match auth.tokens.as_ref() {
|
match auth.tokens.as_ref() {
|
||||||
Some(tokens) => {
|
Some(tokens) => {
|
||||||
if tokens.access_token.trim().is_empty() {
|
if tokens.access_token.trim().is_empty() {
|
||||||
@@ -1396,7 +1397,7 @@ fn stored_auth_issues(
|
|||||||
issues.push("external ChatGPT auth is missing refresh metadata");
|
issues.push("external ChatGPT auth is missing refresh metadata");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
codex_app_server_protocol::AuthMode::AgentIdentity => {
|
AuthMode::AgentIdentity => {
|
||||||
if auth
|
if auth
|
||||||
.agent_identity
|
.agent_identity
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -1405,7 +1406,7 @@ fn stored_auth_issues(
|
|||||||
issues.push("agent identity auth is missing an agent identity token");
|
issues.push("agent identity auth is missing an agent identity token");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
codex_app_server_protocol::AuthMode::PersonalAccessToken => {
|
AuthMode::PersonalAccessToken => {
|
||||||
if auth
|
if auth
|
||||||
.personal_access_token
|
.personal_access_token
|
||||||
.as_deref()
|
.as_deref()
|
||||||
@@ -1414,7 +1415,7 @@ fn stored_auth_issues(
|
|||||||
issues.push("personal access token auth is missing a personal access token");
|
issues.push("personal access token auth is missing a personal access token");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
codex_app_server_protocol::AuthMode::BedrockApiKey => {
|
AuthMode::BedrockApiKey => {
|
||||||
if auth.bedrock_api_key.is_none() {
|
if auth.bedrock_api_key.is_none() {
|
||||||
issues.push("Bedrock API key auth is missing a Bedrock API key");
|
issues.push("Bedrock API key auth is missing a Bedrock API key");
|
||||||
}
|
}
|
||||||
@@ -2462,12 +2463,12 @@ fn websocket_error_detail(err: &ApiError) -> String {
|
|||||||
|
|
||||||
fn auth_mode_name(auth: &CodexAuth) -> &'static str {
|
fn auth_mode_name(auth: &CodexAuth) -> &'static str {
|
||||||
match auth.auth_mode() {
|
match auth.auth_mode() {
|
||||||
codex_app_server_protocol::AuthMode::ApiKey => "api_key",
|
AuthMode::ApiKey => "api_key",
|
||||||
codex_app_server_protocol::AuthMode::Chatgpt => "chatgpt",
|
AuthMode::Chatgpt => "chatgpt",
|
||||||
codex_app_server_protocol::AuthMode::ChatgptAuthTokens => "chatgpt_auth_tokens",
|
AuthMode::ChatgptAuthTokens => "chatgpt_auth_tokens",
|
||||||
codex_app_server_protocol::AuthMode::AgentIdentity => "agent_identity",
|
AuthMode::AgentIdentity => "agent_identity",
|
||||||
codex_app_server_protocol::AuthMode::PersonalAccessToken => "personal_access_token",
|
AuthMode::PersonalAccessToken => "personal_access_token",
|
||||||
codex_app_server_protocol::AuthMode::BedrockApiKey => "bedrock_api_key",
|
AuthMode::BedrockApiKey => "bedrock_api_key",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2600,15 +2601,12 @@ fn provider_auth_reachability_mode_from_auth(
|
|||||||
return ProviderAuthReachabilityMode::Chatgpt;
|
return ProviderAuthReachabilityMode::Chatgpt;
|
||||||
}
|
}
|
||||||
match stored_auth.map(stored_auth_mode_value) {
|
match stored_auth.map(stored_auth_mode_value) {
|
||||||
|
Some(AuthMode::ApiKey | AuthMode::BedrockApiKey) => ProviderAuthReachabilityMode::ApiKey,
|
||||||
Some(
|
Some(
|
||||||
codex_app_server_protocol::AuthMode::ApiKey
|
AuthMode::Chatgpt
|
||||||
| codex_app_server_protocol::AuthMode::BedrockApiKey,
|
| AuthMode::ChatgptAuthTokens
|
||||||
) => ProviderAuthReachabilityMode::ApiKey,
|
| AuthMode::AgentIdentity
|
||||||
Some(
|
| AuthMode::PersonalAccessToken,
|
||||||
codex_app_server_protocol::AuthMode::Chatgpt
|
|
||||||
| codex_app_server_protocol::AuthMode::ChatgptAuthTokens
|
|
||||||
| codex_app_server_protocol::AuthMode::AgentIdentity
|
|
||||||
| codex_app_server_protocol::AuthMode::PersonalAccessToken,
|
|
||||||
)
|
)
|
||||||
| None => ProviderAuthReachabilityMode::Chatgpt,
|
| None => ProviderAuthReachabilityMode::Chatgpt,
|
||||||
}
|
}
|
||||||
@@ -3502,7 +3500,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn stored_auth_validation_rejects_missing_api_key() {
|
fn stored_auth_validation_rejects_missing_api_key() {
|
||||||
let auth = AuthDotJson {
|
let auth = AuthDotJson {
|
||||||
auth_mode: Some(codex_app_server_protocol::AuthMode::ApiKey),
|
auth_mode: Some(AuthMode::ApiKey),
|
||||||
openai_api_key: None,
|
openai_api_key: None,
|
||||||
tokens: None,
|
tokens: None,
|
||||||
last_refresh: None,
|
last_refresh: None,
|
||||||
@@ -3554,7 +3552,7 @@ mod tests {
|
|||||||
assert_eq!(stored_auth_mode(&auth), "personal_access_token");
|
assert_eq!(stored_auth_mode(&auth), "personal_access_token");
|
||||||
assert!(stored_auth_issues(&auth, |_| false).is_empty());
|
assert!(stored_auth_issues(&auth, |_| false).is_empty());
|
||||||
|
|
||||||
auth.auth_mode = Some(codex_app_server_protocol::AuthMode::PersonalAccessToken);
|
auth.auth_mode = Some(AuthMode::PersonalAccessToken);
|
||||||
auth.personal_access_token = None;
|
auth.personal_access_token = None;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
stored_auth_issues(&auth, |_| false),
|
stored_auth_issues(&auth, |_| false),
|
||||||
@@ -3565,7 +3563,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn provider_reachability_mode_uses_api_key_auth() {
|
fn provider_reachability_mode_uses_api_key_auth() {
|
||||||
let api_key_auth = AuthDotJson {
|
let api_key_auth = AuthDotJson {
|
||||||
auth_mode: Some(codex_app_server_protocol::AuthMode::ApiKey),
|
auth_mode: Some(AuthMode::ApiKey),
|
||||||
openai_api_key: Some("sk-test".to_string()),
|
openai_api_key: Some("sk-test".to_string()),
|
||||||
tokens: None,
|
tokens: None,
|
||||||
last_refresh: None,
|
last_refresh: None,
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
//! into a one-shot CLI command while still producing a durable `codex-login.log` artifact that
|
//! into a one-shot CLI command while still producing a durable `codex-login.log` artifact that
|
||||||
//! support can request from users.
|
//! support can request from users.
|
||||||
|
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_config::types::AuthCredentialsStoreMode;
|
use codex_config::types::AuthCredentialsStoreMode;
|
||||||
use codex_core::config::Config;
|
use codex_core::config::Config;
|
||||||
use codex_login::AuthKeyringBackendKind;
|
use codex_login::AuthKeyringBackendKind;
|
||||||
@@ -20,6 +19,7 @@ use codex_login::login_with_api_key;
|
|||||||
use codex_login::logout_with_revoke;
|
use codex_login::logout_with_revoke;
|
||||||
use codex_login::run_device_code_login;
|
use codex_login::run_device_code_login;
|
||||||
use codex_login::run_login_server;
|
use codex_login::run_login_server;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::config_types::ForcedLoginMethod;
|
use codex_protocol::config_types::ForcedLoginMethod;
|
||||||
use codex_utils_cli::CliConfigOverrides;
|
use codex_utils_cli::CliConfigOverrides;
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ use anyhow::Context;
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_core::config::Config;
|
use codex_core::config::Config;
|
||||||
use codex_core::config::find_codex_home;
|
use codex_core::config::find_codex_home;
|
||||||
use codex_core_plugins::ConfiguredMarketplace;
|
use codex_core_plugins::ConfiguredMarketplace;
|
||||||
@@ -22,6 +21,7 @@ use codex_login::CodexAuth;
|
|||||||
use codex_login::auth::read_codex_api_key_from_env;
|
use codex_login::auth::read_codex_api_key_from_env;
|
||||||
use codex_plugin::PluginId;
|
use codex_plugin::PluginId;
|
||||||
use codex_plugin::validate_plugin_segment;
|
use codex_plugin::validate_plugin_segment;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_utils_cli::CliConfigOverrides;
|
use codex_utils_cli::CliConfigOverrides;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_plugin::AppDeclaration;
|
use codex_plugin::AppDeclaration;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ use crate::test_support::write_curated_plugin_sha_with;
|
|||||||
use crate::test_support::write_file;
|
use crate::test_support::write_file;
|
||||||
use crate::test_support::write_openai_api_curated_marketplace;
|
use crate::test_support::write_openai_api_curated_marketplace;
|
||||||
use crate::test_support::write_openai_curated_marketplace;
|
use crate::test_support::write_openai_curated_marketplace;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_config::CONFIG_TOML_FILE;
|
use codex_config::CONFIG_TOML_FILE;
|
||||||
use codex_login::CodexAuth;
|
use codex_login::CodexAuth;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ use crate::remote::RemoteInstalledPlugin;
|
|||||||
use crate::store::PluginStore;
|
use crate::store::PluginStore;
|
||||||
use crate::store::plugin_version_for_source;
|
use crate::store::plugin_version_for_source;
|
||||||
use crate::store::plugin_version_for_source_with_fallback_manifest;
|
use crate::store::plugin_version_for_source_with_fallback_manifest;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_config::ConfigLayerStack;
|
use codex_config::ConfigLayerStack;
|
||||||
use codex_config::HooksFile;
|
use codex_config::HooksFile;
|
||||||
use codex_config::types::McpServerConfig;
|
use codex_config::types::McpServerConfig;
|
||||||
@@ -39,6 +38,7 @@ use codex_plugin::PluginHookSource;
|
|||||||
use codex_plugin::PluginId;
|
use codex_plugin::PluginId;
|
||||||
use codex_plugin::PluginIdError;
|
use codex_plugin::PluginIdError;
|
||||||
use codex_plugin::app_connector_ids_from_declarations;
|
use codex_plugin::app_connector_ids_from_declarations;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::protocol::Product;
|
use codex_protocol::protocol::Product;
|
||||||
use codex_protocol::protocol::SkillScope;
|
use codex_protocol::protocol::SkillScope;
|
||||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ use crate::store::PluginStore;
|
|||||||
use crate::store::PluginStoreError;
|
use crate::store::PluginStoreError;
|
||||||
use crate::tool_suggest_metadata::ToolSuggestMetadataCache;
|
use crate::tool_suggest_metadata::ToolSuggestMetadataCache;
|
||||||
use codex_analytics::AnalyticsEventsClient;
|
use codex_analytics::AnalyticsEventsClient;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_config::ConfigLayerStack;
|
use codex_config::ConfigLayerStack;
|
||||||
use codex_config::clear_user_plugin;
|
use codex_config::clear_user_plugin;
|
||||||
use codex_config::set_user_plugin_enabled;
|
use codex_config::set_user_plugin_enabled;
|
||||||
@@ -75,6 +74,7 @@ use codex_plugin::PluginIdError;
|
|||||||
use codex_plugin::PluginTelemetryMetadata;
|
use codex_plugin::PluginTelemetryMetadata;
|
||||||
use codex_plugin::app_connector_ids_from_declarations;
|
use codex_plugin::app_connector_ids_from_declarations;
|
||||||
use codex_plugin::prompt_safe_plugin_description;
|
use codex_plugin::prompt_safe_plugin_description;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::protocol::HookEventName;
|
use codex_protocol::protocol::HookEventName;
|
||||||
use codex_protocol::protocol::Product;
|
use codex_protocol::protocol::Product;
|
||||||
use codex_tools::DiscoverablePluginInfo;
|
use codex_tools::DiscoverablePluginInfo;
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ use crate::test_support::write_curated_plugin_sha_with as write_curated_plugin_s
|
|||||||
use crate::test_support::write_file;
|
use crate::test_support::write_file;
|
||||||
use crate::test_support::write_openai_api_curated_marketplace;
|
use crate::test_support::write_openai_api_curated_marketplace;
|
||||||
use crate::test_support::write_openai_curated_marketplace;
|
use crate::test_support::write_openai_curated_marketplace;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_app_server_protocol::ConfigLayerSource;
|
use codex_app_server_protocol::ConfigLayerSource;
|
||||||
use codex_config::AppToolApproval;
|
use codex_config::AppToolApproval;
|
||||||
use codex_config::CONFIG_TOML_FILE;
|
use codex_config::CONFIG_TOML_FILE;
|
||||||
@@ -44,6 +43,7 @@ use codex_core_skills::config_rules::SkillConfigRules;
|
|||||||
use codex_login::CodexAuth;
|
use codex_login::CodexAuth;
|
||||||
use codex_plugin::AppDeclaration;
|
use codex_plugin::AppDeclaration;
|
||||||
use codex_plugin::PluginId;
|
use codex_plugin::PluginId;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::protocol::HookEventName;
|
use codex_protocol::protocol::HookEventName;
|
||||||
use codex_protocol::protocol::Product;
|
use codex_protocol::protocol::Product;
|
||||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ use std::collections::HashMap;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
|
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_core_skills::config_rules::SkillConfigRules;
|
use codex_core_skills::config_rules::SkillConfigRules;
|
||||||
use codex_plugin::AppDeclaration;
|
use codex_plugin::AppDeclaration;
|
||||||
use codex_plugin::PluginCapabilitySummary;
|
use codex_plugin::PluginCapabilitySummary;
|
||||||
@@ -10,6 +9,7 @@ use codex_plugin::PluginId;
|
|||||||
use codex_plugin::PluginIdError;
|
use codex_plugin::PluginIdError;
|
||||||
use codex_plugin::app_connector_ids_from_declarations;
|
use codex_plugin::app_connector_ids_from_declarations;
|
||||||
use codex_plugin::prompt_safe_plugin_description;
|
use codex_plugin::prompt_safe_plugin_description;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::protocol::Product;
|
use codex_protocol::protocol::Product;
|
||||||
use tokio::sync::Semaphore;
|
use tokio::sync::Semaphore;
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ use codex_api::auth_header_telemetry;
|
|||||||
use codex_api::build_session_headers;
|
use codex_api::build_session_headers;
|
||||||
use codex_api::create_text_param_for_request;
|
use codex_api::create_text_param_for_request;
|
||||||
use codex_api::response_create_client_metadata;
|
use codex_api::response_create_client_metadata;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_login::AuthManager;
|
use codex_login::AuthManager;
|
||||||
use codex_login::CodexAuth;
|
use codex_login::CodexAuth;
|
||||||
use codex_login::RefreshTokenError;
|
use codex_login::RefreshTokenError;
|
||||||
@@ -69,6 +68,7 @@ use codex_login::UnauthorizedRecovery;
|
|||||||
use codex_login::default_client::build_reqwest_client;
|
use codex_login::default_client::build_reqwest_client;
|
||||||
use codex_otel::SessionTelemetry;
|
use codex_otel::SessionTelemetry;
|
||||||
use codex_otel::current_span_w3c_trace_context;
|
use codex_otel::current_span_w3c_trace_context;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
|
|
||||||
use codex_protocol::ThreadId;
|
use codex_protocol::ThreadId;
|
||||||
use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig;
|
use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ use crate::test_support::responses_metadata as test_responses_metadata;
|
|||||||
use codex_api::ApiError;
|
use codex_api::ApiError;
|
||||||
use codex_api::ResponseEvent;
|
use codex_api::ResponseEvent;
|
||||||
use codex_api::TransportError;
|
use codex_api::TransportError;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_login::AuthManager;
|
use codex_login::AuthManager;
|
||||||
use codex_login::CodexAuth;
|
use codex_login::CodexAuth;
|
||||||
use codex_model_provider::BearerAuthProvider;
|
use codex_model_provider::BearerAuthProvider;
|
||||||
@@ -28,6 +27,7 @@ use codex_model_provider_info::WireApi;
|
|||||||
use codex_model_provider_info::create_oss_provider_with_base_url;
|
use codex_model_provider_info::create_oss_provider_with_base_url;
|
||||||
use codex_otel::SessionTelemetry;
|
use codex_otel::SessionTelemetry;
|
||||||
use codex_protocol::ThreadId;
|
use codex_protocol::ThreadId;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::models::ContentItem;
|
use codex_protocol::models::ContentItem;
|
||||||
use codex_protocol::models::ResponseItem;
|
use codex_protocol::models::ResponseItem;
|
||||||
use codex_protocol::openai_models::ModelInfo;
|
use codex_protocol::openai_models::ModelInfo;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ use codex_analytics::CompactionImplementation;
|
|||||||
use codex_analytics::CompactionPhase;
|
use codex_analytics::CompactionPhase;
|
||||||
use codex_analytics::CompactionReason;
|
use codex_analytics::CompactionReason;
|
||||||
use codex_analytics::CompactionTrigger;
|
use codex_analytics::CompactionTrigger;
|
||||||
use codex_app_server_protocol::AuthMode;
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::error::CodexErr;
|
use codex_protocol::error::CodexErr;
|
||||||
use codex_protocol::error::Result as CodexResult;
|
use codex_protocol::error::Result as CodexResult;
|
||||||
use codex_protocol::items::ContextCompactionItem;
|
use codex_protocol::items::ContextCompactionItem;
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ use codex_api::RealtimeWebsocketClient;
|
|||||||
use codex_api::RealtimeWebsocketEvents;
|
use codex_api::RealtimeWebsocketEvents;
|
||||||
use codex_api::RealtimeWebsocketWriter;
|
use codex_api::RealtimeWebsocketWriter;
|
||||||
use codex_api::map_api_error;
|
use codex_api::map_api_error;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_config::config_toml::RealtimeWsMode;
|
use codex_config::config_toml::RealtimeWsMode;
|
||||||
use codex_config::config_toml::RealtimeWsVersion;
|
use codex_config::config_toml::RealtimeWsVersion;
|
||||||
use codex_login::CodexAuth;
|
use codex_login::CodexAuth;
|
||||||
use codex_login::default_client::default_headers;
|
use codex_login::default_client::default_headers;
|
||||||
use codex_login::read_openai_api_key_from_env;
|
use codex_login::read_openai_api_key_from_env;
|
||||||
use codex_model_provider_info::ModelProviderInfo;
|
use codex_model_provider_info::ModelProviderInfo;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::error::CodexErr;
|
use codex_protocol::error::CodexErr;
|
||||||
use codex_protocol::error::Result as CodexResult;
|
use codex_protocol::error::Result as CodexResult;
|
||||||
use codex_protocol::models::MessagePhase;
|
use codex_protocol::models::MessagePhase;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ workspace = true
|
|||||||
base64 = { workspace = true }
|
base64 = { workspace = true }
|
||||||
chrono = { workspace = true, features = ["serde"] }
|
chrono = { workspace = true, features = ["serde"] }
|
||||||
codex-agent-identity = { workspace = true }
|
codex-agent-identity = { workspace = true }
|
||||||
codex-app-server-protocol = { workspace = true }
|
|
||||||
codex-client = { workspace = true }
|
codex-client = { workspace = true }
|
||||||
codex-config = { workspace = true }
|
codex-config = { workspace = true }
|
||||||
codex-keyring-store = { workspace = true }
|
codex-keyring-store = { workspace = true }
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ use super::*;
|
|||||||
use crate::auth::storage::FileAuthStorage;
|
use crate::auth::storage::FileAuthStorage;
|
||||||
use crate::auth::storage::get_auth_file;
|
use crate::auth::storage::get_auth_file;
|
||||||
use crate::token_data::IdTokenInfo;
|
use crate::token_data::IdTokenInfo;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_protocol::account::PlanType as AccountPlanType;
|
use codex_protocol::account::PlanType as AccountPlanType;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::auth::KnownPlan as InternalKnownPlan;
|
use codex_protocol::auth::KnownPlan as InternalKnownPlan;
|
||||||
use codex_protocol::auth::PlanType as InternalPlanType;
|
use codex_protocol::auth::PlanType as InternalPlanType;
|
||||||
use codex_protocol::protocol::SessionSource;
|
use codex_protocol::protocol::SessionSource;
|
||||||
@@ -162,7 +162,7 @@ async fn stored_agent_identity_jwt_keeps_auth_json_unchanged() -> anyhow::Result
|
|||||||
save_auth(
|
save_auth(
|
||||||
codex_home.path(),
|
codex_home.path(),
|
||||||
&AuthDotJson {
|
&AuthDotJson {
|
||||||
auth_mode: Some(ApiAuthMode::AgentIdentity),
|
auth_mode: Some(AuthMode::AgentIdentity),
|
||||||
openai_api_key: None,
|
openai_api_key: None,
|
||||||
tokens: None,
|
tokens: None,
|
||||||
last_refresh: None,
|
last_refresh: None,
|
||||||
@@ -897,7 +897,7 @@ async fn loads_api_key_from_auth_json() {
|
|||||||
fn logout_removes_auth_file() -> Result<(), std::io::Error> {
|
fn logout_removes_auth_file() -> Result<(), std::io::Error> {
|
||||||
let dir = tempdir()?;
|
let dir = tempdir()?;
|
||||||
let auth_dot_json = AuthDotJson {
|
let auth_dot_json = AuthDotJson {
|
||||||
auth_mode: Some(ApiAuthMode::ApiKey),
|
auth_mode: Some(AuthMode::ApiKey),
|
||||||
openai_api_key: Some("sk-test-key".to_string()),
|
openai_api_key: Some("sk-test-key".to_string()),
|
||||||
tokens: None,
|
tokens: None,
|
||||||
last_refresh: None,
|
last_refresh: None,
|
||||||
@@ -1045,7 +1045,7 @@ async fn external_bearer_only_auth_manager_uses_cached_provider_token() {
|
|||||||
assert_eq!(first.as_deref(), Some("provider-token"));
|
assert_eq!(first.as_deref(), Some("provider-token"));
|
||||||
assert_eq!(second.as_deref(), Some("provider-token"));
|
assert_eq!(second.as_deref(), Some("provider-token"));
|
||||||
assert_eq!(manager.auth_mode(), Some(AuthMode::ApiKey));
|
assert_eq!(manager.auth_mode(), Some(AuthMode::ApiKey));
|
||||||
assert_eq!(manager.get_api_auth_mode(), Some(ApiAuthMode::ApiKey));
|
assert_eq!(manager.get_api_auth_mode(), Some(AuthMode::ApiKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -1822,7 +1822,7 @@ async fn enforce_login_restrictions_logs_out_for_agent_identity_workspace_mismat
|
|||||||
save_auth(
|
save_auth(
|
||||||
codex_home.path(),
|
codex_home.path(),
|
||||||
&AuthDotJson {
|
&AuthDotJson {
|
||||||
auth_mode: Some(ApiAuthMode::AgentIdentity),
|
auth_mode: Some(AuthMode::AgentIdentity),
|
||||||
openai_api_key: None,
|
openai_api_key: None,
|
||||||
tokens: None,
|
tokens: None,
|
||||||
last_refresh: None,
|
last_refresh: None,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use serde::Serialize;
|
|||||||
use super::manager::save_auth;
|
use super::manager::save_auth;
|
||||||
use super::storage::AuthDotJson;
|
use super::storage::AuthDotJson;
|
||||||
use super::storage::AuthKeyringBackendKind;
|
use super::storage::AuthKeyringBackendKind;
|
||||||
use codex_app_server_protocol::AuthMode;
|
use codex_protocol::auth::AuthMode;
|
||||||
|
|
||||||
/// Managed Amazon Bedrock API key persisted in `auth.json`.
|
/// Managed Amazon Bedrock API key persisted in `auth.json`.
|
||||||
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)]
|
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_config::types::AuthCredentialsStoreMode;
|
use codex_config::types::AuthCredentialsStoreMode;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use super::manager::ExternalAuth;
|
|||||||
use super::manager::ExternalAuthFuture;
|
use super::manager::ExternalAuthFuture;
|
||||||
use super::manager::ExternalAuthRefreshContext;
|
use super::manager::ExternalAuthRefreshContext;
|
||||||
use super::manager::ExternalAuthTokens;
|
use super::manager::ExternalAuthTokens;
|
||||||
use codex_app_server_protocol::AuthMode;
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::config_types::ModelProviderAuthInfo;
|
use codex_protocol::config_types::ModelProviderAuthInfo;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ use tokio::sync::watch;
|
|||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use codex_agent_identity::ChatGptEnvironment;
|
use codex_agent_identity::ChatGptEnvironment;
|
||||||
use codex_app_server_protocol::AuthMode;
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_app_server_protocol::AuthMode as ApiAuthMode;
|
|
||||||
use codex_protocol::config_types::ForcedLoginMethod;
|
use codex_protocol::config_types::ForcedLoginMethod;
|
||||||
use codex_protocol::config_types::ModelProviderAuthInfo;
|
use codex_protocol::config_types::ModelProviderAuthInfo;
|
||||||
|
|
||||||
@@ -242,13 +241,13 @@ impl CodexAuth {
|
|||||||
auth_route_config: Option<&AuthRouteConfig>,
|
auth_route_config: Option<&AuthRouteConfig>,
|
||||||
) -> std::io::Result<Self> {
|
) -> std::io::Result<Self> {
|
||||||
let auth_mode = auth_dot_json.resolved_mode();
|
let auth_mode = auth_dot_json.resolved_mode();
|
||||||
if auth_mode == ApiAuthMode::ApiKey {
|
if auth_mode == AuthMode::ApiKey {
|
||||||
let Some(api_key) = auth_dot_json.openai_api_key.as_deref() else {
|
let Some(api_key) = auth_dot_json.openai_api_key.as_deref() else {
|
||||||
return Err(std::io::Error::other("API key auth is missing a key."));
|
return Err(std::io::Error::other("API key auth is missing a key."));
|
||||||
};
|
};
|
||||||
return Ok(Self::from_api_key(api_key));
|
return Ok(Self::from_api_key(api_key));
|
||||||
}
|
}
|
||||||
if auth_mode == ApiAuthMode::AgentIdentity {
|
if auth_mode == AuthMode::AgentIdentity {
|
||||||
let Some(agent_identity) = auth_dot_json.agent_identity.clone() else {
|
let Some(agent_identity) = auth_dot_json.agent_identity.clone() else {
|
||||||
return Err(std::io::Error::other(
|
return Err(std::io::Error::other(
|
||||||
"agent identity auth is missing agent identity auth material.",
|
"agent identity auth is missing agent identity auth material.",
|
||||||
@@ -282,7 +281,7 @@ impl CodexAuth {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if auth_mode == ApiAuthMode::PersonalAccessToken {
|
if auth_mode == AuthMode::PersonalAccessToken {
|
||||||
let Some(personal_access_token) = auth_dot_json.personal_access_token.as_deref() else {
|
let Some(personal_access_token) = auth_dot_json.personal_access_token.as_deref() else {
|
||||||
return Err(std::io::Error::other(
|
return Err(std::io::Error::other(
|
||||||
"personal access token auth is missing a personal access token.",
|
"personal access token auth is missing a personal access token.",
|
||||||
@@ -291,7 +290,7 @@ impl CodexAuth {
|
|||||||
return Self::from_personal_access_token(personal_access_token, auth_route_config)
|
return Self::from_personal_access_token(personal_access_token, auth_route_config)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
if auth_mode == ApiAuthMode::BedrockApiKey {
|
if auth_mode == AuthMode::BedrockApiKey {
|
||||||
let Some(auth) = auth_dot_json.bedrock_api_key else {
|
let Some(auth) = auth_dot_json.bedrock_api_key else {
|
||||||
return Err(std::io::Error::other(
|
return Err(std::io::Error::other(
|
||||||
"Bedrock API key auth is missing a Bedrock API key.",
|
"Bedrock API key auth is missing a Bedrock API key.",
|
||||||
@@ -308,7 +307,7 @@ impl CodexAuth {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match auth_mode {
|
match auth_mode {
|
||||||
ApiAuthMode::Chatgpt => {
|
AuthMode::Chatgpt => {
|
||||||
let storage = create_auth_storage(
|
let storage = create_auth_storage(
|
||||||
codex_home.to_path_buf(),
|
codex_home.to_path_buf(),
|
||||||
storage_mode,
|
storage_mode,
|
||||||
@@ -316,15 +315,13 @@ impl CodexAuth {
|
|||||||
);
|
);
|
||||||
Ok(Self::Chatgpt(ChatgptAuth { state, storage }))
|
Ok(Self::Chatgpt(ChatgptAuth { state, storage }))
|
||||||
}
|
}
|
||||||
ApiAuthMode::ChatgptAuthTokens => {
|
AuthMode::ChatgptAuthTokens => Ok(Self::ChatgptAuthTokens(ChatgptAuthTokens { state })),
|
||||||
Ok(Self::ChatgptAuthTokens(ChatgptAuthTokens { state }))
|
AuthMode::ApiKey => unreachable!("api key mode is handled above"),
|
||||||
}
|
AuthMode::AgentIdentity => unreachable!("agent identity mode is handled above"),
|
||||||
ApiAuthMode::ApiKey => unreachable!("api key mode is handled above"),
|
AuthMode::PersonalAccessToken => {
|
||||||
ApiAuthMode::AgentIdentity => unreachable!("agent identity mode is handled above"),
|
|
||||||
ApiAuthMode::PersonalAccessToken => {
|
|
||||||
unreachable!("personal access token mode is handled above")
|
unreachable!("personal access token mode is handled above")
|
||||||
}
|
}
|
||||||
ApiAuthMode::BedrockApiKey => unreachable!("bedrock api key mode is handled above"),
|
AuthMode::BedrockApiKey => unreachable!("bedrock api key mode is handled above"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,6 +392,9 @@ impl CodexAuth {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the effective backend auth mode.
|
||||||
|
///
|
||||||
|
/// Externally managed ChatGPT tokens are normalized to [`AuthMode::Chatgpt`].
|
||||||
pub fn auth_mode(&self) -> AuthMode {
|
pub fn auth_mode(&self) -> AuthMode {
|
||||||
match self {
|
match self {
|
||||||
Self::ApiKey(_) => AuthMode::ApiKey,
|
Self::ApiKey(_) => AuthMode::ApiKey,
|
||||||
@@ -405,14 +405,15 @@ impl CodexAuth {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn api_auth_mode(&self) -> ApiAuthMode {
|
/// Returns the precise kind of credentials backing this authentication.
|
||||||
|
pub fn api_auth_mode(&self) -> AuthMode {
|
||||||
match self {
|
match self {
|
||||||
Self::ApiKey(_) => ApiAuthMode::ApiKey,
|
Self::ApiKey(_) => AuthMode::ApiKey,
|
||||||
Self::Chatgpt(_) => ApiAuthMode::Chatgpt,
|
Self::Chatgpt(_) => AuthMode::Chatgpt,
|
||||||
Self::ChatgptAuthTokens(_) => ApiAuthMode::ChatgptAuthTokens,
|
Self::ChatgptAuthTokens(_) => AuthMode::ChatgptAuthTokens,
|
||||||
Self::AgentIdentity(_) => ApiAuthMode::AgentIdentity,
|
Self::AgentIdentity(_) => AuthMode::AgentIdentity,
|
||||||
Self::PersonalAccessToken(_) => ApiAuthMode::PersonalAccessToken,
|
Self::PersonalAccessToken(_) => AuthMode::PersonalAccessToken,
|
||||||
Self::BedrockApiKey(_) => ApiAuthMode::BedrockApiKey,
|
Self::BedrockApiKey(_) => AuthMode::BedrockApiKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -660,7 +661,7 @@ impl CodexAuth {
|
|||||||
/// Consider this private to integration tests.
|
/// Consider this private to integration tests.
|
||||||
pub fn create_dummy_chatgpt_auth_for_testing() -> Self {
|
pub fn create_dummy_chatgpt_auth_for_testing() -> Self {
|
||||||
let auth_dot_json = AuthDotJson {
|
let auth_dot_json = AuthDotJson {
|
||||||
auth_mode: Some(ApiAuthMode::Chatgpt),
|
auth_mode: Some(AuthMode::Chatgpt),
|
||||||
openai_api_key: None,
|
openai_api_key: None,
|
||||||
tokens: Some(TokenData {
|
tokens: Some(TokenData {
|
||||||
id_token: Default::default(),
|
id_token: Default::default(),
|
||||||
@@ -851,7 +852,7 @@ pub fn login_with_api_key(
|
|||||||
keyring_backend_kind: AuthKeyringBackendKind,
|
keyring_backend_kind: AuthKeyringBackendKind,
|
||||||
) -> std::io::Result<()> {
|
) -> std::io::Result<()> {
|
||||||
let auth_dot_json = AuthDotJson {
|
let auth_dot_json = AuthDotJson {
|
||||||
auth_mode: Some(ApiAuthMode::ApiKey),
|
auth_mode: Some(AuthMode::ApiKey),
|
||||||
openai_api_key: Some(api_key.to_string()),
|
openai_api_key: Some(api_key.to_string()),
|
||||||
tokens: None,
|
tokens: None,
|
||||||
last_refresh: None,
|
last_refresh: None,
|
||||||
@@ -900,7 +901,7 @@ pub async fn login_with_access_token(
|
|||||||
.to_string();
|
.to_string();
|
||||||
verified_record_from_jwt(jwt, &base_url, auth_route_config).await?;
|
verified_record_from_jwt(jwt, &base_url, auth_route_config).await?;
|
||||||
AuthDotJson {
|
AuthDotJson {
|
||||||
auth_mode: Some(ApiAuthMode::AgentIdentity),
|
auth_mode: Some(AuthMode::AgentIdentity),
|
||||||
openai_api_key: None,
|
openai_api_key: None,
|
||||||
tokens: None,
|
tokens: None,
|
||||||
last_refresh: None,
|
last_refresh: None,
|
||||||
@@ -1419,7 +1420,7 @@ impl AuthDotJson {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
auth_mode: Some(ApiAuthMode::ChatgptAuthTokens),
|
auth_mode: Some(AuthMode::ChatgptAuthTokens),
|
||||||
openai_api_key: None,
|
openai_api_key: None,
|
||||||
tokens: Some(tokens),
|
tokens: Some(tokens),
|
||||||
last_refresh: Some(Utc::now()),
|
last_refresh: Some(Utc::now()),
|
||||||
@@ -1442,27 +1443,27 @@ impl AuthDotJson {
|
|||||||
Self::from_external_tokens(&external)
|
Self::from_external_tokens(&external)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn resolved_mode(&self) -> ApiAuthMode {
|
pub(super) fn resolved_mode(&self) -> AuthMode {
|
||||||
if let Some(mode) = self.auth_mode {
|
if let Some(mode) = self.auth_mode {
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
if self.personal_access_token.is_some() {
|
if self.personal_access_token.is_some() {
|
||||||
return ApiAuthMode::PersonalAccessToken;
|
return AuthMode::PersonalAccessToken;
|
||||||
}
|
}
|
||||||
if self.bedrock_api_key.is_some() {
|
if self.bedrock_api_key.is_some() {
|
||||||
return ApiAuthMode::BedrockApiKey;
|
return AuthMode::BedrockApiKey;
|
||||||
}
|
}
|
||||||
if self.openai_api_key.is_some() {
|
if self.openai_api_key.is_some() {
|
||||||
return ApiAuthMode::ApiKey;
|
return AuthMode::ApiKey;
|
||||||
}
|
}
|
||||||
ApiAuthMode::Chatgpt
|
AuthMode::Chatgpt
|
||||||
}
|
}
|
||||||
|
|
||||||
fn storage_mode(
|
fn storage_mode(
|
||||||
&self,
|
&self,
|
||||||
auth_credentials_store_mode: AuthCredentialsStoreMode,
|
auth_credentials_store_mode: AuthCredentialsStoreMode,
|
||||||
) -> AuthCredentialsStoreMode {
|
) -> AuthCredentialsStoreMode {
|
||||||
if self.resolved_mode() == ApiAuthMode::ChatgptAuthTokens {
|
if self.resolved_mode() == AuthMode::ChatgptAuthTokens {
|
||||||
AuthCredentialsStoreMode::Ephemeral
|
AuthCredentialsStoreMode::Ephemeral
|
||||||
} else {
|
} else {
|
||||||
auth_credentials_store_mode
|
auth_credentials_store_mode
|
||||||
@@ -2072,19 +2073,19 @@ impl AuthManager {
|
|||||||
match (a, b) {
|
match (a, b) {
|
||||||
(None, None) => true,
|
(None, None) => true,
|
||||||
(Some(a), Some(b)) => match (a.api_auth_mode(), b.api_auth_mode()) {
|
(Some(a), Some(b)) => match (a.api_auth_mode(), b.api_auth_mode()) {
|
||||||
(ApiAuthMode::ApiKey, ApiAuthMode::ApiKey) => a.api_key() == b.api_key(),
|
(AuthMode::ApiKey, AuthMode::ApiKey) => a.api_key() == b.api_key(),
|
||||||
(ApiAuthMode::Chatgpt, ApiAuthMode::Chatgpt)
|
(AuthMode::Chatgpt, AuthMode::Chatgpt)
|
||||||
| (ApiAuthMode::ChatgptAuthTokens, ApiAuthMode::ChatgptAuthTokens) => {
|
| (AuthMode::ChatgptAuthTokens, AuthMode::ChatgptAuthTokens) => {
|
||||||
a.get_current_auth_json() == b.get_current_auth_json()
|
a.get_current_auth_json() == b.get_current_auth_json()
|
||||||
}
|
}
|
||||||
(ApiAuthMode::AgentIdentity, ApiAuthMode::AgentIdentity) => match (a, b) {
|
(AuthMode::AgentIdentity, AuthMode::AgentIdentity) => match (a, b) {
|
||||||
(CodexAuth::AgentIdentity(a), CodexAuth::AgentIdentity(b)) => {
|
(CodexAuth::AgentIdentity(a), CodexAuth::AgentIdentity(b)) => {
|
||||||
a.record() == b.record()
|
a.record() == b.record()
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
(ApiAuthMode::PersonalAccessToken, ApiAuthMode::PersonalAccessToken) => a == b,
|
(AuthMode::PersonalAccessToken, AuthMode::PersonalAccessToken) => a == b,
|
||||||
(ApiAuthMode::BedrockApiKey, ApiAuthMode::BedrockApiKey) => a == b,
|
(AuthMode::BedrockApiKey, AuthMode::BedrockApiKey) => a == b,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
@@ -2401,13 +2402,15 @@ impl AuthManager {
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_api_auth_mode(&self) -> Option<ApiAuthMode> {
|
/// Returns the precise kind of credentials backing the current authentication.
|
||||||
|
pub fn get_api_auth_mode(&self) -> Option<AuthMode> {
|
||||||
if self.has_external_api_key_auth() {
|
if self.has_external_api_key_auth() {
|
||||||
return Some(ApiAuthMode::ApiKey);
|
return Some(AuthMode::ApiKey);
|
||||||
}
|
}
|
||||||
self.auth_cached().as_ref().map(CodexAuth::api_auth_mode)
|
self.auth_cached().as_ref().map(CodexAuth::api_auth_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the effective backend auth mode for the current authentication.
|
||||||
pub fn auth_mode(&self) -> Option<AuthMode> {
|
pub fn auth_mode(&self) -> Option<AuthMode> {
|
||||||
if self.has_external_api_key_auth() {
|
if self.has_external_api_key_auth() {
|
||||||
return Some(AuthMode::ApiKey);
|
return Some(AuthMode::ApiKey);
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use codex_app_server_protocol::AuthMode as ApiAuthMode;
|
|
||||||
use codex_client::CodexHttpClient;
|
use codex_client::CodexHttpClient;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
|
|
||||||
use super::manager::REFRESH_TOKEN_URL_OVERRIDE_ENV_VAR;
|
use super::manager::REFRESH_TOKEN_URL_OVERRIDE_ENV_VAR;
|
||||||
use super::manager::REVOKE_TOKEN_URL;
|
use super::manager::REVOKE_TOKEN_URL;
|
||||||
@@ -77,21 +77,21 @@ fn revocable_token(auth_dot_json: &AuthDotJson) -> Option<(&str, RevokeTokenKind
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn managed_chatgpt_tokens(auth_dot_json: &AuthDotJson) -> Option<&TokenData> {
|
fn managed_chatgpt_tokens(auth_dot_json: &AuthDotJson) -> Option<&TokenData> {
|
||||||
if resolved_auth_mode(auth_dot_json) == ApiAuthMode::Chatgpt {
|
if resolved_auth_mode(auth_dot_json) == AuthMode::Chatgpt {
|
||||||
auth_dot_json.tokens.as_ref()
|
auth_dot_json.tokens.as_ref()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolved_auth_mode(auth_dot_json: &AuthDotJson) -> ApiAuthMode {
|
fn resolved_auth_mode(auth_dot_json: &AuthDotJson) -> AuthMode {
|
||||||
if let Some(mode) = auth_dot_json.auth_mode {
|
if let Some(mode) = auth_dot_json.auth_mode {
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
if auth_dot_json.openai_api_key.is_some() {
|
if auth_dot_json.openai_api_key.is_some() {
|
||||||
return ApiAuthMode::ApiKey;
|
return AuthMode::ApiKey;
|
||||||
}
|
}
|
||||||
ApiAuthMode::Chatgpt
|
AuthMode::Chatgpt
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn revoke_oauth_token(
|
async fn revoke_oauth_token(
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ use super::BedrockApiKeyAuth;
|
|||||||
use crate::token_data::TokenData;
|
use crate::token_data::TokenData;
|
||||||
use codex_agent_identity::AgentIdentityJwtClaims;
|
use codex_agent_identity::AgentIdentityJwtClaims;
|
||||||
use codex_agent_identity::decode_agent_identity_jwt;
|
use codex_agent_identity::decode_agent_identity_jwt;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_config::types::AuthCredentialsStoreMode;
|
use codex_config::types::AuthCredentialsStoreMode;
|
||||||
pub use codex_config::types::AuthKeyringBackendKind;
|
pub use codex_config::types::AuthKeyringBackendKind;
|
||||||
use codex_keyring_store::DefaultKeyringStore;
|
use codex_keyring_store::DefaultKeyringStore;
|
||||||
use codex_keyring_store::KeyringStore;
|
use codex_keyring_store::KeyringStore;
|
||||||
use codex_protocol::account::PlanType as AccountPlanType;
|
use codex_protocol::account::PlanType as AccountPlanType;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_secrets::LocalSecretsNamespace;
|
use codex_secrets::LocalSecretsNamespace;
|
||||||
use codex_secrets::SecretName;
|
use codex_secrets::SecretName;
|
||||||
use codex_secrets::SecretScope;
|
use codex_secrets::SecretScope;
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ use crate::token_data::TokenData;
|
|||||||
use crate::token_data::parse_chatgpt_jwt_claims;
|
use crate::token_data::parse_chatgpt_jwt_claims;
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_config::types::AuthCredentialsStoreMode;
|
use codex_config::types::AuthCredentialsStoreMode;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_utils_template::Template;
|
use codex_utils_template::Template;
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
use serde_json::Value as JsonValue;
|
use serde_json::Value as JsonValue;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use anyhow::Result;
|
|||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_config::types::AuthCredentialsStoreMode;
|
use codex_config::types::AuthCredentialsStoreMode;
|
||||||
use codex_login::AuthDotJson;
|
use codex_login::AuthDotJson;
|
||||||
use codex_login::AuthKeyringBackendKind;
|
use codex_login::AuthKeyringBackendKind;
|
||||||
@@ -15,6 +14,7 @@ use codex_login::load_auth_dot_json;
|
|||||||
use codex_login::save_auth;
|
use codex_login::save_auth;
|
||||||
use codex_login::token_data::IdTokenInfo;
|
use codex_login::token_data::IdTokenInfo;
|
||||||
use codex_login::token_data::TokenData;
|
use codex_login::token_data::TokenData;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::auth::RefreshTokenFailedReason;
|
use codex_protocol::auth::RefreshTokenFailedReason;
|
||||||
use core_test_support::skip_if_no_network;
|
use core_test_support::skip_if_no_network;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_config::types::AuthCredentialsStoreMode;
|
use codex_config::types::AuthCredentialsStoreMode;
|
||||||
use codex_login::AuthDotJson;
|
use codex_login::AuthDotJson;
|
||||||
use codex_login::AuthKeyringBackendKind;
|
use codex_login::AuthKeyringBackendKind;
|
||||||
@@ -14,6 +13,7 @@ use codex_login::logout_with_revoke;
|
|||||||
use codex_login::save_auth;
|
use codex_login::save_auth;
|
||||||
use codex_login::token_data::IdTokenInfo;
|
use codex_login::token_data::IdTokenInfo;
|
||||||
use codex_login::token_data::TokenData;
|
use codex_login::token_data::TokenData;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use core_test_support::skip_if_no_network;
|
use core_test_support::skip_if_no_network;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
codex-api = { workspace = true }
|
codex-api = { workspace = true }
|
||||||
codex-app-server-protocol = { workspace = true }
|
|
||||||
codex-protocol = { workspace = true }
|
codex-protocol = { workspace = true }
|
||||||
http = { workspace = true }
|
http = { workspace = true }
|
||||||
schemars = { workspace = true }
|
schemars = { workspace = true }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
use codex_api::Provider as ApiProvider;
|
use codex_api::Provider as ApiProvider;
|
||||||
use codex_api::RetryConfig as ApiRetryConfig;
|
use codex_api::RetryConfig as ApiRetryConfig;
|
||||||
use codex_api::is_azure_responses_provider;
|
use codex_api::is_azure_responses_provider;
|
||||||
use codex_app_server_protocol::AuthMode;
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::config_types::ModelProviderAuthInfo;
|
use codex_protocol::config_types::ModelProviderAuthInfo;
|
||||||
use codex_protocol::error::CodexErr;
|
use codex_protocol::error::CodexErr;
|
||||||
use codex_protocol::error::EnvVarError;
|
use codex_protocol::error::EnvVarError;
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = { workspace = true, features = ["serde"] }
|
chrono = { workspace = true, features = ["serde"] }
|
||||||
codex-app-server-protocol = { workspace = true }
|
|
||||||
codex-collaboration-mode-templates = { workspace = true }
|
codex-collaboration-mode-templates = { workspace = true }
|
||||||
codex-login = { workspace = true }
|
codex-login = { workspace = true }
|
||||||
codex-otel = { workspace = true }
|
codex-otel = { workspace = true }
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ pub mod model_info;
|
|||||||
pub mod model_presets;
|
pub mod model_presets;
|
||||||
pub mod test_support;
|
pub mod test_support;
|
||||||
|
|
||||||
pub use codex_app_server_protocol::AuthMode;
|
pub use codex_protocol::auth::AuthMode;
|
||||||
pub use config::ModelsManagerConfig;
|
pub use config::ModelsManagerConfig;
|
||||||
|
|
||||||
/// Load the bundled model catalog shipped with `codex-models-manager`.
|
/// Load the bundled model catalog shipped with `codex-models-manager`.
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ use super::cache::ModelsCacheManager;
|
|||||||
use crate::collaboration_mode_presets::builtin_collaboration_mode_presets;
|
use crate::collaboration_mode_presets::builtin_collaboration_mode_presets;
|
||||||
use crate::config::ModelsManagerConfig;
|
use crate::config::ModelsManagerConfig;
|
||||||
use crate::model_info;
|
use crate::model_info;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_login::AuthManager;
|
use codex_login::AuthManager;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::config_types::CollaborationModeMask;
|
use codex_protocol::config_types::CollaborationModeMask;
|
||||||
use codex_protocol::error::Result as CoreResult;
|
use codex_protocol::error::Result as CoreResult;
|
||||||
use codex_protocol::openai_models::ModelInfo;
|
use codex_protocol::openai_models::ModelInfo;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::ModelsManagerConfig;
|
use crate::ModelsManagerConfig;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_login::AuthCredentialsStoreMode;
|
use codex_login::AuthCredentialsStoreMode;
|
||||||
use codex_login::AuthKeyringBackendKind;
|
use codex_login::AuthKeyringBackendKind;
|
||||||
use codex_login::AuthManager;
|
use codex_login::AuthManager;
|
||||||
@@ -10,6 +9,7 @@ use codex_login::ExternalAuth;
|
|||||||
use codex_login::ExternalAuthRefreshContext;
|
use codex_login::ExternalAuthRefreshContext;
|
||||||
use codex_login::ExternalAuthTokens;
|
use codex_login::ExternalAuthTokens;
|
||||||
use codex_login::TokenData;
|
use codex_login::TokenData;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::openai_models::ModelsResponse;
|
use codex_protocol::openai_models::ModelsResponse;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ chrono = { workspace = true }
|
|||||||
codex-utils-absolute-path = { workspace = true }
|
codex-utils-absolute-path = { workspace = true }
|
||||||
codex-utils-string = { workspace = true }
|
codex-utils-string = { workspace = true }
|
||||||
codex-api = { workspace = true }
|
codex-api = { workspace = true }
|
||||||
codex-app-server-protocol = { workspace = true }
|
|
||||||
codex-protocol = { workspace = true }
|
codex-protocol = { workspace = true }
|
||||||
eventsource-stream = { workspace = true }
|
eventsource-stream = { workspace = true }
|
||||||
gethostname = { workspace = true }
|
gethostname = { workspace = true }
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ mod otlp;
|
|||||||
mod targets;
|
mod targets;
|
||||||
|
|
||||||
use crate::metrics::Result as MetricsResult;
|
use crate::metrics::Result as MetricsResult;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use strum_macros::Display;
|
use strum_macros::Display;
|
||||||
|
|
||||||
@@ -44,22 +45,21 @@ pub enum ToolDecisionSource {
|
|||||||
User,
|
User,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maps to API/auth `AuthMode` to avoid a circular dependency on codex-core.
|
/// Coarsens the authentication domain into the dimensions used by telemetry.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Display)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Display)]
|
||||||
pub enum TelemetryAuthMode {
|
pub enum TelemetryAuthMode {
|
||||||
ApiKey,
|
ApiKey,
|
||||||
Chatgpt,
|
Chatgpt,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<codex_app_server_protocol::AuthMode> for TelemetryAuthMode {
|
impl From<AuthMode> for TelemetryAuthMode {
|
||||||
fn from(mode: codex_app_server_protocol::AuthMode) -> Self {
|
fn from(mode: AuthMode) -> Self {
|
||||||
match mode {
|
match mode {
|
||||||
codex_app_server_protocol::AuthMode::ApiKey
|
AuthMode::ApiKey | AuthMode::BedrockApiKey => Self::ApiKey,
|
||||||
| codex_app_server_protocol::AuthMode::BedrockApiKey => Self::ApiKey,
|
AuthMode::Chatgpt
|
||||||
codex_app_server_protocol::AuthMode::Chatgpt
|
| AuthMode::ChatgptAuthTokens
|
||||||
| codex_app_server_protocol::AuthMode::ChatgptAuthTokens
|
| AuthMode::AgentIdentity
|
||||||
| codex_app_server_protocol::AuthMode::AgentIdentity
|
| AuthMode::PersonalAccessToken => Self::Chatgpt,
|
||||||
| codex_app_server_protocol::AuthMode::PersonalAccessToken => Self::Chatgpt,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,55 @@
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use strum_macros::Display;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
/// Authentication mode for OpenAI-backed providers.
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Display, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum AuthMode {
|
||||||
|
/// OpenAI API key provided by the caller and stored by Codex.
|
||||||
|
ApiKey,
|
||||||
|
/// ChatGPT OAuth managed by Codex (tokens persisted and refreshed by Codex).
|
||||||
|
Chatgpt,
|
||||||
|
/// ChatGPT auth tokens supplied by an external host application.
|
||||||
|
#[serde(rename = "chatgptAuthTokens")]
|
||||||
|
#[strum(serialize = "chatgptAuthTokens")]
|
||||||
|
ChatgptAuthTokens,
|
||||||
|
/// Programmatic Codex auth backed by a registered Agent Identity.
|
||||||
|
#[serde(rename = "agentIdentity")]
|
||||||
|
#[strum(serialize = "agentIdentity")]
|
||||||
|
AgentIdentity,
|
||||||
|
/// Programmatic Codex auth backed by a personal access token.
|
||||||
|
#[serde(rename = "personalAccessToken")]
|
||||||
|
#[strum(serialize = "personalAccessToken")]
|
||||||
|
PersonalAccessToken,
|
||||||
|
/// Amazon Bedrock bearer token managed by Codex.
|
||||||
|
#[serde(rename = "bedrockApiKey")]
|
||||||
|
#[strum(serialize = "bedrockApiKey")]
|
||||||
|
BedrockApiKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuthMode {
|
||||||
|
/// Returns whether this mode represents an authenticated human ChatGPT account.
|
||||||
|
pub fn has_chatgpt_account(self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::Chatgpt | Self::ChatgptAuthTokens | Self::PersonalAccessToken => true,
|
||||||
|
Self::ApiKey | Self::AgentIdentity | Self::BedrockApiKey => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether this mode is backed by Codex services rather than a direct model API.
|
||||||
|
pub fn uses_codex_backend(self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::Chatgpt
|
||||||
|
| Self::ChatgptAuthTokens
|
||||||
|
| Self::AgentIdentity
|
||||||
|
| Self::PersonalAccessToken => true,
|
||||||
|
Self::ApiKey | Self::BedrockApiKey => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum PlanType {
|
pub enum PlanType {
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ use codex_app_server_client::RemoteAppServerConnectArgs;
|
|||||||
pub use codex_app_server_client::RemoteAppServerEndpoint;
|
pub use codex_app_server_client::RemoteAppServerEndpoint;
|
||||||
use codex_app_server_protocol::Account as AppServerAccount;
|
use codex_app_server_protocol::Account as AppServerAccount;
|
||||||
use codex_app_server_protocol::AskForApproval;
|
use codex_app_server_protocol::AskForApproval;
|
||||||
use codex_app_server_protocol::AuthMode as AppServerAuthMode;
|
|
||||||
use codex_app_server_protocol::ConfigWarningNotification;
|
use codex_app_server_protocol::ConfigWarningNotification;
|
||||||
use codex_app_server_protocol::Thread as AppServerThread;
|
use codex_app_server_protocol::Thread as AppServerThread;
|
||||||
use codex_app_server_protocol::ThreadListCwdFilter;
|
use codex_app_server_protocol::ThreadListCwdFilter;
|
||||||
@@ -51,6 +50,7 @@ use codex_login::default_client::originator;
|
|||||||
use codex_login::default_client::set_default_client_residency_requirement;
|
use codex_login::default_client::set_default_client_residency_requirement;
|
||||||
use codex_login::enforce_login_restrictions;
|
use codex_login::enforce_login_restrictions;
|
||||||
use codex_protocol::ThreadId;
|
use codex_protocol::ThreadId;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use codex_protocol::config_types::AltScreenMode;
|
use codex_protocol::config_types::AltScreenMode;
|
||||||
use codex_protocol::config_types::SandboxMode;
|
use codex_protocol::config_types::SandboxMode;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
@@ -1869,7 +1869,7 @@ fn determine_alt_screen_mode(no_alt_screen: bool, tui_alternate_screen: AltScree
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum LoginStatus {
|
pub enum LoginStatus {
|
||||||
AuthMode(AppServerAuthMode),
|
AuthMode(AuthMode),
|
||||||
NotAuthenticated,
|
NotAuthenticated,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1886,8 +1886,8 @@ async fn get_login_status(
|
|||||||
|
|
||||||
let account = app_server.read_account().await?;
|
let account = app_server.read_account().await?;
|
||||||
Ok(match account.account {
|
Ok(match account.account {
|
||||||
Some(AppServerAccount::ApiKey {}) => LoginStatus::AuthMode(AppServerAuthMode::ApiKey),
|
Some(AppServerAccount::ApiKey {}) => LoginStatus::AuthMode(AuthMode::ApiKey),
|
||||||
Some(AppServerAccount::Chatgpt { .. }) => LoginStatus::AuthMode(AppServerAuthMode::Chatgpt),
|
Some(AppServerAccount::Chatgpt { .. }) => LoginStatus::AuthMode(AuthMode::Chatgpt),
|
||||||
Some(AppServerAccount::AmazonBedrock { .. }) => LoginStatus::NotAuthenticated,
|
Some(AppServerAccount::AmazonBedrock { .. }) => LoginStatus::NotAuthenticated,
|
||||||
None => LoginStatus::NotAuthenticated,
|
None => LoginStatus::NotAuthenticated,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_config::types::AuthCredentialsStoreMode;
|
use codex_config::types::AuthCredentialsStoreMode;
|
||||||
use codex_login::AuthKeyringBackendKind;
|
use codex_login::AuthKeyringBackendKind;
|
||||||
use codex_login::load_auth_dot_json;
|
use codex_login::load_auth_dot_json;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub(crate) struct LocalChatgptAuth {
|
pub(crate) struct LocalChatgptAuth {
|
||||||
@@ -64,11 +64,11 @@ mod tests {
|
|||||||
|
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use codex_app_server_protocol::AuthMode;
|
|
||||||
use codex_login::AuthDotJson;
|
use codex_login::AuthDotJson;
|
||||||
use codex_login::auth::login_with_chatgpt_auth_tokens;
|
use codex_login::auth::login_with_chatgpt_auth_tokens;
|
||||||
use codex_login::save_auth;
|
use codex_login::save_auth;
|
||||||
use codex_login::token_data::TokenData;
|
use codex_login::token_data::TokenData;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|||||||
@@ -10,13 +10,13 @@
|
|||||||
use codex_app_server_client::AppServerRequestHandle;
|
use codex_app_server_client::AppServerRequestHandle;
|
||||||
use codex_app_server_protocol::AccountLoginCompletedNotification;
|
use codex_app_server_protocol::AccountLoginCompletedNotification;
|
||||||
use codex_app_server_protocol::AccountUpdatedNotification;
|
use codex_app_server_protocol::AccountUpdatedNotification;
|
||||||
#[cfg(test)]
|
use codex_app_server_protocol::AuthMode as ApiAuthMode;
|
||||||
use codex_app_server_protocol::AuthMode as AppServerAuthMode;
|
|
||||||
use codex_app_server_protocol::CancelLoginAccountParams;
|
use codex_app_server_protocol::CancelLoginAccountParams;
|
||||||
use codex_app_server_protocol::ClientRequest;
|
use codex_app_server_protocol::ClientRequest;
|
||||||
use codex_app_server_protocol::LoginAccountParams;
|
use codex_app_server_protocol::LoginAccountParams;
|
||||||
use codex_app_server_protocol::LoginAccountResponse;
|
use codex_app_server_protocol::LoginAccountResponse;
|
||||||
use codex_login::read_openai_api_key_from_env;
|
use codex_login::read_openai_api_key_from_env;
|
||||||
|
use codex_protocol::auth::AuthMode;
|
||||||
use crossterm::event::KeyCode;
|
use crossterm::event::KeyCode;
|
||||||
use crossterm::event::KeyEvent;
|
use crossterm::event::KeyEvent;
|
||||||
use crossterm::event::KeyEventKind;
|
use crossterm::event::KeyEventKind;
|
||||||
@@ -945,7 +945,16 @@ impl AuthModeWidget {
|
|||||||
pub(crate) fn on_account_updated(&mut self, notification: AccountUpdatedNotification) {
|
pub(crate) fn on_account_updated(&mut self, notification: AccountUpdatedNotification) {
|
||||||
self.login_status = notification
|
self.login_status = notification
|
||||||
.auth_mode
|
.auth_mode
|
||||||
.map(LoginStatus::AuthMode)
|
.map(|auth_mode| {
|
||||||
|
LoginStatus::AuthMode(match auth_mode {
|
||||||
|
ApiAuthMode::ApiKey => AuthMode::ApiKey,
|
||||||
|
ApiAuthMode::Chatgpt => AuthMode::Chatgpt,
|
||||||
|
ApiAuthMode::ChatgptAuthTokens => AuthMode::ChatgptAuthTokens,
|
||||||
|
ApiAuthMode::AgentIdentity => AuthMode::AgentIdentity,
|
||||||
|
ApiAuthMode::PersonalAccessToken => AuthMode::PersonalAccessToken,
|
||||||
|
ApiAuthMode::BedrockApiKey => AuthMode::BedrockApiKey,
|
||||||
|
})
|
||||||
|
})
|
||||||
.unwrap_or(LoginStatus::NotAuthenticated);
|
.unwrap_or(LoginStatus::NotAuthenticated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1111,10 +1120,7 @@ mod tests {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn existing_non_oauth_chatgpt_login_counts_as_signed_in() {
|
async fn existing_non_oauth_chatgpt_login_counts_as_signed_in() {
|
||||||
for auth_mode in [
|
for auth_mode in [AuthMode::ChatgptAuthTokens, AuthMode::PersonalAccessToken] {
|
||||||
AppServerAuthMode::ChatgptAuthTokens,
|
|
||||||
AppServerAuthMode::PersonalAccessToken,
|
|
||||||
] {
|
|
||||||
let (mut widget, _tmp) = widget_forced_chatgpt().await;
|
let (mut widget, _tmp) = widget_forced_chatgpt().await;
|
||||||
widget.login_status = LoginStatus::AuthMode(auth_mode);
|
widget.login_status = LoginStatus::AuthMode(auth_mode);
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user