pub struct Auth { pub app: std::sync::Arc, } impl Auth { pub async fn get_token(&self) -> Result { let client = reqwest::Client::new(); let endpoint = String::from("api/v1/service/login"); let api_url = format!("{}/{endpoint}", self.app.auth_url); println!("Url: {api_url:?}"); let payload = serde_json::json!({ "username": &self.app.service_username, "passphrase": &self.app.service_passphrase, }); println!("Payload: {payload:?}"); match client.post(api_url).json(&payload).send().await { Ok(response) => match response.status() { reqwest::StatusCode::OK => { println!("Response: {response:?}"); match response.text().await { Ok(val) => match parse_token_response(&val).await { Ok(login_result) => Ok(login_result), Err(err) => Err(err), }, Err(err) => Err(std::io::Error::other(err)), } } _ => Err(std::io::Error::other("Error getting token")), }, Err(err) => Err(std::io::Error::other(err.to_string())), } } pub async fn get_refresh_token( &self, login_result: &textsender_models::token::Login, ) -> Result { let client = reqwest::Client::new(); let endpoint = String::from("api/v1/token/refresh"); let api_url = format!("{}/{endpoint}", self.app.auth_url); println!("Url: {api_url:?}"); let payload = serde_json::json!({ "access_token": login_result.access_token }); match client.post(api_url).json(&payload).send().await { Ok(response) => match response.status() { reqwest::StatusCode::OK => { println!("Response: {response:?}"); match response.text().await { Ok(val) => match parse_token_response(&val).await { Ok(login_result) => Ok(login_result), Err(err) => Err(err), }, Err(err) => Err(std::io::Error::other(err)), } } _ => Err(std::io::Error::other("Error getting token")), }, Err(err) => Err(std::io::Error::other(err.to_string())), } } } async fn parse_token_response( response: &str, ) -> Result { match serde_json::from_str::(response) { Ok(j) => { println!("Good"); let message = &j["message"]; let data = &j["data"]; println!("Message: {message:?}"); println!("Data: {data:?}"); match j.get("data") { Some(serde_json::Value::Array(lrs)) => { if lrs.is_empty() { Err(std::io::Error::other("Error response is empty")) } else { let lr = lrs[0].clone(); let ll: textsender_models::token::LoginResult = match serde_json::from_value(lr) { Ok(lr) => lr, Err(err) => { return Err(std::io::Error::other(err.to_string())); } }; Ok(ll) } } _ => Err(std::io::Error::other("Error parsing response")), } } Err(err) => Err(std::io::Error::other(err.to_string())), } } pub async fn has_token_expired(token: &textsender_models::token::LoginResult) -> bool { let now = time::OffsetDateTime::now_utc(); let expire = match time::OffsetDateTime::from_unix_timestamp(token.expires_in) { Ok(res) => res, Err(err) => { eprintln!("Error: {err:?}"); return false; } }; now > expire }