Skip to content

Commit 07beab6

Browse files
committed
fix(auth): reuse HTTP client and use URL-encoded token in status command
1 parent a8c203e commit 07beab6

File tree

1 file changed

+74
-77
lines changed

1 file changed

+74
-77
lines changed

src/auth_commands.rs

Lines changed: 74 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,71 @@ fn run_simple_scope_picker(services_filter: Option<&HashSet<String>>) -> Option<
923923
}
924924
}
925925

926+
async fn get_status_access_token(
927+
http_client: &reqwest::Client,
928+
output: &mut serde_json::Value,
929+
) -> Option<String> {
930+
let direct_token = std::env::var("GOOGLE_WORKSPACE_CLI_TOKEN")
931+
.ok()
932+
.filter(|t| !t.is_empty());
933+
934+
if let Some(token) = direct_token {
935+
return Some(token);
936+
}
937+
938+
let enc_path = credential_store::encrypted_credentials_path();
939+
let plain_path = plain_credentials_path();
940+
941+
let creds_json_str = if enc_path.exists() {
942+
credential_store::load_encrypted().ok()
943+
} else if plain_path.exists() {
944+
std::fs::read_to_string(&plain_path).ok()
945+
} else {
946+
None
947+
};
948+
949+
let creds_str = creds_json_str?;
950+
let creds: serde_json::Value = serde_json::from_str(&creds_str).ok()?;
951+
let client_id = creds.get("client_id")?.as_str()?;
952+
let client_secret = creds.get("client_secret")?.as_str()?;
953+
let refresh_token = creds.get("refresh_token")?.as_str()?;
954+
955+
// Exchange refresh token for access token
956+
let token_resp = http_client
957+
.post("https://oauth2.googleapis.com/token")
958+
.form(&[
959+
("client_id", client_id),
960+
("client_secret", client_secret),
961+
("refresh_token", refresh_token),
962+
("grant_type", "refresh_token"),
963+
])
964+
.send()
965+
.await;
966+
967+
match token_resp {
968+
Ok(resp) => {
969+
if let Ok(token_json) = resp.json::<serde_json::Value>().await {
970+
if let Some(access_token) = token_json.get("access_token").and_then(|v| v.as_str()) {
971+
Some(access_token.to_string())
972+
} else {
973+
output["token_valid"] = serde_json::json!(false);
974+
if let Some(err) = token_json.get("error_description").and_then(|v| v.as_str()) {
975+
output["token_error"] = serde_json::json!(err);
976+
}
977+
None
978+
}
979+
} else {
980+
None
981+
}
982+
}
983+
Err(e) => {
984+
output["token_valid"] = serde_json::json!(false);
985+
output["token_error"] = serde_json::json!(e.to_string());
986+
None
987+
}
988+
}
989+
}
990+
926991
async fn handle_status() -> Result<(), GwsError> {
927992
let plain_path = plain_credentials_path();
928993
let enc_path = credential_store::encrypted_credentials_path();
@@ -1070,84 +1135,11 @@ async fn handle_status() -> Result<(), GwsError> {
10701135
// If we have credentials or a direct token, try to get live info (user, scopes, APIs)
10711136
// Skip all network calls and subprocess spawning in test builds
10721137
if !cfg!(test) {
1073-
let direct_token = std::env::var("GOOGLE_WORKSPACE_CLI_TOKEN")
1074-
.ok()
1075-
.filter(|t| !t.is_empty());
1076-
1077-
let access_token = if let Some(token) = direct_token {
1078-
Some(token)
1079-
} else {
1080-
let creds_json_str = if has_encrypted {
1081-
credential_store::load_encrypted().ok()
1082-
} else if has_plain {
1083-
tokio::fs::read_to_string(&plain_path).await.ok()
1084-
} else {
1085-
None
1086-
};
1087-
1088-
if let Some(creds_str) = creds_json_str {
1089-
if let Ok(creds) = serde_json::from_str::<serde_json::Value>(&creds_str) {
1090-
let client_id = creds.get("client_id").and_then(|v| v.as_str());
1091-
let client_secret = creds.get("client_secret").and_then(|v| v.as_str());
1092-
let refresh_token = creds.get("refresh_token").and_then(|v| v.as_str());
1093-
1094-
if let (Some(cid), Some(csec), Some(rt)) =
1095-
(client_id, client_secret, refresh_token)
1096-
{
1097-
// Exchange refresh token for access token
1098-
let http_client = reqwest::Client::new();
1099-
let token_resp = http_client
1100-
.post("https://oauth2.googleapis.com/token")
1101-
.form(&[
1102-
("client_id", cid),
1103-
("client_secret", csec),
1104-
("refresh_token", rt),
1105-
("grant_type", "refresh_token"),
1106-
])
1107-
.send()
1108-
.await;
1109-
1110-
match token_resp {
1111-
Ok(resp) => {
1112-
if let Ok(token_json) = resp.json::<serde_json::Value>().await {
1113-
if let Some(access_token) =
1114-
token_json.get("access_token").and_then(|v| v.as_str())
1115-
{
1116-
Some(access_token.to_string())
1117-
} else {
1118-
output["token_valid"] = json!(false);
1119-
if let Some(err) = token_json
1120-
.get("error_description")
1121-
.and_then(|v| v.as_str())
1122-
{
1123-
output["token_error"] = json!(err);
1124-
}
1125-
None
1126-
}
1127-
} else {
1128-
None
1129-
}
1130-
}
1131-
Err(e) => {
1132-
output["token_valid"] = json!(false);
1133-
output["token_error"] = json!(e.to_string());
1134-
None
1135-
}
1136-
}
1137-
} else {
1138-
None
1139-
}
1140-
} else {
1141-
None
1142-
}
1143-
} else {
1144-
None
1145-
}
1146-
};
1138+
let http_client = reqwest::Client::new();
1139+
let access_token = get_status_access_token(&http_client, &mut output).await;
11471140

11481141
if let Some(at) = access_token {
11491142
output["token_valid"] = json!(true);
1150-
let http_client = reqwest::Client::new();
11511143

11521144
// Get user info
11531145
if let Ok(user_resp) = http_client
@@ -1164,8 +1156,12 @@ async fn handle_status() -> Result<(), GwsError> {
11641156
}
11651157

11661158
// Get granted scopes via tokeninfo
1167-
let tokeninfo_url = format!("https://oauth2.googleapis.com/tokeninfo?access_token={}", at);
1168-
if let Ok(info_resp) = http_client.get(&tokeninfo_url).send().await {
1159+
if let Ok(info_resp) = http_client
1160+
.get("https://oauth2.googleapis.com/tokeninfo")
1161+
.query(&[("access_token", &at)])
1162+
.send()
1163+
.await
1164+
{
11691165
if let Ok(info_json) = info_resp.json::<serde_json::Value>().await {
11701166
if let Some(scope_str) = info_json.get("scope").and_then(|v| v.as_str()) {
11711167
let scopes: Vec<&str> = scope_str.split(' ').collect();
@@ -1186,6 +1182,7 @@ async fn handle_status() -> Result<(), GwsError> {
11861182
}
11871183
} // end !cfg!(test)
11881184

1185+
11891186
println!(
11901187
"{}",
11911188
serde_json::to_string_pretty(&output).unwrap_or_default()

0 commit comments

Comments
 (0)