Refactor using Tauri (#278)

This commit is contained in:
Kevin Yue
2024-01-16 22:18:20 +08:00
committed by GitHub
parent edc13ed14d
commit 04a916a3e1
199 changed files with 10153 additions and 7203 deletions

View File

@@ -0,0 +1,74 @@
use log::info;
use reqwest::Client;
use roxmltree::Document;
use urlencoding::encode;
use crate::{credential::Credential, gp_params::GpParams};
pub async fn gateway_login(
gateway: &str,
cred: &Credential,
gp_params: &GpParams,
) -> anyhow::Result<String> {
let login_url = format!("https://{}/ssl-vpn/login.esp", gateway);
let client = Client::builder()
.user_agent(gp_params.user_agent())
.build()?;
let mut params = cred.to_params();
let extra_params = gp_params.to_params();
params.extend(extra_params);
params.insert("server", gateway);
info!("Gateway login, user_agent: {}", gp_params.user_agent());
let res_xml = client
.post(&login_url)
.form(&params)
.send()
.await?
.error_for_status()?
.text()
.await?;
let doc = Document::parse(&res_xml)?;
build_gateway_token(&doc, gp_params.computer())
}
fn build_gateway_token(doc: &Document, computer: &str) -> anyhow::Result<String> {
let args = doc
.descendants()
.filter(|n| n.has_tag_name("argument"))
.map(|n| n.text().unwrap_or("").to_string())
.collect::<Vec<_>>();
let params = [
read_args(&args, 1, "authcookie")?,
read_args(&args, 3, "portal")?,
read_args(&args, 4, "user")?,
read_args(&args, 7, "domain")?,
read_args(&args, 15, "preferred-ip")?,
("computer", computer),
];
let token = params
.iter()
.map(|(k, v)| format!("{}={}", k, encode(v)))
.collect::<Vec<_>>()
.join("&");
Ok(token)
}
fn read_args<'a>(
args: &'a [String],
index: usize,
key: &'a str,
) -> anyhow::Result<(&'a str, &'a str)> {
args
.get(index)
.ok_or_else(|| anyhow::anyhow!("Failed to read {key} from args"))
.map(|s| (key, s.as_ref()))
}

View File

@@ -0,0 +1,41 @@
mod login;
mod parse_gateways;
pub use login::*;
pub(crate) use parse_gateways::*;
use serde::{Deserialize, Serialize};
use specta::Type;
use std::fmt::Display;
#[derive(Debug, Serialize, Deserialize, Type, Clone)]
pub(crate) struct PriorityRule {
pub(crate) name: String,
pub(crate) priority: u32,
}
#[derive(Debug, Serialize, Deserialize, Type, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Gateway {
pub(crate) name: String,
pub(crate) address: String,
pub(crate) priority: u32,
pub(crate) priority_rules: Vec<PriorityRule>,
}
impl Display for Gateway {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} ({})", self.name, self.address)
}
}
impl Gateway {
pub fn name(&self) -> &str {
&self.name
}
pub fn server(&self) -> &str {
&self.address
}
}

View File

@@ -0,0 +1,63 @@
use roxmltree::Document;
use super::{Gateway, PriorityRule};
pub(crate) fn parse_gateways(doc: &Document) -> Option<Vec<Gateway>> {
let node_gateways = doc.descendants().find(|n| n.has_tag_name("gateways"))?;
let list_gateway = node_gateways
.descendants()
.find(|n| n.has_tag_name("list"))?;
let gateways = list_gateway
.children()
.filter_map(|gateway_item| {
if !gateway_item.has_tag_name("entry") {
return None;
}
let address = gateway_item.attribute("name").unwrap_or("").to_string();
let name = gateway_item
.children()
.find(|n| n.has_tag_name("description"))
.and_then(|n| n.text())
.unwrap_or("")
.to_string();
let priority = gateway_item
.children()
.find(|n| n.has_tag_name("priority"))
.and_then(|n| n.text())
.and_then(|s| s.parse().ok())
.unwrap_or(u32::MAX);
let priority_rules = gateway_item
.children()
.find(|n| n.has_tag_name("priority-rule"))
.map(|n| {
n.children()
.filter_map(|n| {
if !n.has_tag_name("entry") {
return None;
}
let name = n.attribute("name").unwrap_or("").to_string();
let priority: u32 = n
.children()
.find(|n| n.has_tag_name("priority"))
.and_then(|n| n.text())
.and_then(|s| s.parse().ok())
.unwrap_or(u32::MAX);
Some(PriorityRule { name, priority })
})
.collect()
})
.unwrap_or_default();
Some(Gateway {
name,
address,
priority,
priority_rules,
})
})
.collect();
Some(gateways)
}