Skip to content

Commit 23a6c55

Browse files
committed
refactor: streamline OpenAI session clearing by consolidating storage methods
1 parent 3d6cb03 commit 23a6c55

File tree

2 files changed

+63
-13
lines changed

2 files changed

+63
-13
lines changed

src/cli/auth.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::future::Future;
33
use vtcode_auth::{
44
AuthCallbackOutcome, AuthCredentialsStoreMode, AuthStatus, OAuthCallbackPage, OAuthProvider,
55
OpenAIChatGptAuthStatus, OpenAIChatGptSession, OpenRouterToken, PkceChallenge,
6-
clear_oauth_token_with_mode, clear_openai_chatgpt_session_with_mode, exchange_code_for_token,
6+
clear_oauth_token_with_mode, clear_openai_chatgpt_session, exchange_code_for_token,
77
exchange_openai_chatgpt_code_for_tokens, generate_openai_oauth_state, generate_pkce_challenge,
88
get_auth_status_with_mode, get_auth_url, get_openai_chatgpt_auth_status_with_mode,
99
get_openai_chatgpt_auth_url, load_openai_chatgpt_session_with_mode,
@@ -221,9 +221,7 @@ pub(crate) fn clear_openrouter_login(vt_cfg: Option<&VTCodeConfig>) -> Result<()
221221
}
222222

223223
pub(crate) fn clear_openai_login(_vt_cfg: Option<&VTCodeConfig>) -> Result<()> {
224-
clear_openai_chatgpt_session_with_mode(AuthCredentialsStoreMode::File)?;
225-
clear_openai_chatgpt_session_with_mode(AuthCredentialsStoreMode::Keyring)?;
226-
Ok(())
224+
clear_openai_chatgpt_session()
227225
}
228226

229227
pub(crate) fn openrouter_auth_status(vt_cfg: Option<&VTCodeConfig>) -> Result<AuthStatus> {

vtcode-auth/src/openai_chatgpt_oauth.rs

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -457,9 +457,7 @@ pub fn load_openai_chatgpt_session_with_mode(
457457
}
458458

459459
pub fn clear_openai_chatgpt_session() -> Result<()> {
460-
let _ = clear_session_from_keyring();
461-
let _ = clear_session_from_file();
462-
Ok(())
460+
clear_session_from_all_stores()
463461
}
464462

465463
pub fn clear_openai_chatgpt_session_with_mode(mode: AuthCredentialsStoreMode) -> Result<()> {
@@ -540,7 +538,7 @@ async fn refresh_openai_chatgpt_session_without_lock(
540538
.context("failed to refresh openai chatgpt token")?;
541539
response
542540
.error_for_status_ref()
543-
.map_err(|err| classify_refresh_error(err, storage_mode))?;
541+
.map_err(classify_refresh_error)?;
544542
let token_response: OpenAITokenResponse = response
545543
.json()
546544
.await
@@ -745,22 +743,43 @@ async fn acquire_refresh_lock() -> Result<RefreshLockGuard> {
745743
Ok(RefreshLockGuard { file })
746744
}
747745

748-
fn classify_refresh_error(
749-
err: reqwest::Error,
750-
storage_mode: AuthCredentialsStoreMode,
751-
) -> anyhow::Error {
746+
fn classify_refresh_error(err: reqwest::Error) -> anyhow::Error {
752747
let status = err.status();
753748
let message = err.to_string();
754749
if status.is_some_and(|status| status == reqwest::StatusCode::BAD_REQUEST)
755750
&& (message.contains("invalid_grant") || message.contains("refresh_token"))
756751
{
757-
let _ = clear_openai_chatgpt_session_with_mode(storage_mode);
752+
if let Err(clear_err) = clear_session_from_all_stores() {
753+
tracing::warn!(
754+
"failed to clear expired openai chatgpt session across all stores: {clear_err}"
755+
);
756+
}
758757
anyhow!("Your ChatGPT session expired. Run `vtcode login openai` again.")
759758
} else {
760759
anyhow!(message)
761760
}
762761
}
763762

763+
fn clear_session_from_all_stores() -> Result<()> {
764+
let mut errors = Vec::new();
765+
766+
if let Err(err) = clear_session_from_keyring() {
767+
errors.push(err.to_string());
768+
}
769+
if let Err(err) = clear_session_from_file() {
770+
errors.push(err.to_string());
771+
}
772+
773+
if errors.is_empty() {
774+
Ok(())
775+
} else {
776+
Err(anyhow!(
777+
"failed to clear openai session from all stores: {}",
778+
errors.join("; ")
779+
))
780+
}
781+
}
782+
764783
fn save_session_to_keyring(serialized: &str) -> Result<()> {
765784
let entry = keyring::Entry::new(OPENAI_STORAGE_SERVICE, OPENAI_STORAGE_USER)
766785
.context("failed to access keyring for openai session")?;
@@ -1245,6 +1264,39 @@ mod tests {
12451264
.expect("clear session");
12461265
}
12471266

1267+
#[test]
1268+
#[serial]
1269+
fn clear_openai_chatgpt_session_removes_file_and_keyring_sessions() {
1270+
let _guard = TestAuthDirGuard::new();
1271+
let session = sample_session();
1272+
save_openai_chatgpt_session_with_mode(&session, AuthCredentialsStoreMode::File)
1273+
.expect("save file session");
1274+
1275+
if save_openai_chatgpt_session_with_mode(&session, AuthCredentialsStoreMode::Keyring)
1276+
.is_err()
1277+
{
1278+
clear_openai_chatgpt_session().expect("clear session");
1279+
assert!(
1280+
load_openai_chatgpt_session_with_mode(AuthCredentialsStoreMode::File)
1281+
.expect("load file session")
1282+
.is_none()
1283+
);
1284+
return;
1285+
}
1286+
1287+
clear_openai_chatgpt_session().expect("clear session");
1288+
assert!(
1289+
load_openai_chatgpt_session_with_mode(AuthCredentialsStoreMode::File)
1290+
.expect("load file session")
1291+
.is_none()
1292+
);
1293+
assert!(
1294+
load_openai_chatgpt_session_with_mode(AuthCredentialsStoreMode::Keyring)
1295+
.expect("load keyring session")
1296+
.is_none()
1297+
);
1298+
}
1299+
12481300
#[test]
12491301
fn active_api_bearer_token_falls_back_to_access_token() {
12501302
let mut session = sample_session();

0 commit comments

Comments
 (0)