diff --git a/crates/gpapi/src/credential.rs b/crates/gpapi/src/credential.rs index 7890283..f54e12d 100644 --- a/crates/gpapi/src/credential.rs +++ b/crates/gpapi/src/credential.rs @@ -141,6 +141,16 @@ impl CachedCredential { } } +impl From for CachedCredential { + fn from(value: PasswordCredential) -> Self { + Self::new( + value.username().to_owned(), + Some(value.password().to_owned()), + AuthCookieCredential::new("", "", ""), + ) + } +} + #[derive(Debug, Serialize, Deserialize, Type, Clone)] #[serde(tag = "type", rename_all = "camelCase")] pub enum Credential { diff --git a/crates/gpapi/src/gateway/login.rs b/crates/gpapi/src/gateway/login.rs index fe737c2..77e6170 100644 --- a/crates/gpapi/src/gateway/login.rs +++ b/crates/gpapi/src/gateway/login.rs @@ -22,11 +22,15 @@ pub async fn gateway_login( params.extend(extra_params); params.insert("server", gateway); + info!("Gateway login params {:?}", params); + info!("Gateway login, user_agent: {}", gp_params.user_agent()); let res = client.post(&login_url).form(¶ms).send().await?; let res_xml = res.error_for_status()?.text().await?; + info!("Gateway login request done"); + let doc = Document::parse(&res_xml)?; build_gateway_token(&doc, gp_params.computer()) diff --git a/crates/gpapi/src/gateway/mod.rs b/crates/gpapi/src/gateway/mod.rs index 7db09bc..ab84223 100644 --- a/crates/gpapi/src/gateway/mod.rs +++ b/crates/gpapi/src/gateway/mod.rs @@ -31,6 +31,15 @@ impl Display for Gateway { } impl Gateway { + pub fn new(name: String, address: String) -> Self { + Self { + name, + address, + priority: 0, + priority_rules: vec![], + } + } + pub fn name(&self) -> &str { &self.name } diff --git a/crates/gpapi/src/portal/config.rs b/crates/gpapi/src/portal/config.rs index 262934f..3ee14cf 100644 --- a/crates/gpapi/src/portal/config.rs +++ b/crates/gpapi/src/portal/config.rs @@ -1,15 +1,15 @@ -use anyhow::ensure; +use anyhow::bail; use log::info; -use reqwest::Client; +use reqwest::{Client, StatusCode}; use roxmltree::Document; use serde::Serialize; use specta::Type; -use thiserror::Error; use crate::{ credential::{AuthCookieCredential, Credential}, gateway::{parse_gateways, Gateway}, gp_params::GpParams, + portal::PortalError, utils::{normalize_server, xml}, }; @@ -98,12 +98,6 @@ impl PortalConfig { } } -#[derive(Error, Debug)] -pub enum PortalConfigError { - #[error("Empty response, retrying can help")] - EmptyResponse, -} - pub async fn retrieve_config( portal: &str, cred: &Credential, @@ -127,14 +121,35 @@ pub async fn retrieve_config( info!("Portal config, user_agent: {}", gp_params.user_agent()); + info!("Portal config params: {:?}", params); + let res = client.post(&url).form(¶ms).send().await?; - let res_xml = res.error_for_status()?.text().await?; + let status = res.status(); - ensure!(!res_xml.is_empty(), PortalConfigError::EmptyResponse); + if status == StatusCode::NOT_FOUND { + bail!(PortalError::ConfigError( + "Config endpoint not found".to_string() + )) + } - let doc = Document::parse(&res_xml)?; - let mut gateways = - parse_gateways(&doc).ok_or_else(|| anyhow::anyhow!("Failed to parse gateways"))?; + let res_xml = res + .error_for_status()? + .text() + .await + .map_err(|e| PortalError::ConfigError(e.to_string()))?; + + if res_xml.is_empty() { + bail!(PortalError::ConfigError( + "Empty portal config response".to_string() + )) + } + + let doc = Document::parse(&res_xml).map_err(|e| PortalError::ConfigError(e.to_string()))?; + + let mut gateways = parse_gateways(&doc).unwrap_or_else(|| { + info!("No gateways found in portal config"); + vec![] + }); let user_auth_cookie = xml::get_child_text(&doc, "portal-userauthcookie").unwrap_or_default(); let prelogon_user_auth_cookie = @@ -142,12 +157,7 @@ pub async fn retrieve_config( let config_digest = xml::get_child_text(&doc, "config-digest"); if gateways.is_empty() { - gateways.push(Gateway { - name: server.to_string(), - address: server.to_string(), - priority: 0, - priority_rules: vec![], - }); + gateways.push(Gateway::new(server.to_string(), server.to_string())); } Ok(PortalConfig::new( diff --git a/crates/gpapi/src/portal/mod.rs b/crates/gpapi/src/portal/mod.rs index 8c111db..a4194d3 100644 --- a/crates/gpapi/src/portal/mod.rs +++ b/crates/gpapi/src/portal/mod.rs @@ -3,3 +3,13 @@ mod prelogin; pub use config::*; pub use prelogin::*; + +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum PortalError { + #[error("Portal prelogin error: {0}")] + PreloginError(String), + #[error("Portal config error: {0}")] + ConfigError(String), +} diff --git a/crates/gpapi/src/portal/prelogin.rs b/crates/gpapi/src/portal/prelogin.rs index 292ffab..2a17935 100644 --- a/crates/gpapi/src/portal/prelogin.rs +++ b/crates/gpapi/src/portal/prelogin.rs @@ -1,12 +1,13 @@ use anyhow::bail; -use log::{info, trace}; -use reqwest::Client; +use log::info; +use reqwest::{Client, StatusCode}; use roxmltree::Document; use serde::Serialize; use specta::Type; use crate::{ gp_params::GpParams, + portal::PortalError, utils::{base64, normalize_server, xml}, }; @@ -118,9 +119,26 @@ pub async fn prelogin(portal: &str, gp_params: &GpParams) -> anyhow::Result anyhow::Result { let doc = Document::parse(&res_xml)?; let status = xml::get_child_text(&doc, "status")