Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send login/logout request without checking status #6

Merged
merged 3 commits into from
Dec 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 4 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,8 @@ pub struct ClientArgs {
/// Optionally provide path to the config file
#[arg(short, long)]
pub config: Option<String>,

/// Force login/logout, don't check login status
#[arg(short, long)]
pub force: bool,
}
48 changes: 38 additions & 10 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub struct SrunLoginState {
}

/// Get the login state of the current device
pub async fn get_login_state(client: &Client) -> Result<SrunLoginState> {
pub async fn get_login_state(client: &Client, verbose: bool) -> Result<SrunLoginState> {
// 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);
Expand All @@ -103,13 +103,21 @@ pub async fn get_login_state(client: &Client) -> Result<SrunLoginState> {
.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::<SrunLoginState>(raw_json).with_context(|| {
format!(
"failed to parse malformed login status response:\n {}",
Expand Down Expand Up @@ -210,7 +218,7 @@ impl SrunClient {
) -> Result<SrunClient> {
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);
let dm = dm.unwrap_or(false);
Ok(SrunClient {
Expand All @@ -225,9 +233,9 @@ impl SrunClient {
}

/// Login to the SRUN portal
pub async fn login(&self) -> Result<SrunPortalResponse> {
pub async fn login(&self, force: bool, verbose: bool) -> Result<SrunPortalResponse> {
// 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
Expand Down Expand Up @@ -292,6 +300,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)
}
Expand All @@ -301,9 +317,9 @@ impl SrunClient {
}

/// Logout of the SRUN portal
pub async fn logout(&self) -> Result<SrunPortalResponse> {
pub async fn logout(&self, force: bool, verbose: bool) -> Result<SrunPortalResponse> {
// 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
Expand Down Expand Up @@ -386,6 +402,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::<SrunPortalResponse>(raw_json)
.with_context(|| format!("failed to parse malformed logout response:\n {}", raw_json))
Expand Down
74 changes: 30 additions & 44 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,39 +41,43 @@ 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())
);
}
}
}

Expand All @@ -98,7 +102,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",
Expand All @@ -116,17 +120,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" | "logout_ok" => println!(
"{} {} logged out",
Expand All @@ -142,15 +137,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
);
}
}
}

Expand Down