Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 82 additions & 78 deletions src/auth_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1067,91 +1067,95 @@ async fn handle_status() -> Result<(), GwsError> {
}
} // end !cfg!(test)

// If we have credentials, try to get live info (user, scopes, APIs)
// If we have credentials or a direct token, try to get live info (user, scopes, APIs)
// Skip all network calls and subprocess spawning in test builds
if !cfg!(test) {
let creds_json_str = if has_encrypted {
credential_store::load_encrypted().ok()
} else if has_plain {
tokio::fs::read_to_string(&plain_path).await.ok()
let direct_token = std::env::var("GOOGLE_WORKSPACE_CLI_TOKEN")
.ok()
.filter(|t| !t.is_empty());

let access_token = if let Some(token) = direct_token {
Some(token)
} else {
None
};
let creds_json_str = if has_encrypted {
credential_store::load_encrypted().ok()
} else if has_plain {
tokio::fs::read_to_string(&plain_path).await.ok()
} else {
None
};

if let Some(creds_str) = creds_json_str {
if let Ok(creds) = serde_json::from_str::<serde_json::Value>(&creds_str) {
let client_id = creds.get("client_id").and_then(|v| v.as_str());
let client_secret = creds.get("client_secret").and_then(|v| v.as_str());
let refresh_token = creds.get("refresh_token").and_then(|v| v.as_str());

if let (Some(cid), Some(csec), Some(rt)) = (client_id, client_secret, refresh_token)
{
// Exchange refresh token for access token
let http_client = reqwest::Client::new();
let token_resp = http_client
.post("https://oauth2.googleapis.com/token")
.form(&[
("client_id", cid),
("client_secret", csec),
("refresh_token", rt),
("grant_type", "refresh_token"),
])
.send()
.await;

if let Ok(resp) = token_resp {
if let Ok(token_json) = resp.json::<serde_json::Value>().await {
if let Some(access_token) =
token_json.get("access_token").and_then(|v| v.as_str())
{
output["token_valid"] = json!(true);

// Get user info
if let Ok(user_resp) = http_client
.get("https://www.googleapis.com/oauth2/v1/userinfo")
.bearer_auth(access_token)
.send()
.await
{
if let Ok(user_json) =
user_resp.json::<serde_json::Value>().await
{
if let Some(email) =
user_json.get("email").and_then(|v| v.as_str())
{
output["user"] = json!(email);
}
}
}

// Get granted scopes via tokeninfo
let tokeninfo_url = format!(
"https://oauth2.googleapis.com/tokeninfo?access_token={}",
access_token
);
if let Ok(info_resp) = http_client.get(&tokeninfo_url).send().await
{
if let Ok(info_json) =
info_resp.json::<serde_json::Value>().await
{
if let Some(scope_str) =
info_json.get("scope").and_then(|v| v.as_str())
{
let scopes: Vec<&str> = scope_str.split(' ').collect();
output["scopes"] = json!(scopes);
output["scope_count"] = json!(scopes.len());
}
}
}
if let Some(creds_str) = creds_json_str {
if let Ok(creds) = serde_json::from_str::<serde_json::Value>(&creds_str) {
let client_id = creds.get("client_id").and_then(|v| v.as_str());
let client_secret = creds.get("client_secret").and_then(|v| v.as_str());
let refresh_token = creds.get("refresh_token").and_then(|v| v.as_str());

if let (Some(cid), Some(csec), Some(rt)) =
(client_id, client_secret, refresh_token)
{
// Exchange refresh token for access token
let http_client = reqwest::Client::new();
let token_resp = http_client
.post("https://oauth2.googleapis.com/token")
.form(&[
("client_id", cid),
("client_secret", csec),
("refresh_token", rt),
("grant_type", "refresh_token"),
])
.send()
.await;

if let Ok(resp) = token_resp {
if let Ok(token_json) = resp.json::<serde_json::Value>().await {
token_json
.get("access_token")
.and_then(|v| v.as_str())
.map(|s| s.to_string())
} else {
output["token_valid"] = json!(false);
if let Some(err) =
token_json.get("error_description").and_then(|v| v.as_str())
{
output["token_error"] = json!(err);
}
None
}
} else {
None
}
} else {
None
}
} else {
None
}
} else {
None
}
};

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

// Get user info
if let Ok(user_resp) = http_client
.get("https://www.googleapis.com/oauth2/v1/userinfo")
.bearer_auth(&at)
.send()
.await
{
if let Ok(user_json) = user_resp.json::<serde_json::Value>().await {
if let Some(email) = user_json.get("email").and_then(|v| v.as_str()) {
output["user"] = json!(email);
}
}
}

// Get granted scopes via tokeninfo
let tokeninfo_url = format!("https://oauth2.googleapis.com/tokeninfo?access_token={}", at);
if let Ok(info_resp) = http_client.get(&tokeninfo_url).send().await {
if let Ok(info_json) = info_resp.json::<serde_json::Value>().await {
if let Some(scope_str) = info_json.get("scope").and_then(|v| v.as_str()) {
let scopes: Vec<&str> = scope_str.split(' ').collect();
output["scopes"] = json!(scopes);
output["scope_count"] = json!(scopes.len());
}
}
}
Expand Down
Loading