@@ -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+
926991async 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