From e70737287c37e0325dce3f8adfc0d60c62ac936f Mon Sep 17 00:00:00 2001 From: spencerwooo Date: Sun, 3 Dec 2023 15:48:04 +0800 Subject: [PATCH 1/2] force login or logout requests without checks --- src/cli.rs | 4 +++ src/client.rs | 48 ++++++++++++++++++++++++++------- src/main.rs | 75 +++++++++++++++++++++------------------------------ 3 files changed, 73 insertions(+), 54 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 2cb67de..d480307 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -54,4 +54,8 @@ pub struct ClientArgs { /// Optionally provide path to the config file #[arg(short, long)] pub config: Option, + + /// Force login/logout, don't check login status + #[arg(short, long)] + pub force: bool, } diff --git a/src/client.rs b/src/client.rs index 7c44cd8..619120a 100644 --- a/src/client.rs +++ b/src/client.rs @@ -91,7 +91,7 @@ pub struct SrunLoginState { } /// Get the login state of the current device -pub async fn get_login_state(client: &Client) -> Result { +pub async fn get_login_state(client: &Client, verbose: bool) -> Result { // call /rad_user_info with callback=jsonp to get the login state let params = [("callback", "jsonp")]; let url = format!("{}/cgi-bin/rad_user_info", SRUN_PORTAL); @@ -103,13 +103,21 @@ pub async fn get_login_state(client: &Client) -> Result { .send() .await .with_context(|| "failed to get login state")?; - let text = resp.text().await?; + let raw_text = resp.text().await?; + + if verbose { + println!( + "{} response from portal:\n{}", + "bitsrun:".if_supports_color(Stdout, |t| t.blue()), + raw_text + ); + } // valid json starts at index 6 and ends at the second to last character - if text.len() < 8 { - bail!("login status response too short: `{}`", text) + if raw_text.len() < 8 { + bail!("login status response too short: `{}`", raw_text) } - let raw_json = &text[6..text.len() - 1]; + let raw_json = &raw_text[6..raw_text.len() - 1]; let parsed_json = serde_json::from_str::(raw_json).with_context(|| { format!( "failed to parse malformed login status response:\n {}", @@ -206,7 +214,7 @@ impl SrunClient { ) -> Result { let http_client = http_client.unwrap_or_default(); let ac_id = get_acid(&http_client).await?; - let login_state = get_login_state(&http_client).await?; + let login_state = get_login_state(&http_client, false).await?; let ip = ip.unwrap_or(login_state.online_ip); Ok(SrunClient { http_client, @@ -219,9 +227,9 @@ impl SrunClient { } /// Login to the SRUN portal - pub async fn login(&self) -> Result { + pub async fn login(&self, force: bool, verbose: bool) -> Result { // check if already logged in - if self.login_state.error == "ok" { + if (self.login_state.error == "ok") & !force { bail!( "{} already logged in", self.login_state @@ -286,6 +294,14 @@ impl SrunClient { .with_context(|| "failed to send request when logging in")?; let raw_text = resp.text().await?; + if verbose { + println!( + "{} response from portal:\n{}", + "bitsrun:".if_supports_color(Stdout, |t| t.blue()), + raw_text + ); + } + if raw_text.len() < 8 { bail!("login response too short: `{}`", raw_text) } @@ -295,9 +311,9 @@ impl SrunClient { } /// Logout of the SRUN portal - pub async fn logout(&self) -> Result { + pub async fn logout(&self, force: bool, verbose: bool) -> Result { // check if already logged out - if self.login_state.error == "not_online_error" { + if (self.login_state.error == "not_online_error") & !force { bail!( "{} already logged out", self.ip @@ -350,6 +366,18 @@ impl SrunClient { .await .with_context(|| "failed to send request when logging out")?; let raw_text = resp.text().await?; + + if verbose { + println!( + "{} response from portal:\n{}", + "bitsrun:".if_supports_color(Stdout, |t| t.blue()), + raw_text + ); + } + + if raw_text.len() < 8 { + bail!("login response too short: `{}`", raw_text) + } let raw_json = &raw_text[6..raw_text.len() - 1]; serde_json::from_str::(raw_json) .with_context(|| format!("failed to parse malformed logout response:\n {}", raw_json)) diff --git a/src/main.rs b/src/main.rs index aab92a6..f90d6e9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,39 +41,44 @@ async fn cli() -> Result<()> { match &args.command { // check login status Some(Commands::Status(status_args)) => { - let login_state = get_login_state(&http_client).await?; + // only verbose on args.verbose = true and not outputting json + let login_state = + get_login_state(&http_client, args.verbose).await?; // output json - if status_args.json { + if status_args.json & !args.verbose { let raw_json = serde_json::to_string(&login_state)?; println!("{}", raw_json); return Ok(()); } // output human readable - if login_state.error == "ok" { - println!( - "{} {} {} is online", - "bitsrun:".if_supports_color(Stdout, |t| t.bright_green()), - &login_state - .online_ip - .to_string() - .if_supports_color(Stdout, |t| t.underline()), - format!("({})", login_state.user_name.clone().unwrap_or_default()) - .if_supports_color(Stdout, |t| t.dimmed()) - ); + match login_state.error.as_str() { + "ok" => { + println!( + "{} {} {} is online", + "bitsrun:".if_supports_color(Stdout, |t| t.bright_green()), + &login_state + .online_ip + .to_string() + .if_supports_color(Stdout, |t| t.underline()), + format!("({})", login_state.user_name.clone().unwrap_or_default()) + .if_supports_color(Stdout, |t| t.dimmed()) + ); - // print status table - print_login_state(login_state); - } else { - println!( - "{} {} is offline", - "bitsrun:".if_supports_color(Stdout, |t| t.blue()), - login_state - .online_ip - .to_string() - .if_supports_color(Stdout, |t| t.underline()) - ); + // print status table + print_login_state(login_state); + } + _ => { + println!( + "{} {} is offline", + "bitsrun:".if_supports_color(Stdout, |t| t.blue()), + login_state + .online_ip + .to_string() + .if_supports_color(Stdout, |t| t.underline()) + ); + } } } @@ -96,7 +101,7 @@ async fn cli() -> Result<()> { .await?; if matches!(args.command, Some(Commands::Login(_))) { - let resp = srun_client.login().await?; + let resp = srun_client.login(client_args.force, args.verbose).await?; match resp.error.as_str() { "ok" => println!( "{} {} {} logged in", @@ -114,17 +119,8 @@ async fn cli() -> Result<()> { format!("({})", resp.error_msg).if_supports_color(Stdout, |t| t.dimmed()) ), } - - if args.verbose { - let pretty_json = serde_json::to_string_pretty(&resp)?; - println!( - "{} response from API\n{}", - "bitsrun:".if_supports_color(Stdout, |t| t.blue()), - pretty_json - ); - } } else if matches!(args.command, Some(Commands::Logout(_))) { - let resp = srun_client.logout().await?; + let resp = srun_client.logout(client_args.force, args.verbose).await?; match resp.error.as_str() { "ok" => println!( "{} {} logged out", @@ -140,15 +136,6 @@ async fn cli() -> Result<()> { format!("({})", resp.error_msg).if_supports_color(Stdout, |t| t.dimmed()) ), } - - if args.verbose { - let pretty_json = serde_json::to_string_pretty(&resp)?; - println!( - "{} response from API\n{}", - "bitsrun:".if_supports_color(Stdout, |t| t.blue()), - pretty_json - ); - } } } From 6477f426bfca487647a0af8f228a568df3489eee Mon Sep 17 00:00:00 2001 From: spencerwooo Date: Sun, 3 Dec 2023 15:55:54 +0800 Subject: [PATCH 2/2] fix formatting --- src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index c174113..96b25ef 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,8 +42,7 @@ async fn cli() -> Result<()> { // check login status Some(Commands::Status(status_args)) => { // only verbose on args.verbose = true and not outputting json - let login_state = - get_login_state(&http_client, args.verbose).await?; + let login_state = get_login_state(&http_client, args.verbose).await?; // output json if status_args.json & !args.verbose {