mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-04-01 01:21:24 +08:00
fix(gemini): write security auth config only to Gemini settings file
- Remove redundant security.auth.selectedType from CC Switch settings - Fix Generic provider type not writing security flag on switch - All non-Google Official providers now correctly write "gemini-api-key" - Delete unused ensure_packycode_security_flag function - Clean up SecuritySettings and SecurityAuthSettings types from AppSettings
This commit is contained in:
@@ -4,7 +4,6 @@
|
||||
|
||||
use crate::error::AppError;
|
||||
use crate::provider::Provider;
|
||||
use crate::settings;
|
||||
|
||||
/// Gemini authentication type enumeration
|
||||
///
|
||||
@@ -19,10 +18,6 @@ pub(crate) enum GeminiAuthType {
|
||||
Generic,
|
||||
}
|
||||
|
||||
// Authentication type constants
|
||||
const PACKYCODE_SECURITY_SELECTED_TYPE: &str = "gemini-api-key";
|
||||
const GOOGLE_OAUTH_SECURITY_SELECTED_TYPE: &str = "oauth-personal";
|
||||
|
||||
// Partner Promotion Key constants
|
||||
const PACKYCODE_PARTNER_KEY: &str = "packycode";
|
||||
const GOOGLE_OFFICIAL_PARTNER_KEY: &str = "google-official";
|
||||
@@ -194,59 +189,13 @@ pub(crate) fn is_google_official_gemini(provider: &Provider) -> bool {
|
||||
name_lower == "google" || name_lower.starts_with("google ")
|
||||
}
|
||||
|
||||
/// Ensure PackyCode Gemini provider security flag is correctly set
|
||||
///
|
||||
/// PackyCode is an official partner using API Key authentication mode.
|
||||
///
|
||||
/// # Why write to two settings.json files
|
||||
///
|
||||
/// 1. **`~/.cc-switch/settings.json`** (application-level config):
|
||||
/// - CC-Switch application global settings
|
||||
/// - Ensures app knows current authentication type
|
||||
/// - Used for UI display and other app logic
|
||||
///
|
||||
/// 2. **`~/.gemini/settings.json`** (Gemini client config):
|
||||
/// - Configuration file read by Gemini CLI client
|
||||
/// - Directly affects Gemini client authentication behavior
|
||||
/// - Ensures Gemini uses correct authentication method to connect API
|
||||
///
|
||||
/// # Value set
|
||||
///
|
||||
/// ```json
|
||||
/// {
|
||||
/// "security": {
|
||||
/// "auth": {
|
||||
/// "selectedType": "gemini-api-key"
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # Error handling
|
||||
///
|
||||
/// If provider is not PackyCode, function returns `Ok(())` immediately without any operation.
|
||||
pub(crate) fn ensure_packycode_security_flag(provider: &Provider) -> Result<(), AppError> {
|
||||
if !is_packycode_gemini(provider) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Write to application-level settings.json (~/.cc-switch/settings.json)
|
||||
settings::ensure_security_auth_selected_type(PACKYCODE_SECURITY_SELECTED_TYPE)?;
|
||||
|
||||
// Write to Gemini directory settings.json (~/.gemini/settings.json)
|
||||
use crate::gemini_config::write_packycode_settings;
|
||||
write_packycode_settings()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Ensure Google Official Gemini provider security flag is correctly set (OAuth mode)
|
||||
///
|
||||
/// Google Official Gemini uses OAuth personal authentication, no API Key needed.
|
||||
///
|
||||
/// # Why write to two settings.json files
|
||||
/// # What it does
|
||||
///
|
||||
/// Same as `ensure_packycode_security_flag`, need to configure both app-level and client-level settings.
|
||||
/// Writes to **`~/.gemini/settings.json`** (Gemini client config).
|
||||
///
|
||||
/// # Value set
|
||||
///
|
||||
@@ -276,9 +225,6 @@ pub(crate) fn ensure_google_oauth_security_flag(provider: &Provider) -> Result<(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Write to application-level settings.json (~/.cc-switch/settings.json)
|
||||
settings::ensure_security_auth_selected_type(GOOGLE_OAUTH_SECURITY_SELECTED_TYPE)?;
|
||||
|
||||
// Write to Gemini directory settings.json (~/.gemini/settings.json)
|
||||
use crate::gemini_config::write_google_oauth_settings;
|
||||
write_google_oauth_settings()?;
|
||||
|
||||
@@ -15,8 +15,7 @@ use crate::services::mcp::McpService;
|
||||
use crate::store::AppState;
|
||||
|
||||
use super::gemini_auth::{
|
||||
detect_gemini_auth_type, ensure_google_oauth_security_flag, ensure_packycode_security_flag,
|
||||
GeminiAuthType,
|
||||
detect_gemini_auth_type, ensure_google_oauth_security_flag, GeminiAuthType,
|
||||
};
|
||||
use super::normalize_claude_models_in_value;
|
||||
|
||||
@@ -375,10 +374,14 @@ pub(crate) fn write_gemini_live(provider: &Provider) -> Result<(), AppError> {
|
||||
write_json_file(&settings_path, &config_value)?;
|
||||
}
|
||||
|
||||
// Set security.auth.selectedType based on auth type
|
||||
// - Google Official: OAuth mode
|
||||
// - All others: API Key mode
|
||||
match auth_type {
|
||||
GeminiAuthType::GoogleOfficial => ensure_google_oauth_security_flag(provider)?,
|
||||
GeminiAuthType::Packycode => ensure_packycode_security_flag(provider)?,
|
||||
GeminiAuthType::Generic => {}
|
||||
GeminiAuthType::Packycode | GeminiAuthType::Generic => {
|
||||
crate::gemini_config::write_packycode_settings()?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -28,10 +28,7 @@ pub use live::{import_default_config, read_live_settings, sync_current_from_db};
|
||||
pub(crate) use live::write_live_snapshot;
|
||||
|
||||
// Internal re-exports
|
||||
use gemini_auth::{
|
||||
detect_gemini_auth_type, ensure_google_oauth_security_flag, ensure_packycode_security_flag,
|
||||
GeminiAuthType,
|
||||
};
|
||||
use gemini_auth::{detect_gemini_auth_type, ensure_google_oauth_security_flag, GeminiAuthType};
|
||||
use live::write_gemini_live;
|
||||
use usage::validate_usage_script;
|
||||
|
||||
@@ -202,13 +199,17 @@ impl ProviderService {
|
||||
// Sync to live
|
||||
write_live_snapshot(&app_type, provider)?;
|
||||
|
||||
// Gemini needs additional security flag handling (PackyCode or Google OAuth)
|
||||
// Gemini needs additional security flag handling
|
||||
// - Google Official: uses OAuth authentication
|
||||
// - All others (PackyCode, Generic): use API Key authentication
|
||||
if matches!(app_type, AppType::Gemini) {
|
||||
let auth_type = detect_gemini_auth_type(provider);
|
||||
match auth_type {
|
||||
GeminiAuthType::GoogleOfficial => ensure_google_oauth_security_flag(provider)?,
|
||||
GeminiAuthType::Packycode => ensure_packycode_security_flag(provider)?,
|
||||
GeminiAuthType::Generic => {}
|
||||
GeminiAuthType::Packycode | GeminiAuthType::Generic => {
|
||||
// All non-Google providers use API Key mode
|
||||
crate::gemini_config::write_packycode_settings()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,20 +17,6 @@ pub struct CustomEndpoint {
|
||||
pub last_used: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SecurityAuthSettings {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub selected_type: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SecuritySettings {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub auth: Option<SecurityAuthSettings>,
|
||||
}
|
||||
|
||||
/// 应用设置结构,允许覆盖默认配置目录
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -53,8 +39,6 @@ pub struct AppSettings {
|
||||
/// 是否开机自启
|
||||
#[serde(default)]
|
||||
pub launch_on_startup: bool,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub security: Option<SecuritySettings>,
|
||||
/// Claude 自定义端点列表
|
||||
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
|
||||
pub custom_endpoints_claude: HashMap<String, CustomEndpoint>,
|
||||
@@ -82,7 +66,6 @@ impl Default for AppSettings {
|
||||
gemini_config_dir: None,
|
||||
language: None,
|
||||
launch_on_startup: false,
|
||||
security: None,
|
||||
custom_endpoints_claude: HashMap::new(),
|
||||
custom_endpoints_codex: HashMap::new(),
|
||||
}
|
||||
@@ -269,27 +252,6 @@ pub fn reload_settings() -> Result<(), AppError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn ensure_security_auth_selected_type(selected_type: &str) -> Result<(), AppError> {
|
||||
let mut settings = get_settings();
|
||||
let current = settings
|
||||
.security
|
||||
.as_ref()
|
||||
.and_then(|sec| sec.auth.as_ref())
|
||||
.and_then(|auth| auth.selected_type.as_deref());
|
||||
|
||||
if current == Some(selected_type) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut security = settings.security.unwrap_or_default();
|
||||
let mut auth = security.auth.unwrap_or_default();
|
||||
auth.selected_type = Some(selected_type.to_string());
|
||||
security.auth = Some(auth);
|
||||
settings.security = Some(security);
|
||||
|
||||
update_settings(settings)
|
||||
}
|
||||
|
||||
pub fn get_claude_override_dir() -> Option<PathBuf> {
|
||||
let settings = settings_store().read().ok()?;
|
||||
settings
|
||||
|
||||
Reference in New Issue
Block a user